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