blob: b007e68fa10c01631e4295b5492b0c2519a06bcf [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhang375a8642016-01-11 11:59:17 -08007#include <algorithm>
8
Tom Sepez5fc239a2016-03-10 14:10:38 -08009#include "core/include/fpdfapi/cpdf_array.h"
Tom Sepez310438f2016-03-08 13:10:55 -080010#include "core/include/fpdfapi/cpdf_document.h"
Tom Sepez5fc239a2016-03-10 14:10:38 -080011#include "core/include/fpdfapi/cpdf_number.h"
Dan Sinclair10cfea12015-11-16 13:09:00 -050012#include "core/include/fxcrt/fx_ext.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080013#include "fpdfsdk/include/fsdk_baseannot.h"
14#include "fpdfsdk/include/fsdk_define.h"
15#include "fpdfsdk/include/fsdk_mgr.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070016
Tom Sepez40e9ff32015-11-30 12:39:54 -080017#ifdef PDF_ENABLE_XFA
18#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
19#endif // PDF_ENABLE_XFA
20
Lei Zhang4467dea2016-02-25 12:39:15 -080021int gAfxGetTimeZoneInSeconds(int8_t tzhour, uint8_t tzminute) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070022 return (int)tzhour * 3600 + (int)tzminute * (tzhour >= 0 ? 60 : -60);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070023}
24
Nico Weber9d8ec5a2015-08-04 13:00:21 -070025FX_BOOL _gAfxIsLeapYear(int16_t year) {
26 return ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070027}
28
Nico Weber9d8ec5a2015-08-04 13:00:21 -070029FX_WORD _gAfxGetYearDays(int16_t year) {
30 return (_gAfxIsLeapYear(year) == TRUE ? 366 : 365);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070031}
32
Nico Weber9d8ec5a2015-08-04 13:00:21 -070033uint8_t _gAfxGetMonthDays(int16_t year, uint8_t month) {
34 uint8_t mDays;
35 switch (month) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -070036 case 1:
37 case 3:
38 case 5:
39 case 7:
40 case 8:
41 case 10:
42 case 12:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070043 mDays = 31;
44 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070045
Tom Sepez2f2ffec2015-07-23 14:42:09 -070046 case 4:
47 case 6:
48 case 9:
49 case 11:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070050 mDays = 30;
51 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070052
Tom Sepez2f2ffec2015-07-23 14:42:09 -070053 case 2:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070054 if (_gAfxIsLeapYear(year) == TRUE)
55 mDays = 29;
56 else
57 mDays = 28;
58 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070059
Tom Sepez2f2ffec2015-07-23 14:42:09 -070060 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070061 mDays = 0;
62 break;
63 }
64
65 return mDays;
66}
67
68CPDFSDK_DateTime::CPDFSDK_DateTime() {
69 ResetDateTime();
70}
71
72CPDFSDK_DateTime::CPDFSDK_DateTime(const CFX_ByteString& dtStr) {
73 ResetDateTime();
74
75 FromPDFDateTimeString(dtStr);
76}
77
78CPDFSDK_DateTime::CPDFSDK_DateTime(const CPDFSDK_DateTime& datetime) {
79 operator=(datetime);
80}
81
82CPDFSDK_DateTime::CPDFSDK_DateTime(const FX_SYSTEMTIME& st) {
83 operator=(st);
84}
85
86void CPDFSDK_DateTime::ResetDateTime() {
87 tzset();
88
89 time_t curTime;
90 time(&curTime);
Tom Sepez007e6c02016-02-26 14:31:56 -080091 struct tm* newtime = localtime(&curTime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092
93 dt.year = newtime->tm_year + 1900;
94 dt.month = newtime->tm_mon + 1;
95 dt.day = newtime->tm_mday;
96 dt.hour = newtime->tm_hour;
97 dt.minute = newtime->tm_min;
98 dt.second = newtime->tm_sec;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070099}
100
101CPDFSDK_DateTime& CPDFSDK_DateTime::operator=(
102 const CPDFSDK_DateTime& datetime) {
103 FXSYS_memcpy(&dt, &datetime.dt, sizeof(FX_DATETIME));
104 return *this;
105}
106
107CPDFSDK_DateTime& CPDFSDK_DateTime::operator=(const FX_SYSTEMTIME& st) {
108 tzset();
109
110 dt.year = (int16_t)st.wYear;
111 dt.month = (uint8_t)st.wMonth;
112 dt.day = (uint8_t)st.wDay;
113 dt.hour = (uint8_t)st.wHour;
114 dt.minute = (uint8_t)st.wMinute;
115 dt.second = (uint8_t)st.wSecond;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700116 return *this;
117}
118
Tom Sepez007e6c02016-02-26 14:31:56 -0800119bool CPDFSDK_DateTime::operator==(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700120 return (FXSYS_memcmp(&dt, &datetime.dt, sizeof(FX_DATETIME)) == 0);
121}
122
Tom Sepez007e6c02016-02-26 14:31:56 -0800123bool CPDFSDK_DateTime::operator!=(const CPDFSDK_DateTime& datetime) const {
124 return !(*this == datetime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700125}
126
Tom Sepez007e6c02016-02-26 14:31:56 -0800127bool CPDFSDK_DateTime::operator>(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128 CPDFSDK_DateTime dt1 = ToGMT();
129 CPDFSDK_DateTime dt2 = datetime.ToGMT();
130 int d1 =
131 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
132 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
133 (int)dt1.dt.second;
134 int d3 =
135 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
136 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
137 (int)dt2.dt.second;
138
Tom Sepez007e6c02016-02-26 14:31:56 -0800139 return d1 > d3 || d2 > d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140}
141
Tom Sepez007e6c02016-02-26 14:31:56 -0800142bool CPDFSDK_DateTime::operator>=(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700143 CPDFSDK_DateTime dt1 = ToGMT();
144 CPDFSDK_DateTime dt2 = datetime.ToGMT();
145 int d1 =
146 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
147 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
148 (int)dt1.dt.second;
149 int d3 =
150 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
151 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
152 (int)dt2.dt.second;
153
Tom Sepez007e6c02016-02-26 14:31:56 -0800154 return d1 >= d3 || d2 >= d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700155}
156
Tom Sepez007e6c02016-02-26 14:31:56 -0800157bool CPDFSDK_DateTime::operator<(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700158 CPDFSDK_DateTime dt1 = ToGMT();
159 CPDFSDK_DateTime dt2 = datetime.ToGMT();
160 int d1 =
161 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
162 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
163 (int)dt1.dt.second;
164 int d3 =
165 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
166 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
167 (int)dt2.dt.second;
168
Tom Sepez007e6c02016-02-26 14:31:56 -0800169 return d1 < d3 || d2 < d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700170}
171
Tom Sepez007e6c02016-02-26 14:31:56 -0800172bool CPDFSDK_DateTime::operator<=(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 CPDFSDK_DateTime dt1 = ToGMT();
174 CPDFSDK_DateTime dt2 = datetime.ToGMT();
175 int d1 =
176 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
177 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
178 (int)dt1.dt.second;
179 int d3 =
180 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
181 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
182 (int)dt2.dt.second;
183
Tom Sepez007e6c02016-02-26 14:31:56 -0800184 return d1 <= d3 || d2 <= d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185}
186
187CPDFSDK_DateTime::operator time_t() {
188 struct tm newtime;
189
190 newtime.tm_year = dt.year - 1900;
191 newtime.tm_mon = dt.month - 1;
192 newtime.tm_mday = dt.day;
193 newtime.tm_hour = dt.hour;
194 newtime.tm_min = dt.minute;
195 newtime.tm_sec = dt.second;
196
197 return mktime(&newtime);
198}
199
200CPDFSDK_DateTime& CPDFSDK_DateTime::FromPDFDateTimeString(
201 const CFX_ByteString& dtStr) {
202 int strLength = dtStr.GetLength();
203 if (strLength > 0) {
204 int i = 0;
205 int j, k;
206 FX_CHAR ch;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500207 while (i < strLength && !std::isdigit(dtStr[i]))
208 ++i;
209
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210 if (i >= strLength)
211 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700212
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213 j = 0;
214 k = 0;
215 while (i < strLength && j < 4) {
216 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500217 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700218 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500219 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220 break;
221 i++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700222 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700223 dt.year = (int16_t)k;
224 if (i >= strLength || j < 4)
225 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700226
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700227 j = 0;
228 k = 0;
229 while (i < strLength && j < 2) {
230 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500231 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700232 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500233 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700234 break;
235 i++;
236 }
237 dt.month = (uint8_t)k;
238 if (i >= strLength || j < 2)
239 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700240
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241 j = 0;
242 k = 0;
243 while (i < strLength && j < 2) {
244 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500245 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500247 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700248 break;
249 i++;
250 }
251 dt.day = (uint8_t)k;
252 if (i >= strLength || j < 2)
253 return *this;
254
255 j = 0;
256 k = 0;
257 while (i < strLength && j < 2) {
258 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500259 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500261 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700262 break;
263 i++;
264 }
265 dt.hour = (uint8_t)k;
266 if (i >= strLength || j < 2)
267 return *this;
268
269 j = 0;
270 k = 0;
271 while (i < strLength && j < 2) {
272 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500273 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700274 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500275 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276 break;
277 i++;
278 }
279 dt.minute = (uint8_t)k;
280 if (i >= strLength || j < 2)
281 return *this;
282
283 j = 0;
284 k = 0;
285 while (i < strLength && j < 2) {
286 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500287 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700288 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500289 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700290 break;
291 i++;
292 }
293 dt.second = (uint8_t)k;
294 if (i >= strLength || j < 2)
295 return *this;
296
297 ch = dtStr[i++];
298 if (ch != '-' && ch != '+')
299 return *this;
300 if (ch == '-')
301 dt.tzHour = -1;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700302 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700303 dt.tzHour = 1;
304 j = 0;
305 k = 0;
306 while (i < strLength && j < 2) {
307 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500308 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700309 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500310 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700311 break;
312 i++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700313 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700314 dt.tzHour *= (FX_CHAR)k;
315 if (i >= strLength || j < 2)
316 return *this;
317
318 ch = dtStr[i++];
319 if (ch != '\'')
320 return *this;
321 j = 0;
322 k = 0;
323 while (i < strLength && j < 2) {
324 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500325 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700326 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500327 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700328 break;
329 i++;
330 }
331 dt.tzMinute = (uint8_t)k;
332 if (i >= strLength || j < 2)
333 return *this;
334 }
335
336 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700337}
338
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700339CFX_ByteString CPDFSDK_DateTime::ToCommonDateTimeString() {
340 CFX_ByteString str1;
341 str1.Format("%04d-%02d-%02d %02d:%02d:%02d ", dt.year, dt.month, dt.day,
342 dt.hour, dt.minute, dt.second);
343 if (dt.tzHour < 0)
344 str1 += "-";
345 else
346 str1 += "+";
347 CFX_ByteString str2;
348 str2.Format("%02d:%02d", abs(dt.tzHour), dt.tzMinute);
349 return str1 + str2;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700350}
351
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700352CFX_ByteString CPDFSDK_DateTime::ToPDFDateTimeString() {
353 CFX_ByteString dtStr;
354 char tempStr[32];
355 memset(tempStr, 0, sizeof(tempStr));
356 FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "D:%04d%02d%02d%02d%02d%02d",
357 dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
358 dtStr = CFX_ByteString(tempStr);
359 if (dt.tzHour < 0)
360 dtStr += CFX_ByteString("-");
361 else
362 dtStr += CFX_ByteString("+");
363 memset(tempStr, 0, sizeof(tempStr));
364 FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "%02d'%02d'", abs(dt.tzHour),
365 dt.tzMinute);
366 dtStr += CFX_ByteString(tempStr);
367 return dtStr;
368}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700369
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700370void CPDFSDK_DateTime::ToSystemTime(FX_SYSTEMTIME& st) {
371 CPDFSDK_DateTime dt = *this;
372 time_t t = (time_t)dt;
373 struct tm* pTime = localtime(&t);
374 if (pTime) {
375 st.wYear = (FX_WORD)pTime->tm_year + 1900;
376 st.wMonth = (FX_WORD)pTime->tm_mon + 1;
377 st.wDay = (FX_WORD)pTime->tm_mday;
378 st.wDayOfWeek = (FX_WORD)pTime->tm_wday;
379 st.wHour = (FX_WORD)pTime->tm_hour;
380 st.wMinute = (FX_WORD)pTime->tm_min;
381 st.wSecond = (FX_WORD)pTime->tm_sec;
382 st.wMilliseconds = 0;
383 }
384}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700385
Tom Sepez007e6c02016-02-26 14:31:56 -0800386CPDFSDK_DateTime CPDFSDK_DateTime::ToGMT() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700387 CPDFSDK_DateTime dt = *this;
Lei Zhang4467dea2016-02-25 12:39:15 -0800388 dt.AddSeconds(-gAfxGetTimeZoneInSeconds(dt.dt.tzHour, dt.dt.tzMinute));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700389 dt.dt.tzHour = 0;
390 dt.dt.tzMinute = 0;
391 return dt;
392}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700393
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700394CPDFSDK_DateTime& CPDFSDK_DateTime::AddDays(short days) {
395 if (days == 0)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700396 return *this;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700397
398 int16_t y = dt.year, yy;
399 uint8_t m = dt.month;
400 uint8_t d = dt.day;
401 int mdays, ydays, ldays;
402
403 ldays = days;
404 if (ldays > 0) {
405 yy = y;
406 if (((FX_WORD)m * 100 + d) > 300)
407 yy++;
408 ydays = _gAfxGetYearDays(yy);
409 while (ldays >= ydays) {
410 y++;
411 ldays -= ydays;
412 yy++;
413 mdays = _gAfxGetMonthDays(y, m);
414 if (d > mdays) {
415 m++;
416 d -= mdays;
417 }
418 ydays = _gAfxGetYearDays(yy);
419 }
420 mdays = _gAfxGetMonthDays(y, m) - d + 1;
421 while (ldays >= mdays) {
422 ldays -= mdays;
423 m++;
424 d = 1;
425 mdays = _gAfxGetMonthDays(y, m);
426 }
427 d += ldays;
428 } else {
429 ldays *= -1;
430 yy = y;
431 if (((FX_WORD)m * 100 + d) < 300)
432 yy--;
433 ydays = _gAfxGetYearDays(yy);
434 while (ldays >= ydays) {
435 y--;
436 ldays -= ydays;
437 yy--;
438 mdays = _gAfxGetMonthDays(y, m);
439 if (d > mdays) {
440 m++;
441 d -= mdays;
442 }
443 ydays = _gAfxGetYearDays(yy);
444 }
445 while (ldays >= d) {
446 ldays -= d;
447 m--;
448 mdays = _gAfxGetMonthDays(y, m);
449 d = mdays;
450 }
451 d -= ldays;
452 }
453
454 dt.year = y;
455 dt.month = m;
456 dt.day = d;
457
458 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700459}
460
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700461CPDFSDK_DateTime& CPDFSDK_DateTime::AddSeconds(int seconds) {
462 if (seconds == 0)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700463 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700464
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700465 int n;
466 int days;
467
468 n = dt.hour * 3600 + dt.minute * 60 + dt.second + seconds;
469 if (n < 0) {
470 days = (n - 86399) / 86400;
471 n -= days * 86400;
472 } else {
473 days = n / 86400;
474 n %= 86400;
475 }
476 dt.hour = (uint8_t)(n / 3600);
477 dt.hour %= 24;
478 n %= 3600;
479 dt.minute = (uint8_t)(n / 60);
480 dt.second = (uint8_t)(n % 60);
481 if (days != 0)
482 AddDays(days);
483
484 return *this;
485}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700486
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700487CPDFSDK_Annot::CPDFSDK_Annot(CPDFSDK_PageView* pPageView)
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500488 : m_pPageView(pPageView), m_bSelected(FALSE), m_nTabOrder(-1) {
489}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700490
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700491CPDFSDK_BAAnnot::CPDFSDK_BAAnnot(CPDF_Annot* pAnnot,
492 CPDFSDK_PageView* pPageView)
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500493 : CPDFSDK_Annot(pPageView), m_pAnnot(pAnnot) {
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700494}
495
Tom Sepez3343d142015-11-02 09:54:54 -0800496CPDF_Annot* CPDFSDK_BAAnnot::GetPDFAnnot() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700497 return m_pAnnot;
Bo Xufdc00a72014-10-28 23:03:33 -0700498}
499
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700500FX_BOOL CPDFSDK_Annot::IsSelected() {
501 return m_bSelected;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700502}
503
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700504void CPDFSDK_Annot::SetSelected(FX_BOOL bSelected) {
505 m_bSelected = bSelected;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700506}
507
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700508// Tab Order
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700509int CPDFSDK_Annot::GetTabOrder() {
510 return m_nTabOrder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700511}
512
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700513void CPDFSDK_Annot::SetTabOrder(int iTabOrder) {
514 m_nTabOrder = iTabOrder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700515}
516
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700517CPDF_Dictionary* CPDFSDK_BAAnnot::GetAnnotDict() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700518 return m_pAnnot->GetAnnotDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700519}
520
Tom Sepez281a9ea2016-02-26 14:24:28 -0800521void CPDFSDK_BAAnnot::SetRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700522 ASSERT(rect.right - rect.left >= GetMinWidth());
523 ASSERT(rect.top - rect.bottom >= GetMinHeight());
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700524
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700525 m_pAnnot->GetAnnotDict()->SetAtRect("Rect", rect);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700526}
527
Tom Sepez281a9ea2016-02-26 14:24:28 -0800528CFX_FloatRect CPDFSDK_BAAnnot::GetRect() const {
529 CFX_FloatRect rect;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700530 m_pAnnot->GetRect(rect);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700531 return rect;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700532}
533
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700534CFX_ByteString CPDFSDK_BAAnnot::GetType() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700535 return m_pAnnot->GetSubType();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700536}
537
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700538CFX_ByteString CPDFSDK_BAAnnot::GetSubType() const {
539 return "";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700540}
541
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700542void CPDFSDK_BAAnnot::DrawAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800543 const CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700544 CPDF_Annot::AppearanceMode mode,
545 const CPDF_RenderOptions* pOptions) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700546 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
547 mode, pOptions);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700548}
549
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700550FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid() {
Wei Li9b761132016-01-29 15:44:20 -0800551 return m_pAnnot->GetAnnotDict()->GetDictBy("AP") != NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700552}
553
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700554FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode) {
Wei Li9b761132016-01-29 15:44:20 -0800555 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
Lei Zhang412e9082015-12-14 18:34:00 -0800556 if (!pAP)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700557 return FALSE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700558
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700559 // Choose the right sub-ap
560 const FX_CHAR* ap_entry = "N";
561 if (mode == CPDF_Annot::Down)
562 ap_entry = "D";
563 else if (mode == CPDF_Annot::Rollover)
564 ap_entry = "R";
565 if (!pAP->KeyExist(ap_entry))
566 ap_entry = "N";
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700567
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700568 // Get the AP stream or subdirectory
569 CPDF_Object* psub = pAP->GetElementValue(ap_entry);
Lei Zhang412e9082015-12-14 18:34:00 -0800570 return !!psub;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700571}
572
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700573void CPDFSDK_BAAnnot::DrawBorder(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800574 const CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700575 const CPDF_RenderOptions* pOptions) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700576 m_pAnnot->DrawBorder(pDevice, pUser2Device, pOptions);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700577}
578
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700579void CPDFSDK_BAAnnot::ClearCachedAP() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700580 m_pAnnot->ClearCachedAP();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700581}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700582
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700583void CPDFSDK_BAAnnot::SetContents(const CFX_WideString& sContents) {
584 if (sContents.IsEmpty())
585 m_pAnnot->GetAnnotDict()->RemoveAt("Contents");
586 else
587 m_pAnnot->GetAnnotDict()->SetAtString("Contents",
588 PDF_EncodeText(sContents));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700589}
590
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700591CFX_WideString CPDFSDK_BAAnnot::GetContents() const {
Wei Li9b761132016-01-29 15:44:20 -0800592 return m_pAnnot->GetAnnotDict()->GetUnicodeTextBy("Contents");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700593}
594
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700595void CPDFSDK_BAAnnot::SetAnnotName(const CFX_WideString& sName) {
596 if (sName.IsEmpty())
597 m_pAnnot->GetAnnotDict()->RemoveAt("NM");
598 else
599 m_pAnnot->GetAnnotDict()->SetAtString("NM", PDF_EncodeText(sName));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700600}
601
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700602CFX_WideString CPDFSDK_BAAnnot::GetAnnotName() const {
Wei Li9b761132016-01-29 15:44:20 -0800603 return m_pAnnot->GetAnnotDict()->GetUnicodeTextBy("NM");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700604}
605
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700606void CPDFSDK_BAAnnot::SetModifiedDate(const FX_SYSTEMTIME& st) {
607 CPDFSDK_DateTime dt(st);
608 CFX_ByteString str = dt.ToPDFDateTimeString();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700609
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700610 if (str.IsEmpty())
611 m_pAnnot->GetAnnotDict()->RemoveAt("M");
612 else
613 m_pAnnot->GetAnnotDict()->SetAtString("M", str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700614}
615
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700616FX_SYSTEMTIME CPDFSDK_BAAnnot::GetModifiedDate() const {
617 FX_SYSTEMTIME systime;
Wei Li9b761132016-01-29 15:44:20 -0800618 CFX_ByteString str = m_pAnnot->GetAnnotDict()->GetStringBy("M");
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700619
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700620 CPDFSDK_DateTime dt(str);
621 dt.ToSystemTime(systime);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700622
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700623 return systime;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700624}
625
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700626void CPDFSDK_BAAnnot::SetFlags(int nFlags) {
627 m_pAnnot->GetAnnotDict()->SetAtInteger("F", nFlags);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700628}
629
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700630int CPDFSDK_BAAnnot::GetFlags() const {
Wei Li9b761132016-01-29 15:44:20 -0800631 return m_pAnnot->GetAnnotDict()->GetIntegerBy("F");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700632}
633
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700634void CPDFSDK_BAAnnot::SetAppState(const CFX_ByteString& str) {
635 if (str.IsEmpty())
636 m_pAnnot->GetAnnotDict()->RemoveAt("AS");
637 else
638 m_pAnnot->GetAnnotDict()->SetAtString("AS", str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700639}
640
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700641CFX_ByteString CPDFSDK_BAAnnot::GetAppState() const {
Wei Li9b761132016-01-29 15:44:20 -0800642 return m_pAnnot->GetAnnotDict()->GetStringBy("AS");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700643}
644
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700645void CPDFSDK_BAAnnot::SetStructParent(int key) {
646 m_pAnnot->GetAnnotDict()->SetAtInteger("StructParent", key);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700647}
648
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700649int CPDFSDK_BAAnnot::GetStructParent() const {
Wei Li9b761132016-01-29 15:44:20 -0800650 return m_pAnnot->GetAnnotDict()->GetIntegerBy("StructParent");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700651}
652
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700653// border
654void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) {
Wei Li9b761132016-01-29 15:44:20 -0800655 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700656
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700657 if (pBorder) {
Tom Sepezae51c812015-08-05 12:34:06 -0700658 pBorder->SetAt(2, new CPDF_Number(nWidth));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700659 } else {
Wei Li9b761132016-01-29 15:44:20 -0800660 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700661
662 if (!pBSDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700663 pBSDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700664 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700665 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700666
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700667 pBSDict->SetAtInteger("W", nWidth);
668 }
669}
670
671int CPDFSDK_BAAnnot::GetBorderWidth() const {
Wei Li9b761132016-01-29 15:44:20 -0800672 if (CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border")) {
673 return pBorder->GetIntegerAt(2);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700674 }
Wei Li9b761132016-01-29 15:44:20 -0800675 if (CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS")) {
676 return pBSDict->GetIntegerBy("W", 1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700677 }
678 return 1;
679}
680
681void CPDFSDK_BAAnnot::SetBorderStyle(int nStyle) {
Wei Li9b761132016-01-29 15:44:20 -0800682 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700683 if (!pBSDict) {
684 pBSDict = new CPDF_Dictionary;
685 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
686 }
687
688 switch (nStyle) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700689 case BBS_SOLID:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700690 pBSDict->SetAtName("S", "S");
691 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700692 case BBS_DASH:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700693 pBSDict->SetAtName("S", "D");
694 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700695 case BBS_BEVELED:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700696 pBSDict->SetAtName("S", "B");
697 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700698 case BBS_INSET:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700699 pBSDict->SetAtName("S", "I");
700 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700701 case BBS_UNDERLINE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700702 pBSDict->SetAtName("S", "U");
703 break;
704 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700705}
706
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700707int CPDFSDK_BAAnnot::GetBorderStyle() const {
Wei Li9b761132016-01-29 15:44:20 -0800708 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700709 if (pBSDict) {
Wei Li9b761132016-01-29 15:44:20 -0800710 CFX_ByteString sBorderStyle = pBSDict->GetStringBy("S", "S");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700711 if (sBorderStyle == "S")
712 return BBS_SOLID;
713 if (sBorderStyle == "D")
714 return BBS_DASH;
715 if (sBorderStyle == "B")
716 return BBS_BEVELED;
717 if (sBorderStyle == "I")
718 return BBS_INSET;
719 if (sBorderStyle == "U")
720 return BBS_UNDERLINE;
721 }
722
Wei Li9b761132016-01-29 15:44:20 -0800723 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700724 if (pBorder) {
725 if (pBorder->GetCount() >= 4) {
Wei Li9b761132016-01-29 15:44:20 -0800726 CPDF_Array* pDP = pBorder->GetArrayAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700727 if (pDP && pDP->GetCount() > 0)
728 return BBS_DASH;
729 }
730 }
731
732 return BBS_SOLID;
733}
734
735void CPDFSDK_BAAnnot::SetBorderDash(const CFX_IntArray& array) {
Wei Li9b761132016-01-29 15:44:20 -0800736 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700737 if (!pBSDict) {
738 pBSDict = new CPDF_Dictionary;
739 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
740 }
741
Tom Sepezae51c812015-08-05 12:34:06 -0700742 CPDF_Array* pArray = new CPDF_Array;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700743 for (int i = 0, sz = array.GetSize(); i < sz; i++) {
744 pArray->AddInteger(array[i]);
745 }
746
747 pBSDict->SetAt("D", pArray);
748}
749
750void CPDFSDK_BAAnnot::GetBorderDash(CFX_IntArray& array) const {
751 CPDF_Array* pDash = NULL;
752
Wei Li9b761132016-01-29 15:44:20 -0800753 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700754 if (pBorder) {
Wei Li9b761132016-01-29 15:44:20 -0800755 pDash = pBorder->GetArrayAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700756 } else {
Wei Li9b761132016-01-29 15:44:20 -0800757 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700758 if (pBSDict) {
Wei Li9b761132016-01-29 15:44:20 -0800759 pDash = pBSDict->GetArrayBy("D");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700760 }
761 }
762
763 if (pDash) {
764 for (int i = 0, sz = pDash->GetCount(); i < sz; i++) {
Wei Li9b761132016-01-29 15:44:20 -0800765 array.Add(pDash->GetIntegerAt(i));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700766 }
767 }
768}
769
770void CPDFSDK_BAAnnot::SetColor(FX_COLORREF color) {
771 CPDF_Array* pArray = new CPDF_Array;
772 pArray->AddNumber((FX_FLOAT)FXSYS_GetRValue(color) / 255.0f);
773 pArray->AddNumber((FX_FLOAT)FXSYS_GetGValue(color) / 255.0f);
774 pArray->AddNumber((FX_FLOAT)FXSYS_GetBValue(color) / 255.0f);
775 m_pAnnot->GetAnnotDict()->SetAt("C", pArray);
776}
777
778void CPDFSDK_BAAnnot::RemoveColor() {
779 m_pAnnot->GetAnnotDict()->RemoveAt("C");
780}
781
782FX_BOOL CPDFSDK_BAAnnot::GetColor(FX_COLORREF& color) const {
Wei Li9b761132016-01-29 15:44:20 -0800783 if (CPDF_Array* pEntry = m_pAnnot->GetAnnotDict()->GetArrayBy("C")) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700784 int nCount = pEntry->GetCount();
785 if (nCount == 1) {
Wei Li9b761132016-01-29 15:44:20 -0800786 FX_FLOAT g = pEntry->GetNumberAt(0) * 255;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700787
788 color = FXSYS_RGB((int)g, (int)g, (int)g);
789
790 return TRUE;
791 } else if (nCount == 3) {
Wei Li9b761132016-01-29 15:44:20 -0800792 FX_FLOAT r = pEntry->GetNumberAt(0) * 255;
793 FX_FLOAT g = pEntry->GetNumberAt(1) * 255;
794 FX_FLOAT b = pEntry->GetNumberAt(2) * 255;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700795
796 color = FXSYS_RGB((int)r, (int)g, (int)b);
797
798 return TRUE;
799 } else if (nCount == 4) {
Wei Li9b761132016-01-29 15:44:20 -0800800 FX_FLOAT c = pEntry->GetNumberAt(0);
801 FX_FLOAT m = pEntry->GetNumberAt(1);
802 FX_FLOAT y = pEntry->GetNumberAt(2);
803 FX_FLOAT k = pEntry->GetNumberAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700804
Lei Zhang375a8642016-01-11 11:59:17 -0800805 FX_FLOAT r = 1.0f - std::min(1.0f, c + k);
806 FX_FLOAT g = 1.0f - std::min(1.0f, m + k);
807 FX_FLOAT b = 1.0f - std::min(1.0f, y + k);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700808
809 color = FXSYS_RGB((int)(r * 255), (int)(g * 255), (int)(b * 255));
810
811 return TRUE;
812 }
813 }
814
815 return FALSE;
816}
817
818void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType,
Tom Sepez281a9ea2016-02-26 14:24:28 -0800819 const CFX_FloatRect& rcBBox,
Tom Sepez60d909e2015-12-10 15:34:55 -0800820 const CFX_Matrix& matrix,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700821 const CFX_ByteString& sContents,
822 const CFX_ByteString& sAPState) {
Wei Li9b761132016-01-29 15:44:20 -0800823 CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700824
825 if (!pAPDict) {
826 pAPDict = new CPDF_Dictionary;
827 m_pAnnot->GetAnnotDict()->SetAt("AP", pAPDict);
828 }
829
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500830 CPDF_Stream* pStream = nullptr;
831 CPDF_Dictionary* pParentDict = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700832
833 if (sAPState.IsEmpty()) {
834 pParentDict = pAPDict;
Wei Li9b761132016-01-29 15:44:20 -0800835 pStream = pAPDict->GetStreamBy(sAPType);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700836 } else {
Wei Li9b761132016-01-29 15:44:20 -0800837 CPDF_Dictionary* pAPTypeDict = pAPDict->GetDictBy(sAPType);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700838 if (!pAPTypeDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700839 pAPTypeDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700840 pAPDict->SetAt(sAPType, pAPTypeDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700841 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700842
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700843 pParentDict = pAPTypeDict;
Wei Li9b761132016-01-29 15:44:20 -0800844 pStream = pAPTypeDict->GetStreamBy(sAPState);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700845 }
846
847 if (!pStream) {
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500848 pStream = new CPDF_Stream(nullptr, 0, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700849
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500850 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700851 int32_t objnum = pDoc->AddIndirectObject(pStream);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700852 pParentDict->SetAtReference(sAPType, pDoc, objnum);
853 }
854
855 CPDF_Dictionary* pStreamDict = pStream->GetDict();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700856 if (!pStreamDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700857 pStreamDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700858 pStreamDict->SetAtName("Type", "XObject");
859 pStreamDict->SetAtName("Subtype", "Form");
860 pStreamDict->SetAtInteger("FormType", 1);
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500861 pStream->InitStream(nullptr, 0, pStreamDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700862 }
863
864 if (pStreamDict) {
865 pStreamDict->SetAtMatrix("Matrix", matrix);
866 pStreamDict->SetAtRect("BBox", rcBBox);
867 }
868
869 pStream->SetData((uint8_t*)sContents.c_str(), sContents.GetLength(), FALSE,
870 FALSE);
871}
872
873#define BA_ANNOT_MINWIDTH 1
874#define BA_ANNOT_MINHEIGHT 1
875
876FX_FLOAT CPDFSDK_Annot::GetMinWidth() const {
877 return BA_ANNOT_MINWIDTH;
878}
879
880FX_FLOAT CPDFSDK_Annot::GetMinHeight() const {
881 return BA_ANNOT_MINHEIGHT;
882}
883
884FX_BOOL CPDFSDK_BAAnnot::CreateFormFiller() {
885 return TRUE;
886}
887FX_BOOL CPDFSDK_BAAnnot::IsVisible() const {
888 int nFlags = GetFlags();
889 return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) ||
890 (nFlags & ANNOTFLAG_NOVIEW));
891}
892
893CPDF_Action CPDFSDK_BAAnnot::GetAction() const {
Wei Li9b761132016-01-29 15:44:20 -0800894 return CPDF_Action(m_pAnnot->GetAnnotDict()->GetDictBy("A"));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700895}
896
897void CPDFSDK_BAAnnot::SetAction(const CPDF_Action& action) {
Wei Li0fc6b252016-03-01 16:29:41 -0800898 ASSERT(action.GetDict());
899 if (action.GetDict() != m_pAnnot->GetAnnotDict()->GetDictBy("A")) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700900 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
901 CPDF_Dictionary* pDict = action.GetDict();
902 if (pDict && pDict->GetObjNum() == 0) {
903 pDoc->AddIndirectObject(pDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700904 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700905 m_pAnnot->GetAnnotDict()->SetAtReference("A", pDoc, pDict->GetObjNum());
906 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700907}
908
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700909void CPDFSDK_BAAnnot::RemoveAction() {
910 m_pAnnot->GetAnnotDict()->RemoveAt("A");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700911}
912
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700913CPDF_AAction CPDFSDK_BAAnnot::GetAAction() const {
Wei Li0fc6b252016-03-01 16:29:41 -0800914 return CPDF_AAction(m_pAnnot->GetAnnotDict()->GetDictBy("AA"));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700915}
916
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700917void CPDFSDK_BAAnnot::SetAAction(const CPDF_AAction& aa) {
Wei Li0fc6b252016-03-01 16:29:41 -0800918 if (aa.GetDict() != m_pAnnot->GetAnnotDict()->GetDictBy("AA"))
919 m_pAnnot->GetAnnotDict()->SetAt("AA", aa.GetDict());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700920}
921
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700922void CPDFSDK_BAAnnot::RemoveAAction() {
923 m_pAnnot->GetAnnotDict()->RemoveAt("AA");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700924}
925
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700926CPDF_Action CPDFSDK_BAAnnot::GetAAction(CPDF_AAction::AActionType eAAT) {
927 CPDF_AAction AAction = GetAAction();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700928
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700929 if (AAction.ActionExist(eAAT))
930 return AAction.GetAction(eAAT);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700931
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700932 if (eAAT == CPDF_AAction::ButtonUp)
933 return GetAction();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700934
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700935 return CPDF_Action();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700936}
937
Tom Sepez51da0932015-11-25 16:05:49 -0800938#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700939FX_BOOL CPDFSDK_BAAnnot::IsXFAField() {
940 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700941}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800942#endif // PDF_ENABLE_XFA
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700943
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700944void CPDFSDK_BAAnnot::Annot_OnDraw(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800945 CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700946 CPDF_RenderOptions* pOptions) {
947 m_pAnnot->GetAPForm(m_pPageView->GetPDFPage(), CPDF_Annot::Normal);
948 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
949 CPDF_Annot::Normal, NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700950}
951
Tom Sepez50d12ad2015-11-24 09:50:51 -0800952UnderlyingPageType* CPDFSDK_Annot::GetUnderlyingPage() {
Tom Sepez40e9ff32015-11-30 12:39:54 -0800953#ifdef PDF_ENABLE_XFA
Tom Sepez50d12ad2015-11-24 09:50:51 -0800954 return GetPDFXFAPage();
Tom Sepez40e9ff32015-11-30 12:39:54 -0800955#else // PDF_ENABLE_XFA
956 return GetPDFPage();
957#endif // PDF_ENABLE_XFA
Tom Sepez50d12ad2015-11-24 09:50:51 -0800958}
959
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700960CPDF_Page* CPDFSDK_Annot::GetPDFPage() {
Lei Zhang05e67412016-01-25 16:35:42 -0800961 return m_pPageView ? m_pPageView->GetPDFPage() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700962}
963
Tom Sepez40e9ff32015-11-30 12:39:54 -0800964#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700965CPDFXFA_Page* CPDFSDK_Annot::GetPDFXFAPage() {
Lei Zhang05e67412016-01-25 16:35:42 -0800966 return m_pPageView ? m_pPageView->GetPDFXFAPage() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700967}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800968#endif // PDF_ENABLE_XFA