diff options
Diffstat (limited to 'core/fpdfapi/fpdf_page/fpdf_page_parser.cpp')
-rw-r--r-- | core/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 88 |
1 files changed, 73 insertions, 15 deletions
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp index 1f10b4ea4e..93ea93dee7 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp @@ -12,6 +12,7 @@ #include "core/fpdfapi/fpdf_font/cpdf_type3font.h" #include "core/fpdfapi/fpdf_font/include/cpdf_font.h" #include "core/fpdfapi/fpdf_page/cpdf_allstates.h" +#include "core/fpdfapi/fpdf_page/cpdf_meshstream.h" #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" #include "core/fpdfapi/fpdf_page/include/cpdf_form.h" #include "core/fpdfapi/fpdf_page/include/cpdf_formobject.h" @@ -33,6 +34,12 @@ namespace { +const int kSingleCoordinatePair = 1; +const int kTensorCoordinatePairs = 16; +const int kCoonsCoordinatePairs = 12; +const int kSingleColorPerPatch = 1; +const int kQuadColorsPerPatch = 4; + const char kPathOperatorSubpath = 'm'; const char kPathOperatorLine = 'l'; const char kPathOperatorCubicBezier1 = 'c'; @@ -90,6 +97,64 @@ CFX_ByteStringC PDF_FindFullName(const PDF_AbbrPair* table, : CFX_ByteStringC(); } +CFX_FloatRect GetShadingBBox(CPDF_Stream* pStream, + ShadingType type, + const CFX_Matrix& matrix, + CPDF_Function** pFuncs, + int nFuncs, + CPDF_ColorSpace* pCS) { + if (!pStream || !pFuncs || !pCS) + return CFX_FloatRect(0, 0, 0, 0); + + CPDF_MeshStream stream; + if (!stream.Load(pStream, pFuncs, nFuncs, pCS)) + return CFX_FloatRect(0, 0, 0, 0); + + CFX_FloatRect rect; + bool bStarted = false; + bool bGouraud = type == kFreeFormGouraudTriangleMeshShading || + type == kLatticeFormGouraudTriangleMeshShading; + + int point_count = kSingleCoordinatePair; + if (type == kTensorProductPatchMeshShading) + point_count = kTensorCoordinatePairs; + else if (type == kCoonsPatchMeshShading) + point_count = kCoonsCoordinatePairs; + + int color_count = kSingleColorPerPatch; + if (type == kCoonsPatchMeshShading || type == kTensorProductPatchMeshShading) + color_count = kQuadColorsPerPatch; + + while (!stream.m_BitStream.IsEOF()) { + uint32_t flag = 0; + if (type != kLatticeFormGouraudTriangleMeshShading) + flag = stream.GetFlag(); + + if (!bGouraud && flag) { + point_count -= 4; + color_count -= 2; + } + + for (int i = 0; i < point_count; i++) { + FX_FLOAT x; + FX_FLOAT y; + stream.GetCoords(x, y); + if (bStarted) { + rect.UpdateRect(x, y); + } else { + rect.InitRect(x, y); + bStarted = true; + } + } + stream.m_BitStream.SkipBits(stream.m_nComps * stream.m_nCompBits * + color_count); + if (bGouraud) + stream.m_BitStream.ByteAlign(); + } + rect.Transform(&matrix); + return rect; +} + } // namespace CFX_ByteStringC PDF_FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr) { @@ -124,7 +189,7 @@ CPDF_StreamContentParser::CPDF_StreamContentParser( CPDF_Document* pDocument, CPDF_Dictionary* pPageResources, CPDF_Dictionary* pParentResources, - CFX_Matrix* pmtContentToUser, + const CFX_Matrix* pmtContentToUser, CPDF_PageObjectHolder* pObjHolder, CPDF_Dictionary* pResources, CFX_FloatRect* pBBox, @@ -985,7 +1050,7 @@ void CPDF_StreamContentParser::Handle_SetColorPS_Fill() { } } if (nvalues != nargs) { - CPDF_Pattern* pPattern = FindPattern(GetString(0), FALSE); + CPDF_Pattern* pPattern = FindPattern(GetString(0), false); if (pPattern) { m_pCurStates->m_ColorState.SetFillPattern(pPattern, values, nvalues); } @@ -1013,7 +1078,7 @@ void CPDF_StreamContentParser::Handle_SetColorPS_Stroke() { } } if (nvalues != nargs) { - CPDF_Pattern* pPattern = FindPattern(GetString(0), FALSE); + CPDF_Pattern* pPattern = FindPattern(GetString(0), false); if (pPattern) { m_pCurStates->m_ColorState.SetStrokePattern(pPattern, values, nvalues); } @@ -1023,15 +1088,8 @@ void CPDF_StreamContentParser::Handle_SetColorPS_Stroke() { FX_Free(values); } -CFX_FloatRect GetShadingBBox(CPDF_Stream* pStream, - ShadingType type, - const CFX_Matrix* pMatrix, - CPDF_Function** pFuncs, - int nFuncs, - CPDF_ColorSpace* pCS); - void CPDF_StreamContentParser::Handle_ShadeFill() { - CPDF_Pattern* pPattern = FindPattern(GetString(0), TRUE); + CPDF_Pattern* pPattern = FindPattern(GetString(0), true); if (!pPattern) return; @@ -1051,7 +1109,7 @@ void CPDF_StreamContentParser::Handle_ShadeFill() { pObj->m_ClipPath.IsNull() ? m_BBox : pObj->m_ClipPath.GetClipBox(); if (pShading->IsMeshShading()) { bbox.Intersect(GetShadingBBox(ToStream(pShading->m_pShadingObj), - pShading->m_ShadingType, &pObj->m_Matrix, + pShading->m_ShadingType, pObj->m_Matrix, pShading->m_pFunctions, pShading->m_nFuncs, pShading->m_pCS)); } @@ -1164,15 +1222,15 @@ CPDF_ColorSpace* CPDF_StreamContentParser::FindColorSpace( } CPDF_Pattern* CPDF_StreamContentParser::FindPattern(const CFX_ByteString& name, - FX_BOOL bShading) { + bool bShading) { CPDF_Object* pPattern = FindResourceObj(bShading ? "Shading" : "Pattern", name); if (!pPattern || (!pPattern->IsDictionary() && !pPattern->IsStream())) { m_bResourceMissing = TRUE; - return NULL; + return nullptr; } return m_pDocument->LoadPattern(pPattern, bShading, - &m_pCurStates->m_ParentMatrix); + m_pCurStates->m_ParentMatrix); } void CPDF_StreamContentParser::ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y) { |