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 sprintf(tempStr, "D:%04d%02d%02d%02d%02d%02d", dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
361 dtStr = CFX_ByteString(tempStr);
362 if (dt.tzHour < 0)
363 dtStr += CFX_ByteString("-");
364 else
365 dtStr += CFX_ByteString("+");
366 sprintf(tempStr, "%02d'%02d'", abs(dt.tzHour), dt.tzMinute);
367 dtStr += CFX_ByteString(tempStr);
368 return dtStr;
369 }
370
ToSystemTime(FX_SYSTEMTIME & st)371 void CPDFSDK_DateTime::ToSystemTime(FX_SYSTEMTIME& st)
372 {
373 CPDFSDK_DateTime dt = *this;
374 time_t t = (time_t)dt;
375 struct tm* pTime = localtime(&t);
376 if(pTime){
377 st.wYear = (FX_WORD)pTime->tm_year + 1900;
378 st.wMonth = (FX_WORD)pTime->tm_mon + 1;
379 st.wDay = (FX_WORD)pTime->tm_mday;
380 st.wDayOfWeek = (FX_WORD)pTime->tm_wday;
381 st.wHour = (FX_WORD)pTime->tm_hour;
382 st.wMinute = (FX_WORD)pTime->tm_min;
383 st.wSecond = (FX_WORD)pTime->tm_sec;
384 st.wMilliseconds = 0;
385 }
386 }
387
ToGMT()388 CPDFSDK_DateTime CPDFSDK_DateTime::ToGMT()
389 {
390 CPDFSDK_DateTime dt = *this;
391 dt.AddSeconds(-_gAfxGetTimeZoneInSeconds(dt.dt.tzHour, dt.dt.tzMinute));
392 dt.dt.tzHour = 0;
393 dt.dt.tzMinute = 0;
394 return dt;
395 }
396
AddDays(short days)397 CPDFSDK_DateTime& CPDFSDK_DateTime::AddDays(short days)
398 {
399 if (days == 0) return *this;
400
401 FX_SHORT y = dt.year, yy;
402 FX_BYTE m = dt.month;
403 FX_BYTE d = dt.day;
404 int mdays, ydays, ldays;
405
406 ldays = days;
407 if (ldays > 0)
408 {
409 yy = y;
410 if (((FX_WORD)m * 100 + d) > 300) yy ++;
411 ydays = _gAfxGetYearDays(yy);
412 while (ldays >= ydays)
413 {
414 y ++;
415 ldays -= ydays;
416 yy ++;
417 mdays = _gAfxGetMonthDays(y, m);
418 if (d > mdays)
419 {
420 m ++;
421 d -= mdays;
422 }
423 ydays = _gAfxGetYearDays(yy);
424 }
425 mdays = _gAfxGetMonthDays(y, m) - d + 1;
426 while (ldays >= mdays)
427 {
428 ldays -= mdays;
429 m ++;
430 d = 1;
431 mdays = _gAfxGetMonthDays(y, m);
432 }
433 d += ldays;
434 }
435 else
436 {
437 ldays *= -1;
438 yy = y;
439 if (((FX_WORD)m * 100 + d) < 300) yy --;
440 ydays = _gAfxGetYearDays(yy);
441 while (ldays >= ydays)
442 {
443 y --;
444 ldays -= ydays;
445 yy --;
446 mdays = _gAfxGetMonthDays(y, m);
447 if (d > mdays)
448 {
449 m ++;
450 d -= mdays;
451 }
452 ydays = _gAfxGetYearDays(yy);
453 }
454 while (ldays >= d)
455 {
456 ldays -= d;
457 m --;
458 mdays = _gAfxGetMonthDays(y, m);
459 d = mdays;
460 }
461 d -= ldays;
462 }
463
464 dt.year = y;
465 dt.month = m;
466 dt.day = d;
467
468 return *this;
469 }
470
AddSeconds(int seconds)471 CPDFSDK_DateTime& CPDFSDK_DateTime::AddSeconds(int seconds)
472 {
473 if (seconds == 0) return *this;
474
475 int n;
476 int days;
477
478 n = dt.hour * 3600 + dt.minute * 60 + dt.second + seconds;
479 if (n < 0)
480 {
481 days = (n - 86399) / 86400;
482 n -= days * 86400;
483 }
484 else
485 {
486 days = n / 86400;
487 n %= 86400;
488 }
489 dt.hour = (FX_BYTE)(n / 3600);
490 dt.hour %= 24;
491 n %= 3600;
492 dt.minute = (FX_BYTE)(n / 60);
493 dt.second = (FX_BYTE)(n % 60);
494 if (days != 0) AddDays(days);
495
496 return *this;
497 }
498
499
500 //---------------------------------------------------------------------------
501 // CPDFSDK_Annot
502 //---------------------------------------------------------------------------
CPDFSDK_Annot(CPDF_Annot * pAnnot,CPDFSDK_PageView * pPageView)503 CPDFSDK_Annot::CPDFSDK_Annot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView) :
504 m_pAnnot(pAnnot),
505 m_pPageView(pPageView),
506 m_bSelected(FALSE),
507 m_nTabOrder(-1)
508 {
509 }
510
~CPDFSDK_Annot()511 CPDFSDK_Annot::~CPDFSDK_Annot()
512 {
513 m_pAnnot = NULL;
514 m_pPageView = NULL;
515 }
516
GetPDFAnnot()517 CPDF_Annot* CPDFSDK_Annot::GetPDFAnnot()
518 {
519 return m_pAnnot;
520 }
521
GetFlags()522 FX_DWORD CPDFSDK_Annot::GetFlags()
523 {
524 ASSERT(m_pAnnot != NULL);
525
526 return m_pAnnot->GetFlags();
527 }
528
SetPage(CPDFSDK_PageView * pPageView)529 void CPDFSDK_Annot::SetPage(CPDFSDK_PageView* pPageView)
530 {
531 m_pPageView = pPageView;
532 }
533
GetPageView()534 CPDFSDK_PageView* CPDFSDK_Annot::GetPageView()
535 {
536 return m_pPageView;
537 }
538
IsSelected()539 FX_BOOL CPDFSDK_Annot::IsSelected()
540 {
541 return m_bSelected;
542 }
543
SetSelected(FX_BOOL bSelected)544 void CPDFSDK_Annot::SetSelected(FX_BOOL bSelected)
545 {
546 m_bSelected = bSelected;
547 }
548
549 // Tab Order
GetTabOrder()550 int CPDFSDK_Annot::GetTabOrder()
551 {
552 return m_nTabOrder;
553 }
554
SetTabOrder(int iTabOrder)555 void CPDFSDK_Annot::SetTabOrder(int iTabOrder)
556 {
557 m_nTabOrder = iTabOrder;
558 }
559
GetAnnotDict() const560 CPDF_Dictionary* CPDFSDK_Annot::GetAnnotDict() const
561 {
562 ASSERT(m_pAnnot != NULL);
563
564 return m_pAnnot->m_pAnnotDict;
565 }
566
SetRect(const CPDF_Rect & rect)567 void CPDFSDK_Annot::SetRect(const CPDF_Rect& rect)
568 {
569 ASSERT(m_pAnnot != NULL);
570 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
571 ASSERT(rect.right - rect.left >= GetMinWidth());
572 ASSERT(rect.top - rect.bottom >= GetMinHeight());
573
574 m_pAnnot->m_pAnnotDict->SetAtRect("Rect", rect);
575 }
576
GetRect() const577 CPDF_Rect CPDFSDK_Annot::GetRect() const
578 {
579 ASSERT(m_pAnnot != NULL);
580
581 CPDF_Rect rect;
582 m_pAnnot->GetRect(rect);
583
584 return rect;
585 }
586
GetType() const587 CFX_ByteString CPDFSDK_Annot::GetType() const
588 {
589 ASSERT(m_pAnnot != NULL);
590
591 return m_pAnnot->GetSubType();
592 }
593
GetSubType() const594 CFX_ByteString CPDFSDK_Annot::GetSubType() const
595 {
596 return "";
597 }
598
ResetAppearance()599 void CPDFSDK_Annot::ResetAppearance()
600 {
601 ASSERT(FALSE);
602 }
603
DrawAppearance(CFX_RenderDevice * pDevice,const CPDF_Matrix * pUser2Device,CPDF_Annot::AppearanceMode mode,const CPDF_RenderOptions * pOptions)604 void CPDFSDK_Annot::DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
605 CPDF_Annot::AppearanceMode mode, const CPDF_RenderOptions* pOptions)
606 {
607 ASSERT(m_pPageView != NULL);
608 ASSERT(m_pAnnot != NULL);
609
610 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device, mode, pOptions);
611 }
612
IsAppearanceValid()613 FX_BOOL CPDFSDK_Annot::IsAppearanceValid()
614 {
615 ASSERT(m_pAnnot != NULL);
616 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
617
618 return m_pAnnot->m_pAnnotDict->GetDict("AP") != NULL;
619 }
620
IsAppearanceValid(CPDF_Annot::AppearanceMode mode)621 FX_BOOL CPDFSDK_Annot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode)
622 {
623 ASSERT(m_pAnnot != NULL);
624 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
625
626 CPDF_Dictionary* pAP = m_pAnnot->m_pAnnotDict->GetDict("AP");
627 if (pAP == NULL) return FALSE;
628
629 // Choose the right sub-ap
630 const FX_CHAR* ap_entry = "N";
631 if (mode == CPDF_Annot::Down)
632 ap_entry = "D";
633 else if (mode == CPDF_Annot::Rollover)
634 ap_entry = "R";
635 if (!pAP->KeyExist(ap_entry))
636 ap_entry = "N";
637
638 // Get the AP stream or subdirectory
639 CPDF_Object* psub = pAP->GetElementValue(ap_entry);
640 if (psub == NULL) return FALSE;
641
642 return TRUE;
643 }
644
DrawBorder(CFX_RenderDevice * pDevice,const CPDF_Matrix * pUser2Device,const CPDF_RenderOptions * pOptions)645 void CPDFSDK_Annot::DrawBorder(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
646 const CPDF_RenderOptions* pOptions)
647 {
648 ASSERT(m_pAnnot != NULL);
649 m_pAnnot->DrawBorder(pDevice, pUser2Device, pOptions);
650 }
651
ClearCachedAP()652 void CPDFSDK_Annot::ClearCachedAP()
653 {
654 ASSERT(m_pAnnot != NULL);
655 m_pAnnot->ClearCachedAP();
656 }
657
SetContents(const CFX_WideString & sContents)658 void CPDFSDK_Annot::SetContents(const CFX_WideString& sContents)
659 {
660 ASSERT(m_pAnnot != NULL);
661 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
662
663 if (sContents.IsEmpty())
664 m_pAnnot->m_pAnnotDict->RemoveAt("Contents");
665 else
666 m_pAnnot->m_pAnnotDict->SetAtString("Contents", PDF_EncodeText(sContents));
667 }
668
GetContents() const669 CFX_WideString CPDFSDK_Annot::GetContents() const
670 {
671 ASSERT(m_pAnnot != NULL);
672 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
673
674 return m_pAnnot->m_pAnnotDict->GetUnicodeText("Contents");
675 }
676
SetAnnotName(const CFX_WideString & sName)677 void CPDFSDK_Annot::SetAnnotName(const CFX_WideString& sName)
678 {
679 ASSERT(m_pAnnot != NULL);
680 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
681
682 if (sName.IsEmpty())
683 m_pAnnot->m_pAnnotDict->RemoveAt("NM");
684 else
685 m_pAnnot->m_pAnnotDict->SetAtString("NM", PDF_EncodeText(sName));
686 }
687
GetAnnotName() const688 CFX_WideString CPDFSDK_Annot::GetAnnotName() const
689 {
690 ASSERT(m_pAnnot != NULL);
691 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
692
693 return m_pAnnot->m_pAnnotDict->GetUnicodeText("NM");
694 }
695
SetModifiedDate(const FX_SYSTEMTIME & st)696 void CPDFSDK_Annot::SetModifiedDate(const FX_SYSTEMTIME& st)
697 {
698 ASSERT(m_pAnnot != NULL);
699 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
700
701 CPDFSDK_DateTime dt(st);
702 CFX_ByteString str = dt.ToPDFDateTimeString();
703
704 if (str.IsEmpty())
705 m_pAnnot->m_pAnnotDict->RemoveAt("M");
706 else
707 m_pAnnot->m_pAnnotDict->SetAtString("M", str);
708 }
709
GetModifiedDate() const710 FX_SYSTEMTIME CPDFSDK_Annot::GetModifiedDate() const
711 {
712 ASSERT(m_pAnnot != NULL);
713 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
714
715 FX_SYSTEMTIME systime;
716 CFX_ByteString str = m_pAnnot->m_pAnnotDict->GetString("M");
717
718 CPDFSDK_DateTime dt(str);
719 dt.ToSystemTime(systime);
720
721 return systime;
722 }
723
SetFlags(int nFlags)724 void CPDFSDK_Annot::SetFlags(int nFlags)
725 {
726 ASSERT(m_pAnnot != NULL);
727 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
728
729 m_pAnnot->m_pAnnotDict->SetAtInteger("F", nFlags);
730 }
731
GetFlags() const732 int CPDFSDK_Annot::GetFlags() const
733 {
734 ASSERT(m_pAnnot != NULL);
735 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
736
737 return m_pAnnot->m_pAnnotDict->GetInteger("F");
738 }
739
SetAppState(const CFX_ByteString & str)740 void CPDFSDK_Annot::SetAppState(const CFX_ByteString& str)
741 {
742 ASSERT(m_pAnnot != NULL);
743 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
744
745 if (str.IsEmpty())
746 m_pAnnot->m_pAnnotDict->RemoveAt("AS");
747 else
748 m_pAnnot->m_pAnnotDict->SetAtString("AS", str);
749 }
750
GetAppState() const751 CFX_ByteString CPDFSDK_Annot::GetAppState() const
752 {
753 ASSERT(m_pAnnot != NULL);
754 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
755
756 return m_pAnnot->m_pAnnotDict->GetString("AS");
757 }
758
SetStructParent(int key)759 void CPDFSDK_Annot::SetStructParent(int key)
760 {
761 ASSERT(m_pAnnot != NULL);
762 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
763
764 m_pAnnot->m_pAnnotDict->SetAtInteger("StructParent", key);
765 }
766
GetStructParent() const767 int CPDFSDK_Annot::GetStructParent() const
768 {
769 ASSERT(m_pAnnot != NULL);
770 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
771
772 return m_pAnnot->m_pAnnotDict->GetInteger("StructParent");
773 }
774
775 //border
SetBorderWidth(int nWidth)776 void CPDFSDK_Annot::SetBorderWidth(int nWidth)
777 {
778 ASSERT(m_pAnnot != NULL);
779 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
780
781 CPDF_Array* pBorder = m_pAnnot->m_pAnnotDict->GetArray("Border");
782
783 if (pBorder)
784 {
785 pBorder->SetAt(2, FX_NEW CPDF_Number(nWidth));
786 }
787 else
788 {
789 CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS");
790
791 if (!pBSDict)
792 {
793 pBSDict = FX_NEW CPDF_Dictionary;
794 m_pAnnot->m_pAnnotDict->SetAt("BS", pBSDict);
795 }
796
797 pBSDict->SetAtInteger("W", nWidth);
798 }
799 }
800
GetBorderWidth() const801 int CPDFSDK_Annot::GetBorderWidth() const
802 {
803 ASSERT(m_pAnnot != NULL);
804 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
805
806 CPDF_Array* pBorder = m_pAnnot->m_pAnnotDict->GetArray("Border");
807
808 if (pBorder)
809 {
810 return pBorder->GetInteger(2);
811 }
812 else
813 {
814 CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS");
815
816 if (pBSDict)
817 {
818 return pBSDict->GetInteger("W", 1);
819 }
820 }
821 return 1;
822 }
823
SetBorderStyle(int nStyle)824 void CPDFSDK_Annot::SetBorderStyle(int nStyle)
825 {
826 ASSERT(m_pAnnot != NULL);
827 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
828
829 CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS");
830 if (!pBSDict)
831 {
832 pBSDict = FX_NEW CPDF_Dictionary;
833 m_pAnnot->m_pAnnotDict->SetAt("BS", pBSDict);
834 }
835
836 switch (nStyle)
837 {
838 case BBS_SOLID:
839 pBSDict->SetAtName("S", "S");
840 break;
841 case BBS_DASH:
842 pBSDict->SetAtName("S", "D");
843 break;
844 case BBS_BEVELED:
845 pBSDict->SetAtName("S", "B");
846 break;
847 case BBS_INSET:
848 pBSDict->SetAtName("S", "I");
849 break;
850 case BBS_UNDERLINE:
851 pBSDict->SetAtName("S", "U");
852 break;
853 }
854 }
855
GetBorderStyle() const856 int CPDFSDK_Annot::GetBorderStyle() const
857 {
858 ASSERT(m_pAnnot != NULL);
859 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
860
861 CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS");
862 if (pBSDict)
863 {
864 CFX_ByteString sBorderStyle = pBSDict->GetString("S", "S");
865 if (sBorderStyle == "S") return BBS_SOLID;
866 if (sBorderStyle == "D") return BBS_DASH;
867 if (sBorderStyle == "B") return BBS_BEVELED;
868 if (sBorderStyle == "I") return BBS_INSET;
869 if (sBorderStyle == "U") return BBS_UNDERLINE;
870 }
871
872 CPDF_Array* pBorder = m_pAnnot->m_pAnnotDict->GetArray("Border");
873 if (pBorder)
874 {
875 if (pBorder->GetCount() >= 4)
876 {
877 CPDF_Array *pDP = pBorder->GetArray(3);
878 if (pDP && pDP->GetCount() > 0)
879 return BBS_DASH;
880 }
881 }
882
883 return BBS_SOLID;
884 }
885
SetBorderDash(const CFX_IntArray & array)886 void CPDFSDK_Annot::SetBorderDash(const CFX_IntArray& array)
887 {
888 ASSERT(m_pAnnot != NULL);
889 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
890
891 CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS");
892 if (!pBSDict)
893 {
894 pBSDict = FX_NEW CPDF_Dictionary;
895 m_pAnnot->m_pAnnotDict->SetAt("BS", pBSDict);
896 }
897
898 CPDF_Array* pArray = FX_NEW CPDF_Array;
899 for (int i=0,sz=array.GetSize(); i<sz; i++)
900 {
901 pArray->AddInteger(array[i]);
902 }
903
904 pBSDict->SetAt("D", pArray);
905 }
906
GetBorderDash(CFX_IntArray & array) const907 void CPDFSDK_Annot::GetBorderDash(CFX_IntArray& array) const
908 {
909 ASSERT(m_pAnnot != NULL);
910 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
911
912 CPDF_Array* pDash = NULL;
913
914 CPDF_Array* pBorder = m_pAnnot->m_pAnnotDict->GetArray("Border");
915 if (pBorder)
916 {
917 pDash = pBorder->GetArray(3);
918 }
919 else
920 {
921 CPDF_Dictionary* pBSDict = m_pAnnot->m_pAnnotDict->GetDict("BS");
922 if (pBSDict)
923 {
924 pDash = pBSDict->GetArray("D");
925 }
926 }
927
928 if (pDash)
929 {
930 for (int i=0,sz=pDash->GetCount(); i<sz; i++)
931 {
932 array.Add(pDash->GetInteger(i));
933 }
934 }
935 }
936
SetColor(FX_COLORREF color)937 void CPDFSDK_Annot::SetColor(FX_COLORREF color)
938 {
939 ASSERT(m_pAnnot != NULL);
940 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
941
942 CPDF_Array* pArray = FX_NEW CPDF_Array;
943 pArray->AddNumber((FX_FLOAT)FXSYS_GetRValue(color) / 255.0f);
944 pArray->AddNumber((FX_FLOAT)FXSYS_GetGValue(color) / 255.0f);
945 pArray->AddNumber((FX_FLOAT)FXSYS_GetBValue(color) / 255.0f);
946 m_pAnnot->m_pAnnotDict->SetAt("C", pArray);
947 }
948
RemoveColor()949 void CPDFSDK_Annot::RemoveColor()
950 {
951 ASSERT(m_pAnnot != NULL);
952 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
953
954 m_pAnnot->m_pAnnotDict->RemoveAt("C") ;
955 }
956
GetColor(FX_COLORREF & color) const957 FX_BOOL CPDFSDK_Annot::GetColor(FX_COLORREF& color) const
958 {
959 ASSERT(m_pAnnot != NULL);
960 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
961
962 if (CPDF_Array* pEntry = m_pAnnot->m_pAnnotDict->GetArray("C"))
963 {
964 int nCount = pEntry->GetCount();
965 if (nCount == 1)
966 {
967 FX_FLOAT g = pEntry->GetNumber(0) * 255;
968
969 color = FXSYS_RGB((int)g, (int)g, (int)g);
970
971 return TRUE;
972 }
973 else if (nCount == 3)
974 {
975 FX_FLOAT r = pEntry->GetNumber(0) * 255;
976 FX_FLOAT g = pEntry->GetNumber(1) * 255;
977 FX_FLOAT b = pEntry->GetNumber(2) * 255;
978
979 color = FXSYS_RGB((int)r, (int)g, (int)b);
980
981 return TRUE;
982 }
983 else if (nCount == 4)
984 {
985 FX_FLOAT c = pEntry->GetNumber(0);
986 FX_FLOAT m = pEntry->GetNumber(1);
987 FX_FLOAT y = pEntry->GetNumber(2);
988 FX_FLOAT k = pEntry->GetNumber(3);
989
990 FX_FLOAT r = 1.0f - FX_MIN(1.0f, c + k);
991 FX_FLOAT g = 1.0f - FX_MIN(1.0f, m + k);
992 FX_FLOAT b = 1.0f - FX_MIN(1.0f, y + k);
993
994 color = FXSYS_RGB((int)(r * 255), (int)(g * 255), (int)(b * 255));
995
996 return TRUE;
997 }
998 }
999
1000 return FALSE;
1001 }
1002
1003
WriteAppearance(const CFX_ByteString & sAPType,const CPDF_Rect & rcBBox,const CPDF_Matrix & matrix,const CFX_ByteString & sContents,const CFX_ByteString & sAPState)1004 void CPDFSDK_Annot::WriteAppearance(const CFX_ByteString& sAPType, const CPDF_Rect& rcBBox,
1005 const CPDF_Matrix& matrix, const CFX_ByteString& sContents,
1006 const CFX_ByteString& sAPState)
1007 {
1008 ASSERT(m_pAnnot != NULL);
1009 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
1010
1011 CPDF_Dictionary* pAPDict = m_pAnnot->m_pAnnotDict->GetDict("AP");
1012
1013 if (!pAPDict)
1014 {
1015 pAPDict = FX_NEW CPDF_Dictionary;
1016 m_pAnnot->m_pAnnotDict->SetAt("AP", pAPDict);
1017 }
1018
1019 CPDF_Stream* pStream = NULL;
1020 CPDF_Dictionary* pParentDict = NULL;
1021
1022 if (sAPState.IsEmpty())
1023 {
1024 pParentDict = pAPDict;
1025 pStream = pAPDict->GetStream(sAPType);
1026 }
1027 else
1028 {
1029 CPDF_Dictionary* pAPTypeDict = pAPDict->GetDict(sAPType);
1030 if (!pAPTypeDict)
1031 {
1032 pAPTypeDict = FX_NEW CPDF_Dictionary;
1033 pAPDict->SetAt(sAPType, pAPTypeDict);
1034 }
1035
1036 pParentDict = pAPTypeDict;
1037 pStream = pAPTypeDict->GetStream(sAPState);
1038 }
1039
1040 if (!pStream)
1041 {
1042 ASSERT(m_pPageView != NULL);
1043 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
1044 ASSERT(pDoc != NULL);
1045
1046 pStream = FX_NEW CPDF_Stream(NULL, 0, NULL);
1047 FX_INT32 objnum = pDoc->AddIndirectObject(pStream);
1048 //pAPDict->SetAtReference(sAPType, pDoc, objnum);
1049 ASSERT(pParentDict != NULL);
1050 pParentDict->SetAtReference(sAPType, pDoc, objnum);
1051 }
1052
1053 CPDF_Dictionary * pStreamDict = pStream->GetDict();
1054
1055 if (!pStreamDict)
1056 {
1057 pStreamDict = FX_NEW CPDF_Dictionary;
1058 pStreamDict->SetAtName("Type", "XObject");
1059 pStreamDict->SetAtName("Subtype", "Form");
1060 pStreamDict->SetAtInteger("FormType", 1);
1061 pStream->InitStream(NULL,0,pStreamDict);
1062 }
1063
1064 if (pStreamDict)
1065 {
1066 pStreamDict->SetAtMatrix("Matrix",matrix);
1067 pStreamDict->SetAtRect("BBox", rcBBox);
1068 }
1069
1070 pStream->SetData((FX_BYTE*)(FX_LPCSTR)sContents, sContents.GetLength(), FALSE, FALSE);
1071 }
1072
1073 #define BA_ANNOT_MINWIDTH 1
1074 #define BA_ANNOT_MINHEIGHT 1
1075
GetMinWidth() const1076 FX_FLOAT CPDFSDK_Annot::GetMinWidth() const
1077 {
1078 return BA_ANNOT_MINWIDTH;
1079 }
1080
GetMinHeight() const1081 FX_FLOAT CPDFSDK_Annot::GetMinHeight() const
1082 {
1083 return BA_ANNOT_MINHEIGHT;
1084 }
1085
CreateFormFiller()1086 FX_BOOL CPDFSDK_Annot::CreateFormFiller()
1087 {
1088 return TRUE;
1089 }
IsVisible() const1090 FX_BOOL CPDFSDK_Annot::IsVisible() const
1091 {
1092 int nFlags = GetFlags();
1093 return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) || (nFlags & ANNOTFLAG_NOVIEW));
1094 }
1095
GetAction() const1096 CPDF_Action CPDFSDK_Annot::GetAction() const
1097 {
1098 ASSERT(m_pAnnot != NULL);
1099 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
1100
1101 return m_pAnnot->m_pAnnotDict->GetDict("A");
1102 }
1103
SetAction(const CPDF_Action & action)1104 void CPDFSDK_Annot::SetAction(const CPDF_Action& action)
1105 {
1106 ASSERT(m_pAnnot != NULL);
1107 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
1108
1109 ASSERT(action != NULL);
1110
1111 if ((CPDF_Action&)action != m_pAnnot->m_pAnnotDict->GetDict("A"))
1112 {
1113 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
1114 ASSERT(pDoc != NULL);
1115
1116 if (action.m_pDict && (action.m_pDict->GetObjNum() == 0))
1117 pDoc->AddIndirectObject(action.m_pDict);
1118 m_pAnnot->m_pAnnotDict->SetAtReference("A", pDoc, action.m_pDict->GetObjNum());
1119 }
1120 }
1121
RemoveAction()1122 void CPDFSDK_Annot::RemoveAction()
1123 {
1124 ASSERT(m_pAnnot != NULL);
1125 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
1126
1127 m_pAnnot->m_pAnnotDict->RemoveAt("A");
1128 }
1129
GetAAction() const1130 CPDF_AAction CPDFSDK_Annot::GetAAction() const
1131 {
1132 ASSERT(m_pAnnot != NULL);
1133 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
1134
1135 return m_pAnnot->m_pAnnotDict->GetDict("AA");
1136 }
1137
SetAAction(const CPDF_AAction & aa)1138 void CPDFSDK_Annot::SetAAction(const CPDF_AAction& aa)
1139 {
1140 ASSERT(m_pAnnot != NULL);
1141 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
1142 ASSERT(aa != NULL);
1143
1144 if ((CPDF_AAction&)aa != m_pAnnot->m_pAnnotDict->GetDict("AA"))
1145 m_pAnnot->m_pAnnotDict->SetAt("AA", (CPDF_AAction&)aa);
1146 }
1147
RemoveAAction()1148 void CPDFSDK_Annot::RemoveAAction()
1149 {
1150 ASSERT(m_pAnnot != NULL);
1151 ASSERT(m_pAnnot->m_pAnnotDict != NULL);
1152
1153 m_pAnnot->m_pAnnotDict->RemoveAt("AA");
1154 }
1155
GetAAction(CPDF_AAction::AActionType eAAT)1156 CPDF_Action CPDFSDK_Annot::GetAAction(CPDF_AAction::AActionType eAAT)
1157 {
1158 CPDF_AAction AAction = GetAAction();
1159
1160 if (AAction.ActionExist(eAAT))
1161 {
1162 return AAction.GetAction(eAAT);
1163 }
1164 else if (eAAT == CPDF_AAction::ButtonUp)
1165 {
1166 return GetAction();
1167 }
1168
1169 return NULL;
1170 }
1171
Annot_OnDraw(CFX_RenderDevice * pDevice,CPDF_Matrix * pUser2Device,CPDF_RenderOptions * pOptions)1172 void CPDFSDK_Annot::Annot_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, CPDF_RenderOptions* pOptions)
1173 {
1174
1175 m_pAnnot->GetAPForm(m_pPageView->GetPDFPage(), CPDF_Annot::Normal);
1176 m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
1177
1178 return ;
1179 }
1180
GetPDFPage()1181 CPDF_Page* CPDFSDK_Annot::GetPDFPage()
1182 {
1183 if(m_pPageView)
1184 return m_pPageView->GetPDFPage();
1185 return NULL;
1186 }
1187
1188