blob: e2ee6f7c73f5fc6a2286727ddbdffd53a6d91f38 [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
dsinclair92cb5e52016-05-16 11:38:28 -070022namespace {
23
24const float kMinWidth = 1.0f;
25const float kMinHeight = 1.0f;
26
Lei Zhang4467dea2016-02-25 12:39:15 -080027int gAfxGetTimeZoneInSeconds(int8_t tzhour, uint8_t tzminute) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070028 return (int)tzhour * 3600 + (int)tzminute * (tzhour >= 0 ? 60 : -60);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070029}
30
dsinclair92cb5e52016-05-16 11:38:28 -070031bool gAfxIsLeapYear(int16_t year) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070032 return ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070033}
34
dsinclair92cb5e52016-05-16 11:38:28 -070035uint16_t gAfxGetYearDays(int16_t year) {
36 return (gAfxIsLeapYear(year) ? 366 : 365);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070037}
38
dsinclair92cb5e52016-05-16 11:38:28 -070039uint8_t gAfxGetMonthDays(int16_t year, uint8_t month) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070040 uint8_t mDays;
41 switch (month) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -070042 case 1:
43 case 3:
44 case 5:
45 case 7:
46 case 8:
47 case 10:
48 case 12:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070049 mDays = 31;
50 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070051
Tom Sepez2f2ffec2015-07-23 14:42:09 -070052 case 4:
53 case 6:
54 case 9:
55 case 11:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070056 mDays = 30;
57 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070058
Tom Sepez2f2ffec2015-07-23 14:42:09 -070059 case 2:
dsinclair92cb5e52016-05-16 11:38:28 -070060 if (gAfxIsLeapYear(year))
Nico Weber9d8ec5a2015-08-04 13:00:21 -070061 mDays = 29;
62 else
63 mDays = 28;
64 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070065
Tom Sepez2f2ffec2015-07-23 14:42:09 -070066 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -070067 mDays = 0;
68 break;
69 }
70
71 return mDays;
72}
73
dsinclair92cb5e52016-05-16 11:38:28 -070074} // namespace
75
Nico Weber9d8ec5a2015-08-04 13:00:21 -070076CPDFSDK_DateTime::CPDFSDK_DateTime() {
77 ResetDateTime();
78}
79
80CPDFSDK_DateTime::CPDFSDK_DateTime(const CFX_ByteString& dtStr) {
81 ResetDateTime();
82
83 FromPDFDateTimeString(dtStr);
84}
85
86CPDFSDK_DateTime::CPDFSDK_DateTime(const CPDFSDK_DateTime& datetime) {
87 operator=(datetime);
88}
89
90CPDFSDK_DateTime::CPDFSDK_DateTime(const FX_SYSTEMTIME& st) {
91 operator=(st);
92}
93
94void CPDFSDK_DateTime::ResetDateTime() {
95 tzset();
96
97 time_t curTime;
98 time(&curTime);
Tom Sepez007e6c02016-02-26 14:31:56 -080099 struct tm* newtime = localtime(&curTime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100
101 dt.year = newtime->tm_year + 1900;
102 dt.month = newtime->tm_mon + 1;
103 dt.day = newtime->tm_mday;
104 dt.hour = newtime->tm_hour;
105 dt.minute = newtime->tm_min;
106 dt.second = newtime->tm_sec;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700107}
108
109CPDFSDK_DateTime& CPDFSDK_DateTime::operator=(
110 const CPDFSDK_DateTime& datetime) {
111 FXSYS_memcpy(&dt, &datetime.dt, sizeof(FX_DATETIME));
112 return *this;
113}
114
115CPDFSDK_DateTime& CPDFSDK_DateTime::operator=(const FX_SYSTEMTIME& st) {
116 tzset();
117
118 dt.year = (int16_t)st.wYear;
119 dt.month = (uint8_t)st.wMonth;
120 dt.day = (uint8_t)st.wDay;
121 dt.hour = (uint8_t)st.wHour;
122 dt.minute = (uint8_t)st.wMinute;
123 dt.second = (uint8_t)st.wSecond;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700124 return *this;
125}
126
Tom Sepez007e6c02016-02-26 14:31:56 -0800127bool CPDFSDK_DateTime::operator==(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128 return (FXSYS_memcmp(&dt, &datetime.dt, sizeof(FX_DATETIME)) == 0);
129}
130
Tom Sepez007e6c02016-02-26 14:31:56 -0800131bool CPDFSDK_DateTime::operator!=(const CPDFSDK_DateTime& datetime) const {
132 return !(*this == datetime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700133}
134
Tom Sepez007e6c02016-02-26 14:31:56 -0800135bool CPDFSDK_DateTime::operator>(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700136 CPDFSDK_DateTime dt1 = ToGMT();
137 CPDFSDK_DateTime dt2 = datetime.ToGMT();
138 int d1 =
139 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
140 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
141 (int)dt1.dt.second;
142 int d3 =
143 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
144 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
145 (int)dt2.dt.second;
146
Tom Sepez007e6c02016-02-26 14:31:56 -0800147 return d1 > d3 || d2 > d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700148}
149
Tom Sepez007e6c02016-02-26 14:31:56 -0800150bool CPDFSDK_DateTime::operator>=(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700151 CPDFSDK_DateTime dt1 = ToGMT();
152 CPDFSDK_DateTime dt2 = datetime.ToGMT();
153 int d1 =
154 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
155 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
156 (int)dt1.dt.second;
157 int d3 =
158 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
159 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
160 (int)dt2.dt.second;
161
Tom Sepez007e6c02016-02-26 14:31:56 -0800162 return d1 >= d3 || d2 >= d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163}
164
Tom Sepez007e6c02016-02-26 14:31:56 -0800165bool CPDFSDK_DateTime::operator<(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700166 CPDFSDK_DateTime dt1 = ToGMT();
167 CPDFSDK_DateTime dt2 = datetime.ToGMT();
168 int d1 =
169 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
170 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
171 (int)dt1.dt.second;
172 int d3 =
173 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
174 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
175 (int)dt2.dt.second;
176
Tom Sepez007e6c02016-02-26 14:31:56 -0800177 return d1 < d3 || d2 < d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700178}
179
Tom Sepez007e6c02016-02-26 14:31:56 -0800180bool CPDFSDK_DateTime::operator<=(const CPDFSDK_DateTime& datetime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700181 CPDFSDK_DateTime dt1 = ToGMT();
182 CPDFSDK_DateTime dt2 = datetime.ToGMT();
183 int d1 =
184 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day;
185 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) |
186 (int)dt1.dt.second;
187 int d3 =
188 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day;
189 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) |
190 (int)dt2.dt.second;
191
Tom Sepez007e6c02016-02-26 14:31:56 -0800192 return d1 <= d3 || d2 <= d4;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700193}
194
195CPDFSDK_DateTime::operator time_t() {
196 struct tm newtime;
197
198 newtime.tm_year = dt.year - 1900;
199 newtime.tm_mon = dt.month - 1;
200 newtime.tm_mday = dt.day;
201 newtime.tm_hour = dt.hour;
202 newtime.tm_min = dt.minute;
203 newtime.tm_sec = dt.second;
204
205 return mktime(&newtime);
206}
207
208CPDFSDK_DateTime& CPDFSDK_DateTime::FromPDFDateTimeString(
209 const CFX_ByteString& dtStr) {
210 int strLength = dtStr.GetLength();
211 if (strLength > 0) {
212 int i = 0;
213 int j, k;
214 FX_CHAR ch;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500215 while (i < strLength && !std::isdigit(dtStr[i]))
216 ++i;
217
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700218 if (i >= strLength)
219 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700220
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700221 j = 0;
222 k = 0;
223 while (i < strLength && j < 4) {
224 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500225 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700226 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500227 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228 break;
229 i++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700230 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700231 dt.year = (int16_t)k;
232 if (i >= strLength || j < 4)
233 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700234
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235 j = 0;
236 k = 0;
237 while (i < strLength && j < 2) {
238 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500239 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700240 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500241 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242 break;
243 i++;
244 }
245 dt.month = (uint8_t)k;
246 if (i >= strLength || j < 2)
247 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700248
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249 j = 0;
250 k = 0;
251 while (i < strLength && j < 2) {
252 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500253 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500255 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700256 break;
257 i++;
258 }
259 dt.day = (uint8_t)k;
260 if (i >= strLength || j < 2)
261 return *this;
262
263 j = 0;
264 k = 0;
265 while (i < strLength && j < 2) {
266 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500267 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500269 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700270 break;
271 i++;
272 }
273 dt.hour = (uint8_t)k;
274 if (i >= strLength || j < 2)
275 return *this;
276
277 j = 0;
278 k = 0;
279 while (i < strLength && j < 2) {
280 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500281 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700282 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500283 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700284 break;
285 i++;
286 }
287 dt.minute = (uint8_t)k;
288 if (i >= strLength || j < 2)
289 return *this;
290
291 j = 0;
292 k = 0;
293 while (i < strLength && j < 2) {
294 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500295 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700296 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500297 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700298 break;
299 i++;
300 }
301 dt.second = (uint8_t)k;
302 if (i >= strLength || j < 2)
303 return *this;
304
305 ch = dtStr[i++];
306 if (ch != '-' && ch != '+')
307 return *this;
308 if (ch == '-')
309 dt.tzHour = -1;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700310 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700311 dt.tzHour = 1;
312 j = 0;
313 k = 0;
314 while (i < strLength && j < 2) {
315 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500316 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700317 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500318 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700319 break;
320 i++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700321 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700322 dt.tzHour *= (FX_CHAR)k;
323 if (i >= strLength || j < 2)
324 return *this;
325
326 ch = dtStr[i++];
327 if (ch != '\'')
328 return *this;
329 j = 0;
330 k = 0;
331 while (i < strLength && j < 2) {
332 ch = dtStr[i];
Dan Sinclair10cfea12015-11-16 13:09:00 -0500333 k = k * 10 + FXSYS_toDecimalDigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700334 j++;
Dan Sinclair10cfea12015-11-16 13:09:00 -0500335 if (!std::isdigit(ch))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700336 break;
337 i++;
338 }
339 dt.tzMinute = (uint8_t)k;
340 if (i >= strLength || j < 2)
341 return *this;
342 }
343
344 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700345}
346
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700347CFX_ByteString CPDFSDK_DateTime::ToCommonDateTimeString() {
348 CFX_ByteString str1;
349 str1.Format("%04d-%02d-%02d %02d:%02d:%02d ", dt.year, dt.month, dt.day,
350 dt.hour, dt.minute, dt.second);
351 if (dt.tzHour < 0)
352 str1 += "-";
353 else
354 str1 += "+";
355 CFX_ByteString str2;
356 str2.Format("%02d:%02d", abs(dt.tzHour), dt.tzMinute);
357 return str1 + str2;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700358}
359
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700360CFX_ByteString CPDFSDK_DateTime::ToPDFDateTimeString() {
361 CFX_ByteString dtStr;
362 char tempStr[32];
363 memset(tempStr, 0, sizeof(tempStr));
364 FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "D:%04d%02d%02d%02d%02d%02d",
365 dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
366 dtStr = CFX_ByteString(tempStr);
367 if (dt.tzHour < 0)
368 dtStr += CFX_ByteString("-");
369 else
370 dtStr += CFX_ByteString("+");
371 memset(tempStr, 0, sizeof(tempStr));
372 FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "%02d'%02d'", abs(dt.tzHour),
373 dt.tzMinute);
374 dtStr += CFX_ByteString(tempStr);
375 return dtStr;
376}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700377
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700378void CPDFSDK_DateTime::ToSystemTime(FX_SYSTEMTIME& st) {
379 CPDFSDK_DateTime dt = *this;
380 time_t t = (time_t)dt;
381 struct tm* pTime = localtime(&t);
382 if (pTime) {
Tom Sepez62a70f92016-03-21 15:00:20 -0700383 st.wYear = (uint16_t)pTime->tm_year + 1900;
384 st.wMonth = (uint16_t)pTime->tm_mon + 1;
385 st.wDay = (uint16_t)pTime->tm_mday;
386 st.wDayOfWeek = (uint16_t)pTime->tm_wday;
387 st.wHour = (uint16_t)pTime->tm_hour;
388 st.wMinute = (uint16_t)pTime->tm_min;
389 st.wSecond = (uint16_t)pTime->tm_sec;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700390 st.wMilliseconds = 0;
391 }
392}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700393
Tom Sepez007e6c02016-02-26 14:31:56 -0800394CPDFSDK_DateTime CPDFSDK_DateTime::ToGMT() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700395 CPDFSDK_DateTime dt = *this;
Lei Zhang4467dea2016-02-25 12:39:15 -0800396 dt.AddSeconds(-gAfxGetTimeZoneInSeconds(dt.dt.tzHour, dt.dt.tzMinute));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700397 dt.dt.tzHour = 0;
398 dt.dt.tzMinute = 0;
399 return dt;
400}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700401
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700402CPDFSDK_DateTime& CPDFSDK_DateTime::AddDays(short days) {
403 if (days == 0)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700404 return *this;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700405
406 int16_t y = dt.year, yy;
407 uint8_t m = dt.month;
408 uint8_t d = dt.day;
409 int mdays, ydays, ldays;
410
411 ldays = days;
412 if (ldays > 0) {
413 yy = y;
Tom Sepez62a70f92016-03-21 15:00:20 -0700414 if (((uint16_t)m * 100 + d) > 300)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700415 yy++;
dsinclair92cb5e52016-05-16 11:38:28 -0700416 ydays = gAfxGetYearDays(yy);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700417 while (ldays >= ydays) {
418 y++;
419 ldays -= ydays;
420 yy++;
dsinclair92cb5e52016-05-16 11:38:28 -0700421 mdays = gAfxGetMonthDays(y, m);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700422 if (d > mdays) {
423 m++;
424 d -= mdays;
425 }
dsinclair92cb5e52016-05-16 11:38:28 -0700426 ydays = gAfxGetYearDays(yy);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700427 }
dsinclair92cb5e52016-05-16 11:38:28 -0700428 mdays = gAfxGetMonthDays(y, m) - d + 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700429 while (ldays >= mdays) {
430 ldays -= mdays;
431 m++;
432 d = 1;
dsinclair92cb5e52016-05-16 11:38:28 -0700433 mdays = gAfxGetMonthDays(y, m);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700434 }
435 d += ldays;
436 } else {
437 ldays *= -1;
438 yy = y;
Tom Sepez62a70f92016-03-21 15:00:20 -0700439 if (((uint16_t)m * 100 + d) < 300)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700440 yy--;
dsinclair92cb5e52016-05-16 11:38:28 -0700441 ydays = gAfxGetYearDays(yy);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700442 while (ldays >= ydays) {
443 y--;
444 ldays -= ydays;
445 yy--;
dsinclair92cb5e52016-05-16 11:38:28 -0700446 mdays = gAfxGetMonthDays(y, m);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700447 if (d > mdays) {
448 m++;
449 d -= mdays;
450 }
dsinclair92cb5e52016-05-16 11:38:28 -0700451 ydays = gAfxGetYearDays(yy);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700452 }
453 while (ldays >= d) {
454 ldays -= d;
455 m--;
dsinclair92cb5e52016-05-16 11:38:28 -0700456 mdays = gAfxGetMonthDays(y, m);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700457 d = mdays;
458 }
459 d -= ldays;
460 }
461
462 dt.year = y;
463 dt.month = m;
464 dt.day = d;
465
466 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700467}
468
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700469CPDFSDK_DateTime& CPDFSDK_DateTime::AddSeconds(int seconds) {
470 if (seconds == 0)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700471 return *this;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700472
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700473 int n;
474 int days;
475
476 n = dt.hour * 3600 + dt.minute * 60 + dt.second + seconds;
477 if (n < 0) {
478 days = (n - 86399) / 86400;
479 n -= days * 86400;
480 } else {
481 days = n / 86400;
482 n %= 86400;
483 }
484 dt.hour = (uint8_t)(n / 3600);
485 dt.hour %= 24;
486 n %= 3600;
487 dt.minute = (uint8_t)(n / 60);
488 dt.second = (uint8_t)(n % 60);
489 if (days != 0)
490 AddDays(days);
491
492 return *this;
493}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700494
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700495CPDFSDK_Annot::CPDFSDK_Annot(CPDFSDK_PageView* pPageView)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400496 : m_pPageView(pPageView), m_bSelected(FALSE), m_nTabOrder(-1) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700497
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700498CPDFSDK_BAAnnot::CPDFSDK_BAAnnot(CPDF_Annot* pAnnot,
499 CPDFSDK_PageView* pPageView)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400500 : CPDFSDK_Annot(pPageView), m_pAnnot(pAnnot) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700501
Tom Sepez3343d142015-11-02 09:54:54 -0800502CPDF_Annot* CPDFSDK_BAAnnot::GetPDFAnnot() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700503 return m_pAnnot;
Bo Xufdc00a72014-10-28 23:03:33 -0700504}
505
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700506FX_BOOL CPDFSDK_Annot::IsSelected() {
507 return m_bSelected;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700508}
509
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700510void CPDFSDK_Annot::SetSelected(FX_BOOL bSelected) {
511 m_bSelected = bSelected;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700512}
513
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700514// Tab Order
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700515int CPDFSDK_Annot::GetTabOrder() {
516 return m_nTabOrder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700517}
518
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700519void CPDFSDK_Annot::SetTabOrder(int iTabOrder) {
520 m_nTabOrder = iTabOrder;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700521}
522
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700523CPDF_Dictionary* CPDFSDK_BAAnnot::GetAnnotDict() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700524 return m_pAnnot->GetAnnotDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700525}
526
Tom Sepez281a9ea2016-02-26 14:24:28 -0800527void CPDFSDK_BAAnnot::SetRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700528 ASSERT(rect.right - rect.left >= GetMinWidth());
529 ASSERT(rect.top - rect.bottom >= GetMinHeight());
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700530
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700531 m_pAnnot->GetAnnotDict()->SetAtRect("Rect", rect);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700532}
533
Tom Sepez281a9ea2016-02-26 14:24:28 -0800534CFX_FloatRect CPDFSDK_BAAnnot::GetRect() const {
535 CFX_FloatRect rect;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700536 m_pAnnot->GetRect(rect);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700537 return rect;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700538}
539
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700540CFX_ByteString CPDFSDK_BAAnnot::GetType() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700541 return m_pAnnot->GetSubType();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700542}
543
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700544CFX_ByteString CPDFSDK_BAAnnot::GetSubType() const {
545 return "";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700546}
547
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700548void CPDFSDK_BAAnnot::DrawAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800549 const CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700550 CPDF_Annot::AppearanceMode mode,
551 const CPDF_RenderOptions* pOptions) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700552 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
553 mode, pOptions);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700554}
555
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700556FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid() {
Wei Li9b761132016-01-29 15:44:20 -0800557 return m_pAnnot->GetAnnotDict()->GetDictBy("AP") != NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700558}
559
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700560FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode) {
Wei Li9b761132016-01-29 15:44:20 -0800561 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
Lei Zhang412e9082015-12-14 18:34:00 -0800562 if (!pAP)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700563 return FALSE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700564
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700565 // Choose the right sub-ap
566 const FX_CHAR* ap_entry = "N";
567 if (mode == CPDF_Annot::Down)
568 ap_entry = "D";
569 else if (mode == CPDF_Annot::Rollover)
570 ap_entry = "R";
571 if (!pAP->KeyExist(ap_entry))
572 ap_entry = "N";
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700573
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700574 // Get the AP stream or subdirectory
tsepezbd567552016-03-29 14:51:50 -0700575 CPDF_Object* psub = pAP->GetDirectObjectBy(ap_entry);
Lei Zhang412e9082015-12-14 18:34:00 -0800576 return !!psub;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700577}
578
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700579void CPDFSDK_BAAnnot::DrawBorder(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800580 const CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700581 const CPDF_RenderOptions* pOptions) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700582 m_pAnnot->DrawBorder(pDevice, pUser2Device, pOptions);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700583}
584
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700585void CPDFSDK_BAAnnot::ClearCachedAP() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700586 m_pAnnot->ClearCachedAP();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700587}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700588
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700589void CPDFSDK_BAAnnot::SetContents(const CFX_WideString& sContents) {
590 if (sContents.IsEmpty())
591 m_pAnnot->GetAnnotDict()->RemoveAt("Contents");
592 else
593 m_pAnnot->GetAnnotDict()->SetAtString("Contents",
594 PDF_EncodeText(sContents));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700595}
596
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700597CFX_WideString CPDFSDK_BAAnnot::GetContents() const {
Wei Li9b761132016-01-29 15:44:20 -0800598 return m_pAnnot->GetAnnotDict()->GetUnicodeTextBy("Contents");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700599}
600
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700601void CPDFSDK_BAAnnot::SetAnnotName(const CFX_WideString& sName) {
602 if (sName.IsEmpty())
603 m_pAnnot->GetAnnotDict()->RemoveAt("NM");
604 else
605 m_pAnnot->GetAnnotDict()->SetAtString("NM", PDF_EncodeText(sName));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700606}
607
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700608CFX_WideString CPDFSDK_BAAnnot::GetAnnotName() const {
Wei Li9b761132016-01-29 15:44:20 -0800609 return m_pAnnot->GetAnnotDict()->GetUnicodeTextBy("NM");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700610}
611
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700612void CPDFSDK_BAAnnot::SetModifiedDate(const FX_SYSTEMTIME& st) {
613 CPDFSDK_DateTime dt(st);
614 CFX_ByteString str = dt.ToPDFDateTimeString();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700615
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700616 if (str.IsEmpty())
617 m_pAnnot->GetAnnotDict()->RemoveAt("M");
618 else
619 m_pAnnot->GetAnnotDict()->SetAtString("M", str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700620}
621
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700622FX_SYSTEMTIME CPDFSDK_BAAnnot::GetModifiedDate() const {
623 FX_SYSTEMTIME systime;
Wei Li9b761132016-01-29 15:44:20 -0800624 CFX_ByteString str = m_pAnnot->GetAnnotDict()->GetStringBy("M");
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700625
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700626 CPDFSDK_DateTime dt(str);
627 dt.ToSystemTime(systime);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700628
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700629 return systime;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700630}
631
tsepezc3255f52016-03-25 14:52:27 -0700632void CPDFSDK_BAAnnot::SetFlags(uint32_t nFlags) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700633 m_pAnnot->GetAnnotDict()->SetAtInteger("F", nFlags);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700634}
635
tsepezc3255f52016-03-25 14:52:27 -0700636uint32_t CPDFSDK_BAAnnot::GetFlags() const {
Wei Li9b761132016-01-29 15:44:20 -0800637 return m_pAnnot->GetAnnotDict()->GetIntegerBy("F");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700638}
639
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700640void CPDFSDK_BAAnnot::SetAppState(const CFX_ByteString& str) {
641 if (str.IsEmpty())
642 m_pAnnot->GetAnnotDict()->RemoveAt("AS");
643 else
644 m_pAnnot->GetAnnotDict()->SetAtString("AS", str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700645}
646
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700647CFX_ByteString CPDFSDK_BAAnnot::GetAppState() const {
Wei Li9b761132016-01-29 15:44:20 -0800648 return m_pAnnot->GetAnnotDict()->GetStringBy("AS");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700649}
650
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700651void CPDFSDK_BAAnnot::SetStructParent(int key) {
652 m_pAnnot->GetAnnotDict()->SetAtInteger("StructParent", key);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700653}
654
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700655int CPDFSDK_BAAnnot::GetStructParent() const {
Wei Li9b761132016-01-29 15:44:20 -0800656 return m_pAnnot->GetAnnotDict()->GetIntegerBy("StructParent");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700657}
658
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700659// border
660void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) {
Wei Li9b761132016-01-29 15:44:20 -0800661 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700662
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700663 if (pBorder) {
Tom Sepezae51c812015-08-05 12:34:06 -0700664 pBorder->SetAt(2, new CPDF_Number(nWidth));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700665 } else {
Wei Li9b761132016-01-29 15:44:20 -0800666 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700667
668 if (!pBSDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700669 pBSDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700670 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700671 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700672
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700673 pBSDict->SetAtInteger("W", nWidth);
674 }
675}
676
677int CPDFSDK_BAAnnot::GetBorderWidth() const {
Wei Li9b761132016-01-29 15:44:20 -0800678 if (CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border")) {
679 return pBorder->GetIntegerAt(2);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700680 }
Wei Li9b761132016-01-29 15:44:20 -0800681 if (CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS")) {
682 return pBSDict->GetIntegerBy("W", 1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700683 }
684 return 1;
685}
686
dsinclair92cb5e52016-05-16 11:38:28 -0700687void CPDFSDK_BAAnnot::SetBorderStyle(BorderStyle nStyle) {
Wei Li9b761132016-01-29 15:44:20 -0800688 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700689 if (!pBSDict) {
690 pBSDict = new CPDF_Dictionary;
691 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict);
692 }
693
694 switch (nStyle) {
dsinclair92cb5e52016-05-16 11:38:28 -0700695 case BorderStyle::SOLID:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700696 pBSDict->SetAtName("S", "S");
697 break;
dsinclair92cb5e52016-05-16 11:38:28 -0700698 case BorderStyle::DASH:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700699 pBSDict->SetAtName("S", "D");
700 break;
dsinclair92cb5e52016-05-16 11:38:28 -0700701 case BorderStyle::BEVELED:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700702 pBSDict->SetAtName("S", "B");
703 break;
dsinclair92cb5e52016-05-16 11:38:28 -0700704 case BorderStyle::INSET:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700705 pBSDict->SetAtName("S", "I");
706 break;
dsinclair92cb5e52016-05-16 11:38:28 -0700707 case BorderStyle::UNDERLINE:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700708 pBSDict->SetAtName("S", "U");
709 break;
dsinclair92cb5e52016-05-16 11:38:28 -0700710 default:
711 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700712 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700713}
714
dsinclair92cb5e52016-05-16 11:38:28 -0700715BorderStyle CPDFSDK_BAAnnot::GetBorderStyle() const {
Wei Li9b761132016-01-29 15:44:20 -0800716 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700717 if (pBSDict) {
Wei Li9b761132016-01-29 15:44:20 -0800718 CFX_ByteString sBorderStyle = pBSDict->GetStringBy("S", "S");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700719 if (sBorderStyle == "S")
dsinclair92cb5e52016-05-16 11:38:28 -0700720 return BorderStyle::SOLID;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700721 if (sBorderStyle == "D")
dsinclair92cb5e52016-05-16 11:38:28 -0700722 return BorderStyle::DASH;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700723 if (sBorderStyle == "B")
dsinclair92cb5e52016-05-16 11:38:28 -0700724 return BorderStyle::BEVELED;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700725 if (sBorderStyle == "I")
dsinclair92cb5e52016-05-16 11:38:28 -0700726 return BorderStyle::INSET;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700727 if (sBorderStyle == "U")
dsinclair92cb5e52016-05-16 11:38:28 -0700728 return BorderStyle::UNDERLINE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700729 }
730
Wei Li9b761132016-01-29 15:44:20 -0800731 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700732 if (pBorder) {
733 if (pBorder->GetCount() >= 4) {
Wei Li9b761132016-01-29 15:44:20 -0800734 CPDF_Array* pDP = pBorder->GetArrayAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700735 if (pDP && pDP->GetCount() > 0)
dsinclair92cb5e52016-05-16 11:38:28 -0700736 return BorderStyle::DASH;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700737 }
738 }
739
dsinclair92cb5e52016-05-16 11:38:28 -0700740 return BorderStyle::SOLID;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700741}
742
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700743void CPDFSDK_BAAnnot::SetColor(FX_COLORREF color) {
744 CPDF_Array* pArray = new CPDF_Array;
745 pArray->AddNumber((FX_FLOAT)FXSYS_GetRValue(color) / 255.0f);
746 pArray->AddNumber((FX_FLOAT)FXSYS_GetGValue(color) / 255.0f);
747 pArray->AddNumber((FX_FLOAT)FXSYS_GetBValue(color) / 255.0f);
748 m_pAnnot->GetAnnotDict()->SetAt("C", pArray);
749}
750
751void CPDFSDK_BAAnnot::RemoveColor() {
752 m_pAnnot->GetAnnotDict()->RemoveAt("C");
753}
754
755FX_BOOL CPDFSDK_BAAnnot::GetColor(FX_COLORREF& color) const {
Wei Li9b761132016-01-29 15:44:20 -0800756 if (CPDF_Array* pEntry = m_pAnnot->GetAnnotDict()->GetArrayBy("C")) {
Wei Lie1aebd42016-04-11 10:02:09 -0700757 size_t nCount = pEntry->GetCount();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700758 if (nCount == 1) {
Wei Li9b761132016-01-29 15:44:20 -0800759 FX_FLOAT g = pEntry->GetNumberAt(0) * 255;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700760
761 color = FXSYS_RGB((int)g, (int)g, (int)g);
762
763 return TRUE;
764 } else if (nCount == 3) {
Wei Li9b761132016-01-29 15:44:20 -0800765 FX_FLOAT r = pEntry->GetNumberAt(0) * 255;
766 FX_FLOAT g = pEntry->GetNumberAt(1) * 255;
767 FX_FLOAT b = pEntry->GetNumberAt(2) * 255;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700768
769 color = FXSYS_RGB((int)r, (int)g, (int)b);
770
771 return TRUE;
772 } else if (nCount == 4) {
Wei Li9b761132016-01-29 15:44:20 -0800773 FX_FLOAT c = pEntry->GetNumberAt(0);
774 FX_FLOAT m = pEntry->GetNumberAt(1);
775 FX_FLOAT y = pEntry->GetNumberAt(2);
776 FX_FLOAT k = pEntry->GetNumberAt(3);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700777
Lei Zhang375a8642016-01-11 11:59:17 -0800778 FX_FLOAT r = 1.0f - std::min(1.0f, c + k);
779 FX_FLOAT g = 1.0f - std::min(1.0f, m + k);
780 FX_FLOAT b = 1.0f - std::min(1.0f, y + k);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700781
782 color = FXSYS_RGB((int)(r * 255), (int)(g * 255), (int)(b * 255));
783
784 return TRUE;
785 }
786 }
787
788 return FALSE;
789}
790
791void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType,
Tom Sepez281a9ea2016-02-26 14:24:28 -0800792 const CFX_FloatRect& rcBBox,
Tom Sepez60d909e2015-12-10 15:34:55 -0800793 const CFX_Matrix& matrix,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700794 const CFX_ByteString& sContents,
795 const CFX_ByteString& sAPState) {
Wei Li9b761132016-01-29 15:44:20 -0800796 CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictBy("AP");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700797
798 if (!pAPDict) {
799 pAPDict = new CPDF_Dictionary;
800 m_pAnnot->GetAnnotDict()->SetAt("AP", pAPDict);
801 }
802
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500803 CPDF_Stream* pStream = nullptr;
804 CPDF_Dictionary* pParentDict = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700805
806 if (sAPState.IsEmpty()) {
807 pParentDict = pAPDict;
tsepez7b1ccf92016-04-14 11:04:57 -0700808 pStream = pAPDict->GetStreamBy(sAPType);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700809 } else {
tsepez7b1ccf92016-04-14 11:04:57 -0700810 CPDF_Dictionary* pAPTypeDict = pAPDict->GetDictBy(sAPType);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700811 if (!pAPTypeDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700812 pAPTypeDict = new CPDF_Dictionary;
tsepez7b1ccf92016-04-14 11:04:57 -0700813 pAPDict->SetAt(sAPType, pAPTypeDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700814 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700815 pParentDict = pAPTypeDict;
tsepez7b1ccf92016-04-14 11:04:57 -0700816 pStream = pAPTypeDict->GetStreamBy(sAPState);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700817 }
818
819 if (!pStream) {
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500820 pStream = new CPDF_Stream(nullptr, 0, nullptr);
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500821 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700822 int32_t objnum = pDoc->AddIndirectObject(pStream);
tsepez7b1ccf92016-04-14 11:04:57 -0700823 pParentDict->SetAtReference(sAPType, pDoc, objnum);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700824 }
825
826 CPDF_Dictionary* pStreamDict = pStream->GetDict();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700827 if (!pStreamDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700828 pStreamDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700829 pStreamDict->SetAtName("Type", "XObject");
830 pStreamDict->SetAtName("Subtype", "Form");
831 pStreamDict->SetAtInteger("FormType", 1);
Dan Sinclairbfe042a2015-11-04 14:04:13 -0500832 pStream->InitStream(nullptr, 0, pStreamDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700833 }
834
835 if (pStreamDict) {
836 pStreamDict->SetAtMatrix("Matrix", matrix);
837 pStreamDict->SetAtRect("BBox", rcBBox);
838 }
839
840 pStream->SetData((uint8_t*)sContents.c_str(), sContents.GetLength(), FALSE,
841 FALSE);
842}
843
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700844FX_FLOAT CPDFSDK_Annot::GetMinWidth() const {
dsinclair92cb5e52016-05-16 11:38:28 -0700845 return kMinWidth;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700846}
847
848FX_FLOAT CPDFSDK_Annot::GetMinHeight() const {
dsinclair92cb5e52016-05-16 11:38:28 -0700849 return kMinHeight;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700850}
851
852FX_BOOL CPDFSDK_BAAnnot::CreateFormFiller() {
853 return TRUE;
854}
855FX_BOOL CPDFSDK_BAAnnot::IsVisible() const {
tsepezc3255f52016-03-25 14:52:27 -0700856 uint32_t nFlags = GetFlags();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700857 return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) ||
858 (nFlags & ANNOTFLAG_NOVIEW));
859}
860
861CPDF_Action CPDFSDK_BAAnnot::GetAction() const {
Wei Li9b761132016-01-29 15:44:20 -0800862 return CPDF_Action(m_pAnnot->GetAnnotDict()->GetDictBy("A"));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700863}
864
865void CPDFSDK_BAAnnot::SetAction(const CPDF_Action& action) {
Wei Li0fc6b252016-03-01 16:29:41 -0800866 ASSERT(action.GetDict());
867 if (action.GetDict() != m_pAnnot->GetAnnotDict()->GetDictBy("A")) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700868 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
869 CPDF_Dictionary* pDict = action.GetDict();
870 if (pDict && pDict->GetObjNum() == 0) {
871 pDoc->AddIndirectObject(pDict);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700872 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700873 m_pAnnot->GetAnnotDict()->SetAtReference("A", pDoc, pDict->GetObjNum());
874 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700875}
876
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700877void CPDFSDK_BAAnnot::RemoveAction() {
878 m_pAnnot->GetAnnotDict()->RemoveAt("A");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700879}
880
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700881CPDF_AAction CPDFSDK_BAAnnot::GetAAction() const {
Wei Li0fc6b252016-03-01 16:29:41 -0800882 return CPDF_AAction(m_pAnnot->GetAnnotDict()->GetDictBy("AA"));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700883}
884
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700885void CPDFSDK_BAAnnot::SetAAction(const CPDF_AAction& aa) {
Wei Li0fc6b252016-03-01 16:29:41 -0800886 if (aa.GetDict() != m_pAnnot->GetAnnotDict()->GetDictBy("AA"))
887 m_pAnnot->GetAnnotDict()->SetAt("AA", aa.GetDict());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700888}
889
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700890void CPDFSDK_BAAnnot::RemoveAAction() {
891 m_pAnnot->GetAnnotDict()->RemoveAt("AA");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700892}
893
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700894CPDF_Action CPDFSDK_BAAnnot::GetAAction(CPDF_AAction::AActionType eAAT) {
895 CPDF_AAction AAction = GetAAction();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700896
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700897 if (AAction.ActionExist(eAAT))
898 return AAction.GetAction(eAAT);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700899
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700900 if (eAAT == CPDF_AAction::ButtonUp)
901 return GetAction();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700902
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700903 return CPDF_Action();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700904}
905
Tom Sepez51da0932015-11-25 16:05:49 -0800906#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700907FX_BOOL CPDFSDK_BAAnnot::IsXFAField() {
908 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700909}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800910#endif // PDF_ENABLE_XFA
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700911
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700912void CPDFSDK_BAAnnot::Annot_OnDraw(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800913 CFX_Matrix* pUser2Device,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700914 CPDF_RenderOptions* pOptions) {
915 m_pAnnot->GetAPForm(m_pPageView->GetPDFPage(), CPDF_Annot::Normal);
916 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device,
917 CPDF_Annot::Normal, NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700918}
919
Tom Sepez50d12ad2015-11-24 09:50:51 -0800920UnderlyingPageType* CPDFSDK_Annot::GetUnderlyingPage() {
Tom Sepez40e9ff32015-11-30 12:39:54 -0800921#ifdef PDF_ENABLE_XFA
Tom Sepez50d12ad2015-11-24 09:50:51 -0800922 return GetPDFXFAPage();
Tom Sepez40e9ff32015-11-30 12:39:54 -0800923#else // PDF_ENABLE_XFA
924 return GetPDFPage();
925#endif // PDF_ENABLE_XFA
Tom Sepez50d12ad2015-11-24 09:50:51 -0800926}
927
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700928CPDF_Page* CPDFSDK_Annot::GetPDFPage() {
Lei Zhang05e67412016-01-25 16:35:42 -0800929 return m_pPageView ? m_pPageView->GetPDFPage() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700930}
931
Tom Sepez40e9ff32015-11-30 12:39:54 -0800932#ifdef PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700933CPDFXFA_Page* CPDFSDK_Annot::GetPDFXFAPage() {
Lei Zhang05e67412016-01-25 16:35:42 -0800934 return m_pPageView ? m_pPageView->GetPDFXFAPage() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700935}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800936#endif // PDF_ENABLE_XFA