blob: 0c7cfac0deea74954a05b5c7e1b8c270bc8d2406 [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 Sepez310438f2016-03-08 13:10:55 -08009#include "core/include/fpdfapi/cpdf_document.h"
Dan Sinclair10cfea12015-11-16 13:09:00 -050010#include "core/include/fxcrt/fx_ext.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080011#include "fpdfsdk/include/fsdk_baseannot.h"
12#include "fpdfsdk/include/fsdk_define.h"
13#include "fpdfsdk/include/fsdk_mgr.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070014
Tom Sepez40e9ff32015-11-30 12:39:54 -080015#ifdef PDF_ENABLE_XFA
16#include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h"
17#endif // PDF_ENABLE_XFA
18
Lei Zhang4467dea2016-02-25 12:39:15 -080019int gAfxGetTimeZoneInSeconds(int8_t tzhour, uint8_t tzminute) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070020 return (int)tzhour * 3600 + (int)tzminute * (tzhour >= 0 ? 60 : -60);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070021}
22
Nico Weber9d8ec5a2015-08-04 13:00:21 -070023FX_BOOL _gAfxIsLeapYear(int16_t year) {
24 return ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070025}
26
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027FX_WORD _gAfxGetYearDays(int16_t year) {
28 return (_gAfxIsLeapYear(year) == TRUE ? 366 : 365);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070029}
30
Nico Weber9d8ec5a2015-08-04 13:00:21 -070031uint8_t _gAfxGetMonthDays(int16_t year, uint8_t month) {
32 uint8_t mDays;
33 switch (month) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -070034 case 1:
35 case 3:
36 case 5:
37 case 7:
38 case 8:
39 case 10:
40 case 12:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070041 mDays = 31;
42 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070043
Tom Sepez2f2ffec2015-07-23 14:42:09 -070044 case 4:
45 case 6:
46 case 9:
47 case 11:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070048 mDays = 30;
49 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070050
Tom Sepez2f2ffec2015-07-23 14:42:09 -070051 case 2:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070052 if (_gAfxIsLeapYear(year) == TRUE)
53 mDays = 29;
54 else
55 mDays = 28;
56 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070057
Tom Sepez2f2ffec2015-07-23 14:42:09 -070058 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070059 mDays = 0;
60 break;
61 }
62
63 return mDays;
64}
65
66CPDFSDK_DateTime::CPDFSDK_DateTime() {
67 ResetDateTime();
68}
69
70CPDFSDK_DateTime::CPDFSDK_DateTime(const CFX_ByteString& dtStr) {
71 ResetDateTime();
72
73 FromPDFDateTimeString(dtStr);
74}
75
76CPDFSDK_DateTime::CPDFSDK_DateTime(const CPDFSDK_DateTime& datetime) {
77 operator=(datetime);
78}
79
80CPDFSDK_DateTime::CPDFSDK_DateTime(const FX_SYSTEMTIME& st) {
81 operator=(st);
82}
83
84void CPDFSDK_DateTime::ResetDateTime() {
85 tzset();
86
87 time_t curTime;
88 time(&curTime);
Tom Sepez007e6c02016-02-26 14:31:56 -080089 struct tm* newtime = localtime(&curTime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090
91 dt.year = newtime->tm_year + 1900;
92 dt.month = newtime->tm_mon + 1;
93 dt.day = newtime->tm_mday;
94 dt.hour = newtime->tm_hour;
95 dt.minute = newtime->tm_min;
96 dt.second = newtime->tm_sec;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070097}
98
99CPDFSDK_DateTime& CPDFSDK_DateTime::operator=(
100 const CPDFSDK_DateTime& datetime) {
101 FXSYS_memcpy(&dt, &datetime.dt, sizeof(FX_DATETIME));
102 return *this;
103}
104
105CPDFSDK_DateTime& CPDFSDK_DateTime::operator=(const FX_SYSTEMTIME& st) {
106 tzset();
107
108 dt.year = (int16_t)st.wYear;
109 dt.month = (uint8_t)st.wMonth;
110 dt.day = (uint8_t)st.wDay;
111 dt.hour = (uint8_t)st.wHour;
112 dt.minute = (uint8_t)st.wMinute;
113 dt.second = (uint8_t)st.wSecond;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700114 return *this;
115}
116
Tom Sepez007e6c02016-02-26 14:31:56 -0800117bool CPDFSDK_DateTime::operator==(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700118 return (FXSYS_memcmp(&dt, &datetime.dt, sizeof(FX_DATETIME)) == 0);
119}
120
Tom Sepez007e6c02016-02-26 14:31:56 -0800121bool CPDFSDK_DateTime::operator!=(const CPDFSDK_DateTime& datetime) const {
122 return !(*this == datetime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123}
124
Tom Sepez007e6c02016-02-26 14:31:56 -0800125bool CPDFSDK_DateTime::operator>(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126 CPDFSDK_DateTime dt1 = ToGMT();
127 CPDFSDK_DateTime dt2 = datetime.ToGMT();
128 int d1 =
129 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
130 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
131 (int)dt1.dt.second;
132 int d3 =
133 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
134 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
135 (int)dt2.dt.second;
136
Tom Sepez007e6c02016-02-26 14:31:56 -0800137 return d1 > d3 || d2 > d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700138}
139
Tom Sepez007e6c02016-02-26 14:31:56 -0800140bool CPDFSDK_DateTime::operator>=(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700141 CPDFSDK_DateTime dt1 = ToGMT();
142 CPDFSDK_DateTime dt2 = datetime.ToGMT();
143 int d1 =
144 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
145 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
146 (int)dt1.dt.second;
147 int d3 =
148 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
149 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
150 (int)dt2.dt.second;
151
Tom Sepez007e6c02016-02-26 14:31:56 -0800152 return d1 >= d3 || d2 >= d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153}
154
Tom Sepez007e6c02016-02-26 14:31:56 -0800155bool CPDFSDK_DateTime::operator<(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700156 CPDFSDK_DateTime dt1 = ToGMT();
157 CPDFSDK_DateTime dt2 = datetime.ToGMT();
158 int d1 =
159 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
160 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
161 (int)dt1.dt.second;
162 int d3 =
163 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
164 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
165 (int)dt2.dt.second;
166
Tom Sepez007e6c02016-02-26 14:31:56 -0800167 return d1 < d3 || d2 < d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168}
169
Tom Sepez007e6c02016-02-26 14:31:56 -0800170bool CPDFSDK_DateTime::operator<=(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171 CPDFSDK_DateTime dt1 = ToGMT();
172 CPDFSDK_DateTime dt2 = datetime.ToGMT();
173 int d1 =
174 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
175 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
176 (int)dt1.dt.second;
177 int d3 =
178 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
179 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
180 (int)dt2.dt.second;
181
Tom Sepez007e6c02016-02-26 14:31:56 -0800182 return d1 <= d3 || d2 <= d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183}
184
185CPDFSDK_DateTime::operator time_t() {
186 struct tm newtime;
187
188 newtime.tm_year = dt.year - 1900;
189 newtime.tm_mon = dt.month - 1;
190 newtime.tm_mday = dt.day;
191 newtime.tm_hour = dt.hour;
192 newtime.tm_min = dt.minute;
193 newtime.tm_sec = dt.second;
194
195 return mktime(&newtime);
196}
197
198CPDFSDK_DateTime& CPDFSDK_DateTime::FromPDFDateTimeString(
199 const CFX_ByteString& dtStr) {
200 int strLength = dtStr.GetLength();
201 if (strLength > 0) {
202 int i = 0;
203 int j, k;
204 FX_CHAR ch;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500205 while (i < strLength && !std::isdigit(dtStr[i]))
206 ++i;
207
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700208 if (i >= strLength)
209 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700210
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700211 j = 0;
212 k = 0;
213 while (i < strLength && j < 4) {
214 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500215 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700216 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500217 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700218 break;
219 i++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700220 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700221 dt.year = (int16_t)k;
222 if (i >= strLength || j < 4)
223 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700224
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700225 j = 0;
226 k = 0;
227 while (i < strLength && j < 2) {
228 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500229 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700230 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500231 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700232 break;
233 i++;
234 }
235 dt.month = (uint8_t)k;
236 if (i >= strLength || j < 2)
237 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700238
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700239 j = 0;
240 k = 0;
241 while (i < strLength && j < 2) {
242 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500243 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700244 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500245 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 break;
247 i++;
248 }
249 dt.day = (uint8_t)k;
250 if (i >= strLength || j < 2)
251 return *this;
252
253 j = 0;
254 k = 0;
255 while (i < strLength && j < 2) {
256 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500257 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700258 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500259 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260 break;
261 i++;
262 }
263 dt.hour = (uint8_t)k;
264 if (i >= strLength || j < 2)
265 return *this;
266
267 j = 0;
268 k = 0;
269 while (i < strLength && j < 2) {
270 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500271 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700272 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500273 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700274 break;
275 i++;
276 }
277 dt.minute = (uint8_t)k;
278 if (i >= strLength || j < 2)
279 return *this;
280
281 j = 0;
282 k = 0;
283 while (i < strLength && j < 2) {
284 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500285 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700286 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500287 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700288 break;
289 i++;
290 }
291 dt.second = (uint8_t)k;
292 if (i >= strLength || j < 2)
293 return *this;
294
295 ch = dtStr[i++];
296 if (ch != '-' && ch != '+')
297 return *this;
298 if (ch == '-')
299 dt.tzHour = -1;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700300 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700301 dt.tzHour = 1;
302 j = 0;
303 k = 0;
304 while (i < strLength && j < 2) {
305 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500306 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700307 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500308 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700309 break;
310 i++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700311 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700312 dt.tzHour *= (FX_CHAR)k;
313 if (i >= strLength || j < 2)
314 return *this;
315
316 ch = dtStr[i++];
317 if (ch != '\'')
318 return *this;
319 j = 0;
320 k = 0;
321 while (i < strLength && j < 2) {
322 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500323 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700324 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500325 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700326 break;
327 i++;
328 }
329 dt.tzMinute = (uint8_t)k;
330 if (i >= strLength || j < 2)
331 return *this;
332 }
333
334 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700335}
336
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700337CFX_ByteString CPDFSDK_DateTime::ToCommonDateTimeString() {
338 CFX_ByteString str1;
339 str1.Format("%04d-%02d-%02d %02d:%02d:%02d ", dt.year, dt.month, dt.day,
340 dt.hour, dt.minute, dt.second);
341 if (dt.tzHour < 0)
342 str1 += "-";
343 else
344 str1 += "+";
345 CFX_ByteString str2;
346 str2.Format("%02d:%02d", abs(dt.tzHour), dt.tzMinute);
347 return str1 + str2;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700348}
349
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700350CFX_ByteString CPDFSDK_DateTime::ToPDFDateTimeString() {
351 CFX_ByteString dtStr;
352 char tempStr[32];
353 memset(tempStr, 0, sizeof(tempStr));
354 FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "D:%04d%02d%02d%02d%02d%02d",
355 dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
356 dtStr = CFX_ByteString(tempStr);
357 if (dt.tzHour < 0)
358 dtStr += CFX_ByteString("-");
359 else
360 dtStr += CFX_ByteString("+");
361 memset(tempStr, 0, sizeof(tempStr));
362 FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "%02d'%02d'", abs(dt.tzHour),
363 dt.tzMinute);
364 dtStr += CFX_ByteString(tempStr);
365 return dtStr;
366}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700367
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700368void CPDFSDK_DateTime::ToSystemTime(FX_SYSTEMTIME& st) {
369 CPDFSDK_DateTime dt = *this;
370 time_t t = (time_t)dt;
371 struct tm* pTime = localtime(&t);
372 if (pTime) {
373 st.wYear = (FX_WORD)pTime->tm_year + 1900;
374 st.wMonth = (FX_WORD)pTime->tm_mon + 1;
375 st.wDay = (FX_WORD)pTime->tm_mday;
376 st.wDayOfWeek = (FX_WORD)pTime->tm_wday;
377 st.wHour = (FX_WORD)pTime->tm_hour;
378 st.wMinute = (FX_WORD)pTime->tm_min;
379 st.wSecond = (FX_WORD)pTime->tm_sec;
380 st.wMilliseconds = 0;
381 }
382}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700383
Tom Sepez007e6c02016-02-26 14:31:56 -0800384CPDFSDK_DateTime CPDFSDK_DateTime::ToGMT() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700385 CPDFSDK_DateTime dt = *this;
Lei Zhang4467dea2016-02-25 12:39:15 -0800386 dt.AddSeconds(-gAfxGetTimeZoneInSeconds(dt.dt.tzHour, dt.dt.tzMinute));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700387 dt.dt.tzHour = 0;
388 dt.dt.tzMinute = 0;
389 return dt;
390}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700391
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700392CPDFSDK_DateTime& CPDFSDK_DateTime::AddDays(short days) {
393 if (days == 0)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700394 return *this;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700395
396 int16_t y = dt.year, yy;
397 uint8_t m = dt.month;
398 uint8_t d = dt.day;
399 int mdays, ydays, ldays;
400
401 ldays = days;
402 if (ldays > 0) {
403 yy = y;
404 if (((FX_WORD)m * 100 + d) > 300)
405 yy++;
406 ydays = _gAfxGetYearDays(yy);
407 while (ldays >= ydays) {
408 y++;
409 ldays -= ydays;
410 yy++;
411 mdays = _gAfxGetMonthDays(y, m);
412 if (d > mdays) {
413 m++;
414 d -= mdays;
415 }
416 ydays = _gAfxGetYearDays(yy);
417 }
418 mdays = _gAfxGetMonthDays(y, m) - d + 1;
419 while (ldays >= mdays) {
420 ldays -= mdays;
421 m++;
422 d = 1;
423 mdays = _gAfxGetMonthDays(y, m);
424 }
425 d += ldays;
426 } else {
427 ldays *= -1;
428 yy = y;
429 if (((FX_WORD)m * 100 + d) < 300)
430 yy--;
431 ydays = _gAfxGetYearDays(yy);
432 while (ldays >= ydays) {
433 y--;
434 ldays -= ydays;
435 yy--;
436 mdays = _gAfxGetMonthDays(y, m);
437 if (d > mdays) {
438 m++;
439 d -= mdays;
440 }
441 ydays = _gAfxGetYearDays(yy);
442 }
443 while (ldays >= d) {
444 ldays -= d;
445 m--;
446 mdays = _gAfxGetMonthDays(y, m);
447 d = mdays;
448 }
449 d -= ldays;
450 }
451
452 dt.year = y;
453 dt.month = m;
454 dt.day = d;
455
456 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700457}
458
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700459CPDFSDK_DateTime& CPDFSDK_DateTime::AddSeconds(int seconds) {
460 if (seconds == 0)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700461 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700462
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700463 int n;
464 int days;
465
466 n = dt.hour * 3600 + dt.minute * 60 + dt.second + seconds;
467 if (n < 0) {
468 days = (n - 86399) / 86400;
469 n -= days * 86400;
470 } else {
471 days = n / 86400;
472 n %= 86400;
473 }
474 dt.hour = (uint8_t)(n / 3600);
475 dt.hour %= 24;
476 n %= 3600;
477 dt.minute = (uint8_t)(n / 60);
478 dt.second = (uint8_t)(n % 60);
479 if (days != 0)
480 AddDays(days);
481
482 return *this;
483}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700484
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700485CPDFSDK_Annot::CPDFSDK_Annot(CPDFSDK_PageView* pPageView)
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500486 : m_pPageView(pPageView), m_bSelected(FALSE), m_nTabOrder(-1) {
487}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700488
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700489CPDFSDK_BAAnnot::CPDFSDK_BAAnnot(CPDF_Annot* pAnnot,
490 CPDFSDK_PageView* pPageView)
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500491 : CPDFSDK_Annot(pPageView), m_pAnnot(pAnnot) {
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700492}
493
Tom Sepez3343d142015-11-02 09:54:54 -0800494CPDF_Annot* CPDFSDK_BAAnnot::GetPDFAnnot() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700495 return m_pAnnot;
Bo Xufdc00a72014-10-28 23:03:33 -0700496}
497
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700498FX_BOOL CPDFSDK_Annot::IsSelected() {
499 return m_bSelected;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700500}
501
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700502void CPDFSDK_Annot::SetSelected(FX_BOOL bSelected) {
503 m_bSelected = bSelected;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700504}
505
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700506// Tab Order
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700507int CPDFSDK_Annot::GetTabOrder() {
508 return m_nTabOrder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700509}
510
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700511void CPDFSDK_Annot::SetTabOrder(int iTabOrder) {
512 m_nTabOrder = iTabOrder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700513}
514
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700515CPDF_Dictionary* CPDFSDK_BAAnnot::GetAnnotDict() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700516 return m_pAnnot->GetAnnotDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700517}
518
Tom Sepez281a9ea2016-02-26 14:24:28 -0800519void CPDFSDK_BAAnnot::SetRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700520 ASSERT(rect.right - rect.left >= GetMinWidth());
521 ASSERT(rect.top - rect.bottom >= GetMinHeight());
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700522
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700523 m_pAnnot->GetAnnotDict()->SetAtRect("Rect", rect);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700524}
525
Tom Sepez281a9ea2016-02-26 14:24:28 -0800526CFX_FloatRect CPDFSDK_BAAnnot::GetRect() const {
527 CFX_FloatRect rect;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700528 m_pAnnot->GetRect(rect);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700529 return rect;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700530}
531
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700532CFX_ByteString CPDFSDK_BAAnnot::GetType() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700533 return m_pAnnot->GetSubType();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700534}
535
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700536CFX_ByteString CPDFSDK_BAAnnot::GetSubType() const {
537 return "";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700538}
539
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700540void CPDFSDK_BAAnnot::DrawAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800541 const CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700542 CPDF_Annot::AppearanceMode mode,
543 const CPDF_RenderOptions* pOptions) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700544 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
545 mode, pOptions);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700546}
547
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700548FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid() {
Wei Li9b761132016-01-29 15:44:20 -0800549 return m_pAnnot->GetAnnotDict()->GetDictBy("AP") != NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700550}
551
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700552FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode) {
Wei Li9b761132016-01-29 15:44:20 -0800553 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
Lei Zhang412e9082015-12-14 18:34:00 -0800554 if (!pAP)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700555 return FALSE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700556
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700557 // Choose the right sub-ap
558 const FX_CHAR* ap_entry = "N";
559 if (mode == CPDF_Annot::Down)
560 ap_entry = "D";
561 else if (mode == CPDF_Annot::Rollover)
562 ap_entry = "R";
563 if (!pAP->KeyExist(ap_entry))
564 ap_entry = "N";
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700565
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700566 // Get the AP stream or subdirectory
567 CPDF_Object* psub = pAP->GetElementValue(ap_entry);
Lei Zhang412e9082015-12-14 18:34:00 -0800568 return !!psub;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700569}
570
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700571void CPDFSDK_BAAnnot::DrawBorder(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800572 const CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700573 const CPDF_RenderOptions* pOptions) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700574 m_pAnnot->DrawBorder(pDevice, pUser2Device, pOptions);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700575}
576
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700577void CPDFSDK_BAAnnot::ClearCachedAP() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700578 m_pAnnot->ClearCachedAP();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700579}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700580
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700581void CPDFSDK_BAAnnot::SetContents(const CFX_WideString& sContents) {
582 if (sContents.IsEmpty())
583 m_pAnnot->GetAnnotDict()->RemoveAt("Contents");
584 else
585 m_pAnnot->GetAnnotDict()->SetAtString("Contents",
586 PDF_EncodeText(sContents));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700587}
588
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700589CFX_WideString CPDFSDK_BAAnnot::GetContents() const {
Wei Li9b761132016-01-29 15:44:20 -0800590 return m_pAnnot->GetAnnotDict()->GetUnicodeTextBy("Contents");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700591}
592
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700593void CPDFSDK_BAAnnot::SetAnnotName(const CFX_WideString& sName) {
594 if (sName.IsEmpty())
595 m_pAnnot->GetAnnotDict()->RemoveAt("NM");
596 else
597 m_pAnnot->GetAnnotDict()->SetAtString("NM", PDF_EncodeText(sName));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700598}
599
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700600CFX_WideString CPDFSDK_BAAnnot::GetAnnotName() const {
Wei Li9b761132016-01-29 15:44:20 -0800601 return m_pAnnot->GetAnnotDict()->GetUnicodeTextBy("NM");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700602}
603
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700604void CPDFSDK_BAAnnot::SetModifiedDate(const FX_SYSTEMTIME& st) {
605 CPDFSDK_DateTime dt(st);
606 CFX_ByteString str = dt.ToPDFDateTimeString();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700607
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700608 if (str.IsEmpty())
609 m_pAnnot->GetAnnotDict()->RemoveAt("M");
610 else
611 m_pAnnot->GetAnnotDict()->SetAtString("M", str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700612}
613
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700614FX_SYSTEMTIME CPDFSDK_BAAnnot::GetModifiedDate() const {
615 FX_SYSTEMTIME systime;
Wei Li9b761132016-01-29 15:44:20 -0800616 CFX_ByteString str = m_pAnnot->GetAnnotDict()->GetStringBy("M");
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700617
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700618 CPDFSDK_DateTime dt(str);
619 dt.ToSystemTime(systime);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700620
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700621 return systime;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700622}
623
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700624void CPDFSDK_BAAnnot::SetFlags(int nFlags) {
625 m_pAnnot->GetAnnotDict()->SetAtInteger("F", nFlags);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700626}
627
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700628int CPDFSDK_BAAnnot::GetFlags() const {
Wei Li9b761132016-01-29 15:44:20 -0800629 return m_pAnnot->GetAnnotDict()->GetIntegerBy("F");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700630}
631
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700632void CPDFSDK_BAAnnot::SetAppState(const CFX_ByteString& str) {
633 if (str.IsEmpty())
634 m_pAnnot->GetAnnotDict()->RemoveAt("AS");
635 else
636 m_pAnnot->GetAnnotDict()->SetAtString("AS", str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700637}
638
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700639CFX_ByteString CPDFSDK_BAAnnot::GetAppState() const {
Wei Li9b761132016-01-29 15:44:20 -0800640 return m_pAnnot->GetAnnotDict()->GetStringBy("AS");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700641}
642
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700643void CPDFSDK_BAAnnot::SetStructParent(int key) {
644 m_pAnnot->GetAnnotDict()->SetAtInteger("StructParent", key);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700645}
646
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700647int CPDFSDK_BAAnnot::GetStructParent() const {
Wei Li9b761132016-01-29 15:44:20 -0800648 return m_pAnnot->GetAnnotDict()->GetIntegerBy("StructParent");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700649}
650
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700651// border
652void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) {
Wei Li9b761132016-01-29 15:44:20 -0800653 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700654
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700655 if (pBorder) {
Tom Sepezae51c812015-08-05 12:34:06 -0700656 pBorder->SetAt(2, new CPDF_Number(nWidth));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700657 } else {
Wei Li9b761132016-01-29 15:44:20 -0800658 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700659
660 if (!pBSDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700661 pBSDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700662 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700663 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700664
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700665 pBSDict->SetAtInteger("W", nWidth);
666 }
667}
668
669int CPDFSDK_BAAnnot::GetBorderWidth() const {
Wei Li9b761132016-01-29 15:44:20 -0800670 if (CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border")) {
671 return pBorder->GetIntegerAt(2);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700672 }
Wei Li9b761132016-01-29 15:44:20 -0800673 if (CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS")) {
674 return pBSDict->GetIntegerBy("W", 1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700675 }
676 return 1;
677}
678
679void CPDFSDK_BAAnnot::SetBorderStyle(int nStyle) {
Wei Li9b761132016-01-29 15:44:20 -0800680 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700681 if (!pBSDict) {
682 pBSDict = new CPDF_Dictionary;
683 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
684 }
685
686 switch (nStyle) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700687 case BBS_SOLID:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700688 pBSDict->SetAtName("S", "S");
689 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700690 case BBS_DASH:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700691 pBSDict->SetAtName("S", "D");
692 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700693 case BBS_BEVELED:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700694 pBSDict->SetAtName("S", "B");
695 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700696 case BBS_INSET:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700697 pBSDict->SetAtName("S", "I");
698 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700699 case BBS_UNDERLINE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700700 pBSDict->SetAtName("S", "U");
701 break;
702 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700703}
704
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700705int CPDFSDK_BAAnnot::GetBorderStyle() const {
Wei Li9b761132016-01-29 15:44:20 -0800706 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700707 if (pBSDict) {
Wei Li9b761132016-01-29 15:44:20 -0800708 CFX_ByteString sBorderStyle = pBSDict->GetStringBy("S", "S");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700709 if (sBorderStyle == "S")
710 return BBS_SOLID;
711 if (sBorderStyle == "D")
712 return BBS_DASH;
713 if (sBorderStyle == "B")
714 return BBS_BEVELED;
715 if (sBorderStyle == "I")
716 return BBS_INSET;
717 if (sBorderStyle == "U")
718 return BBS_UNDERLINE;
719 }
720
Wei Li9b761132016-01-29 15:44:20 -0800721 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700722 if (pBorder) {
723 if (pBorder->GetCount() >= 4) {
Wei Li9b761132016-01-29 15:44:20 -0800724 CPDF_Array* pDP = pBorder->GetArrayAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700725 if (pDP && pDP->GetCount() > 0)
726 return BBS_DASH;
727 }
728 }
729
730 return BBS_SOLID;
731}
732
733void CPDFSDK_BAAnnot::SetBorderDash(const CFX_IntArray& array) {
Wei Li9b761132016-01-29 15:44:20 -0800734 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700735 if (!pBSDict) {
736 pBSDict = new CPDF_Dictionary;
737 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
738 }
739
Tom Sepezae51c812015-08-05 12:34:06 -0700740 CPDF_Array* pArray = new CPDF_Array;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700741 for (int i = 0, sz = array.GetSize(); i < sz; i++) {
742 pArray->AddInteger(array[i]);
743 }
744
745 pBSDict->SetAt("D", pArray);
746}
747
748void CPDFSDK_BAAnnot::GetBorderDash(CFX_IntArray& array) const {
749 CPDF_Array* pDash = NULL;
750
Wei Li9b761132016-01-29 15:44:20 -0800751 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700752 if (pBorder) {
Wei Li9b761132016-01-29 15:44:20 -0800753 pDash = pBorder->GetArrayAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700754 } else {
Wei Li9b761132016-01-29 15:44:20 -0800755 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700756 if (pBSDict) {
Wei Li9b761132016-01-29 15:44:20 -0800757 pDash = pBSDict->GetArrayBy("D");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700758 }
759 }
760
761 if (pDash) {
762 for (int i = 0, sz = pDash->GetCount(); i < sz; i++) {
Wei Li9b761132016-01-29 15:44:20 -0800763 array.Add(pDash->GetIntegerAt(i));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700764 }
765 }
766}
767
768void CPDFSDK_BAAnnot::SetColor(FX_COLORREF color) {
769 CPDF_Array* pArray = new CPDF_Array;
770 pArray->AddNumber((FX_FLOAT)FXSYS_GetRValue(color) / 255.0f);
771 pArray->AddNumber((FX_FLOAT)FXSYS_GetGValue(color) / 255.0f);
772 pArray->AddNumber((FX_FLOAT)FXSYS_GetBValue(color) / 255.0f);
773 m_pAnnot->GetAnnotDict()->SetAt("C", pArray);
774}
775
776void CPDFSDK_BAAnnot::RemoveColor() {
777 m_pAnnot->GetAnnotDict()->RemoveAt("C");
778}
779
780FX_BOOL CPDFSDK_BAAnnot::GetColor(FX_COLORREF& color) const {
Wei Li9b761132016-01-29 15:44:20 -0800781 if (CPDF_Array* pEntry = m_pAnnot->GetAnnotDict()->GetArrayBy("C")) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700782 int nCount = pEntry->GetCount();
783 if (nCount == 1) {
Wei Li9b761132016-01-29 15:44:20 -0800784 FX_FLOAT g = pEntry->GetNumberAt(0) * 255;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700785
786 color = FXSYS_RGB((int)g, (int)g, (int)g);
787
788 return TRUE;
789 } else if (nCount == 3) {
Wei Li9b761132016-01-29 15:44:20 -0800790 FX_FLOAT r = pEntry->GetNumberAt(0) * 255;
791 FX_FLOAT g = pEntry->GetNumberAt(1) * 255;
792 FX_FLOAT b = pEntry->GetNumberAt(2) * 255;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700793
794 color = FXSYS_RGB((int)r, (int)g, (int)b);
795
796 return TRUE;
797 } else if (nCount == 4) {
Wei Li9b761132016-01-29 15:44:20 -0800798 FX_FLOAT c = pEntry->GetNumberAt(0);
799 FX_FLOAT m = pEntry->GetNumberAt(1);
800 FX_FLOAT y = pEntry->GetNumberAt(2);
801 FX_FLOAT k = pEntry->GetNumberAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700802
Lei Zhang375a8642016-01-11 11:59:17 -0800803 FX_FLOAT r = 1.0f - std::min(1.0f, c + k);
804 FX_FLOAT g = 1.0f - std::min(1.0f, m + k);
805 FX_FLOAT b = 1.0f - std::min(1.0f, y + k);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700806
807 color = FXSYS_RGB((int)(r * 255), (int)(g * 255), (int)(b * 255));
808
809 return TRUE;
810 }
811 }
812
813 return FALSE;
814}
815
816void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType,
Tom Sepez281a9ea2016-02-26 14:24:28 -0800817 const CFX_FloatRect& rcBBox,
Tom Sepez60d909e2015-12-10 15:34:55 -0800818 const CFX_Matrix& matrix,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700819 const CFX_ByteString& sContents,
820 const CFX_ByteString& sAPState) {
Wei Li9b761132016-01-29 15:44:20 -0800821 CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700822
823 if (!pAPDict) {
824 pAPDict = new CPDF_Dictionary;
825 m_pAnnot->GetAnnotDict()->SetAt("AP", pAPDict);
826 }
827
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500828 CPDF_Stream* pStream = nullptr;
829 CPDF_Dictionary* pParentDict = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700830
831 if (sAPState.IsEmpty()) {
832 pParentDict = pAPDict;
Wei Li9b761132016-01-29 15:44:20 -0800833 pStream = pAPDict->GetStreamBy(sAPType);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700834 } else {
Wei Li9b761132016-01-29 15:44:20 -0800835 CPDF_Dictionary* pAPTypeDict = pAPDict->GetDictBy(sAPType);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700836 if (!pAPTypeDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700837 pAPTypeDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700838 pAPDict->SetAt(sAPType, pAPTypeDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700839 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700840
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700841 pParentDict = pAPTypeDict;
Wei Li9b761132016-01-29 15:44:20 -0800842 pStream = pAPTypeDict->GetStreamBy(sAPState);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700843 }
844
845 if (!pStream) {
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500846 pStream = new CPDF_Stream(nullptr, 0, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700847
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500848 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700849 int32_t objnum = pDoc->AddIndirectObject(pStream);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700850 pParentDict->SetAtReference(sAPType, pDoc, objnum);
851 }
852
853 CPDF_Dictionary* pStreamDict = pStream->GetDict();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700854 if (!pStreamDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700855 pStreamDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700856 pStreamDict->SetAtName("Type", "XObject");
857 pStreamDict->SetAtName("Subtype", "Form");
858 pStreamDict->SetAtInteger("FormType", 1);
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500859 pStream->InitStream(nullptr, 0, pStreamDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700860 }
861
862 if (pStreamDict) {
863 pStreamDict->SetAtMatrix("Matrix", matrix);
864 pStreamDict->SetAtRect("BBox", rcBBox);
865 }
866
867 pStream->SetData((uint8_t*)sContents.c_str(), sContents.GetLength(), FALSE,
868 FALSE);
869}
870
871#define BA_ANNOT_MINWIDTH 1
872#define BA_ANNOT_MINHEIGHT 1
873
874FX_FLOAT CPDFSDK_Annot::GetMinWidth() const {
875 return BA_ANNOT_MINWIDTH;
876}
877
878FX_FLOAT CPDFSDK_Annot::GetMinHeight() const {
879 return BA_ANNOT_MINHEIGHT;
880}
881
882FX_BOOL CPDFSDK_BAAnnot::CreateFormFiller() {
883 return TRUE;
884}
885FX_BOOL CPDFSDK_BAAnnot::IsVisible() const {
886 int nFlags = GetFlags();
887 return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) ||
888 (nFlags & ANNOTFLAG_NOVIEW));
889}
890
891CPDF_Action CPDFSDK_BAAnnot::GetAction() const {
Wei Li9b761132016-01-29 15:44:20 -0800892 return CPDF_Action(m_pAnnot->GetAnnotDict()->GetDictBy("A"));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700893}
894
895void CPDFSDK_BAAnnot::SetAction(const CPDF_Action& action) {
Wei Li0fc6b252016-03-01 16:29:41 -0800896 ASSERT(action.GetDict());
897 if (action.GetDict() != 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 Li0fc6b252016-03-01 16:29:41 -0800912 return CPDF_AAction(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 Li0fc6b252016-03-01 16:29:41 -0800916 if (aa.GetDict() != m_pAnnot->GetAnnotDict()->GetDictBy("AA"))
917 m_pAnnot->GetAnnotDict()->SetAt("AA", aa.GetDict());
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