blob: b3363bfbc797628b92452f5e5effc850902a14a0 [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 Sinclairaa403d32016-03-15 14:57:22 -04009#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
10#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
11#include "core/fpdfapi/fpdf_parser/include/cpdf_number.h"
Dan Sinclair584b1e62016-03-21 09:15:45 -040012#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
Dan Sinclaira8a28e02016-03-23 15:41:39 -040013#include "core/fxcrt/include/fx_ext.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080014#include "fpdfsdk/include/fsdk_baseannot.h"
15#include "fpdfsdk/include/fsdk_define.h"
16#include "fpdfsdk/include/fsdk_mgr.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070017
Tom Sepez40e9ff32015-11-30 12:39:54 -080018#ifdef PDF_ENABLE_XFA
dsinclair89bdd082016-04-06 10:47:54 -070019#include "fpdfsdk/fpdfxfa/include/fpdfxfa_doc.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080020#endif // PDF_ENABLE_XFA
21
Lei Zhang4467dea2016-02-25 12:39:15 -080022int gAfxGetTimeZoneInSeconds(int8_t tzhour, uint8_t tzminute) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070023 return (int)tzhour * 3600 + (int)tzminute * (tzhour >= 0 ? 60 : -60);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070024}
25
Nico Weber9d8ec5a2015-08-04 13:00:21 -070026FX_BOOL _gAfxIsLeapYear(int16_t year) {
27 return ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070028}
29
Tom Sepez62a70f92016-03-21 15:00:20 -070030uint16_t _gAfxGetYearDays(int16_t year) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070031 return (_gAfxIsLeapYear(year) == TRUE ? 366 : 365);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070032}
33
Nico Weber9d8ec5a2015-08-04 13:00:21 -070034uint8_t _gAfxGetMonthDays(int16_t year, uint8_t month) {
35 uint8_t mDays;
36 switch (month) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -070037 case 1:
38 case 3:
39 case 5:
40 case 7:
41 case 8:
42 case 10:
43 case 12:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070044 mDays = 31;
45 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070046
Tom Sepez2f2ffec2015-07-23 14:42:09 -070047 case 4:
48 case 6:
49 case 9:
50 case 11:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070051 mDays = 30;
52 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070053
Tom Sepez2f2ffec2015-07-23 14:42:09 -070054 case 2:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070055 if (_gAfxIsLeapYear(year) == TRUE)
56 mDays = 29;
57 else
58 mDays = 28;
59 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070060
Tom Sepez2f2ffec2015-07-23 14:42:09 -070061 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070062 mDays = 0;
63 break;
64 }
65
66 return mDays;
67}
68
69CPDFSDK_DateTime::CPDFSDK_DateTime() {
70 ResetDateTime();
71}
72
73CPDFSDK_DateTime::CPDFSDK_DateTime(const CFX_ByteString& dtStr) {
74 ResetDateTime();
75
76 FromPDFDateTimeString(dtStr);
77}
78
79CPDFSDK_DateTime::CPDFSDK_DateTime(const CPDFSDK_DateTime& datetime) {
80 operator=(datetime);
81}
82
83CPDFSDK_DateTime::CPDFSDK_DateTime(const FX_SYSTEMTIME& st) {
84 operator=(st);
85}
86
87void CPDFSDK_DateTime::ResetDateTime() {
88 tzset();
89
90 time_t curTime;
91 time(&curTime);
Tom Sepez007e6c02016-02-26 14:31:56 -080092 struct tm* newtime = localtime(&curTime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070093
94 dt.year = newtime->tm_year + 1900;
95 dt.month = newtime->tm_mon + 1;
96 dt.day = newtime->tm_mday;
97 dt.hour = newtime->tm_hour;
98 dt.minute = newtime->tm_min;
99 dt.second = newtime->tm_sec;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100}
101
102CPDFSDK_DateTime& CPDFSDK_DateTime::operator=(
103 const CPDFSDK_DateTime& datetime) {
104 FXSYS_memcpy(&dt, &datetime.dt, sizeof(FX_DATETIME));
105 return *this;
106}
107
108CPDFSDK_DateTime& CPDFSDK_DateTime::operator=(const FX_SYSTEMTIME& st) {
109 tzset();
110
111 dt.year = (int16_t)st.wYear;
112 dt.month = (uint8_t)st.wMonth;
113 dt.day = (uint8_t)st.wDay;
114 dt.hour = (uint8_t)st.wHour;
115 dt.minute = (uint8_t)st.wMinute;
116 dt.second = (uint8_t)st.wSecond;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700117 return *this;
118}
119
Tom Sepez007e6c02016-02-26 14:31:56 -0800120bool CPDFSDK_DateTime::operator==(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121 return (FXSYS_memcmp(&dt, &datetime.dt, sizeof(FX_DATETIME)) == 0);
122}
123
Tom Sepez007e6c02016-02-26 14:31:56 -0800124bool CPDFSDK_DateTime::operator!=(const CPDFSDK_DateTime& datetime) const {
125 return !(*this == datetime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126}
127
Tom Sepez007e6c02016-02-26 14:31:56 -0800128bool CPDFSDK_DateTime::operator>(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700129 CPDFSDK_DateTime dt1 = ToGMT();
130 CPDFSDK_DateTime dt2 = datetime.ToGMT();
131 int d1 =
132 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
133 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
134 (int)dt1.dt.second;
135 int d3 =
136 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
137 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
138 (int)dt2.dt.second;
139
Tom Sepez007e6c02016-02-26 14:31:56 -0800140 return d1 > d3 || d2 > d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700141}
142
Tom Sepez007e6c02016-02-26 14:31:56 -0800143bool CPDFSDK_DateTime::operator>=(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 CPDFSDK_DateTime dt1 = ToGMT();
145 CPDFSDK_DateTime dt2 = datetime.ToGMT();
146 int d1 =
147 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
148 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
149 (int)dt1.dt.second;
150 int d3 =
151 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
152 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
153 (int)dt2.dt.second;
154
Tom Sepez007e6c02016-02-26 14:31:56 -0800155 return d1 >= d3 || d2 >= d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700156}
157
Tom Sepez007e6c02016-02-26 14:31:56 -0800158bool CPDFSDK_DateTime::operator<(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 CPDFSDK_DateTime dt1 = ToGMT();
160 CPDFSDK_DateTime dt2 = datetime.ToGMT();
161 int d1 =
162 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
163 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
164 (int)dt1.dt.second;
165 int d3 =
166 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
167 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
168 (int)dt2.dt.second;
169
Tom Sepez007e6c02016-02-26 14:31:56 -0800170 return d1 < d3 || d2 < d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171}
172
Tom Sepez007e6c02016-02-26 14:31:56 -0800173bool CPDFSDK_DateTime::operator<=(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700174 CPDFSDK_DateTime dt1 = ToGMT();
175 CPDFSDK_DateTime dt2 = datetime.ToGMT();
176 int d1 =
177 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
178 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
179 (int)dt1.dt.second;
180 int d3 =
181 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
182 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
183 (int)dt2.dt.second;
184
Tom Sepez007e6c02016-02-26 14:31:56 -0800185 return d1 <= d3 || d2 <= d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700186}
187
188CPDFSDK_DateTime::operator time_t() {
189 struct tm newtime;
190
191 newtime.tm_year = dt.year - 1900;
192 newtime.tm_mon = dt.month - 1;
193 newtime.tm_mday = dt.day;
194 newtime.tm_hour = dt.hour;
195 newtime.tm_min = dt.minute;
196 newtime.tm_sec = dt.second;
197
198 return mktime(&newtime);
199}
200
201CPDFSDK_DateTime& CPDFSDK_DateTime::FromPDFDateTimeString(
202 const CFX_ByteString& dtStr) {
203 int strLength = dtStr.GetLength();
204 if (strLength > 0) {
205 int i = 0;
206 int j, k;
207 FX_CHAR ch;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500208 while (i < strLength && !std::isdigit(dtStr[i]))
209 ++i;
210
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700211 if (i >= strLength)
212 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700213
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700214 j = 0;
215 k = 0;
216 while (i < strLength && j < 4) {
217 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500218 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700219 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500220 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700221 break;
222 i++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700223 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700224 dt.year = (int16_t)k;
225 if (i >= strLength || j < 4)
226 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700227
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228 j = 0;
229 k = 0;
230 while (i < strLength && j < 2) {
231 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500232 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700233 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500234 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235 break;
236 i++;
237 }
238 dt.month = (uint8_t)k;
239 if (i >= strLength || j < 2)
240 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700241
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242 j = 0;
243 k = 0;
244 while (i < strLength && j < 2) {
245 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500246 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500248 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249 break;
250 i++;
251 }
252 dt.day = (uint8_t)k;
253 if (i >= strLength || j < 2)
254 return *this;
255
256 j = 0;
257 k = 0;
258 while (i < strLength && j < 2) {
259 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500260 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700261 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500262 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263 break;
264 i++;
265 }
266 dt.hour = (uint8_t)k;
267 if (i >= strLength || j < 2)
268 return *this;
269
270 j = 0;
271 k = 0;
272 while (i < strLength && j < 2) {
273 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500274 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500276 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277 break;
278 i++;
279 }
280 dt.minute = (uint8_t)k;
281 if (i >= strLength || j < 2)
282 return *this;
283
284 j = 0;
285 k = 0;
286 while (i < strLength && j < 2) {
287 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500288 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700289 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500290 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700291 break;
292 i++;
293 }
294 dt.second = (uint8_t)k;
295 if (i >= strLength || j < 2)
296 return *this;
297
298 ch = dtStr[i++];
299 if (ch != '-' && ch != '+')
300 return *this;
301 if (ch == '-')
302 dt.tzHour = -1;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700303 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700304 dt.tzHour = 1;
305 j = 0;
306 k = 0;
307 while (i < strLength && j < 2) {
308 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500309 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700310 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500311 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700312 break;
313 i++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700314 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700315 dt.tzHour *= (FX_CHAR)k;
316 if (i >= strLength || j < 2)
317 return *this;
318
319 ch = dtStr[i++];
320 if (ch != '\'')
321 return *this;
322 j = 0;
323 k = 0;
324 while (i < strLength && j < 2) {
325 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500326 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700327 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500328 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700329 break;
330 i++;
331 }
332 dt.tzMinute = (uint8_t)k;
333 if (i >= strLength || j < 2)
334 return *this;
335 }
336
337 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700338}
339
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700340CFX_ByteString CPDFSDK_DateTime::ToCommonDateTimeString() {
341 CFX_ByteString str1;
342 str1.Format("%04d-%02d-%02d %02d:%02d:%02d ", dt.year, dt.month, dt.day,
343 dt.hour, dt.minute, dt.second);
344 if (dt.tzHour < 0)
345 str1 += "-";
346 else
347 str1 += "+";
348 CFX_ByteString str2;
349 str2.Format("%02d:%02d", abs(dt.tzHour), dt.tzMinute);
350 return str1 + str2;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700351}
352
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700353CFX_ByteString CPDFSDK_DateTime::ToPDFDateTimeString() {
354 CFX_ByteString dtStr;
355 char tempStr[32];
356 memset(tempStr, 0, sizeof(tempStr));
357 FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "D:%04d%02d%02d%02d%02d%02d",
358 dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
359 dtStr = CFX_ByteString(tempStr);
360 if (dt.tzHour < 0)
361 dtStr += CFX_ByteString("-");
362 else
363 dtStr += CFX_ByteString("+");
364 memset(tempStr, 0, sizeof(tempStr));
365 FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "%02d'%02d'", abs(dt.tzHour),
366 dt.tzMinute);
367 dtStr += CFX_ByteString(tempStr);
368 return dtStr;
369}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700370
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700371void CPDFSDK_DateTime::ToSystemTime(FX_SYSTEMTIME& st) {
372 CPDFSDK_DateTime dt = *this;
373 time_t t = (time_t)dt;
374 struct tm* pTime = localtime(&t);
375 if (pTime) {
Tom Sepez62a70f92016-03-21 15:00:20 -0700376 st.wYear = (uint16_t)pTime->tm_year + 1900;
377 st.wMonth = (uint16_t)pTime->tm_mon + 1;
378 st.wDay = (uint16_t)pTime->tm_mday;
379 st.wDayOfWeek = (uint16_t)pTime->tm_wday;
380 st.wHour = (uint16_t)pTime->tm_hour;
381 st.wMinute = (uint16_t)pTime->tm_min;
382 st.wSecond = (uint16_t)pTime->tm_sec;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700383 st.wMilliseconds = 0;
384 }
385}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700386
Tom Sepez007e6c02016-02-26 14:31:56 -0800387CPDFSDK_DateTime CPDFSDK_DateTime::ToGMT() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700388 CPDFSDK_DateTime dt = *this;
Lei Zhang4467dea2016-02-25 12:39:15 -0800389 dt.AddSeconds(-gAfxGetTimeZoneInSeconds(dt.dt.tzHour, dt.dt.tzMinute));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700390 dt.dt.tzHour = 0;
391 dt.dt.tzMinute = 0;
392 return dt;
393}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700394
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700395CPDFSDK_DateTime& CPDFSDK_DateTime::AddDays(short days) {
396 if (days == 0)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700397 return *this;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700398
399 int16_t y = dt.year, yy;
400 uint8_t m = dt.month;
401 uint8_t d = dt.day;
402 int mdays, ydays, ldays;
403
404 ldays = days;
405 if (ldays > 0) {
406 yy = y;
Tom Sepez62a70f92016-03-21 15:00:20 -0700407 if (((uint16_t)m * 100 + d) > 300)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700408 yy++;
409 ydays = _gAfxGetYearDays(yy);
410 while (ldays >= ydays) {
411 y++;
412 ldays -= ydays;
413 yy++;
414 mdays = _gAfxGetMonthDays(y, m);
415 if (d > mdays) {
416 m++;
417 d -= mdays;
418 }
419 ydays = _gAfxGetYearDays(yy);
420 }
421 mdays = _gAfxGetMonthDays(y, m) - d + 1;
422 while (ldays >= mdays) {
423 ldays -= mdays;
424 m++;
425 d = 1;
426 mdays = _gAfxGetMonthDays(y, m);
427 }
428 d += ldays;
429 } else {
430 ldays *= -1;
431 yy = y;
Tom Sepez62a70f92016-03-21 15:00:20 -0700432 if (((uint16_t)m * 100 + d) < 300)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700433 yy--;
434 ydays = _gAfxGetYearDays(yy);
435 while (ldays >= ydays) {
436 y--;
437 ldays -= ydays;
438 yy--;
439 mdays = _gAfxGetMonthDays(y, m);
440 if (d > mdays) {
441 m++;
442 d -= mdays;
443 }
444 ydays = _gAfxGetYearDays(yy);
445 }
446 while (ldays >= d) {
447 ldays -= d;
448 m--;
449 mdays = _gAfxGetMonthDays(y, m);
450 d = mdays;
451 }
452 d -= ldays;
453 }
454
455 dt.year = y;
456 dt.month = m;
457 dt.day = d;
458
459 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700460}
461
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700462CPDFSDK_DateTime& CPDFSDK_DateTime::AddSeconds(int seconds) {
463 if (seconds == 0)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700464 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700465
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700466 int n;
467 int days;
468
469 n = dt.hour * 3600 + dt.minute * 60 + dt.second + seconds;
470 if (n < 0) {
471 days = (n - 86399) / 86400;
472 n -= days * 86400;
473 } else {
474 days = n / 86400;
475 n %= 86400;
476 }
477 dt.hour = (uint8_t)(n / 3600);
478 dt.hour %= 24;
479 n %= 3600;
480 dt.minute = (uint8_t)(n / 60);
481 dt.second = (uint8_t)(n % 60);
482 if (days != 0)
483 AddDays(days);
484
485 return *this;
486}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700487
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700488CPDFSDK_Annot::CPDFSDK_Annot(CPDFSDK_PageView* pPageView)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400489 : m_pPageView(pPageView), m_bSelected(FALSE), m_nTabOrder(-1) {}
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 Sinclairf766ad22016-03-14 13:51:24 -0400493 : CPDFSDK_Annot(pPageView), m_pAnnot(pAnnot) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700494
Tom Sepez3343d142015-11-02 09:54:54 -0800495CPDF_Annot* CPDFSDK_BAAnnot::GetPDFAnnot() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700496 return m_pAnnot;
Bo Xufdc00a72014-10-28 23:03:33 -0700497}
498
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700499FX_BOOL CPDFSDK_Annot::IsSelected() {
500 return m_bSelected;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700501}
502
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700503void CPDFSDK_Annot::SetSelected(FX_BOOL bSelected) {
504 m_bSelected = bSelected;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700505}
506
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700507// Tab Order
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700508int CPDFSDK_Annot::GetTabOrder() {
509 return m_nTabOrder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700510}
511
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700512void CPDFSDK_Annot::SetTabOrder(int iTabOrder) {
513 m_nTabOrder = iTabOrder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700514}
515
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700516CPDF_Dictionary* CPDFSDK_BAAnnot::GetAnnotDict() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700517 return m_pAnnot->GetAnnotDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700518}
519
Tom Sepez281a9ea2016-02-26 14:24:28 -0800520void CPDFSDK_BAAnnot::SetRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700521 ASSERT(rect.right - rect.left >= GetMinWidth());
522 ASSERT(rect.top - rect.bottom >= GetMinHeight());
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700523
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700524 m_pAnnot->GetAnnotDict()->SetAtRect("Rect", rect);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700525}
526
Tom Sepez281a9ea2016-02-26 14:24:28 -0800527CFX_FloatRect CPDFSDK_BAAnnot::GetRect() const {
528 CFX_FloatRect rect;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700529 m_pAnnot->GetRect(rect);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700530 return rect;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700531}
532
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700533CFX_ByteString CPDFSDK_BAAnnot::GetType() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700534 return m_pAnnot->GetSubType();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700535}
536
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700537CFX_ByteString CPDFSDK_BAAnnot::GetSubType() const {
538 return "";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700539}
540
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700541void CPDFSDK_BAAnnot::DrawAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800542 const CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700543 CPDF_Annot::AppearanceMode mode,
544 const CPDF_RenderOptions* pOptions) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700545 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
546 mode, pOptions);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700547}
548
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700549FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid() {
Wei Li9b761132016-01-29 15:44:20 -0800550 return m_pAnnot->GetAnnotDict()->GetDictBy("AP") != NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700551}
552
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700553FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode) {
Wei Li9b761132016-01-29 15:44:20 -0800554 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
Lei Zhang412e9082015-12-14 18:34:00 -0800555 if (!pAP)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700556 return FALSE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700557
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700558 // Choose the right sub-ap
559 const FX_CHAR* ap_entry = "N";
560 if (mode == CPDF_Annot::Down)
561 ap_entry = "D";
562 else if (mode == CPDF_Annot::Rollover)
563 ap_entry = "R";
564 if (!pAP->KeyExist(ap_entry))
565 ap_entry = "N";
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700566
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700567 // Get the AP stream or subdirectory
tsepezbd567552016-03-29 14:51:50 -0700568 CPDF_Object* psub = pAP->GetDirectObjectBy(ap_entry);
Lei Zhang412e9082015-12-14 18:34:00 -0800569 return !!psub;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700570}
571
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700572void CPDFSDK_BAAnnot::DrawBorder(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800573 const CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700574 const CPDF_RenderOptions* pOptions) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700575 m_pAnnot->DrawBorder(pDevice, pUser2Device, pOptions);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700576}
577
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700578void CPDFSDK_BAAnnot::ClearCachedAP() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700579 m_pAnnot->ClearCachedAP();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700580}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700581
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700582void CPDFSDK_BAAnnot::SetContents(const CFX_WideString& sContents) {
583 if (sContents.IsEmpty())
584 m_pAnnot->GetAnnotDict()->RemoveAt("Contents");
585 else
586 m_pAnnot->GetAnnotDict()->SetAtString("Contents",
587 PDF_EncodeText(sContents));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700588}
589
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700590CFX_WideString CPDFSDK_BAAnnot::GetContents() const {
Wei Li9b761132016-01-29 15:44:20 -0800591 return m_pAnnot->GetAnnotDict()->GetUnicodeTextBy("Contents");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700592}
593
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700594void CPDFSDK_BAAnnot::SetAnnotName(const CFX_WideString& sName) {
595 if (sName.IsEmpty())
596 m_pAnnot->GetAnnotDict()->RemoveAt("NM");
597 else
598 m_pAnnot->GetAnnotDict()->SetAtString("NM", PDF_EncodeText(sName));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700599}
600
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700601CFX_WideString CPDFSDK_BAAnnot::GetAnnotName() const {
Wei Li9b761132016-01-29 15:44:20 -0800602 return m_pAnnot->GetAnnotDict()->GetUnicodeTextBy("NM");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700603}
604
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700605void CPDFSDK_BAAnnot::SetModifiedDate(const FX_SYSTEMTIME& st) {
606 CPDFSDK_DateTime dt(st);
607 CFX_ByteString str = dt.ToPDFDateTimeString();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700608
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700609 if (str.IsEmpty())
610 m_pAnnot->GetAnnotDict()->RemoveAt("M");
611 else
612 m_pAnnot->GetAnnotDict()->SetAtString("M", str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700613}
614
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700615FX_SYSTEMTIME CPDFSDK_BAAnnot::GetModifiedDate() const {
616 FX_SYSTEMTIME systime;
Wei Li9b761132016-01-29 15:44:20 -0800617 CFX_ByteString str = m_pAnnot->GetAnnotDict()->GetStringBy("M");
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700618
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700619 CPDFSDK_DateTime dt(str);
620 dt.ToSystemTime(systime);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700621
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700622 return systime;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700623}
624
tsepezc3255f52016-03-25 14:52:27 -0700625void CPDFSDK_BAAnnot::SetFlags(uint32_t nFlags) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700626 m_pAnnot->GetAnnotDict()->SetAtInteger("F", nFlags);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700627}
628
tsepezc3255f52016-03-25 14:52:27 -0700629uint32_t CPDFSDK_BAAnnot::GetFlags() const {
Wei Li9b761132016-01-29 15:44:20 -0800630 return m_pAnnot->GetAnnotDict()->GetIntegerBy("F");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700631}
632
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700633void CPDFSDK_BAAnnot::SetAppState(const CFX_ByteString& str) {
634 if (str.IsEmpty())
635 m_pAnnot->GetAnnotDict()->RemoveAt("AS");
636 else
637 m_pAnnot->GetAnnotDict()->SetAtString("AS", str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700638}
639
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700640CFX_ByteString CPDFSDK_BAAnnot::GetAppState() const {
Wei Li9b761132016-01-29 15:44:20 -0800641 return m_pAnnot->GetAnnotDict()->GetStringBy("AS");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700642}
643
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700644void CPDFSDK_BAAnnot::SetStructParent(int key) {
645 m_pAnnot->GetAnnotDict()->SetAtInteger("StructParent", key);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700646}
647
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700648int CPDFSDK_BAAnnot::GetStructParent() const {
Wei Li9b761132016-01-29 15:44:20 -0800649 return m_pAnnot->GetAnnotDict()->GetIntegerBy("StructParent");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700650}
651
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700652// border
653void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) {
Wei Li9b761132016-01-29 15:44:20 -0800654 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700655
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700656 if (pBorder) {
Tom Sepezae51c812015-08-05 12:34:06 -0700657 pBorder->SetAt(2, new CPDF_Number(nWidth));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700658 } else {
Wei Li9b761132016-01-29 15:44:20 -0800659 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700660
661 if (!pBSDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700662 pBSDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700663 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700664 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700665
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700666 pBSDict->SetAtInteger("W", nWidth);
667 }
668}
669
670int CPDFSDK_BAAnnot::GetBorderWidth() const {
Wei Li9b761132016-01-29 15:44:20 -0800671 if (CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border")) {
672 return pBorder->GetIntegerAt(2);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700673 }
Wei Li9b761132016-01-29 15:44:20 -0800674 if (CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS")) {
675 return pBSDict->GetIntegerBy("W", 1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700676 }
677 return 1;
678}
679
680void CPDFSDK_BAAnnot::SetBorderStyle(int nStyle) {
Wei Li9b761132016-01-29 15:44:20 -0800681 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700682 if (!pBSDict) {
683 pBSDict = new CPDF_Dictionary;
684 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
685 }
686
687 switch (nStyle) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700688 case BBS_SOLID:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700689 pBSDict->SetAtName("S", "S");
690 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700691 case BBS_DASH:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700692 pBSDict->SetAtName("S", "D");
693 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700694 case BBS_BEVELED:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700695 pBSDict->SetAtName("S", "B");
696 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700697 case BBS_INSET:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700698 pBSDict->SetAtName("S", "I");
699 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700700 case BBS_UNDERLINE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700701 pBSDict->SetAtName("S", "U");
702 break;
703 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700704}
705
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700706int CPDFSDK_BAAnnot::GetBorderStyle() const {
Wei Li9b761132016-01-29 15:44:20 -0800707 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700708 if (pBSDict) {
Wei Li9b761132016-01-29 15:44:20 -0800709 CFX_ByteString sBorderStyle = pBSDict->GetStringBy("S", "S");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700710 if (sBorderStyle == "S")
711 return BBS_SOLID;
712 if (sBorderStyle == "D")
713 return BBS_DASH;
714 if (sBorderStyle == "B")
715 return BBS_BEVELED;
716 if (sBorderStyle == "I")
717 return BBS_INSET;
718 if (sBorderStyle == "U")
719 return BBS_UNDERLINE;
720 }
721
Wei Li9b761132016-01-29 15:44:20 -0800722 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700723 if (pBorder) {
724 if (pBorder->GetCount() >= 4) {
Wei Li9b761132016-01-29 15:44:20 -0800725 CPDF_Array* pDP = pBorder->GetArrayAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700726 if (pDP && pDP->GetCount() > 0)
727 return BBS_DASH;
728 }
729 }
730
731 return BBS_SOLID;
732}
733
734void CPDFSDK_BAAnnot::SetBorderDash(const CFX_IntArray& array) {
Wei Li9b761132016-01-29 15:44:20 -0800735 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700736 if (!pBSDict) {
737 pBSDict = new CPDF_Dictionary;
738 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
739 }
740
Tom Sepezae51c812015-08-05 12:34:06 -0700741 CPDF_Array* pArray = new CPDF_Array;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700742 for (int i = 0, sz = array.GetSize(); i < sz; i++) {
743 pArray->AddInteger(array[i]);
744 }
745
746 pBSDict->SetAt("D", pArray);
747}
748
749void CPDFSDK_BAAnnot::GetBorderDash(CFX_IntArray& array) const {
750 CPDF_Array* pDash = NULL;
751
Wei Li9b761132016-01-29 15:44:20 -0800752 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700753 if (pBorder) {
Wei Li9b761132016-01-29 15:44:20 -0800754 pDash = pBorder->GetArrayAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700755 } else {
Wei Li9b761132016-01-29 15:44:20 -0800756 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700757 if (pBSDict) {
Wei Li9b761132016-01-29 15:44:20 -0800758 pDash = pBSDict->GetArrayBy("D");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700759 }
760 }
761
762 if (pDash) {
763 for (int i = 0, sz = pDash->GetCount(); i < sz; i++) {
Wei Li9b761132016-01-29 15:44:20 -0800764 array.Add(pDash->GetIntegerAt(i));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700765 }
766 }
767}
768
769void CPDFSDK_BAAnnot::SetColor(FX_COLORREF color) {
770 CPDF_Array* pArray = new CPDF_Array;
771 pArray->AddNumber((FX_FLOAT)FXSYS_GetRValue(color) / 255.0f);
772 pArray->AddNumber((FX_FLOAT)FXSYS_GetGValue(color) / 255.0f);
773 pArray->AddNumber((FX_FLOAT)FXSYS_GetBValue(color) / 255.0f);
774 m_pAnnot->GetAnnotDict()->SetAt("C", pArray);
775}
776
777void CPDFSDK_BAAnnot::RemoveColor() {
778 m_pAnnot->GetAnnotDict()->RemoveAt("C");
779}
780
781FX_BOOL CPDFSDK_BAAnnot::GetColor(FX_COLORREF& color) const {
Wei Li9b761132016-01-29 15:44:20 -0800782 if (CPDF_Array* pEntry = m_pAnnot->GetAnnotDict()->GetArrayBy("C")) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700783 int nCount = pEntry->GetCount();
784 if (nCount == 1) {
Wei Li9b761132016-01-29 15:44:20 -0800785 FX_FLOAT g = pEntry->GetNumberAt(0) * 255;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700786
787 color = FXSYS_RGB((int)g, (int)g, (int)g);
788
789 return TRUE;
790 } else if (nCount == 3) {
Wei Li9b761132016-01-29 15:44:20 -0800791 FX_FLOAT r = pEntry->GetNumberAt(0) * 255;
792 FX_FLOAT g = pEntry->GetNumberAt(1) * 255;
793 FX_FLOAT b = pEntry->GetNumberAt(2) * 255;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700794
795 color = FXSYS_RGB((int)r, (int)g, (int)b);
796
797 return TRUE;
798 } else if (nCount == 4) {
Wei Li9b761132016-01-29 15:44:20 -0800799 FX_FLOAT c = pEntry->GetNumberAt(0);
800 FX_FLOAT m = pEntry->GetNumberAt(1);
801 FX_FLOAT y = pEntry->GetNumberAt(2);
802 FX_FLOAT k = pEntry->GetNumberAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700803
Lei Zhang375a8642016-01-11 11:59:17 -0800804 FX_FLOAT r = 1.0f - std::min(1.0f, c + k);
805 FX_FLOAT g = 1.0f - std::min(1.0f, m + k);
806 FX_FLOAT b = 1.0f - std::min(1.0f, y + k);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700807
808 color = FXSYS_RGB((int)(r * 255), (int)(g * 255), (int)(b * 255));
809
810 return TRUE;
811 }
812 }
813
814 return FALSE;
815}
816
817void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType,
Tom Sepez281a9ea2016-02-26 14:24:28 -0800818 const CFX_FloatRect& rcBBox,
Tom Sepez60d909e2015-12-10 15:34:55 -0800819 const CFX_Matrix& matrix,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700820 const CFX_ByteString& sContents,
821 const CFX_ByteString& sAPState) {
Wei Li9b761132016-01-29 15:44:20 -0800822 CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700823
824 if (!pAPDict) {
825 pAPDict = new CPDF_Dictionary;
826 m_pAnnot->GetAnnotDict()->SetAt("AP", pAPDict);
827 }
828
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500829 CPDF_Stream* pStream = nullptr;
830 CPDF_Dictionary* pParentDict = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700831
832 if (sAPState.IsEmpty()) {
833 pParentDict = pAPDict;
tsepez28f97ff2016-04-04 16:41:35 -0700834 pStream = pAPDict->GetStreamBy(sAPType.AsByteStringC());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700835 } else {
tsepez28f97ff2016-04-04 16:41:35 -0700836 CPDF_Dictionary* pAPTypeDict = pAPDict->GetDictBy(sAPType.AsByteStringC());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700837 if (!pAPTypeDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700838 pAPTypeDict = new CPDF_Dictionary;
tsepez28f97ff2016-04-04 16:41:35 -0700839 pAPDict->SetAt(sAPType.AsByteStringC(), pAPTypeDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700840 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700841 pParentDict = pAPTypeDict;
tsepez28f97ff2016-04-04 16:41:35 -0700842 pStream = pAPTypeDict->GetStreamBy(sAPState.AsByteStringC());
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);
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);
tsepez28f97ff2016-04-04 16:41:35 -0700849 pParentDict->SetAtReference(sAPType.AsByteStringC(), pDoc, objnum);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700850 }
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 {
tsepezc3255f52016-03-25 14:52:27 -0700885 uint32_t nFlags = GetFlags();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700886 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) {
Wei Li0fc6b252016-03-01 16:29:41 -0800895 ASSERT(action.GetDict());
896 if (action.GetDict() != m_pAnnot->GetAnnotDict()->GetDictBy("A")) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700897 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
898 CPDF_Dictionary* pDict = action.GetDict();
899 if (pDict && pDict->GetObjNum() == 0) {
900 pDoc->AddIndirectObject(pDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700901 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700902 m_pAnnot->GetAnnotDict()->SetAtReference("A", pDoc, pDict->GetObjNum());
903 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700904}
905
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700906void CPDFSDK_BAAnnot::RemoveAction() {
907 m_pAnnot->GetAnnotDict()->RemoveAt("A");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700908}
909
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700910CPDF_AAction CPDFSDK_BAAnnot::GetAAction() const {
Wei Li0fc6b252016-03-01 16:29:41 -0800911 return CPDF_AAction(m_pAnnot->GetAnnotDict()->GetDictBy("AA"));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700912}
913
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700914void CPDFSDK_BAAnnot::SetAAction(const CPDF_AAction& aa) {
Wei Li0fc6b252016-03-01 16:29:41 -0800915 if (aa.GetDict() != m_pAnnot->GetAnnotDict()->GetDictBy("AA"))
916 m_pAnnot->GetAnnotDict()->SetAt("AA", aa.GetDict());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700917}
918
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700919void CPDFSDK_BAAnnot::RemoveAAction() {
920 m_pAnnot->GetAnnotDict()->RemoveAt("AA");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700921}
922
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700923CPDF_Action CPDFSDK_BAAnnot::GetAAction(CPDF_AAction::AActionType eAAT) {
924 CPDF_AAction AAction = GetAAction();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700925
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700926 if (AAction.ActionExist(eAAT))
927 return AAction.GetAction(eAAT);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700928
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700929 if (eAAT == CPDF_AAction::ButtonUp)
930 return GetAction();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700931
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700932 return CPDF_Action();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700933}
934
Tom Sepez51da0932015-11-25 16:05:49 -0800935#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700936FX_BOOL CPDFSDK_BAAnnot::IsXFAField() {
937 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700938}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800939#endif // PDF_ENABLE_XFA
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700940
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700941void CPDFSDK_BAAnnot::Annot_OnDraw(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800942 CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700943 CPDF_RenderOptions* pOptions) {
944 m_pAnnot->GetAPForm(m_pPageView->GetPDFPage(), CPDF_Annot::Normal);
945 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
946 CPDF_Annot::Normal, NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700947}
948
Tom Sepez50d12ad2015-11-24 09:50:51 -0800949UnderlyingPageType* CPDFSDK_Annot::GetUnderlyingPage() {
Tom Sepez40e9ff32015-11-30 12:39:54 -0800950#ifdef PDF_ENABLE_XFA
Tom Sepez50d12ad2015-11-24 09:50:51 -0800951 return GetPDFXFAPage();
Tom Sepez40e9ff32015-11-30 12:39:54 -0800952#else // PDF_ENABLE_XFA
953 return GetPDFPage();
954#endif // PDF_ENABLE_XFA
Tom Sepez50d12ad2015-11-24 09:50:51 -0800955}
956
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700957CPDF_Page* CPDFSDK_Annot::GetPDFPage() {
Lei Zhang05e67412016-01-25 16:35:42 -0800958 return m_pPageView ? m_pPageView->GetPDFPage() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700959}
960
Tom Sepez40e9ff32015-11-30 12:39:54 -0800961#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700962CPDFXFA_Page* CPDFSDK_Annot::GetPDFXFAPage() {
Lei Zhang05e67412016-01-25 16:35:42 -0800963 return m_pPageView ? m_pPageView->GetPDFXFAPage() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700964}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800965#endif // PDF_ENABLE_XFA