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