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