blob: 132d30b857409b9801ac7dc100aa2407cd7ecab3 [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
Dan Sinclair10cfea12015-11-16 13:09:00 -05009#include "core/include/fxcrt/fx_ext.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080010#include "fpdfsdk/include/fsdk_baseannot.h"
11#include "fpdfsdk/include/fsdk_define.h"
12#include "fpdfsdk/include/fsdk_mgr.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070013
Tom Sepez40e9ff32015-11-30 12:39:54 -080014#ifdef PDF_ENABLE_XFA
15#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
16#endif // PDF_ENABLE_XFA
17
Lei Zhang4467dea2016-02-25 12:39:15 -080018int gAfxGetTimeZoneInSeconds(int8_t tzhour, uint8_t tzminute) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070019 return (int)tzhour * 3600 + (int)tzminute * (tzhour >= 0 ? 60 : -60);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070020}
21
Nico Weber9d8ec5a2015-08-04 13:00:21 -070022FX_BOOL _gAfxIsLeapYear(int16_t year) {
23 return ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070024}
25
Nico Weber9d8ec5a2015-08-04 13:00:21 -070026FX_WORD _gAfxGetYearDays(int16_t year) {
27 return (_gAfxIsLeapYear(year) == TRUE ? 366 : 365);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070028}
29
Nico Weber9d8ec5a2015-08-04 13:00:21 -070030uint8_t _gAfxGetMonthDays(int16_t year, uint8_t month) {
31 uint8_t mDays;
32 switch (month) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -070033 case 1:
34 case 3:
35 case 5:
36 case 7:
37 case 8:
38 case 10:
39 case 12:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070040 mDays = 31;
41 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070042
Tom Sepez2f2ffec2015-07-23 14:42:09 -070043 case 4:
44 case 6:
45 case 9:
46 case 11:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070047 mDays = 30;
48 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070049
Tom Sepez2f2ffec2015-07-23 14:42:09 -070050 case 2:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070051 if (_gAfxIsLeapYear(year) == TRUE)
52 mDays = 29;
53 else
54 mDays = 28;
55 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070056
Tom Sepez2f2ffec2015-07-23 14:42:09 -070057 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070058 mDays = 0;
59 break;
60 }
61
62 return mDays;
63}
64
65CPDFSDK_DateTime::CPDFSDK_DateTime() {
66 ResetDateTime();
67}
68
69CPDFSDK_DateTime::CPDFSDK_DateTime(const CFX_ByteString& dtStr) {
70 ResetDateTime();
71
72 FromPDFDateTimeString(dtStr);
73}
74
75CPDFSDK_DateTime::CPDFSDK_DateTime(const CPDFSDK_DateTime& datetime) {
76 operator=(datetime);
77}
78
79CPDFSDK_DateTime::CPDFSDK_DateTime(const FX_SYSTEMTIME& st) {
80 operator=(st);
81}
82
83void CPDFSDK_DateTime::ResetDateTime() {
84 tzset();
85
86 time_t curTime;
87 time(&curTime);
Tom Sepez007e6c02016-02-26 14:31:56 -080088 struct tm* newtime = localtime(&curTime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070089
90 dt.year = newtime->tm_year + 1900;
91 dt.month = newtime->tm_mon + 1;
92 dt.day = newtime->tm_mday;
93 dt.hour = newtime->tm_hour;
94 dt.minute = newtime->tm_min;
95 dt.second = newtime->tm_sec;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070096}
97
98CPDFSDK_DateTime& CPDFSDK_DateTime::operator=(
99 const CPDFSDK_DateTime& datetime) {
100 FXSYS_memcpy(&dt, &datetime.dt, sizeof(FX_DATETIME));
101 return *this;
102}
103
104CPDFSDK_DateTime& CPDFSDK_DateTime::operator=(const FX_SYSTEMTIME& st) {
105 tzset();
106
107 dt.year = (int16_t)st.wYear;
108 dt.month = (uint8_t)st.wMonth;
109 dt.day = (uint8_t)st.wDay;
110 dt.hour = (uint8_t)st.wHour;
111 dt.minute = (uint8_t)st.wMinute;
112 dt.second = (uint8_t)st.wSecond;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700113 return *this;
114}
115
Tom Sepez007e6c02016-02-26 14:31:56 -0800116bool CPDFSDK_DateTime::operator==(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700117 return (FXSYS_memcmp(&dt, &datetime.dt, sizeof(FX_DATETIME)) == 0);
118}
119
Tom Sepez007e6c02016-02-26 14:31:56 -0800120bool CPDFSDK_DateTime::operator!=(const CPDFSDK_DateTime& datetime) const {
121 return !(*this == datetime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700122}
123
Tom Sepez007e6c02016-02-26 14:31:56 -0800124bool CPDFSDK_DateTime::operator>(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700125 CPDFSDK_DateTime dt1 = ToGMT();
126 CPDFSDK_DateTime dt2 = datetime.ToGMT();
127 int d1 =
128 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
129 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
130 (int)dt1.dt.second;
131 int d3 =
132 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
133 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
134 (int)dt2.dt.second;
135
Tom Sepez007e6c02016-02-26 14:31:56 -0800136 return d1 > d3 || d2 > d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700137}
138
Tom Sepez007e6c02016-02-26 14:31:56 -0800139bool CPDFSDK_DateTime::operator>=(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140 CPDFSDK_DateTime dt1 = ToGMT();
141 CPDFSDK_DateTime dt2 = datetime.ToGMT();
142 int d1 =
143 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
144 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
145 (int)dt1.dt.second;
146 int d3 =
147 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
148 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
149 (int)dt2.dt.second;
150
Tom Sepez007e6c02016-02-26 14:31:56 -0800151 return d1 >= d3 || d2 >= d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700152}
153
Tom Sepez007e6c02016-02-26 14:31:56 -0800154bool CPDFSDK_DateTime::operator<(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700155 CPDFSDK_DateTime dt1 = ToGMT();
156 CPDFSDK_DateTime dt2 = datetime.ToGMT();
157 int d1 =
158 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
159 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
160 (int)dt1.dt.second;
161 int d3 =
162 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
163 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
164 (int)dt2.dt.second;
165
Tom Sepez007e6c02016-02-26 14:31:56 -0800166 return d1 < d3 || d2 < d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167}
168
Tom Sepez007e6c02016-02-26 14:31:56 -0800169bool CPDFSDK_DateTime::operator<=(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700170 CPDFSDK_DateTime dt1 = ToGMT();
171 CPDFSDK_DateTime dt2 = datetime.ToGMT();
172 int d1 =
173 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
174 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
175 (int)dt1.dt.second;
176 int d3 =
177 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
178 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
179 (int)dt2.dt.second;
180
Tom Sepez007e6c02016-02-26 14:31:56 -0800181 return d1 <= d3 || d2 <= d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182}
183
184CPDFSDK_DateTime::operator time_t() {
185 struct tm newtime;
186
187 newtime.tm_year = dt.year - 1900;
188 newtime.tm_mon = dt.month - 1;
189 newtime.tm_mday = dt.day;
190 newtime.tm_hour = dt.hour;
191 newtime.tm_min = dt.minute;
192 newtime.tm_sec = dt.second;
193
194 return mktime(&newtime);
195}
196
197CPDFSDK_DateTime& CPDFSDK_DateTime::FromPDFDateTimeString(
198 const CFX_ByteString& dtStr) {
199 int strLength = dtStr.GetLength();
200 if (strLength > 0) {
201 int i = 0;
202 int j, k;
203 FX_CHAR ch;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500204 while (i < strLength && !std::isdigit(dtStr[i]))
205 ++i;
206
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700207 if (i >= strLength)
208 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700209
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210 j = 0;
211 k = 0;
212 while (i < strLength && j < 4) {
213 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500214 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700215 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500216 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700217 break;
218 i++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700219 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220 dt.year = (int16_t)k;
221 if (i >= strLength || j < 4)
222 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700223
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700224 j = 0;
225 k = 0;
226 while (i < strLength && j < 2) {
227 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500228 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500230 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700231 break;
232 i++;
233 }
234 dt.month = (uint8_t)k;
235 if (i >= strLength || j < 2)
236 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700237
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700238 j = 0;
239 k = 0;
240 while (i < strLength && j < 2) {
241 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500242 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700243 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500244 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700245 break;
246 i++;
247 }
248 dt.day = (uint8_t)k;
249 if (i >= strLength || j < 2)
250 return *this;
251
252 j = 0;
253 k = 0;
254 while (i < strLength && j < 2) {
255 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500256 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500258 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700259 break;
260 i++;
261 }
262 dt.hour = (uint8_t)k;
263 if (i >= strLength || j < 2)
264 return *this;
265
266 j = 0;
267 k = 0;
268 while (i < strLength && j < 2) {
269 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500270 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700271 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500272 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700273 break;
274 i++;
275 }
276 dt.minute = (uint8_t)k;
277 if (i >= strLength || j < 2)
278 return *this;
279
280 j = 0;
281 k = 0;
282 while (i < strLength && j < 2) {
283 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500284 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500286 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287 break;
288 i++;
289 }
290 dt.second = (uint8_t)k;
291 if (i >= strLength || j < 2)
292 return *this;
293
294 ch = dtStr[i++];
295 if (ch != '-' && ch != '+')
296 return *this;
297 if (ch == '-')
298 dt.tzHour = -1;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700299 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700300 dt.tzHour = 1;
301 j = 0;
302 k = 0;
303 while (i < strLength && j < 2) {
304 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500305 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700306 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500307 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700308 break;
309 i++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700310 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700311 dt.tzHour *= (FX_CHAR)k;
312 if (i >= strLength || j < 2)
313 return *this;
314
315 ch = dtStr[i++];
316 if (ch != '\'')
317 return *this;
318 j = 0;
319 k = 0;
320 while (i < strLength && j < 2) {
321 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500322 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700323 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500324 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700325 break;
326 i++;
327 }
328 dt.tzMinute = (uint8_t)k;
329 if (i >= strLength || j < 2)
330 return *this;
331 }
332
333 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700334}
335
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700336CFX_ByteString CPDFSDK_DateTime::ToCommonDateTimeString() {
337 CFX_ByteString str1;
338 str1.Format("%04d-%02d-%02d %02d:%02d:%02d ", dt.year, dt.month, dt.day,
339 dt.hour, dt.minute, dt.second);
340 if (dt.tzHour < 0)
341 str1 += "-";
342 else
343 str1 += "+";
344 CFX_ByteString str2;
345 str2.Format("%02d:%02d", abs(dt.tzHour), dt.tzMinute);
346 return str1 + str2;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700347}
348
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700349CFX_ByteString CPDFSDK_DateTime::ToPDFDateTimeString() {
350 CFX_ByteString dtStr;
351 char tempStr[32];
352 memset(tempStr, 0, sizeof(tempStr));
353 FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "D:%04d%02d%02d%02d%02d%02d",
354 dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
355 dtStr = CFX_ByteString(tempStr);
356 if (dt.tzHour < 0)
357 dtStr += CFX_ByteString("-");
358 else
359 dtStr += CFX_ByteString("+");
360 memset(tempStr, 0, sizeof(tempStr));
361 FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "%02d'%02d'", abs(dt.tzHour),
362 dt.tzMinute);
363 dtStr += CFX_ByteString(tempStr);
364 return dtStr;
365}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700366
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700367void CPDFSDK_DateTime::ToSystemTime(FX_SYSTEMTIME& st) {
368 CPDFSDK_DateTime dt = *this;
369 time_t t = (time_t)dt;
370 struct tm* pTime = localtime(&t);
371 if (pTime) {
372 st.wYear = (FX_WORD)pTime->tm_year + 1900;
373 st.wMonth = (FX_WORD)pTime->tm_mon + 1;
374 st.wDay = (FX_WORD)pTime->tm_mday;
375 st.wDayOfWeek = (FX_WORD)pTime->tm_wday;
376 st.wHour = (FX_WORD)pTime->tm_hour;
377 st.wMinute = (FX_WORD)pTime->tm_min;
378 st.wSecond = (FX_WORD)pTime->tm_sec;
379 st.wMilliseconds = 0;
380 }
381}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700382
Tom Sepez007e6c02016-02-26 14:31:56 -0800383CPDFSDK_DateTime CPDFSDK_DateTime::ToGMT() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700384 CPDFSDK_DateTime dt = *this;
Lei Zhang4467dea2016-02-25 12:39:15 -0800385 dt.AddSeconds(-gAfxGetTimeZoneInSeconds(dt.dt.tzHour, dt.dt.tzMinute));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700386 dt.dt.tzHour = 0;
387 dt.dt.tzMinute = 0;
388 return dt;
389}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700390
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700391CPDFSDK_DateTime& CPDFSDK_DateTime::AddDays(short days) {
392 if (days == 0)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700393 return *this;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700394
395 int16_t y = dt.year, yy;
396 uint8_t m = dt.month;
397 uint8_t d = dt.day;
398 int mdays, ydays, ldays;
399
400 ldays = days;
401 if (ldays > 0) {
402 yy = y;
403 if (((FX_WORD)m * 100 + d) > 300)
404 yy++;
405 ydays = _gAfxGetYearDays(yy);
406 while (ldays >= ydays) {
407 y++;
408 ldays -= ydays;
409 yy++;
410 mdays = _gAfxGetMonthDays(y, m);
411 if (d > mdays) {
412 m++;
413 d -= mdays;
414 }
415 ydays = _gAfxGetYearDays(yy);
416 }
417 mdays = _gAfxGetMonthDays(y, m) - d + 1;
418 while (ldays >= mdays) {
419 ldays -= mdays;
420 m++;
421 d = 1;
422 mdays = _gAfxGetMonthDays(y, m);
423 }
424 d += ldays;
425 } else {
426 ldays *= -1;
427 yy = y;
428 if (((FX_WORD)m * 100 + d) < 300)
429 yy--;
430 ydays = _gAfxGetYearDays(yy);
431 while (ldays >= ydays) {
432 y--;
433 ldays -= ydays;
434 yy--;
435 mdays = _gAfxGetMonthDays(y, m);
436 if (d > mdays) {
437 m++;
438 d -= mdays;
439 }
440 ydays = _gAfxGetYearDays(yy);
441 }
442 while (ldays >= d) {
443 ldays -= d;
444 m--;
445 mdays = _gAfxGetMonthDays(y, m);
446 d = mdays;
447 }
448 d -= ldays;
449 }
450
451 dt.year = y;
452 dt.month = m;
453 dt.day = d;
454
455 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700456}
457
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700458CPDFSDK_DateTime& CPDFSDK_DateTime::AddSeconds(int seconds) {
459 if (seconds == 0)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700460 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700461
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700462 int n;
463 int days;
464
465 n = dt.hour * 3600 + dt.minute * 60 + dt.second + seconds;
466 if (n < 0) {
467 days = (n - 86399) / 86400;
468 n -= days * 86400;
469 } else {
470 days = n / 86400;
471 n %= 86400;
472 }
473 dt.hour = (uint8_t)(n / 3600);
474 dt.hour %= 24;
475 n %= 3600;
476 dt.minute = (uint8_t)(n / 60);
477 dt.second = (uint8_t)(n % 60);
478 if (days != 0)
479 AddDays(days);
480
481 return *this;
482}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700483
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700484CPDFSDK_Annot::CPDFSDK_Annot(CPDFSDK_PageView* pPageView)
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500485 : m_pPageView(pPageView), m_bSelected(FALSE), m_nTabOrder(-1) {
486}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700487
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700488CPDFSDK_BAAnnot::CPDFSDK_BAAnnot(CPDF_Annot* pAnnot,
489 CPDFSDK_PageView* pPageView)
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500490 : CPDFSDK_Annot(pPageView), m_pAnnot(pAnnot) {
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700491}
492
Tom Sepez3343d142015-11-02 09:54:54 -0800493CPDF_Annot* CPDFSDK_BAAnnot::GetPDFAnnot() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700494 return m_pAnnot;
Bo Xufdc00a72014-10-28 23:03:33 -0700495}
496
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700497FX_BOOL CPDFSDK_Annot::IsSelected() {
498 return m_bSelected;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700499}
500
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700501void CPDFSDK_Annot::SetSelected(FX_BOOL bSelected) {
502 m_bSelected = bSelected;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700503}
504
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700505// Tab Order
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700506int CPDFSDK_Annot::GetTabOrder() {
507 return m_nTabOrder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700508}
509
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700510void CPDFSDK_Annot::SetTabOrder(int iTabOrder) {
511 m_nTabOrder = iTabOrder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700512}
513
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700514CPDF_Dictionary* CPDFSDK_BAAnnot::GetAnnotDict() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700515 return m_pAnnot->GetAnnotDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700516}
517
Tom Sepez281a9ea2016-02-26 14:24:28 -0800518void CPDFSDK_BAAnnot::SetRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700519 ASSERT(rect.right - rect.left >= GetMinWidth());
520 ASSERT(rect.top - rect.bottom >= GetMinHeight());
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700521
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700522 m_pAnnot->GetAnnotDict()->SetAtRect("Rect", rect);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700523}
524
Tom Sepez281a9ea2016-02-26 14:24:28 -0800525CFX_FloatRect CPDFSDK_BAAnnot::GetRect() const {
526 CFX_FloatRect rect;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700527 m_pAnnot->GetRect(rect);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700528 return rect;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700529}
530
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700531CFX_ByteString CPDFSDK_BAAnnot::GetType() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700532 return m_pAnnot->GetSubType();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700533}
534
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700535CFX_ByteString CPDFSDK_BAAnnot::GetSubType() const {
536 return "";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700537}
538
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700539void CPDFSDK_BAAnnot::DrawAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800540 const CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700541 CPDF_Annot::AppearanceMode mode,
542 const CPDF_RenderOptions* pOptions) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700543 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
544 mode, pOptions);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700545}
546
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700547FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid() {
Wei Li9b761132016-01-29 15:44:20 -0800548 return m_pAnnot->GetAnnotDict()->GetDictBy("AP") != NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700549}
550
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700551FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode) {
Wei Li9b761132016-01-29 15:44:20 -0800552 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
Lei Zhang412e9082015-12-14 18:34:00 -0800553 if (!pAP)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700554 return FALSE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700555
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700556 // Choose the right sub-ap
557 const FX_CHAR* ap_entry = "N";
558 if (mode == CPDF_Annot::Down)
559 ap_entry = "D";
560 else if (mode == CPDF_Annot::Rollover)
561 ap_entry = "R";
562 if (!pAP->KeyExist(ap_entry))
563 ap_entry = "N";
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700564
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700565 // Get the AP stream or subdirectory
566 CPDF_Object* psub = pAP->GetElementValue(ap_entry);
Lei Zhang412e9082015-12-14 18:34:00 -0800567 return !!psub;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700568}
569
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700570void CPDFSDK_BAAnnot::DrawBorder(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800571 const CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700572 const CPDF_RenderOptions* pOptions) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700573 m_pAnnot->DrawBorder(pDevice, pUser2Device, pOptions);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700574}
575
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700576void CPDFSDK_BAAnnot::ClearCachedAP() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700577 m_pAnnot->ClearCachedAP();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700578}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700579
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700580void CPDFSDK_BAAnnot::SetContents(const CFX_WideString& sContents) {
581 if (sContents.IsEmpty())
582 m_pAnnot->GetAnnotDict()->RemoveAt("Contents");
583 else
584 m_pAnnot->GetAnnotDict()->SetAtString("Contents",
585 PDF_EncodeText(sContents));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700586}
587
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700588CFX_WideString CPDFSDK_BAAnnot::GetContents() const {
Wei Li9b761132016-01-29 15:44:20 -0800589 return m_pAnnot->GetAnnotDict()->GetUnicodeTextBy("Contents");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700590}
591
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700592void CPDFSDK_BAAnnot::SetAnnotName(const CFX_WideString& sName) {
593 if (sName.IsEmpty())
594 m_pAnnot->GetAnnotDict()->RemoveAt("NM");
595 else
596 m_pAnnot->GetAnnotDict()->SetAtString("NM", PDF_EncodeText(sName));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700597}
598
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700599CFX_WideString CPDFSDK_BAAnnot::GetAnnotName() const {
Wei Li9b761132016-01-29 15:44:20 -0800600 return m_pAnnot->GetAnnotDict()->GetUnicodeTextBy("NM");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700601}
602
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700603void CPDFSDK_BAAnnot::SetModifiedDate(const FX_SYSTEMTIME& st) {
604 CPDFSDK_DateTime dt(st);
605 CFX_ByteString str = dt.ToPDFDateTimeString();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700606
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700607 if (str.IsEmpty())
608 m_pAnnot->GetAnnotDict()->RemoveAt("M");
609 else
610 m_pAnnot->GetAnnotDict()->SetAtString("M", str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700611}
612
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700613FX_SYSTEMTIME CPDFSDK_BAAnnot::GetModifiedDate() const {
614 FX_SYSTEMTIME systime;
Wei Li9b761132016-01-29 15:44:20 -0800615 CFX_ByteString str = m_pAnnot->GetAnnotDict()->GetStringBy("M");
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700616
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700617 CPDFSDK_DateTime dt(str);
618 dt.ToSystemTime(systime);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700619
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700620 return systime;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700621}
622
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700623void CPDFSDK_BAAnnot::SetFlags(int nFlags) {
624 m_pAnnot->GetAnnotDict()->SetAtInteger("F", nFlags);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700625}
626
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700627int CPDFSDK_BAAnnot::GetFlags() const {
Wei Li9b761132016-01-29 15:44:20 -0800628 return m_pAnnot->GetAnnotDict()->GetIntegerBy("F");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700629}
630
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700631void CPDFSDK_BAAnnot::SetAppState(const CFX_ByteString& str) {
632 if (str.IsEmpty())
633 m_pAnnot->GetAnnotDict()->RemoveAt("AS");
634 else
635 m_pAnnot->GetAnnotDict()->SetAtString("AS", str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700636}
637
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700638CFX_ByteString CPDFSDK_BAAnnot::GetAppState() const {
Wei Li9b761132016-01-29 15:44:20 -0800639 return m_pAnnot->GetAnnotDict()->GetStringBy("AS");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700640}
641
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700642void CPDFSDK_BAAnnot::SetStructParent(int key) {
643 m_pAnnot->GetAnnotDict()->SetAtInteger("StructParent", key);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700644}
645
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700646int CPDFSDK_BAAnnot::GetStructParent() const {
Wei Li9b761132016-01-29 15:44:20 -0800647 return m_pAnnot->GetAnnotDict()->GetIntegerBy("StructParent");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700648}
649
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700650// border
651void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) {
Wei Li9b761132016-01-29 15:44:20 -0800652 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700653
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700654 if (pBorder) {
Tom Sepezae51c812015-08-05 12:34:06 -0700655 pBorder->SetAt(2, new CPDF_Number(nWidth));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700656 } else {
Wei Li9b761132016-01-29 15:44:20 -0800657 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700658
659 if (!pBSDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700660 pBSDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700661 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700662 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700663
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700664 pBSDict->SetAtInteger("W", nWidth);
665 }
666}
667
668int CPDFSDK_BAAnnot::GetBorderWidth() const {
Wei Li9b761132016-01-29 15:44:20 -0800669 if (CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border")) {
670 return pBorder->GetIntegerAt(2);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700671 }
Wei Li9b761132016-01-29 15:44:20 -0800672 if (CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS")) {
673 return pBSDict->GetIntegerBy("W", 1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700674 }
675 return 1;
676}
677
678void CPDFSDK_BAAnnot::SetBorderStyle(int nStyle) {
Wei Li9b761132016-01-29 15:44:20 -0800679 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700680 if (!pBSDict) {
681 pBSDict = new CPDF_Dictionary;
682 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
683 }
684
685 switch (nStyle) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700686 case BBS_SOLID:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700687 pBSDict->SetAtName("S", "S");
688 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700689 case BBS_DASH:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700690 pBSDict->SetAtName("S", "D");
691 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700692 case BBS_BEVELED:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700693 pBSDict->SetAtName("S", "B");
694 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700695 case BBS_INSET:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700696 pBSDict->SetAtName("S", "I");
697 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700698 case BBS_UNDERLINE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700699 pBSDict->SetAtName("S", "U");
700 break;
701 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700702}
703
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700704int CPDFSDK_BAAnnot::GetBorderStyle() const {
Wei Li9b761132016-01-29 15:44:20 -0800705 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700706 if (pBSDict) {
Wei Li9b761132016-01-29 15:44:20 -0800707 CFX_ByteString sBorderStyle = pBSDict->GetStringBy("S", "S");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700708 if (sBorderStyle == "S")
709 return BBS_SOLID;
710 if (sBorderStyle == "D")
711 return BBS_DASH;
712 if (sBorderStyle == "B")
713 return BBS_BEVELED;
714 if (sBorderStyle == "I")
715 return BBS_INSET;
716 if (sBorderStyle == "U")
717 return BBS_UNDERLINE;
718 }
719
Wei Li9b761132016-01-29 15:44:20 -0800720 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700721 if (pBorder) {
722 if (pBorder->GetCount() >= 4) {
Wei Li9b761132016-01-29 15:44:20 -0800723 CPDF_Array* pDP = pBorder->GetArrayAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700724 if (pDP && pDP->GetCount() > 0)
725 return BBS_DASH;
726 }
727 }
728
729 return BBS_SOLID;
730}
731
732void CPDFSDK_BAAnnot::SetBorderDash(const CFX_IntArray& array) {
Wei Li9b761132016-01-29 15:44:20 -0800733 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700734 if (!pBSDict) {
735 pBSDict = new CPDF_Dictionary;
736 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
737 }
738
Tom Sepezae51c812015-08-05 12:34:06 -0700739 CPDF_Array* pArray = new CPDF_Array;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700740 for (int i = 0, sz = array.GetSize(); i < sz; i++) {
741 pArray->AddInteger(array[i]);
742 }
743
744 pBSDict->SetAt("D", pArray);
745}
746
747void CPDFSDK_BAAnnot::GetBorderDash(CFX_IntArray& array) const {
748 CPDF_Array* pDash = NULL;
749
Wei Li9b761132016-01-29 15:44:20 -0800750 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700751 if (pBorder) {
Wei Li9b761132016-01-29 15:44:20 -0800752 pDash = pBorder->GetArrayAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700753 } else {
Wei Li9b761132016-01-29 15:44:20 -0800754 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700755 if (pBSDict) {
Wei Li9b761132016-01-29 15:44:20 -0800756 pDash = pBSDict->GetArrayBy("D");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700757 }
758 }
759
760 if (pDash) {
761 for (int i = 0, sz = pDash->GetCount(); i < sz; i++) {
Wei Li9b761132016-01-29 15:44:20 -0800762 array.Add(pDash->GetIntegerAt(i));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700763 }
764 }
765}
766
767void CPDFSDK_BAAnnot::SetColor(FX_COLORREF color) {
768 CPDF_Array* pArray = new CPDF_Array;
769 pArray->AddNumber((FX_FLOAT)FXSYS_GetRValue(color) / 255.0f);
770 pArray->AddNumber((FX_FLOAT)FXSYS_GetGValue(color) / 255.0f);
771 pArray->AddNumber((FX_FLOAT)FXSYS_GetBValue(color) / 255.0f);
772 m_pAnnot->GetAnnotDict()->SetAt("C", pArray);
773}
774
775void CPDFSDK_BAAnnot::RemoveColor() {
776 m_pAnnot->GetAnnotDict()->RemoveAt("C");
777}
778
779FX_BOOL CPDFSDK_BAAnnot::GetColor(FX_COLORREF& color) const {
Wei Li9b761132016-01-29 15:44:20 -0800780 if (CPDF_Array* pEntry = m_pAnnot->GetAnnotDict()->GetArrayBy("C")) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700781 int nCount = pEntry->GetCount();
782 if (nCount == 1) {
Wei Li9b761132016-01-29 15:44:20 -0800783 FX_FLOAT g = pEntry->GetNumberAt(0) * 255;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700784
785 color = FXSYS_RGB((int)g, (int)g, (int)g);
786
787 return TRUE;
788 } else if (nCount == 3) {
Wei Li9b761132016-01-29 15:44:20 -0800789 FX_FLOAT r = pEntry->GetNumberAt(0) * 255;
790 FX_FLOAT g = pEntry->GetNumberAt(1) * 255;
791 FX_FLOAT b = pEntry->GetNumberAt(2) * 255;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700792
793 color = FXSYS_RGB((int)r, (int)g, (int)b);
794
795 return TRUE;
796 } else if (nCount == 4) {
Wei Li9b761132016-01-29 15:44:20 -0800797 FX_FLOAT c = pEntry->GetNumberAt(0);
798 FX_FLOAT m = pEntry->GetNumberAt(1);
799 FX_FLOAT y = pEntry->GetNumberAt(2);
800 FX_FLOAT k = pEntry->GetNumberAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700801
Lei Zhang375a8642016-01-11 11:59:17 -0800802 FX_FLOAT r = 1.0f - std::min(1.0f, c + k);
803 FX_FLOAT g = 1.0f - std::min(1.0f, m + k);
804 FX_FLOAT b = 1.0f - std::min(1.0f, y + k);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700805
806 color = FXSYS_RGB((int)(r * 255), (int)(g * 255), (int)(b * 255));
807
808 return TRUE;
809 }
810 }
811
812 return FALSE;
813}
814
815void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType,
Tom Sepez281a9ea2016-02-26 14:24:28 -0800816 const CFX_FloatRect& rcBBox,
Tom Sepez60d909e2015-12-10 15:34:55 -0800817 const CFX_Matrix& matrix,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700818 const CFX_ByteString& sContents,
819 const CFX_ByteString& sAPState) {
Wei Li9b761132016-01-29 15:44:20 -0800820 CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700821
822 if (!pAPDict) {
823 pAPDict = new CPDF_Dictionary;
824 m_pAnnot->GetAnnotDict()->SetAt("AP", pAPDict);
825 }
826
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500827 CPDF_Stream* pStream = nullptr;
828 CPDF_Dictionary* pParentDict = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700829
830 if (sAPState.IsEmpty()) {
831 pParentDict = pAPDict;
Wei Li9b761132016-01-29 15:44:20 -0800832 pStream = pAPDict->GetStreamBy(sAPType);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700833 } else {
Wei Li9b761132016-01-29 15:44:20 -0800834 CPDF_Dictionary* pAPTypeDict = pAPDict->GetDictBy(sAPType);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700835 if (!pAPTypeDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700836 pAPTypeDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700837 pAPDict->SetAt(sAPType, pAPTypeDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700838 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700839
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700840 pParentDict = pAPTypeDict;
Wei Li9b761132016-01-29 15:44:20 -0800841 pStream = pAPTypeDict->GetStreamBy(sAPState);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700842 }
843
844 if (!pStream) {
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500845 pStream = new CPDF_Stream(nullptr, 0, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700846
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500847 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700848 int32_t objnum = pDoc->AddIndirectObject(pStream);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700849 pParentDict->SetAtReference(sAPType, pDoc, objnum);
850 }
851
852 CPDF_Dictionary* pStreamDict = pStream->GetDict();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700853 if (!pStreamDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700854 pStreamDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700855 pStreamDict->SetAtName("Type", "XObject");
856 pStreamDict->SetAtName("Subtype", "Form");
857 pStreamDict->SetAtInteger("FormType", 1);
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500858 pStream->InitStream(nullptr, 0, pStreamDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700859 }
860
861 if (pStreamDict) {
862 pStreamDict->SetAtMatrix("Matrix", matrix);
863 pStreamDict->SetAtRect("BBox", rcBBox);
864 }
865
866 pStream->SetData((uint8_t*)sContents.c_str(), sContents.GetLength(), FALSE,
867 FALSE);
868}
869
870#define BA_ANNOT_MINWIDTH 1
871#define BA_ANNOT_MINHEIGHT 1
872
873FX_FLOAT CPDFSDK_Annot::GetMinWidth() const {
874 return BA_ANNOT_MINWIDTH;
875}
876
877FX_FLOAT CPDFSDK_Annot::GetMinHeight() const {
878 return BA_ANNOT_MINHEIGHT;
879}
880
881FX_BOOL CPDFSDK_BAAnnot::CreateFormFiller() {
882 return TRUE;
883}
884FX_BOOL CPDFSDK_BAAnnot::IsVisible() const {
885 int nFlags = GetFlags();
886 return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) ||
887 (nFlags & ANNOTFLAG_NOVIEW));
888}
889
890CPDF_Action CPDFSDK_BAAnnot::GetAction() const {
Wei Li9b761132016-01-29 15:44:20 -0800891 return CPDF_Action(m_pAnnot->GetAnnotDict()->GetDictBy("A"));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700892}
893
894void CPDFSDK_BAAnnot::SetAction(const CPDF_Action& action) {
895 ASSERT(action);
896 if ((CPDF_Action&)action !=
Wei Li9b761132016-01-29 15:44:20 -0800897 CPDF_Action(m_pAnnot->GetAnnotDict()->GetDictBy("A"))) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700898 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
899 CPDF_Dictionary* pDict = action.GetDict();
900 if (pDict && pDict->GetObjNum() == 0) {
901 pDoc->AddIndirectObject(pDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700902 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700903 m_pAnnot->GetAnnotDict()->SetAtReference("A", pDoc, pDict->GetObjNum());
904 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700905}
906
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700907void CPDFSDK_BAAnnot::RemoveAction() {
908 m_pAnnot->GetAnnotDict()->RemoveAt("A");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700909}
910
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700911CPDF_AAction CPDFSDK_BAAnnot::GetAAction() const {
Wei Li9b761132016-01-29 15:44:20 -0800912 return m_pAnnot->GetAnnotDict()->GetDictBy("AA");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700913}
914
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700915void CPDFSDK_BAAnnot::SetAAction(const CPDF_AAction& aa) {
Wei Li9b761132016-01-29 15:44:20 -0800916 if ((CPDF_AAction&)aa != m_pAnnot->GetAnnotDict()->GetDictBy("AA"))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700917 m_pAnnot->GetAnnotDict()->SetAt("AA", (CPDF_AAction&)aa);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700918}
919
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700920void CPDFSDK_BAAnnot::RemoveAAction() {
921 m_pAnnot->GetAnnotDict()->RemoveAt("AA");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700922}
923
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700924CPDF_Action CPDFSDK_BAAnnot::GetAAction(CPDF_AAction::AActionType eAAT) {
925 CPDF_AAction AAction = GetAAction();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700926
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700927 if (AAction.ActionExist(eAAT))
928 return AAction.GetAction(eAAT);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700929
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700930 if (eAAT == CPDF_AAction::ButtonUp)
931 return GetAction();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700932
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700933 return CPDF_Action();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700934}
935
Tom Sepez51da0932015-11-25 16:05:49 -0800936#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700937FX_BOOL CPDFSDK_BAAnnot::IsXFAField() {
938 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700939}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800940#endif // PDF_ENABLE_XFA
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700941
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700942void CPDFSDK_BAAnnot::Annot_OnDraw(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800943 CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700944 CPDF_RenderOptions* pOptions) {
945 m_pAnnot->GetAPForm(m_pPageView->GetPDFPage(), CPDF_Annot::Normal);
946 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
947 CPDF_Annot::Normal, NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700948}
949
Tom Sepez50d12ad2015-11-24 09:50:51 -0800950UnderlyingPageType* CPDFSDK_Annot::GetUnderlyingPage() {
Tom Sepez40e9ff32015-11-30 12:39:54 -0800951#ifdef PDF_ENABLE_XFA
Tom Sepez50d12ad2015-11-24 09:50:51 -0800952 return GetPDFXFAPage();
Tom Sepez40e9ff32015-11-30 12:39:54 -0800953#else // PDF_ENABLE_XFA
954 return GetPDFPage();
955#endif // PDF_ENABLE_XFA
Tom Sepez50d12ad2015-11-24 09:50:51 -0800956}
957
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700958CPDF_Page* CPDFSDK_Annot::GetPDFPage() {
Lei Zhang05e67412016-01-25 16:35:42 -0800959 return m_pPageView ? m_pPageView->GetPDFPage() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700960}
961
Tom Sepez40e9ff32015-11-30 12:39:54 -0800962#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700963CPDFXFA_Page* CPDFSDK_Annot::GetPDFXFAPage() {
Lei Zhang05e67412016-01-25 16:35:42 -0800964 return m_pPageView ? m_pPageView->GetPDFXFAPage() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700965}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800966#endif // PDF_ENABLE_XFA