Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(976)

Side by Side Diff: core/fpdfdoc/cpvt_generateap.cpp

Issue 2219683002: Generate default AP stream for square annotation. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Generate default AP stream for square annotation. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/fpdfdoc/cpvt_generateap.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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, 455 CFX_ByteString GetColorStringWithDefault(CPDF_Array* pColor,
456 const CPVT_Color& crDefaultColor, 456 const CPVT_Color& crDefaultColor,
457 PaintOperation nOperation) { 457 PaintOperation nOperation) {
458 if (CPDF_Array* pColor = pAnnotDict->GetArrayBy("C")) { 458 if (pColor) {
459 CPVT_Color color = CPVT_Color::ParseColor(*pColor); 459 CPVT_Color color = CPVT_Color::ParseColor(*pColor);
460 return CPVT_GenerateAP::GenerateColorAP(color, nOperation); 460 return CPVT_GenerateAP::GenerateColorAP(color, nOperation);
461 } 461 }
462 462
463 return CPVT_GenerateAP::GenerateColorAP(crDefaultColor, nOperation); 463 return CPVT_GenerateAP::GenerateColorAP(crDefaultColor, nOperation);
464 } 464 }
465 465
466 FX_FLOAT GetBorderWidth(const CPDF_Dictionary& pAnnotDict) {
467 if (CPDF_Dictionary* pBorderStyleDict = pAnnotDict.GetDictBy("BS")) {
468 if (pBorderStyleDict->KeyExist("W"))
469 return pBorderStyleDict->GetNumberBy("W");
470 }
471
472 if (CPDF_Array* pBorderArray = pAnnotDict.GetArrayBy("Border")) {
473 if (pBorderArray->GetCount() > 2)
474 return pBorderArray->GetNumberAt(2);
475 }
476
477 return 1;
478 }
479
480 CPDF_Array* GetDashArray(const CPDF_Dictionary& pAnnotDict) {
481 if (CPDF_Dictionary* pBorderStyleDict = pAnnotDict.GetDictBy("BS")) {
482 if (pBorderStyleDict->GetStringBy("S") == "D")
483 return pBorderStyleDict->GetArrayBy("D");
484 }
485
486 if (CPDF_Array* pBorderArray = pAnnotDict.GetArrayBy("Border")) {
487 if (pBorderArray->GetCount() == 4)
488 return pBorderArray->GetArrayAt(3);
489 }
490
491 return nullptr;
492 }
493
494 CFX_ByteString GetDashPatternString(const CPDF_Dictionary& pAnnotDict) {
495 CPDF_Array* pDashArray = GetDashArray(pAnnotDict);
496 if (!pDashArray)
497 return CFX_ByteString();
498
499 size_t pDashArrayCount = pDashArray->GetCount();
500 if (pDashArrayCount == 0 || pDashArrayCount > 10)
Lei Zhang 2016/08/08 23:10:41 BTW, do you want to make a sample PDF where the ar
jaepark 2016/08/09 00:11:03 I've changed it to truncate at 10.
501 return CFX_ByteString();
502
503 CFX_ByteTextBuf sDashStream;
504 sDashStream << "[";
505 for (size_t i = 0; i < pDashArrayCount; ++i)
506 sDashStream << pDashArray->GetNumberAt(i) << " ";
507 sDashStream << "] 0 d\n";
508
509 return sDashStream.MakeString();
510 }
511
466 CPDF_Dictionary* GenerateExtGStateDict(const CPDF_Dictionary& pAnnotDict, 512 CPDF_Dictionary* GenerateExtGStateDict(const CPDF_Dictionary& pAnnotDict,
467 const CFX_ByteString& sExtGSDictName, 513 const CFX_ByteString& sExtGSDictName,
468 const CFX_ByteString& sBlendMode) { 514 const CFX_ByteString& sBlendMode) {
469 CPDF_Dictionary* pGSDict = new CPDF_Dictionary; 515 CPDF_Dictionary* pGSDict = new CPDF_Dictionary;
470 pGSDict->SetAtString("Type", "ExtGState"); 516 pGSDict->SetAtString("Type", "ExtGState");
471 517
472 FX_FLOAT fOpacity = 518 FX_FLOAT fOpacity =
473 pAnnotDict.KeyExist("CA") ? pAnnotDict.GetNumberBy("CA") : 1; 519 pAnnotDict.KeyExist("CA") ? pAnnotDict.GetNumberBy("CA") : 1;
474 pGSDict->SetAtNumber("CA", fOpacity); 520 pGSDict->SetAtNumber("CA", fOpacity);
475 pGSDict->SetAtNumber("ca", fOpacity); 521 pGSDict->SetAtNumber("ca", fOpacity);
(...skipping 28 matching lines...) Expand all
504 550
505 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect"); 551 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect");
506 pStreamDict->SetAtRect("BBox", rect); 552 pStreamDict->SetAtRect("BBox", rect);
507 553
508 CPDF_Dictionary* pResourceDict = new CPDF_Dictionary; 554 CPDF_Dictionary* pResourceDict = new CPDF_Dictionary;
509 pResourceDict->SetAt("ExtGState", pExtGStateDict); 555 pResourceDict->SetAt("ExtGState", pExtGStateDict);
510 556
511 pStreamDict->SetAt("Resources", pResourceDict); 557 pStreamDict->SetAt("Resources", pResourceDict);
512 } 558 }
513 559
560 CFX_ByteString GetPaintOperatorString(bool bIsStrokeRect, bool bIsFillRect) {
561 if (bIsStrokeRect)
562 return bIsFillRect ? "b" : "s";
563 return bIsFillRect ? "f" : "n";
564 }
565
514 } // namespace 566 } // namespace
515 567
516 bool FPDF_GenerateAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict) { 568 bool FPDF_GenerateAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict) {
517 if (!pAnnotDict || pAnnotDict->GetStringBy("Subtype") != "Widget") 569 if (!pAnnotDict || pAnnotDict->GetStringBy("Subtype") != "Widget")
518 return false; 570 return false;
519 571
520 CFX_ByteString field_type = FPDF_GetFieldAttr(pAnnotDict, "FT")->GetString(); 572 CFX_ByteString field_type = FPDF_GetFieldAttr(pAnnotDict, "FT")->GetString();
521 uint32_t flags = FPDF_GetFieldAttr(pAnnotDict, "Ff") 573 uint32_t flags = FPDF_GetFieldAttr(pAnnotDict, "Ff")
522 ? FPDF_GetFieldAttr(pAnnotDict, "Ff")->GetInteger() 574 ? FPDF_GetFieldAttr(pAnnotDict, "Ff")->GetInteger()
523 : 0; 575 : 0;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 CPDF_Dictionary* pAnnotDict) { 617 CPDF_Dictionary* pAnnotDict) {
566 // If AP dictionary exists, we use the appearance defined in the 618 // If AP dictionary exists, we use the appearance defined in the
567 // existing AP dictionary. 619 // existing AP dictionary.
568 if (pAnnotDict->KeyExist("AP")) 620 if (pAnnotDict->KeyExist("AP"))
569 return false; 621 return false;
570 622
571 CFX_ByteTextBuf sAppStream; 623 CFX_ByteTextBuf sAppStream;
572 CFX_ByteString sExtGSDictName = "GS"; 624 CFX_ByteString sExtGSDictName = "GS";
573 sAppStream << "/" << sExtGSDictName << " gs "; 625 sAppStream << "/" << sExtGSDictName << " gs ";
574 626
575 sAppStream << GetColorStringWithDefault( 627 sAppStream << GetColorStringWithDefault(pAnnotDict->GetArrayBy("C"),
576 pAnnotDict, CPVT_Color(CPVT_Color::kRGB, 1, 1, 0), PaintOperation::FILL); 628 CPVT_Color(CPVT_Color::kRGB, 1, 1, 0),
629 PaintOperation::FILL);
577 630
578 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect"); 631 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect");
579 rect.Normalize(); 632 rect.Normalize();
580 633
581 sAppStream << rect.left << " " << rect.top << " m " << rect.right << " " 634 sAppStream << rect.left << " " << rect.top << " m " << rect.right << " "
582 << rect.top << " l " << rect.right << " " << rect.bottom << " l " 635 << rect.top << " l " << rect.right << " " << rect.bottom << " l "
583 << rect.left << " " << rect.bottom << " l " 636 << rect.left << " " << rect.bottom << " l "
584 << "h f\n"; 637 << "h f\n";
585 638
586 CPDF_Dictionary* pExtGStateDict = 639 CPDF_Dictionary* pExtGStateDict =
587 GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Multiply"); 640 GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Multiply");
588 GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pExtGStateDict); 641 GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pExtGStateDict);
589 642
590 return true; 643 return true;
591 } 644 }
592 645
593 bool CPVT_GenerateAP::GenerateUnderlineAP(CPDF_Document* pDoc, 646 bool CPVT_GenerateAP::GenerateUnderlineAP(CPDF_Document* pDoc,
594 CPDF_Dictionary* pAnnotDict) { 647 CPDF_Dictionary* pAnnotDict) {
595 // If AP dictionary exists, we use the appearance defined in the 648 // If AP dictionary exists, we use the appearance defined in the
596 // existing AP dictionary. 649 // existing AP dictionary.
597 if (pAnnotDict->KeyExist("AP")) 650 if (pAnnotDict->KeyExist("AP"))
598 return false; 651 return false;
599 652
600 CFX_ByteTextBuf sAppStream; 653 CFX_ByteTextBuf sAppStream;
601 CFX_ByteString sExtGSDictName = "GS"; 654 CFX_ByteString sExtGSDictName = "GS";
602 sAppStream << "/" << sExtGSDictName << " gs "; 655 sAppStream << "/" << sExtGSDictName << " gs ";
603 656
604 sAppStream << GetColorStringWithDefault(pAnnotDict, 657 sAppStream << GetColorStringWithDefault(pAnnotDict->GetArrayBy("C"),
605 CPVT_Color(CPVT_Color::kRGB, 0, 0, 0), 658 CPVT_Color(CPVT_Color::kRGB, 0, 0, 0),
606 PaintOperation::STROKE); 659 PaintOperation::STROKE);
607 660
608 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect"); 661 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect");
609 rect.Normalize(); 662 rect.Normalize();
610 663
611 FX_FLOAT fLineWidth = 1.0; 664 FX_FLOAT fLineWidth = 1.0;
612 sAppStream << fLineWidth << " w " << rect.left << " " 665 sAppStream << fLineWidth << " w " << rect.left << " "
613 << rect.bottom + fLineWidth << " m " << rect.right << " " 666 << rect.bottom + fLineWidth << " m " << rect.right << " "
614 << rect.bottom + fLineWidth << " l S\n"; 667 << rect.bottom + fLineWidth << " l S\n";
615 668
616 CPDF_Dictionary* pExtGStateDict = 669 CPDF_Dictionary* pExtGStateDict =
617 GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal"); 670 GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal");
618 GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pExtGStateDict); 671 GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pExtGStateDict);
619 return true; 672 return true;
620 } 673 }
621 674
675 bool CPVT_GenerateAP::GenerateSquareAP(CPDF_Document* pDoc,
676 CPDF_Dictionary* pAnnotDict) {
677 // If AP dictionary exists, we use the appearance defined in the
678 // existing AP dictionary.
679 if (pAnnotDict->KeyExist("AP"))
680 return false;
681
682 CFX_ByteTextBuf sAppStream;
683 CFX_ByteString sExtGSDictName = "GS";
684 sAppStream << "/" << sExtGSDictName << " gs ";
685
686 CPDF_Array* pInteriorColor = pAnnotDict->GetArrayBy("IC");
687 sAppStream << GetColorStringWithDefault(pInteriorColor,
688 CPVT_Color(CPVT_Color::kTransparent),
689 PaintOperation::FILL);
690
691 sAppStream << GetColorStringWithDefault(pAnnotDict->GetArrayBy("C"),
692 CPVT_Color(CPVT_Color::kRGB, 0, 0, 0),
693 PaintOperation::STROKE);
694
695 FX_FLOAT fBorderWidth = GetBorderWidth(*pAnnotDict);
696 bool bIsStrokeRect = fBorderWidth > 0;
697
698 if (bIsStrokeRect) {
699 sAppStream << fBorderWidth << " w ";
700 sAppStream << GetDashPatternString(*pAnnotDict);
701 }
702
703 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect");
704 rect.Normalize();
705
706 if (bIsStrokeRect) {
707 // Deflating rect because stroking a path entails painting all points whose
708 // perpendicular distance from the path in user space is less than or equal
709 // to half the line width.
710 rect.Deflate(fBorderWidth / 2, fBorderWidth / 2);
711 }
712
713 bool bIsFillRect = pInteriorColor && (pInteriorColor->GetCount() > 0);
714
715 sAppStream << rect.left << " " << rect.bottom << " " << rect.Width() << " "
716 << rect.Height() << " re "
717 << GetPaintOperatorString(bIsStrokeRect, bIsFillRect) << "\n";
718
719 CPDF_Dictionary* pExtGStateDict =
720 GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal");
721 GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pExtGStateDict);
722 return true;
723 }
724
622 bool CPVT_GenerateAP::GenerateSquigglyAP(CPDF_Document* pDoc, 725 bool CPVT_GenerateAP::GenerateSquigglyAP(CPDF_Document* pDoc,
623 CPDF_Dictionary* pAnnotDict) { 726 CPDF_Dictionary* pAnnotDict) {
624 // If AP dictionary exists, we use the appearance defined in the 727 // If AP dictionary exists, we use the appearance defined in the
625 // existing AP dictionary. 728 // existing AP dictionary.
626 if (pAnnotDict->KeyExist("AP")) 729 if (pAnnotDict->KeyExist("AP"))
627 return false; 730 return false;
628 731
629 CFX_ByteTextBuf sAppStream; 732 CFX_ByteTextBuf sAppStream;
630 CFX_ByteString sExtGSDictName = "GS"; 733 CFX_ByteString sExtGSDictName = "GS";
631 sAppStream << "/" << sExtGSDictName << " gs "; 734 sAppStream << "/" << sExtGSDictName << " gs ";
632 735
633 sAppStream << GetColorStringWithDefault(pAnnotDict, 736 sAppStream << GetColorStringWithDefault(pAnnotDict->GetArrayBy("C"),
634 CPVT_Color(CPVT_Color::kRGB, 0, 0, 0), 737 CPVT_Color(CPVT_Color::kRGB, 0, 0, 0),
635 PaintOperation::STROKE); 738 PaintOperation::STROKE);
636 739
637 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect"); 740 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect");
638 rect.Normalize(); 741 rect.Normalize();
639 742
640 FX_FLOAT fLineWidth = 1.0; 743 FX_FLOAT fLineWidth = 1.0;
641 sAppStream << fLineWidth << " w "; 744 sAppStream << fLineWidth << " w ";
642 745
643 const FX_FLOAT fDelta = 2.0; 746 const FX_FLOAT fDelta = 2.0;
(...skipping 30 matching lines...) Expand all
674 CPDF_Dictionary* pAnnotDict) { 777 CPDF_Dictionary* pAnnotDict) {
675 // If AP dictionary exists, we use the appearance defined in the 778 // If AP dictionary exists, we use the appearance defined in the
676 // existing AP dictionary. 779 // existing AP dictionary.
677 if (pAnnotDict->KeyExist("AP")) 780 if (pAnnotDict->KeyExist("AP"))
678 return false; 781 return false;
679 782
680 CFX_ByteTextBuf sAppStream; 783 CFX_ByteTextBuf sAppStream;
681 CFX_ByteString sExtGSDictName = "GS"; 784 CFX_ByteString sExtGSDictName = "GS";
682 sAppStream << "/" << sExtGSDictName << " gs "; 785 sAppStream << "/" << sExtGSDictName << " gs ";
683 786
684 sAppStream << GetColorStringWithDefault(pAnnotDict, 787 sAppStream << GetColorStringWithDefault(pAnnotDict->GetArrayBy("C"),
685 CPVT_Color(CPVT_Color::kRGB, 0, 0, 0), 788 CPVT_Color(CPVT_Color::kRGB, 0, 0, 0),
686 PaintOperation::STROKE); 789 PaintOperation::STROKE);
687 790
688 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect"); 791 CFX_FloatRect rect = pAnnotDict->GetRectBy("Rect");
689 rect.Normalize(); 792 rect.Normalize();
690 793
691 FX_FLOAT fLineWidth = 1.0; 794 FX_FLOAT fLineWidth = 1.0;
692 FX_FLOAT fY = (rect.top + rect.bottom) / 2; 795 FX_FLOAT fY = (rect.top + rect.bottom) / 2;
693 sAppStream << fLineWidth << " w " << rect.left << " " << fY << " m " 796 sAppStream << fLineWidth << " w " << rect.left << " " << fY << " m "
694 << rect.right << " " << fY << " l S\n"; 797 << rect.right << " " << fY << " l S\n";
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 int32_t nFontIndex, 1063 int32_t nFontIndex,
961 FX_FLOAT fFontSize) { 1064 FX_FLOAT fFontSize) {
962 CFX_ByteTextBuf sRet; 1065 CFX_ByteTextBuf sRet;
963 if (pFontMap) { 1066 if (pFontMap) {
964 CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex); 1067 CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
965 if (sFontAlias.GetLength() > 0 && fFontSize > 0) 1068 if (sFontAlias.GetLength() > 0 && fFontSize > 0)
966 sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n"; 1069 sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
967 } 1070 }
968 return sRet.MakeString(); 1071 return sRet.MakeString();
969 } 1072 }
OLDNEW
« no previous file with comments | « core/fpdfdoc/cpvt_generateap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698