diff options
-rw-r--r-- | core/include/fpdfapi/fpdf_resource.h | 22 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 23 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp | 68 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp | 24 |
4 files changed, 97 insertions, 40 deletions
diff --git a/core/include/fpdfapi/fpdf_resource.h b/core/include/fpdfapi/fpdf_resource.h index 9fe6e2b95f..dee15cf941 100644 --- a/core/include/fpdfapi/fpdf_resource.h +++ b/core/include/fpdfapi/fpdf_resource.h @@ -679,6 +679,19 @@ class CPDF_TilingPattern : public CPDF_Pattern { CPDF_Form* m_pForm; }; + +typedef enum { + kInvalidShading = 0, + kFunctionBasedShading = 1, + kAxialShading = 2, + kRadialShading = 3, + kFreeFormGouraudTriangleMeshShading = 4, + kLatticeFormGouraudTriangleMeshShading = 5, + kCoonsPatchMeshShading = 6, + kTensorProductPatchMeshShading = 7, + kMaxShading = 8 +} ShadingType; + class CPDF_ShadingPattern : public CPDF_Pattern { public: CPDF_ShadingPattern(CPDF_Document* pDoc, @@ -688,6 +701,13 @@ class CPDF_ShadingPattern : public CPDF_Pattern { ~CPDF_ShadingPattern() override; + bool IsMeshShading() const { + return m_ShadingType == kFreeFormGouraudTriangleMeshShading || + m_ShadingType == kLatticeFormGouraudTriangleMeshShading || + m_ShadingType == kCoonsPatchMeshShading || + m_ShadingType == kTensorProductPatchMeshShading; + } + CPDF_Object* m_pShadingObj; FX_BOOL m_bShadingObj; @@ -696,7 +716,7 @@ class CPDF_ShadingPattern : public CPDF_Pattern { FX_BOOL Reload(); - int m_ShadingType; + ShadingType m_ShadingType; CPDF_ColorSpace* m_pCS; // Still keep m_pCS as some CPDF_ColorSpace (name // object) are not managed as counted objects. Refer diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp index b12a65a844..3057948959 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp @@ -1092,12 +1092,13 @@ void CPDF_StreamContentParser::Handle_SetColorPS_Stroke() { } FX_Free(values); } -CFX_FloatRect _GetShadingBBox(CPDF_Stream* pStream, - int type, - const CFX_AffineMatrix* pMatrix, - CPDF_Function** pFuncs, - int nFuncs, - CPDF_ColorSpace* pCS); +CFX_FloatRect GetShadingBBox(CPDF_Stream* pStream, + ShadingType type, + const CFX_AffineMatrix* pMatrix, + CPDF_Function** pFuncs, + int nFuncs, + CPDF_ColorSpace* pCS); + void CPDF_StreamContentParser::Handle_ShadeFill() { if (m_Options.m_bTextOnly) { return; @@ -1127,11 +1128,11 @@ void CPDF_StreamContentParser::Handle_ShadeFill() { } else { bbox = m_BBox; } - if (pShading->m_ShadingType >= 4) { - bbox.Intersect(_GetShadingBBox(ToStream(pShading->m_pShadingObj), - pShading->m_ShadingType, &pObj->m_Matrix, - pShading->m_pFunctions, pShading->m_nFuncs, - pShading->m_pCS)); + if (pShading->IsMeshShading()) { + bbox.Intersect(GetShadingBBox(ToStream(pShading->m_pShadingObj), + pShading->m_ShadingType, &pObj->m_Matrix, + pShading->m_pFunctions, pShading->m_nFuncs, + pShading->m_pCS)); } pObj->m_Left = bbox.left; pObj->m_Right = bbox.right; diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp index ded6c878ea..b669b3b5d2 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_pattern.cpp @@ -7,6 +7,24 @@ #include "../../../include/fpdfapi/fpdf_page.h" #include "pageint.h" +namespace { + +const int kSingleCoordinatePair = 1; +const int kTensorCoordinatePairs = 16; +const int kCoonsCoordinatePairs = 12; + +const int kSingleColorPerPatch = 1; +const int kQuadColorsPerPatch = 4; + +ShadingType ToShadingType(int type) { + return (type > static_cast<int>(kInvalidShading) && + type < static_cast<int>(kMaxShading)) + ? static_cast<ShadingType>(type) + : kInvalidShading; +} + +} // namespace + CPDF_Pattern::CPDF_Pattern(const CFX_AffineMatrix* pParentMatrix) : m_pPatternObj(NULL), m_PatternType(PATTERN_TILING), @@ -78,7 +96,7 @@ CPDF_ShadingPattern::CPDF_ShadingPattern(CPDF_Document* pDoc, } else { m_pShadingObj = pPatternObj; } - m_ShadingType = 0; + m_ShadingType = kInvalidShading; m_pCS = NULL; m_nFuncs = 0; for (int i = 0; i < 4; i++) { @@ -98,15 +116,16 @@ void CPDF_ShadingPattern::Clear() { if (pCS && m_pDocument) { m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); } - m_ShadingType = 0; + m_ShadingType = kInvalidShading; m_pCS = NULL; m_pCountedCS = NULL; m_nFuncs = 0; } + FX_BOOL CPDF_ShadingPattern::Load() { - if (m_ShadingType != 0) { + if (m_ShadingType != kInvalidShading) return TRUE; - } + CPDF_Dictionary* pShadingDict = m_pShadingObj ? m_pShadingObj->GetDict() : NULL; if (pShadingDict == NULL) { @@ -139,10 +158,12 @@ FX_BOOL CPDF_ShadingPattern::Load() { if (m_pCS) { m_pCountedCS = pDocPageData->FindColorSpacePtr(m_pCS->GetArray()); } - m_ShadingType = pShadingDict->GetInteger(FX_BSTRC("ShadingType")); + + m_ShadingType = + ToShadingType(pShadingDict->GetInteger(FX_BSTRC("ShadingType"))); // We expect to have a stream if our shading type is a mesh. - if (m_ShadingType >= 4 && !ToStream(m_pShadingObj)) + if (IsMeshShading() && !ToStream(m_pShadingObj)) return FALSE; return TRUE; @@ -253,12 +274,13 @@ FX_BOOL CPDF_MeshStream::GetVertexRow(CPDF_MeshVertex* vertex, } return TRUE; } -CFX_FloatRect _GetShadingBBox(CPDF_Stream* pStream, - int type, - const CFX_AffineMatrix* pMatrix, - CPDF_Function** pFuncs, - int nFuncs, - CPDF_ColorSpace* pCS) { + +CFX_FloatRect GetShadingBBox(CPDF_Stream* pStream, + ShadingType type, + const CFX_AffineMatrix* pMatrix, + CPDF_Function** pFuncs, + int nFuncs, + CPDF_ColorSpace* pCS) { if (!pStream || !pStream->IsStream() || !pFuncs || !pCS) return CFX_FloatRect(0, 0, 0, 0); @@ -268,19 +290,29 @@ CFX_FloatRect _GetShadingBBox(CPDF_Stream* pStream, CFX_FloatRect rect; FX_BOOL bStarted = FALSE; - FX_BOOL bGouraud = type == 4 || type == 5; - int full_point_count = type == 7 ? 16 : (type == 6 ? 12 : 1); - int full_color_count = (type == 6 || type == 7) ? 4 : 1; + FX_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()) { FX_DWORD flag = 0; - if (type != 5) { + if (type != kLatticeFormGouraudTriangleMeshShading) flag = stream.GetFlag(); - } - int point_count = full_point_count, color_count = full_color_count; + if (!bGouraud && flag) { point_count -= 4; color_count -= 2; } + for (int i = 0; i < point_count; i++) { FX_FLOAT x, y; stream.GetCoords(x, y); diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp index 4ed6c07675..467ffc900c 100644 --- a/core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp @@ -868,33 +868,37 @@ void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern, pBitmap->Clear(background); int fill_mode = m_Options.m_Flags; switch (pPattern->m_ShadingType) { - case 1: + case kInvalidShading: + case kMaxShading: + return; + case kFunctionBasedShading: DrawFuncShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColorSpace, alpha); break; - case 2: + case kAxialShading: DrawAxialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColorSpace, alpha); break; - case 3: + case kRadialShading: DrawRadialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColorSpace, alpha); break; - case 4: { + case kFreeFormGouraudTriangleMeshShading: { DrawFreeGouraudShading(pBitmap, &FinalMatrix, ToStream(pPattern->m_pShadingObj), pFuncs, nFuncs, pColorSpace, alpha); } break; - case 5: { + case kLatticeFormGouraudTriangleMeshShading: { DrawLatticeGouraudShading(pBitmap, &FinalMatrix, ToStream(pPattern->m_pShadingObj), pFuncs, nFuncs, pColorSpace, alpha); } break; - case 6: - case 7: { - DrawCoonPatchMeshes(pPattern->m_ShadingType - 6, pBitmap, &FinalMatrix, - ToStream(pPattern->m_pShadingObj), pFuncs, nFuncs, - pColorSpace, fill_mode, alpha); + case kCoonsPatchMeshShading: + case kTensorProductPatchMeshShading: { + DrawCoonPatchMeshes( + pPattern->m_ShadingType == kTensorProductPatchMeshShading, pBitmap, + &FinalMatrix, ToStream(pPattern->m_pShadingObj), pFuncs, nFuncs, + pColorSpace, fill_mode, alpha); } break; } if (bAlphaMode) { |