Index: core/fpdfapi/fpdf_page/fpdf_page_parser.cpp |
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp |
index 1f10b4ea4eecfb0529bb9388370f630b64144f87..93ea93dee76403bb50b8bc83c95ea0dae962b56d 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) { |