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 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 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 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 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 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 //--------------------------------------------------------------------------- 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 511 CPDFSDK_Annot::~CPDFSDK_Annot() 512 { 513 m_pAnnot = NULL; 514 m_pPageView = NULL; 515 } 516 517 CPDF_Annot* CPDFSDK_Annot::GetPDFAnnot() 518 { 519 return m_pAnnot; 520 } 521 522 FX_DWORD CPDFSDK_Annot::GetFlags() 523 { 524 ASSERT(m_pAnnot != NULL); 525 526 return m_pAnnot->GetFlags(); 527 } 528 529 void CPDFSDK_Annot::SetPage(CPDFSDK_PageView* pPageView) 530 { 531 m_pPageView = pPageView; 532 } 533 534 CPDFSDK_PageView* CPDFSDK_Annot::GetPageView() 535 { 536 return m_pPageView; 537 } 538 539 FX_BOOL CPDFSDK_Annot::IsSelected() 540 { 541 return m_bSelected; 542 } 543 544 void CPDFSDK_Annot::SetSelected(FX_BOOL bSelected) 545 { 546 m_bSelected = bSelected; 547 } 548 549 // Tab Order 550 int CPDFSDK_Annot::GetTabOrder() 551 { 552 return m_nTabOrder; 553 } 554 555 void CPDFSDK_Annot::SetTabOrder(int iTabOrder) 556 { 557 m_nTabOrder = iTabOrder; 558 } 559 560 CPDF_Dictionary* CPDFSDK_Annot::GetAnnotDict() const 561 { 562 ASSERT(m_pAnnot != NULL); 563 564 return m_pAnnot->m_pAnnotDict; 565 } 566 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 577 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 587 CFX_ByteString CPDFSDK_Annot::GetType() const 588 { 589 ASSERT(m_pAnnot != NULL); 590 591 return m_pAnnot->GetSubType(); 592 } 593 594 CFX_ByteString CPDFSDK_Annot::GetSubType() const 595 { 596 return ""; 597 } 598 599 void CPDFSDK_Annot::ResetAppearance() 600 { 601 ASSERT(FALSE); 602 } 603 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 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 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 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 652 void CPDFSDK_Annot::ClearCachedAP() 653 { 654 ASSERT(m_pAnnot != NULL); 655 m_pAnnot->ClearCachedAP(); 656 } 657 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 669 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 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 688 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 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 710 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 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 732 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 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 751 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 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 767 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 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 801 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 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 856 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 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 907 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 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 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 957 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 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 1076 FX_FLOAT CPDFSDK_Annot::GetMinWidth() const 1077 { 1078 return BA_ANNOT_MINWIDTH; 1079 } 1080 1081 FX_FLOAT CPDFSDK_Annot::GetMinHeight() const 1082 { 1083 return BA_ANNOT_MINHEIGHT; 1084 } 1085 1086 FX_BOOL CPDFSDK_Annot::CreateFormFiller() 1087 { 1088 return TRUE; 1089 } 1090 FX_BOOL CPDFSDK_Annot::IsVisible() const 1091 { 1092 int nFlags = GetFlags(); 1093 return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) || (nFlags & ANNOTFLAG_NOVIEW)); 1094 } 1095 1096 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 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 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 1130 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 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 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 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 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 1181 CPDF_Page* CPDFSDK_Annot::GetPDFPage() 1182 { 1183 if(m_pPageView) 1184 return m_pPageView->GetPDFPage(); 1185 return NULL; 1186 } 1187 1188