OLD | NEW |
1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fpdfdoc/cpvt_generateap.h" | 7 #include "core/fpdfdoc/cpvt_generateap.h" |
8 | 8 |
9 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h" | 9 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h" |
10 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" | 10 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 pStreamResFontList->SetAtReference(sFontName, pDoc, pFontDict); | 445 pStreamResFontList->SetAtReference(sFontName, pDoc, pFontDict); |
446 } else { | 446 } else { |
447 pStreamDict->SetAt("Resources", pFormDict->GetDictBy("DR")->Clone()); | 447 pStreamDict->SetAt("Resources", pFormDict->GetDictBy("DR")->Clone()); |
448 pStreamResList = pStreamDict->GetDictBy("Resources"); | 448 pStreamResList = pStreamDict->GetDictBy("Resources"); |
449 } | 449 } |
450 } | 450 } |
451 } | 451 } |
452 return true; | 452 return true; |
453 } | 453 } |
454 | 454 |
| 455 CFX_ByteString GetColorStringWithDefault(CPDF_Dictionary* pAnnotDict, |
| 456 const CPVT_Color& crDefaultColor, |
| 457 PaintOperation nOperation) { |
| 458 if (CPDF_Array* pColor = pAnnotDict->GetArrayBy("C")) { |
| 459 CPVT_Color color = CPVT_Color::ParseColor(*pColor); |
| 460 return CPVT_GenerateAP::GenerateColorAP(color, nOperation); |
| 461 } |
| 462 |
| 463 return CPVT_GenerateAP::GenerateColorAP(crDefaultColor, nOperation); |
| 464 } |
| 465 |
| 466 CPDF_Dictionary* GenerateExtGStateDict(const CPDF_Dictionary& pAnnotDict, |
| 467 const CFX_ByteString& sExtGSDictName, |
| 468 const CFX_ByteString& sBlendMode) { |
| 469 CPDF_Dictionary* pGSDict = new CPDF_Dictionary; |
| 470 pGSDict->SetAtString("Type", "ExtGState"); |
| 471 |
| 472 FX_FLOAT fOpacity = |
| 473 pAnnotDict.KeyExist("CA") ? pAnnotDict.GetNumberBy("CA") : 1; |
| 474 pGSDict->SetAtNumber("CA", fOpacity); |
| 475 pGSDict->SetAtNumber("ca", fOpacity); |
| 476 pGSDict->SetAtBoolean("AIS", false); |
| 477 pGSDict->SetAtString("BM", sBlendMode); |
| 478 |
| 479 CPDF_Dictionary* pExtGStateDict = new CPDF_Dictionary; |
| 480 pExtGStateDict->SetAt(sExtGSDictName, pGSDict); |
| 481 |
| 482 return pExtGStateDict; |
| 483 } |
| 484 |
| 485 // Takes ownership of |pExtGStateDict|. |
| 486 void GenerateAndSetAPDict(CPDF_Document* pDoc, |
| 487 CPDF_Dictionary* pAnnotDict, |
| 488 const CFX_ByteTextBuf& sAppStream, |
| 489 CPDF_Dictionary* pExtGStateDict) { |
| 490 CPDF_Dictionary* pAPDict = new CPDF_Dictionary; |
| 491 pAnnotDict->SetAt("AP", pAPDict); |
| 492 |
| 493 CPDF_Stream* pNormalStream = new CPDF_Stream(nullptr, 0, nullptr); |
| 494 int32_t objnum = pDoc->AddIndirectObject(pNormalStream); |
| 495 pAnnotDict->GetDictBy("AP")->SetAtReference("N", pDoc, objnum); |
| 496 |
| 497 pNormalStream->SetData(reinterpret_cast<uint8_t*>(sAppStream.GetBuffer()), |
| 498 sAppStream.GetSize(), FALSE, FALSE); |
| 499 |
| 500 CPDF_Dictionary* pStreamDict = pNormalStream->GetDict(); |
| 501 pStreamDict->SetAtInteger("FormType", 1); |
| 502 pStreamDict->SetAtString("Subtype", "Form"); |
| 503 pStreamDict->SetAtMatrix("Matrix", CFX_Matrix()); |
| 504 |
| 505 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect"); |
| 506 pStreamDict->SetAtRect("BBox", rect); |
| 507 |
| 508 CPDF_Dictionary* pResourceDict = new CPDF_Dictionary; |
| 509 pResourceDict->SetAt("ExtGState", pExtGStateDict); |
| 510 |
| 511 pStreamDict->SetAt("Resources", pResourceDict); |
| 512 } |
| 513 |
455 } // namespace | 514 } // namespace |
456 | 515 |
457 bool FPDF_GenerateAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict) { | 516 bool FPDF_GenerateAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict) { |
458 if (!pAnnotDict || pAnnotDict->GetStringBy("Subtype") != "Widget") | 517 if (!pAnnotDict || pAnnotDict->GetStringBy("Subtype") != "Widget") |
459 return false; | 518 return false; |
460 | 519 |
461 CFX_ByteString field_type = FPDF_GetFieldAttr(pAnnotDict, "FT")->GetString(); | 520 CFX_ByteString field_type = FPDF_GetFieldAttr(pAnnotDict, "FT")->GetString(); |
462 uint32_t flags = FPDF_GetFieldAttr(pAnnotDict, "Ff") | 521 uint32_t flags = FPDF_GetFieldAttr(pAnnotDict, "Ff") |
463 ? FPDF_GetFieldAttr(pAnnotDict, "Ff")->GetInteger() | 522 ? FPDF_GetFieldAttr(pAnnotDict, "Ff")->GetInteger() |
464 : 0; | 523 : 0; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 } | 562 } |
504 | 563 |
505 bool CPVT_GenerateAP::GenerateHighlightAP(CPDF_Document* pDoc, | 564 bool CPVT_GenerateAP::GenerateHighlightAP(CPDF_Document* pDoc, |
506 CPDF_Dictionary* pAnnotDict) { | 565 CPDF_Dictionary* pAnnotDict) { |
507 // If AP dictionary exists, we use the appearance defined in the | 566 // If AP dictionary exists, we use the appearance defined in the |
508 // existing AP dictionary. | 567 // existing AP dictionary. |
509 if (pAnnotDict->KeyExist("AP")) | 568 if (pAnnotDict->KeyExist("AP")) |
510 return false; | 569 return false; |
511 | 570 |
512 CFX_ByteTextBuf sAppStream; | 571 CFX_ByteTextBuf sAppStream; |
513 sAppStream << "/GS gs "; | 572 CFX_ByteString sExtGSDictName = "GS"; |
| 573 sAppStream << "/" << sExtGSDictName << " gs "; |
514 | 574 |
515 if (pAnnotDict->KeyExist("C")) { | 575 sAppStream << GetColorStringWithDefault( |
516 CPDF_Array* pColor = pAnnotDict->GetArrayBy("C"); | 576 pAnnotDict, CPVT_Color(CPVT_Color::kRGB, 1, 1, 0), PaintOperation::FILL); |
517 CPVT_Color color = CPVT_Color::ParseColor(*pColor); | |
518 sAppStream << CPVT_GenerateAP::GenerateColorAP(color, PaintOperation::FILL); | |
519 } else { | |
520 // Defaults to 0xFFFF00 color for highlight. | |
521 sAppStream << "1 1 0 rg \n"; | |
522 } | |
523 | 577 |
524 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect"); | 578 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect"); |
525 rect.Normalize(); | 579 rect.Normalize(); |
526 | 580 |
527 sAppStream << rect.left << " " << rect.top << " m " << rect.right << " " | 581 sAppStream << rect.left << " " << rect.top << " m " << rect.right << " " |
528 << rect.top << " l " << rect.right << " " << rect.bottom << " l " | 582 << rect.top << " l " << rect.right << " " << rect.bottom << " l " |
529 << rect.left << " " << rect.bottom << " l " | 583 << rect.left << " " << rect.bottom << " l " |
530 << "h f\n"; | 584 << "h f\n"; |
531 | 585 |
532 CPDF_Dictionary* pAPDict = new CPDF_Dictionary; | 586 CPDF_Dictionary* pExtGStateDict = |
533 pAnnotDict->SetAt("AP", pAPDict); | 587 GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Multiply"); |
| 588 GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pExtGStateDict); |
534 | 589 |
535 CPDF_Stream* pNormalStream = new CPDF_Stream(nullptr, 0, nullptr); | |
536 int32_t objnum = pDoc->AddIndirectObject(pNormalStream); | |
537 pAnnotDict->GetDictBy("AP")->SetAtReference("N", pDoc, objnum); | |
538 | |
539 pNormalStream->SetData(reinterpret_cast<uint8_t*>(sAppStream.GetBuffer()), | |
540 sAppStream.GetSize(), FALSE, FALSE); | |
541 | |
542 CPDF_Dictionary* pStreamDict = pNormalStream->GetDict(); | |
543 pStreamDict->SetAtInteger("FormType", 1); | |
544 pStreamDict->SetAtString("Subtype", "Form"); | |
545 pStreamDict->SetAtMatrix("Matrix", CFX_Matrix()); | |
546 pStreamDict->SetAtRect("BBox", rect); | |
547 | |
548 CPDF_Dictionary* pGSDict = new CPDF_Dictionary; | |
549 pGSDict->SetAtString("Type", "ExtGState"); | |
550 | |
551 FX_FLOAT fOpacity = | |
552 pAnnotDict->KeyExist("CA") ? pAnnotDict->GetNumberBy("CA") : 1; | |
553 pGSDict->SetAtNumber("ca", fOpacity); | |
554 pGSDict->SetAtNumber("CA", fOpacity); | |
555 pGSDict->SetAtBoolean("AIS", false); | |
556 pGSDict->SetAtString("BM", "Multiply"); | |
557 | |
558 CPDF_Dictionary* pExtGStateDict = new CPDF_Dictionary; | |
559 pExtGStateDict->SetAt("GS", pGSDict); | |
560 | |
561 CPDF_Dictionary* pResourceDict = new CPDF_Dictionary; | |
562 pResourceDict->SetAt("ExtGState", pExtGStateDict); | |
563 | |
564 pStreamDict->SetAt("Resources", pResourceDict); | |
565 return true; | 590 return true; |
566 } | 591 } |
567 | 592 |
| 593 bool CPVT_GenerateAP::GenerateUnderlineAP(CPDF_Document* pDoc, |
| 594 CPDF_Dictionary* pAnnotDict) { |
| 595 // If AP dictionary exists, we use the appearance defined in the |
| 596 // existing AP dictionary. |
| 597 if (pAnnotDict->KeyExist("AP")) |
| 598 return false; |
| 599 |
| 600 CFX_ByteTextBuf sAppStream; |
| 601 CFX_ByteString sExtGSDictName = "GS"; |
| 602 sAppStream << "/" << sExtGSDictName << " gs "; |
| 603 |
| 604 sAppStream << GetColorStringWithDefault(pAnnotDict, |
| 605 CPVT_Color(CPVT_Color::kRGB, 0, 0, 0), |
| 606 PaintOperation::STROKE); |
| 607 |
| 608 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect"); |
| 609 rect.Normalize(); |
| 610 |
| 611 FX_FLOAT fLineWidth = 1.0; |
| 612 sAppStream << fLineWidth << " w " << rect.left << " " |
| 613 << rect.bottom + fLineWidth << " m " << rect.right << " " |
| 614 << rect.bottom + fLineWidth << " l S\n"; |
| 615 |
| 616 CPDF_Dictionary* pExtGStateDict = |
| 617 GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal"); |
| 618 GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pExtGStateDict); |
| 619 return true; |
| 620 } |
| 621 |
568 // Static. | 622 // Static. |
569 CFX_ByteString CPVT_GenerateAP::GenerateEditAP( | 623 CFX_ByteString CPVT_GenerateAP::GenerateEditAP( |
570 IPVT_FontMap* pFontMap, | 624 IPVT_FontMap* pFontMap, |
571 CPDF_VariableText::Iterator* pIterator, | 625 CPDF_VariableText::Iterator* pIterator, |
572 const CFX_FloatPoint& ptOffset, | 626 const CFX_FloatPoint& ptOffset, |
573 FX_BOOL bContinuous, | 627 FX_BOOL bContinuous, |
574 uint16_t SubWord) { | 628 uint16_t SubWord) { |
575 CFX_ByteTextBuf sEditStream; | 629 CFX_ByteTextBuf sEditStream; |
576 CFX_ByteTextBuf sLineStream; | 630 CFX_ByteTextBuf sLineStream; |
577 CFX_ByteTextBuf sWords; | 631 CFX_ByteTextBuf sWords; |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 int32_t nFontIndex, | 880 int32_t nFontIndex, |
827 FX_FLOAT fFontSize) { | 881 FX_FLOAT fFontSize) { |
828 CFX_ByteTextBuf sRet; | 882 CFX_ByteTextBuf sRet; |
829 if (pFontMap) { | 883 if (pFontMap) { |
830 CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex); | 884 CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex); |
831 if (sFontAlias.GetLength() > 0 && fFontSize > 0) | 885 if (sFontAlias.GetLength() > 0 && fFontSize > 0) |
832 sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n"; | 886 sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n"; |
833 } | 887 } |
834 return sRet.MakeString(); | 888 return sRet.MakeString(); |
835 } | 889 } |
OLD | NEW |