OLD | NEW |
| (Empty) |
1 // 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. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "core/include/fpdfapi/cpdf_array.h" | |
10 #include "core/include/fpdfapi/cpdf_document.h" | |
11 #include "core/include/fpdfapi/cpdf_number.h" | |
12 #include "core/include/fxcrt/fx_ext.h" | |
13 #include "fpdfsdk/include/fsdk_baseannot.h" | |
14 #include "fpdfsdk/include/fsdk_define.h" | |
15 #include "fpdfsdk/include/fsdk_mgr.h" | |
16 | |
17 #ifdef PDF_ENABLE_XFA | |
18 #include "fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h" | |
19 #endif // PDF_ENABLE_XFA | |
20 | |
21 int gAfxGetTimeZoneInSeconds(int8_t tzhour, uint8_t tzminute) { | |
22 return (int)tzhour * 3600 + (int)tzminute * (tzhour >= 0 ? 60 : -60); | |
23 } | |
24 | |
25 FX_BOOL _gAfxIsLeapYear(int16_t year) { | |
26 return ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))); | |
27 } | |
28 | |
29 FX_WORD _gAfxGetYearDays(int16_t year) { | |
30 return (_gAfxIsLeapYear(year) == TRUE ? 366 : 365); | |
31 } | |
32 | |
33 uint8_t _gAfxGetMonthDays(int16_t year, uint8_t month) { | |
34 uint8_t mDays; | |
35 switch (month) { | |
36 case 1: | |
37 case 3: | |
38 case 5: | |
39 case 7: | |
40 case 8: | |
41 case 10: | |
42 case 12: | |
43 mDays = 31; | |
44 break; | |
45 | |
46 case 4: | |
47 case 6: | |
48 case 9: | |
49 case 11: | |
50 mDays = 30; | |
51 break; | |
52 | |
53 case 2: | |
54 if (_gAfxIsLeapYear(year) == TRUE) | |
55 mDays = 29; | |
56 else | |
57 mDays = 28; | |
58 break; | |
59 | |
60 default: | |
61 mDays = 0; | |
62 break; | |
63 } | |
64 | |
65 return mDays; | |
66 } | |
67 | |
68 CPDFSDK_DateTime::CPDFSDK_DateTime() { | |
69 ResetDateTime(); | |
70 } | |
71 | |
72 CPDFSDK_DateTime::CPDFSDK_DateTime(const CFX_ByteString& dtStr) { | |
73 ResetDateTime(); | |
74 | |
75 FromPDFDateTimeString(dtStr); | |
76 } | |
77 | |
78 CPDFSDK_DateTime::CPDFSDK_DateTime(const CPDFSDK_DateTime& datetime) { | |
79 operator=(datetime); | |
80 } | |
81 | |
82 CPDFSDK_DateTime::CPDFSDK_DateTime(const FX_SYSTEMTIME& st) { | |
83 operator=(st); | |
84 } | |
85 | |
86 void CPDFSDK_DateTime::ResetDateTime() { | |
87 tzset(); | |
88 | |
89 time_t curTime; | |
90 time(&curTime); | |
91 struct tm* newtime = localtime(&curTime); | |
92 | |
93 dt.year = newtime->tm_year + 1900; | |
94 dt.month = newtime->tm_mon + 1; | |
95 dt.day = newtime->tm_mday; | |
96 dt.hour = newtime->tm_hour; | |
97 dt.minute = newtime->tm_min; | |
98 dt.second = newtime->tm_sec; | |
99 } | |
100 | |
101 CPDFSDK_DateTime& CPDFSDK_DateTime::operator=( | |
102 const CPDFSDK_DateTime& datetime) { | |
103 FXSYS_memcpy(&dt, &datetime.dt, sizeof(FX_DATETIME)); | |
104 return *this; | |
105 } | |
106 | |
107 CPDFSDK_DateTime& CPDFSDK_DateTime::operator=(const FX_SYSTEMTIME& st) { | |
108 tzset(); | |
109 | |
110 dt.year = (int16_t)st.wYear; | |
111 dt.month = (uint8_t)st.wMonth; | |
112 dt.day = (uint8_t)st.wDay; | |
113 dt.hour = (uint8_t)st.wHour; | |
114 dt.minute = (uint8_t)st.wMinute; | |
115 dt.second = (uint8_t)st.wSecond; | |
116 return *this; | |
117 } | |
118 | |
119 bool CPDFSDK_DateTime::operator==(const CPDFSDK_DateTime& datetime) const { | |
120 return (FXSYS_memcmp(&dt, &datetime.dt, sizeof(FX_DATETIME)) == 0); | |
121 } | |
122 | |
123 bool CPDFSDK_DateTime::operator!=(const CPDFSDK_DateTime& datetime) const { | |
124 return !(*this == datetime); | |
125 } | |
126 | |
127 bool CPDFSDK_DateTime::operator>(const CPDFSDK_DateTime& datetime) const { | |
128 CPDFSDK_DateTime dt1 = ToGMT(); | |
129 CPDFSDK_DateTime dt2 = datetime.ToGMT(); | |
130 int d1 = | |
131 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day; | |
132 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) | | |
133 (int)dt1.dt.second; | |
134 int d3 = | |
135 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day; | |
136 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) | | |
137 (int)dt2.dt.second; | |
138 | |
139 return d1 > d3 || d2 > d4; | |
140 } | |
141 | |
142 bool CPDFSDK_DateTime::operator>=(const CPDFSDK_DateTime& datetime) const { | |
143 CPDFSDK_DateTime dt1 = ToGMT(); | |
144 CPDFSDK_DateTime dt2 = datetime.ToGMT(); | |
145 int d1 = | |
146 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day; | |
147 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) | | |
148 (int)dt1.dt.second; | |
149 int d3 = | |
150 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day; | |
151 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) | | |
152 (int)dt2.dt.second; | |
153 | |
154 return d1 >= d3 || d2 >= d4; | |
155 } | |
156 | |
157 bool CPDFSDK_DateTime::operator<(const CPDFSDK_DateTime& datetime) const { | |
158 CPDFSDK_DateTime dt1 = ToGMT(); | |
159 CPDFSDK_DateTime dt2 = datetime.ToGMT(); | |
160 int d1 = | |
161 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day; | |
162 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) | | |
163 (int)dt1.dt.second; | |
164 int d3 = | |
165 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day; | |
166 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) | | |
167 (int)dt2.dt.second; | |
168 | |
169 return d1 < d3 || d2 < d4; | |
170 } | |
171 | |
172 bool CPDFSDK_DateTime::operator<=(const CPDFSDK_DateTime& datetime) const { | |
173 CPDFSDK_DateTime dt1 = ToGMT(); | |
174 CPDFSDK_DateTime dt2 = datetime.ToGMT(); | |
175 int d1 = | |
176 (((int)dt1.dt.year) << 16) | (((int)dt1.dt.month) << 8) | (int)dt1.dt.day; | |
177 int d2 = (((int)dt1.dt.hour) << 16) | (((int)dt1.dt.minute) << 8) | | |
178 (int)dt1.dt.second; | |
179 int d3 = | |
180 (((int)dt2.dt.year) << 16) | (((int)dt2.dt.month) << 8) | (int)dt2.dt.day; | |
181 int d4 = (((int)dt2.dt.hour) << 16) | (((int)dt2.dt.minute) << 8) | | |
182 (int)dt2.dt.second; | |
183 | |
184 return d1 <= d3 || d2 <= d4; | |
185 } | |
186 | |
187 CPDFSDK_DateTime::operator time_t() { | |
188 struct tm newtime; | |
189 | |
190 newtime.tm_year = dt.year - 1900; | |
191 newtime.tm_mon = dt.month - 1; | |
192 newtime.tm_mday = dt.day; | |
193 newtime.tm_hour = dt.hour; | |
194 newtime.tm_min = dt.minute; | |
195 newtime.tm_sec = dt.second; | |
196 | |
197 return mktime(&newtime); | |
198 } | |
199 | |
200 CPDFSDK_DateTime& CPDFSDK_DateTime::FromPDFDateTimeString( | |
201 const CFX_ByteString& dtStr) { | |
202 int strLength = dtStr.GetLength(); | |
203 if (strLength > 0) { | |
204 int i = 0; | |
205 int j, k; | |
206 FX_CHAR ch; | |
207 while (i < strLength && !std::isdigit(dtStr[i])) | |
208 ++i; | |
209 | |
210 if (i >= strLength) | |
211 return *this; | |
212 | |
213 j = 0; | |
214 k = 0; | |
215 while (i < strLength && j < 4) { | |
216 ch = dtStr[i]; | |
217 k = k * 10 + FXSYS_toDecimalDigit(ch); | |
218 j++; | |
219 if (!std::isdigit(ch)) | |
220 break; | |
221 i++; | |
222 } | |
223 dt.year = (int16_t)k; | |
224 if (i >= strLength || j < 4) | |
225 return *this; | |
226 | |
227 j = 0; | |
228 k = 0; | |
229 while (i < strLength && j < 2) { | |
230 ch = dtStr[i]; | |
231 k = k * 10 + FXSYS_toDecimalDigit(ch); | |
232 j++; | |
233 if (!std::isdigit(ch)) | |
234 break; | |
235 i++; | |
236 } | |
237 dt.month = (uint8_t)k; | |
238 if (i >= strLength || j < 2) | |
239 return *this; | |
240 | |
241 j = 0; | |
242 k = 0; | |
243 while (i < strLength && j < 2) { | |
244 ch = dtStr[i]; | |
245 k = k * 10 + FXSYS_toDecimalDigit(ch); | |
246 j++; | |
247 if (!std::isdigit(ch)) | |
248 break; | |
249 i++; | |
250 } | |
251 dt.day = (uint8_t)k; | |
252 if (i >= strLength || j < 2) | |
253 return *this; | |
254 | |
255 j = 0; | |
256 k = 0; | |
257 while (i < strLength && j < 2) { | |
258 ch = dtStr[i]; | |
259 k = k * 10 + FXSYS_toDecimalDigit(ch); | |
260 j++; | |
261 if (!std::isdigit(ch)) | |
262 break; | |
263 i++; | |
264 } | |
265 dt.hour = (uint8_t)k; | |
266 if (i >= strLength || j < 2) | |
267 return *this; | |
268 | |
269 j = 0; | |
270 k = 0; | |
271 while (i < strLength && j < 2) { | |
272 ch = dtStr[i]; | |
273 k = k * 10 + FXSYS_toDecimalDigit(ch); | |
274 j++; | |
275 if (!std::isdigit(ch)) | |
276 break; | |
277 i++; | |
278 } | |
279 dt.minute = (uint8_t)k; | |
280 if (i >= strLength || j < 2) | |
281 return *this; | |
282 | |
283 j = 0; | |
284 k = 0; | |
285 while (i < strLength && j < 2) { | |
286 ch = dtStr[i]; | |
287 k = k * 10 + FXSYS_toDecimalDigit(ch); | |
288 j++; | |
289 if (!std::isdigit(ch)) | |
290 break; | |
291 i++; | |
292 } | |
293 dt.second = (uint8_t)k; | |
294 if (i >= strLength || j < 2) | |
295 return *this; | |
296 | |
297 ch = dtStr[i++]; | |
298 if (ch != '-' && ch != '+') | |
299 return *this; | |
300 if (ch == '-') | |
301 dt.tzHour = -1; | |
302 else | |
303 dt.tzHour = 1; | |
304 j = 0; | |
305 k = 0; | |
306 while (i < strLength && j < 2) { | |
307 ch = dtStr[i]; | |
308 k = k * 10 + FXSYS_toDecimalDigit(ch); | |
309 j++; | |
310 if (!std::isdigit(ch)) | |
311 break; | |
312 i++; | |
313 } | |
314 dt.tzHour *= (FX_CHAR)k; | |
315 if (i >= strLength || j < 2) | |
316 return *this; | |
317 | |
318 ch = dtStr[i++]; | |
319 if (ch != '\'') | |
320 return *this; | |
321 j = 0; | |
322 k = 0; | |
323 while (i < strLength && j < 2) { | |
324 ch = dtStr[i]; | |
325 k = k * 10 + FXSYS_toDecimalDigit(ch); | |
326 j++; | |
327 if (!std::isdigit(ch)) | |
328 break; | |
329 i++; | |
330 } | |
331 dt.tzMinute = (uint8_t)k; | |
332 if (i >= strLength || j < 2) | |
333 return *this; | |
334 } | |
335 | |
336 return *this; | |
337 } | |
338 | |
339 CFX_ByteString CPDFSDK_DateTime::ToCommonDateTimeString() { | |
340 CFX_ByteString str1; | |
341 str1.Format("%04d-%02d-%02d %02d:%02d:%02d ", dt.year, dt.month, dt.day, | |
342 dt.hour, dt.minute, dt.second); | |
343 if (dt.tzHour < 0) | |
344 str1 += "-"; | |
345 else | |
346 str1 += "+"; | |
347 CFX_ByteString str2; | |
348 str2.Format("%02d:%02d", abs(dt.tzHour), dt.tzMinute); | |
349 return str1 + str2; | |
350 } | |
351 | |
352 CFX_ByteString CPDFSDK_DateTime::ToPDFDateTimeString() { | |
353 CFX_ByteString dtStr; | |
354 char tempStr[32]; | |
355 memset(tempStr, 0, sizeof(tempStr)); | |
356 FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "D:%04d%02d%02d%02d%02d%02d", | |
357 dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second); | |
358 dtStr = CFX_ByteString(tempStr); | |
359 if (dt.tzHour < 0) | |
360 dtStr += CFX_ByteString("-"); | |
361 else | |
362 dtStr += CFX_ByteString("+"); | |
363 memset(tempStr, 0, sizeof(tempStr)); | |
364 FXSYS_snprintf(tempStr, sizeof(tempStr) - 1, "%02d'%02d'", abs(dt.tzHour), | |
365 dt.tzMinute); | |
366 dtStr += CFX_ByteString(tempStr); | |
367 return dtStr; | |
368 } | |
369 | |
370 void CPDFSDK_DateTime::ToSystemTime(FX_SYSTEMTIME& st) { | |
371 CPDFSDK_DateTime dt = *this; | |
372 time_t t = (time_t)dt; | |
373 struct tm* pTime = localtime(&t); | |
374 if (pTime) { | |
375 st.wYear = (FX_WORD)pTime->tm_year + 1900; | |
376 st.wMonth = (FX_WORD)pTime->tm_mon + 1; | |
377 st.wDay = (FX_WORD)pTime->tm_mday; | |
378 st.wDayOfWeek = (FX_WORD)pTime->tm_wday; | |
379 st.wHour = (FX_WORD)pTime->tm_hour; | |
380 st.wMinute = (FX_WORD)pTime->tm_min; | |
381 st.wSecond = (FX_WORD)pTime->tm_sec; | |
382 st.wMilliseconds = 0; | |
383 } | |
384 } | |
385 | |
386 CPDFSDK_DateTime CPDFSDK_DateTime::ToGMT() const { | |
387 CPDFSDK_DateTime dt = *this; | |
388 dt.AddSeconds(-gAfxGetTimeZoneInSeconds(dt.dt.tzHour, dt.dt.tzMinute)); | |
389 dt.dt.tzHour = 0; | |
390 dt.dt.tzMinute = 0; | |
391 return dt; | |
392 } | |
393 | |
394 CPDFSDK_DateTime& CPDFSDK_DateTime::AddDays(short days) { | |
395 if (days == 0) | |
396 return *this; | |
397 | |
398 int16_t y = dt.year, yy; | |
399 uint8_t m = dt.month; | |
400 uint8_t d = dt.day; | |
401 int mdays, ydays, ldays; | |
402 | |
403 ldays = days; | |
404 if (ldays > 0) { | |
405 yy = y; | |
406 if (((FX_WORD)m * 100 + d) > 300) | |
407 yy++; | |
408 ydays = _gAfxGetYearDays(yy); | |
409 while (ldays >= ydays) { | |
410 y++; | |
411 ldays -= ydays; | |
412 yy++; | |
413 mdays = _gAfxGetMonthDays(y, m); | |
414 if (d > mdays) { | |
415 m++; | |
416 d -= mdays; | |
417 } | |
418 ydays = _gAfxGetYearDays(yy); | |
419 } | |
420 mdays = _gAfxGetMonthDays(y, m) - d + 1; | |
421 while (ldays >= mdays) { | |
422 ldays -= mdays; | |
423 m++; | |
424 d = 1; | |
425 mdays = _gAfxGetMonthDays(y, m); | |
426 } | |
427 d += ldays; | |
428 } else { | |
429 ldays *= -1; | |
430 yy = y; | |
431 if (((FX_WORD)m * 100 + d) < 300) | |
432 yy--; | |
433 ydays = _gAfxGetYearDays(yy); | |
434 while (ldays >= ydays) { | |
435 y--; | |
436 ldays -= ydays; | |
437 yy--; | |
438 mdays = _gAfxGetMonthDays(y, m); | |
439 if (d > mdays) { | |
440 m++; | |
441 d -= mdays; | |
442 } | |
443 ydays = _gAfxGetYearDays(yy); | |
444 } | |
445 while (ldays >= d) { | |
446 ldays -= d; | |
447 m--; | |
448 mdays = _gAfxGetMonthDays(y, m); | |
449 d = mdays; | |
450 } | |
451 d -= ldays; | |
452 } | |
453 | |
454 dt.year = y; | |
455 dt.month = m; | |
456 dt.day = d; | |
457 | |
458 return *this; | |
459 } | |
460 | |
461 CPDFSDK_DateTime& CPDFSDK_DateTime::AddSeconds(int seconds) { | |
462 if (seconds == 0) | |
463 return *this; | |
464 | |
465 int n; | |
466 int days; | |
467 | |
468 n = dt.hour * 3600 + dt.minute * 60 + dt.second + seconds; | |
469 if (n < 0) { | |
470 days = (n - 86399) / 86400; | |
471 n -= days * 86400; | |
472 } else { | |
473 days = n / 86400; | |
474 n %= 86400; | |
475 } | |
476 dt.hour = (uint8_t)(n / 3600); | |
477 dt.hour %= 24; | |
478 n %= 3600; | |
479 dt.minute = (uint8_t)(n / 60); | |
480 dt.second = (uint8_t)(n % 60); | |
481 if (days != 0) | |
482 AddDays(days); | |
483 | |
484 return *this; | |
485 } | |
486 | |
487 CPDFSDK_Annot::CPDFSDK_Annot(CPDFSDK_PageView* pPageView) | |
488 : m_pPageView(pPageView), m_bSelected(FALSE), m_nTabOrder(-1) { | |
489 } | |
490 | |
491 CPDFSDK_BAAnnot::CPDFSDK_BAAnnot(CPDF_Annot* pAnnot, | |
492 CPDFSDK_PageView* pPageView) | |
493 : CPDFSDK_Annot(pPageView), m_pAnnot(pAnnot) { | |
494 } | |
495 | |
496 CPDF_Annot* CPDFSDK_BAAnnot::GetPDFAnnot() const { | |
497 return m_pAnnot; | |
498 } | |
499 | |
500 FX_BOOL CPDFSDK_Annot::IsSelected() { | |
501 return m_bSelected; | |
502 } | |
503 | |
504 void CPDFSDK_Annot::SetSelected(FX_BOOL bSelected) { | |
505 m_bSelected = bSelected; | |
506 } | |
507 | |
508 // Tab Order | |
509 int CPDFSDK_Annot::GetTabOrder() { | |
510 return m_nTabOrder; | |
511 } | |
512 | |
513 void CPDFSDK_Annot::SetTabOrder(int iTabOrder) { | |
514 m_nTabOrder = iTabOrder; | |
515 } | |
516 | |
517 CPDF_Dictionary* CPDFSDK_BAAnnot::GetAnnotDict() const { | |
518 return m_pAnnot->GetAnnotDict(); | |
519 } | |
520 | |
521 void CPDFSDK_BAAnnot::SetRect(const CFX_FloatRect& rect) { | |
522 ASSERT(rect.right - rect.left >= GetMinWidth()); | |
523 ASSERT(rect.top - rect.bottom >= GetMinHeight()); | |
524 | |
525 m_pAnnot->GetAnnotDict()->SetAtRect("Rect", rect); | |
526 } | |
527 | |
528 CFX_FloatRect CPDFSDK_BAAnnot::GetRect() const { | |
529 CFX_FloatRect rect; | |
530 m_pAnnot->GetRect(rect); | |
531 return rect; | |
532 } | |
533 | |
534 CFX_ByteString CPDFSDK_BAAnnot::GetType() const { | |
535 return m_pAnnot->GetSubType(); | |
536 } | |
537 | |
538 CFX_ByteString CPDFSDK_BAAnnot::GetSubType() const { | |
539 return ""; | |
540 } | |
541 | |
542 void CPDFSDK_BAAnnot::DrawAppearance(CFX_RenderDevice* pDevice, | |
543 const CFX_Matrix* pUser2Device, | |
544 CPDF_Annot::AppearanceMode mode, | |
545 const CPDF_RenderOptions* pOptions) { | |
546 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device, | |
547 mode, pOptions); | |
548 } | |
549 | |
550 FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid() { | |
551 return m_pAnnot->GetAnnotDict()->GetDictBy("AP") != NULL; | |
552 } | |
553 | |
554 FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode) { | |
555 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictBy("AP"); | |
556 if (!pAP) | |
557 return FALSE; | |
558 | |
559 // Choose the right sub-ap | |
560 const FX_CHAR* ap_entry = "N"; | |
561 if (mode == CPDF_Annot::Down) | |
562 ap_entry = "D"; | |
563 else if (mode == CPDF_Annot::Rollover) | |
564 ap_entry = "R"; | |
565 if (!pAP->KeyExist(ap_entry)) | |
566 ap_entry = "N"; | |
567 | |
568 // Get the AP stream or subdirectory | |
569 CPDF_Object* psub = pAP->GetElementValue(ap_entry); | |
570 return !!psub; | |
571 } | |
572 | |
573 void CPDFSDK_BAAnnot::DrawBorder(CFX_RenderDevice* pDevice, | |
574 const CFX_Matrix* pUser2Device, | |
575 const CPDF_RenderOptions* pOptions) { | |
576 m_pAnnot->DrawBorder(pDevice, pUser2Device, pOptions); | |
577 } | |
578 | |
579 void CPDFSDK_BAAnnot::ClearCachedAP() { | |
580 m_pAnnot->ClearCachedAP(); | |
581 } | |
582 | |
583 void CPDFSDK_BAAnnot::SetContents(const CFX_WideString& sContents) { | |
584 if (sContents.IsEmpty()) | |
585 m_pAnnot->GetAnnotDict()->RemoveAt("Contents"); | |
586 else | |
587 m_pAnnot->GetAnnotDict()->SetAtString("Contents", | |
588 PDF_EncodeText(sContents)); | |
589 } | |
590 | |
591 CFX_WideString CPDFSDK_BAAnnot::GetContents() const { | |
592 return m_pAnnot->GetAnnotDict()->GetUnicodeTextBy("Contents"); | |
593 } | |
594 | |
595 void CPDFSDK_BAAnnot::SetAnnotName(const CFX_WideString& sName) { | |
596 if (sName.IsEmpty()) | |
597 m_pAnnot->GetAnnotDict()->RemoveAt("NM"); | |
598 else | |
599 m_pAnnot->GetAnnotDict()->SetAtString("NM", PDF_EncodeText(sName)); | |
600 } | |
601 | |
602 CFX_WideString CPDFSDK_BAAnnot::GetAnnotName() const { | |
603 return m_pAnnot->GetAnnotDict()->GetUnicodeTextBy("NM"); | |
604 } | |
605 | |
606 void CPDFSDK_BAAnnot::SetModifiedDate(const FX_SYSTEMTIME& st) { | |
607 CPDFSDK_DateTime dt(st); | |
608 CFX_ByteString str = dt.ToPDFDateTimeString(); | |
609 | |
610 if (str.IsEmpty()) | |
611 m_pAnnot->GetAnnotDict()->RemoveAt("M"); | |
612 else | |
613 m_pAnnot->GetAnnotDict()->SetAtString("M", str); | |
614 } | |
615 | |
616 FX_SYSTEMTIME CPDFSDK_BAAnnot::GetModifiedDate() const { | |
617 FX_SYSTEMTIME systime; | |
618 CFX_ByteString str = m_pAnnot->GetAnnotDict()->GetStringBy("M"); | |
619 | |
620 CPDFSDK_DateTime dt(str); | |
621 dt.ToSystemTime(systime); | |
622 | |
623 return systime; | |
624 } | |
625 | |
626 void CPDFSDK_BAAnnot::SetFlags(FX_DWORD nFlags) { | |
627 m_pAnnot->GetAnnotDict()->SetAtInteger("F", nFlags); | |
628 } | |
629 | |
630 FX_DWORD CPDFSDK_BAAnnot::GetFlags() const { | |
631 return m_pAnnot->GetAnnotDict()->GetIntegerBy("F"); | |
632 } | |
633 | |
634 void CPDFSDK_BAAnnot::SetAppState(const CFX_ByteString& str) { | |
635 if (str.IsEmpty()) | |
636 m_pAnnot->GetAnnotDict()->RemoveAt("AS"); | |
637 else | |
638 m_pAnnot->GetAnnotDict()->SetAtString("AS", str); | |
639 } | |
640 | |
641 CFX_ByteString CPDFSDK_BAAnnot::GetAppState() const { | |
642 return m_pAnnot->GetAnnotDict()->GetStringBy("AS"); | |
643 } | |
644 | |
645 void CPDFSDK_BAAnnot::SetStructParent(int key) { | |
646 m_pAnnot->GetAnnotDict()->SetAtInteger("StructParent", key); | |
647 } | |
648 | |
649 int CPDFSDK_BAAnnot::GetStructParent() const { | |
650 return m_pAnnot->GetAnnotDict()->GetIntegerBy("StructParent"); | |
651 } | |
652 | |
653 // border | |
654 void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth) { | |
655 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border"); | |
656 | |
657 if (pBorder) { | |
658 pBorder->SetAt(2, new CPDF_Number(nWidth)); | |
659 } else { | |
660 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS"); | |
661 | |
662 if (!pBSDict) { | |
663 pBSDict = new CPDF_Dictionary; | |
664 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict); | |
665 } | |
666 | |
667 pBSDict->SetAtInteger("W", nWidth); | |
668 } | |
669 } | |
670 | |
671 int CPDFSDK_BAAnnot::GetBorderWidth() const { | |
672 if (CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border")) { | |
673 return pBorder->GetIntegerAt(2); | |
674 } | |
675 if (CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS")) { | |
676 return pBSDict->GetIntegerBy("W", 1); | |
677 } | |
678 return 1; | |
679 } | |
680 | |
681 void CPDFSDK_BAAnnot::SetBorderStyle(int nStyle) { | |
682 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS"); | |
683 if (!pBSDict) { | |
684 pBSDict = new CPDF_Dictionary; | |
685 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict); | |
686 } | |
687 | |
688 switch (nStyle) { | |
689 case BBS_SOLID: | |
690 pBSDict->SetAtName("S", "S"); | |
691 break; | |
692 case BBS_DASH: | |
693 pBSDict->SetAtName("S", "D"); | |
694 break; | |
695 case BBS_BEVELED: | |
696 pBSDict->SetAtName("S", "B"); | |
697 break; | |
698 case BBS_INSET: | |
699 pBSDict->SetAtName("S", "I"); | |
700 break; | |
701 case BBS_UNDERLINE: | |
702 pBSDict->SetAtName("S", "U"); | |
703 break; | |
704 } | |
705 } | |
706 | |
707 int CPDFSDK_BAAnnot::GetBorderStyle() const { | |
708 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS"); | |
709 if (pBSDict) { | |
710 CFX_ByteString sBorderStyle = pBSDict->GetStringBy("S", "S"); | |
711 if (sBorderStyle == "S") | |
712 return BBS_SOLID; | |
713 if (sBorderStyle == "D") | |
714 return BBS_DASH; | |
715 if (sBorderStyle == "B") | |
716 return BBS_BEVELED; | |
717 if (sBorderStyle == "I") | |
718 return BBS_INSET; | |
719 if (sBorderStyle == "U") | |
720 return BBS_UNDERLINE; | |
721 } | |
722 | |
723 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border"); | |
724 if (pBorder) { | |
725 if (pBorder->GetCount() >= 4) { | |
726 CPDF_Array* pDP = pBorder->GetArrayAt(3); | |
727 if (pDP && pDP->GetCount() > 0) | |
728 return BBS_DASH; | |
729 } | |
730 } | |
731 | |
732 return BBS_SOLID; | |
733 } | |
734 | |
735 void CPDFSDK_BAAnnot::SetBorderDash(const CFX_IntArray& array) { | |
736 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS"); | |
737 if (!pBSDict) { | |
738 pBSDict = new CPDF_Dictionary; | |
739 m_pAnnot->GetAnnotDict()->SetAt("BS", pBSDict); | |
740 } | |
741 | |
742 CPDF_Array* pArray = new CPDF_Array; | |
743 for (int i = 0, sz = array.GetSize(); i < sz; i++) { | |
744 pArray->AddInteger(array[i]); | |
745 } | |
746 | |
747 pBSDict->SetAt("D", pArray); | |
748 } | |
749 | |
750 void CPDFSDK_BAAnnot::GetBorderDash(CFX_IntArray& array) const { | |
751 CPDF_Array* pDash = NULL; | |
752 | |
753 CPDF_Array* pBorder = m_pAnnot->GetAnnotDict()->GetArrayBy("Border"); | |
754 if (pBorder) { | |
755 pDash = pBorder->GetArrayAt(3); | |
756 } else { | |
757 CPDF_Dictionary* pBSDict = m_pAnnot->GetAnnotDict()->GetDictBy("BS"); | |
758 if (pBSDict) { | |
759 pDash = pBSDict->GetArrayBy("D"); | |
760 } | |
761 } | |
762 | |
763 if (pDash) { | |
764 for (int i = 0, sz = pDash->GetCount(); i < sz; i++) { | |
765 array.Add(pDash->GetIntegerAt(i)); | |
766 } | |
767 } | |
768 } | |
769 | |
770 void CPDFSDK_BAAnnot::SetColor(FX_COLORREF color) { | |
771 CPDF_Array* pArray = new CPDF_Array; | |
772 pArray->AddNumber((FX_FLOAT)FXSYS_GetRValue(color) / 255.0f); | |
773 pArray->AddNumber((FX_FLOAT)FXSYS_GetGValue(color) / 255.0f); | |
774 pArray->AddNumber((FX_FLOAT)FXSYS_GetBValue(color) / 255.0f); | |
775 m_pAnnot->GetAnnotDict()->SetAt("C", pArray); | |
776 } | |
777 | |
778 void CPDFSDK_BAAnnot::RemoveColor() { | |
779 m_pAnnot->GetAnnotDict()->RemoveAt("C"); | |
780 } | |
781 | |
782 FX_BOOL CPDFSDK_BAAnnot::GetColor(FX_COLORREF& color) const { | |
783 if (CPDF_Array* pEntry = m_pAnnot->GetAnnotDict()->GetArrayBy("C")) { | |
784 int nCount = pEntry->GetCount(); | |
785 if (nCount == 1) { | |
786 FX_FLOAT g = pEntry->GetNumberAt(0) * 255; | |
787 | |
788 color = FXSYS_RGB((int)g, (int)g, (int)g); | |
789 | |
790 return TRUE; | |
791 } else if (nCount == 3) { | |
792 FX_FLOAT r = pEntry->GetNumberAt(0) * 255; | |
793 FX_FLOAT g = pEntry->GetNumberAt(1) * 255; | |
794 FX_FLOAT b = pEntry->GetNumberAt(2) * 255; | |
795 | |
796 color = FXSYS_RGB((int)r, (int)g, (int)b); | |
797 | |
798 return TRUE; | |
799 } else if (nCount == 4) { | |
800 FX_FLOAT c = pEntry->GetNumberAt(0); | |
801 FX_FLOAT m = pEntry->GetNumberAt(1); | |
802 FX_FLOAT y = pEntry->GetNumberAt(2); | |
803 FX_FLOAT k = pEntry->GetNumberAt(3); | |
804 | |
805 FX_FLOAT r = 1.0f - std::min(1.0f, c + k); | |
806 FX_FLOAT g = 1.0f - std::min(1.0f, m + k); | |
807 FX_FLOAT b = 1.0f - std::min(1.0f, y + k); | |
808 | |
809 color = FXSYS_RGB((int)(r * 255), (int)(g * 255), (int)(b * 255)); | |
810 | |
811 return TRUE; | |
812 } | |
813 } | |
814 | |
815 return FALSE; | |
816 } | |
817 | |
818 void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType, | |
819 const CFX_FloatRect& rcBBox, | |
820 const CFX_Matrix& matrix, | |
821 const CFX_ByteString& sContents, | |
822 const CFX_ByteString& sAPState) { | |
823 CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictBy("AP"); | |
824 | |
825 if (!pAPDict) { | |
826 pAPDict = new CPDF_Dictionary; | |
827 m_pAnnot->GetAnnotDict()->SetAt("AP", pAPDict); | |
828 } | |
829 | |
830 CPDF_Stream* pStream = nullptr; | |
831 CPDF_Dictionary* pParentDict = nullptr; | |
832 | |
833 if (sAPState.IsEmpty()) { | |
834 pParentDict = pAPDict; | |
835 pStream = pAPDict->GetStreamBy(sAPType); | |
836 } else { | |
837 CPDF_Dictionary* pAPTypeDict = pAPDict->GetDictBy(sAPType); | |
838 if (!pAPTypeDict) { | |
839 pAPTypeDict = new CPDF_Dictionary; | |
840 pAPDict->SetAt(sAPType, pAPTypeDict); | |
841 } | |
842 | |
843 pParentDict = pAPTypeDict; | |
844 pStream = pAPTypeDict->GetStreamBy(sAPState); | |
845 } | |
846 | |
847 if (!pStream) { | |
848 pStream = new CPDF_Stream(nullptr, 0, nullptr); | |
849 | |
850 CPDF_Document* pDoc = m_pPageView->GetPDFDocument(); | |
851 int32_t objnum = pDoc->AddIndirectObject(pStream); | |
852 pParentDict->SetAtReference(sAPType, pDoc, objnum); | |
853 } | |
854 | |
855 CPDF_Dictionary* pStreamDict = pStream->GetDict(); | |
856 if (!pStreamDict) { | |
857 pStreamDict = new CPDF_Dictionary; | |
858 pStreamDict->SetAtName("Type", "XObject"); | |
859 pStreamDict->SetAtName("Subtype", "Form"); | |
860 pStreamDict->SetAtInteger("FormType", 1); | |
861 pStream->InitStream(nullptr, 0, pStreamDict); | |
862 } | |
863 | |
864 if (pStreamDict) { | |
865 pStreamDict->SetAtMatrix("Matrix", matrix); | |
866 pStreamDict->SetAtRect("BBox", rcBBox); | |
867 } | |
868 | |
869 pStream->SetData((uint8_t*)sContents.c_str(), sContents.GetLength(), FALSE, | |
870 FALSE); | |
871 } | |
872 | |
873 #define BA_ANNOT_MINWIDTH 1 | |
874 #define BA_ANNOT_MINHEIGHT 1 | |
875 | |
876 FX_FLOAT CPDFSDK_Annot::GetMinWidth() const { | |
877 return BA_ANNOT_MINWIDTH; | |
878 } | |
879 | |
880 FX_FLOAT CPDFSDK_Annot::GetMinHeight() const { | |
881 return BA_ANNOT_MINHEIGHT; | |
882 } | |
883 | |
884 FX_BOOL CPDFSDK_BAAnnot::CreateFormFiller() { | |
885 return TRUE; | |
886 } | |
887 FX_BOOL CPDFSDK_BAAnnot::IsVisible() const { | |
888 FX_DWORD nFlags = GetFlags(); | |
889 return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) || | |
890 (nFlags & ANNOTFLAG_NOVIEW)); | |
891 } | |
892 | |
893 CPDF_Action CPDFSDK_BAAnnot::GetAction() const { | |
894 return CPDF_Action(m_pAnnot->GetAnnotDict()->GetDictBy("A")); | |
895 } | |
896 | |
897 void CPDFSDK_BAAnnot::SetAction(const CPDF_Action& action) { | |
898 ASSERT(action.GetDict()); | |
899 if (action.GetDict() != m_pAnnot->GetAnnotDict()->GetDictBy("A")) { | |
900 CPDF_Document* pDoc = m_pPageView->GetPDFDocument(); | |
901 CPDF_Dictionary* pDict = action.GetDict(); | |
902 if (pDict && pDict->GetObjNum() == 0) { | |
903 pDoc->AddIndirectObject(pDict); | |
904 } | |
905 m_pAnnot->GetAnnotDict()->SetAtReference("A", pDoc, pDict->GetObjNum()); | |
906 } | |
907 } | |
908 | |
909 void CPDFSDK_BAAnnot::RemoveAction() { | |
910 m_pAnnot->GetAnnotDict()->RemoveAt("A"); | |
911 } | |
912 | |
913 CPDF_AAction CPDFSDK_BAAnnot::GetAAction() const { | |
914 return CPDF_AAction(m_pAnnot->GetAnnotDict()->GetDictBy("AA")); | |
915 } | |
916 | |
917 void CPDFSDK_BAAnnot::SetAAction(const CPDF_AAction& aa) { | |
918 if (aa.GetDict() != m_pAnnot->GetAnnotDict()->GetDictBy("AA")) | |
919 m_pAnnot->GetAnnotDict()->SetAt("AA", aa.GetDict()); | |
920 } | |
921 | |
922 void CPDFSDK_BAAnnot::RemoveAAction() { | |
923 m_pAnnot->GetAnnotDict()->RemoveAt("AA"); | |
924 } | |
925 | |
926 CPDF_Action CPDFSDK_BAAnnot::GetAAction(CPDF_AAction::AActionType eAAT) { | |
927 CPDF_AAction AAction = GetAAction(); | |
928 | |
929 if (AAction.ActionExist(eAAT)) | |
930 return AAction.GetAction(eAAT); | |
931 | |
932 if (eAAT == CPDF_AAction::ButtonUp) | |
933 return GetAction(); | |
934 | |
935 return CPDF_Action(); | |
936 } | |
937 | |
938 #ifdef PDF_ENABLE_XFA | |
939 FX_BOOL CPDFSDK_BAAnnot::IsXFAField() { | |
940 return FALSE; | |
941 } | |
942 #endif // PDF_ENABLE_XFA | |
943 | |
944 void CPDFSDK_BAAnnot::Annot_OnDraw(CFX_RenderDevice* pDevice, | |
945 CFX_Matrix* pUser2Device, | |
946 CPDF_RenderOptions* pOptions) { | |
947 m_pAnnot->GetAPForm(m_pPageView->GetPDFPage(), CPDF_Annot::Normal); | |
948 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device, | |
949 CPDF_Annot::Normal, NULL); | |
950 } | |
951 | |
952 UnderlyingPageType* CPDFSDK_Annot::GetUnderlyingPage() { | |
953 #ifdef PDF_ENABLE_XFA | |
954 return GetPDFXFAPage(); | |
955 #else // PDF_ENABLE_XFA | |
956 return GetPDFPage(); | |
957 #endif // PDF_ENABLE_XFA | |
958 } | |
959 | |
960 CPDF_Page* CPDFSDK_Annot::GetPDFPage() { | |
961 return m_pPageView ? m_pPageView->GetPDFPage() : nullptr; | |
962 } | |
963 | |
964 #ifdef PDF_ENABLE_XFA | |
965 CPDFXFA_Page* CPDFSDK_Annot::GetPDFXFAPage() { | |
966 return m_pPageView ? m_pPageView->GetPDFXFAPage() : nullptr; | |
967 } | |
968 #endif // PDF_ENABLE_XFA | |
OLD | NEW |