diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/fpdfdoc/cpdf_annot.cpp | 50 | ||||
-rw-r--r-- | core/fpdfdoc/cpdf_annot.h | 8 | ||||
-rw-r--r-- | core/fpdfdoc/cpvt_generateap.cpp | 112 |
3 files changed, 113 insertions, 57 deletions
diff --git a/core/fpdfdoc/cpdf_annot.cpp b/core/fpdfdoc/cpdf_annot.cpp index cc70a3087c..91cdb12d9f 100644 --- a/core/fpdfdoc/cpdf_annot.cpp +++ b/core/fpdfdoc/cpdf_annot.cpp @@ -6,6 +6,7 @@ #include "core/fpdfdoc/cpdf_annot.h" +#include <algorithm> #include <utility> #include "core/fpdfapi/page/cpdf_form.h" @@ -158,7 +159,7 @@ CFX_FloatRect CPDF_Annot::RectForDrawing() const { bool bShouldUseQuadPointsCoords = m_bIsTextMarkupAnnotation && m_bHasGeneratedAP; if (bShouldUseQuadPointsCoords) - return RectFromQuadPoints(m_pAnnotDict.Get()); + return BoundingRectFromQuadPoints(m_pAnnotDict.Get()); return m_pAnnotDict->GetRectFor("Rect"); } @@ -205,11 +206,8 @@ CPDF_Form* CPDF_Annot::GetAPForm(const CPDF_Page* pPage, AppearanceMode mode) { } // Static. -CFX_FloatRect CPDF_Annot::RectFromQuadPoints(CPDF_Dictionary* pAnnotDict) { - CPDF_Array* pArray = pAnnotDict->GetArrayFor("QuadPoints"); - if (!pArray) - return CFX_FloatRect(); - +CFX_FloatRect CPDF_Annot::RectFromQuadPointsArray(const CPDF_Array* pArray, + size_t nIndex) { // QuadPoints are defined with 4 pairs of numbers // ([ pair0, pair1, pair2, pair3 ]), where // pair0 = top_left @@ -217,11 +215,40 @@ CFX_FloatRect CPDF_Annot::RectFromQuadPoints(CPDF_Dictionary* pAnnotDict) { // pair2 = bottom_left // pair3 = bottom_right // - // On the other hand, /Rect is define as 2 pairs [pair0, pair1] where: + // On the other hand, /Rect is defined as 2 pairs [pair0, pair1] where: // pair0 = bottom_left // pair1 = top_right. - return CFX_FloatRect(pArray->GetNumberAt(4), pArray->GetNumberAt(5), - pArray->GetNumberAt(2), pArray->GetNumberAt(3)); + + return CFX_FloatRect( + pArray->GetNumberAt(4 + nIndex * 8), pArray->GetNumberAt(5 + nIndex * 8), + pArray->GetNumberAt(2 + nIndex * 8), pArray->GetNumberAt(3 + nIndex * 8)); +} + +// Static. +CFX_FloatRect CPDF_Annot::BoundingRectFromQuadPoints( + CPDF_Dictionary* pAnnotDict) { + CPDF_Array* pArray = pAnnotDict->GetArrayFor("QuadPoints"); + if (!pArray) + return CFX_FloatRect(); + + CFX_FloatRect ret = RectFromQuadPointsArray(pArray, 0); + size_t nQuadPointCount = QuadPointCount(pArray); + for (size_t i = 1; i < nQuadPointCount; ++i) { + CFX_FloatRect rect = RectFromQuadPointsArray(pArray, i); + ret.Union(rect); + } + return ret; +} + +// Static. +CFX_FloatRect CPDF_Annot::RectFromQuadPoints(CPDF_Dictionary* pAnnotDict, + size_t nIndex) { + CPDF_Array* pArray = pAnnotDict->GetArrayFor("QuadPoints"); + + if (!pArray) + return CFX_FloatRect(); + + return RectFromQuadPointsArray(pArray, nIndex); } // Static. @@ -348,6 +375,11 @@ ByteString CPDF_Annot::AnnotSubtypeToString(CPDF_Annot::Subtype nSubtype) { return ""; } +// Static. +size_t CPDF_Annot::QuadPointCount(const CPDF_Array* pArray) { + return pArray->GetCount() / 8; +} + bool CPDF_Annot::DrawAppearance(CPDF_Page* pPage, CFX_RenderDevice* pDevice, const CFX_Matrix& mtUser2Device, diff --git a/core/fpdfdoc/cpdf_annot.h b/core/fpdfdoc/cpdf_annot.h index 499c62dcba..3f1164ad18 100644 --- a/core/fpdfdoc/cpdf_annot.h +++ b/core/fpdfdoc/cpdf_annot.h @@ -16,6 +16,7 @@ #include "core/fxcrt/maybe_owned.h" class CFX_RenderDevice; +class CPDF_Array; class CPDF_Dictionary; class CPDF_Document; class CPDF_Form; @@ -66,7 +67,12 @@ class CPDF_Annot { static bool IsAnnotationHidden(CPDF_Dictionary* pAnnotDict); static CPDF_Annot::Subtype StringToAnnotSubtype(const ByteString& sSubtype); static ByteString AnnotSubtypeToString(CPDF_Annot::Subtype nSubtype); - static CFX_FloatRect RectFromQuadPoints(CPDF_Dictionary* pAnnotDict); + static CFX_FloatRect RectFromQuadPointsArray(const CPDF_Array* pArray, + size_t nIndex); + static CFX_FloatRect BoundingRectFromQuadPoints(CPDF_Dictionary* pAnnotDict); + static CFX_FloatRect RectFromQuadPoints(CPDF_Dictionary* pAnnotDict, + size_t nIndex); + static size_t QuadPointCount(const CPDF_Array* pArray); // The second constructor does not take ownership of the dictionary. CPDF_Annot(std::unique_ptr<CPDF_Dictionary> pDict, CPDF_Document* pDocument); diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp index eb3e22d870..e2fbcc9720 100644 --- a/core/fpdfdoc/cpvt_generateap.cpp +++ b/core/fpdfdoc/cpvt_generateap.cpp @@ -519,7 +519,7 @@ void GenerateAndSetAPDict(CPDF_Document* pDoc, pStreamDict->SetMatrixFor("Matrix", CFX_Matrix()); CFX_FloatRect rect = bIsTextMarkupAnnotation - ? CPDF_Annot::RectFromQuadPoints(pAnnotDict) + ? CPDF_Annot::BoundingRectFromQuadPoints(pAnnotDict) : pAnnotDict->GetRectFor("Rect"); pStreamDict->SetRectFor("BBox", rect); pStreamDict->SetFor("Resources", std::move(pResourceDict)); @@ -606,13 +606,18 @@ bool GenerateHighlightAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict) { CFX_Color(CFX_Color::kRGB, 1, 1, 0), PaintOperation::FILL); - CFX_FloatRect rect = CPDF_Annot::RectFromQuadPoints(pAnnotDict); - rect.Normalize(); + CPDF_Array* pArray = pAnnotDict->GetArrayFor("QuadPoints"); + if (pArray) { + size_t nQuadPointCount = CPDF_Annot::QuadPointCount(pArray); + for (size_t i = 0; i < nQuadPointCount; ++i) { + CFX_FloatRect rect = CPDF_Annot::RectFromQuadPoints(pAnnotDict, i); + rect.Normalize(); - sAppStream << rect.left << " " << rect.top << " m " << rect.right << " " - << rect.top << " l " << rect.right << " " << rect.bottom << " l " - << rect.left << " " << rect.bottom << " l " - << "h f\n"; + sAppStream << rect.left << " " << rect.top << " m " << rect.right << " " + << rect.top << " l " << rect.right << " " << rect.bottom + << " l " << rect.left << " " << rect.bottom << " l h f\n"; + } + } auto pExtGStateDict = GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Multiply"); @@ -708,13 +713,18 @@ bool GenerateUnderlineAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict) { CFX_Color(CFX_Color::kRGB, 0, 0, 0), PaintOperation::STROKE); - CFX_FloatRect rect = CPDF_Annot::RectFromQuadPoints(pAnnotDict); - rect.Normalize(); - - float fLineWidth = 1.0; - sAppStream << fLineWidth << " w " << rect.left << " " - << rect.bottom + fLineWidth << " m " << rect.right << " " - << rect.bottom + fLineWidth << " l S\n"; + CPDF_Array* pArray = pAnnotDict->GetArrayFor("QuadPoints"); + if (pArray) { + static constexpr float kLineWidth = 1.0f; + sAppStream << kLineWidth << " w "; + size_t nQuadPointCount = CPDF_Annot::QuadPointCount(pArray); + for (size_t i = 0; i < nQuadPointCount; ++i) { + CFX_FloatRect rect = CPDF_Annot::RectFromQuadPoints(pAnnotDict, i); + rect.Normalize(); + sAppStream << rect.left << " " << rect.bottom + kLineWidth << " m " + << rect.right << " " << rect.bottom + kLineWidth << " l S\n"; + } + } auto pExtGStateDict = GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal"); @@ -817,36 +827,38 @@ bool GenerateSquigglyAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict) { CFX_Color(CFX_Color::kRGB, 0, 0, 0), PaintOperation::STROKE); - CFX_FloatRect rect = CPDF_Annot::RectFromQuadPoints(pAnnotDict); - rect.Normalize(); - - float fLineWidth = 1.0; - sAppStream << fLineWidth << " w "; - - const float fDelta = 2.0; - const float fTop = rect.bottom + fDelta; - const float fBottom = rect.bottom; - - sAppStream << rect.left << " " << fTop << " m "; - - float fX = rect.left + fDelta; - bool isUpwards = false; + CPDF_Array* pArray = pAnnotDict->GetArrayFor("QuadPoints"); + if (pArray) { + static constexpr float kLineWidth = 1.0f; + static constexpr float kDelta = 2.0f; + sAppStream << kLineWidth << " w "; + size_t nQuadPointCount = CPDF_Annot::QuadPointCount(pArray); + for (size_t i = 0; i < nQuadPointCount; ++i) { + CFX_FloatRect rect = CPDF_Annot::RectFromQuadPoints(pAnnotDict, i); + rect.Normalize(); + + const float fTop = rect.bottom + kDelta; + const float fBottom = rect.bottom; + sAppStream << rect.left << " " << fTop << " m "; + + float fX = rect.left + kDelta; + bool isUpwards = false; + while (fX < rect.right) { + sAppStream << fX << " " << (isUpwards ? fTop : fBottom) << " l "; + fX += kDelta; + isUpwards = !isUpwards; + } - while (fX < rect.right) { - sAppStream << fX << " " << (isUpwards ? fTop : fBottom) << " l "; + float fRemainder = rect.right - (fX - kDelta); + if (isUpwards) + sAppStream << rect.right << " " << fBottom + fRemainder << " l "; + else + sAppStream << rect.right << " " << fTop - fRemainder << " l "; - fX += fDelta; - isUpwards = !isUpwards; + sAppStream << "S\n"; + } } - float fRemainder = rect.right - (fX - fDelta); - if (isUpwards) - sAppStream << rect.right << " " << fBottom + fRemainder << " l "; - else - sAppStream << rect.right << " " << fTop - fRemainder << " l "; - - sAppStream << "S\n"; - auto pExtGStateDict = GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal"); auto pResourceDict = @@ -865,13 +877,19 @@ bool GenerateStrikeOutAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict) { CFX_Color(CFX_Color::kRGB, 0, 0, 0), PaintOperation::STROKE); - CFX_FloatRect rect = CPDF_Annot::RectFromQuadPoints(pAnnotDict); - rect.Normalize(); - - float fLineWidth = 1.0; - float fY = (rect.top + rect.bottom) / 2; - sAppStream << fLineWidth << " w " << rect.left << " " << fY << " m " - << rect.right << " " << fY << " l S\n"; + CPDF_Array* pArray = pAnnotDict->GetArrayFor("QuadPoints"); + if (pArray) { + static constexpr float kLineWidth = 1.0f; + size_t nQuadPointCount = CPDF_Annot::QuadPointCount(pArray); + for (size_t i = 0; i < nQuadPointCount; ++i) { + CFX_FloatRect rect = CPDF_Annot::RectFromQuadPoints(pAnnotDict, i); + rect.Normalize(); + + float fY = (rect.top + rect.bottom) / 2; + sAppStream << kLineWidth << " w " << rect.left << " " << fY << " m " + << rect.right << " " << fY << " l S\n"; + } + } auto pExtGStateDict = GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal"); |