• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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