| 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) { | 
|  |