1 // Copyright 2016 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef CORE_FPDFAPI_PAGE_CPDF_STREAMCONTENTPARSER_H_ 8 #define CORE_FPDFAPI_PAGE_CPDF_STREAMCONTENTPARSER_H_ 9 10 #include <map> 11 #include <memory> 12 #include <set> 13 #include <stack> 14 #include <vector> 15 16 #include "core/fpdfapi/page/cpdf_contentmarks.h" 17 #include "core/fxcrt/fx_number.h" 18 #include "core/fxcrt/fx_string.h" 19 #include "core/fxcrt/retain_ptr.h" 20 #include "core/fxge/cfx_pathdata.h" 21 22 class CPDF_AllStates; 23 class CPDF_ColorSpace; 24 class CPDF_Dictionary; 25 class CPDF_Document; 26 class CPDF_Font; 27 class CPDF_Image; 28 class CPDF_ImageObject; 29 class CPDF_Object; 30 class CPDF_PageObject; 31 class CPDF_PageObjectHolder; 32 class CPDF_Pattern; 33 class CPDF_Stream; 34 class CPDF_StreamParser; 35 class CPDF_TextObject; 36 37 class CPDF_StreamContentParser { 38 public: 39 CPDF_StreamContentParser(CPDF_Document* pDoc, 40 CPDF_Dictionary* pPageResources, 41 CPDF_Dictionary* pParentResources, 42 const CFX_Matrix* pmtContentToUser, 43 CPDF_PageObjectHolder* pObjHolder, 44 CPDF_Dictionary* pResources, 45 const CFX_FloatRect& rcBBox, 46 const CPDF_AllStates* pStates, 47 std::set<const uint8_t*>* pParsedSet); 48 ~CPDF_StreamContentParser(); 49 50 uint32_t Parse(const uint8_t* pData, 51 uint32_t dwSize, 52 uint32_t start_offset, 53 uint32_t max_cost, 54 const std::vector<uint32_t>& stream_start_offsets); GetPageObjectHolder()55 CPDF_PageObjectHolder* GetPageObjectHolder() const { 56 return m_pObjectHolder.Get(); 57 } GetCurStates()58 CPDF_AllStates* GetCurStates() const { return m_pCurStates.get(); } IsColored()59 bool IsColored() const { return m_bColored; } GetType3Data()60 const float* GetType3Data() const { return m_Type3Data; } 61 RetainPtr<CPDF_Font> FindFont(const ByteString& name); 62 63 static ByteStringView FindKeyAbbreviationForTesting(ByteStringView abbr); 64 static ByteStringView FindValueAbbreviationForTesting(ByteStringView abbr); 65 66 private: 67 struct ContentParam { 68 enum Type { OBJECT = 0, NUMBER, NAME }; 69 70 ContentParam(); 71 ~ContentParam(); 72 73 Type m_Type; 74 FX_Number m_Number; 75 ByteString m_Name; 76 RetainPtr<CPDF_Object> m_pObject; 77 }; 78 79 static const int kParamBufSize = 16; 80 81 using OpCodes = std::map<uint32_t, void (CPDF_StreamContentParser::*)()>; 82 static OpCodes InitializeOpCodes(); 83 84 void AddNameParam(ByteStringView bsName); 85 void AddNumberParam(ByteStringView str); 86 void AddObjectParam(RetainPtr<CPDF_Object> pObj); 87 int GetNextParamPos(); 88 void ClearAllParams(); 89 CPDF_Object* GetObject(uint32_t index); 90 ByteString GetString(uint32_t index) const; 91 float GetNumber(uint32_t index) const; 92 // Calls GetNumber() |count| times and returns the values in reverse order. 93 // e.g. for |count| = 3, returns [GetNumber(2), GetNumber(1), GetNumber(0)]. 94 std::vector<float> GetNumbers(size_t count) const; GetInteger(uint32_t index)95 int GetInteger(uint32_t index) const { 96 return static_cast<int>(GetNumber(index)); 97 } 98 void OnOperator(ByteStringView op); 99 void AddTextObject(const ByteString* pStrs, 100 float fInitKerning, 101 const std::vector<float>& kernings, 102 size_t nSegs); 103 float GetHorizontalTextSize(float fKerning) const; 104 float GetVerticalTextSize(float fKerning) const; 105 106 void OnChangeTextMatrix(); 107 void ParsePathObject(); 108 void AddPathPoint(float x, float y, FXPT_TYPE type, bool close); 109 void AddPathRect(float x, float y, float w, float h); 110 void AddPathObject(int FillType, bool bStroke); 111 CPDF_ImageObject* AddImage(RetainPtr<CPDF_Stream> pStream); 112 CPDF_ImageObject* AddImage(uint32_t streamObjNum); 113 CPDF_ImageObject* AddImage(const RetainPtr<CPDF_Image>& pImage); 114 115 void AddForm(CPDF_Stream* pStream); 116 void SetGraphicStates(CPDF_PageObject* pObj, 117 bool bColor, 118 bool bText, 119 bool bGraph); 120 RetainPtr<CPDF_ColorSpace> FindColorSpace(const ByteString& name); 121 RetainPtr<CPDF_Pattern> FindPattern(const ByteString& name, bool bShading); 122 CPDF_Dictionary* FindResourceHolder(const ByteString& type); 123 CPDF_Object* FindResourceObj(const ByteString& type, const ByteString& name); 124 125 // Takes ownership of |pImageObj|, returns unowned pointer to it. 126 CPDF_ImageObject* AddImageObject(std::unique_ptr<CPDF_ImageObject> pImageObj); 127 128 std::vector<float> GetColors() const; 129 std::vector<float> GetNamedColors() const; 130 int32_t GetCurrentStreamIndex(); 131 132 void Handle_CloseFillStrokePath(); 133 void Handle_FillStrokePath(); 134 void Handle_CloseEOFillStrokePath(); 135 void Handle_EOFillStrokePath(); 136 void Handle_BeginMarkedContent_Dictionary(); 137 void Handle_BeginImage(); 138 void Handle_BeginMarkedContent(); 139 void Handle_BeginText(); 140 void Handle_CurveTo_123(); 141 void Handle_ConcatMatrix(); 142 void Handle_SetColorSpace_Fill(); 143 void Handle_SetColorSpace_Stroke(); 144 void Handle_SetDash(); 145 void Handle_SetCharWidth(); 146 void Handle_SetCachedDevice(); 147 void Handle_ExecuteXObject(); 148 void Handle_MarkPlace_Dictionary(); 149 void Handle_EndImage(); 150 void Handle_EndMarkedContent(); 151 void Handle_EndText(); 152 void Handle_FillPath(); 153 void Handle_FillPathOld(); 154 void Handle_EOFillPath(); 155 void Handle_SetGray_Fill(); 156 void Handle_SetGray_Stroke(); 157 void Handle_SetExtendGraphState(); 158 void Handle_ClosePath(); 159 void Handle_SetFlat(); 160 void Handle_BeginImageData(); 161 void Handle_SetLineJoin(); 162 void Handle_SetLineCap(); 163 void Handle_SetCMYKColor_Fill(); 164 void Handle_SetCMYKColor_Stroke(); 165 void Handle_LineTo(); 166 void Handle_MoveTo(); 167 void Handle_SetMiterLimit(); 168 void Handle_MarkPlace(); 169 void Handle_EndPath(); 170 void Handle_SaveGraphState(); 171 void Handle_RestoreGraphState(); 172 void Handle_Rectangle(); 173 void Handle_SetRGBColor_Fill(); 174 void Handle_SetRGBColor_Stroke(); 175 void Handle_SetRenderIntent(); 176 void Handle_CloseStrokePath(); 177 void Handle_StrokePath(); 178 void Handle_SetColor_Fill(); 179 void Handle_SetColor_Stroke(); 180 void Handle_SetColorPS_Fill(); 181 void Handle_SetColorPS_Stroke(); 182 void Handle_ShadeFill(); 183 void Handle_SetCharSpace(); 184 void Handle_MoveTextPoint(); 185 void Handle_MoveTextPoint_SetLeading(); 186 void Handle_SetFont(); 187 void Handle_ShowText(); 188 void Handle_ShowText_Positioning(); 189 void Handle_SetTextLeading(); 190 void Handle_SetTextMatrix(); 191 void Handle_SetTextRenderMode(); 192 void Handle_SetTextRise(); 193 void Handle_SetWordSpace(); 194 void Handle_SetHorzScale(); 195 void Handle_MoveToNextLine(); 196 void Handle_CurveTo_23(); 197 void Handle_SetLineWidth(); 198 void Handle_Clip(); 199 void Handle_EOClip(); 200 void Handle_CurveTo_13(); 201 void Handle_NextLineShowText(); 202 void Handle_NextLineShowText_Space(); 203 void Handle_Invalid(); 204 205 UnownedPtr<CPDF_Document> const m_pDocument; 206 RetainPtr<CPDF_Dictionary> const m_pPageResources; 207 RetainPtr<CPDF_Dictionary> const m_pParentResources; 208 RetainPtr<CPDF_Dictionary> const m_pResources; 209 UnownedPtr<CPDF_PageObjectHolder> const m_pObjectHolder; 210 UnownedPtr<std::set<const uint8_t*>> const m_ParsedSet; 211 CFX_Matrix m_mtContentToUser; 212 const CFX_FloatRect m_BBox; 213 uint32_t m_ParamStartPos = 0; 214 uint32_t m_ParamCount = 0; 215 UnownedPtr<CPDF_StreamParser> m_pSyntax; 216 std::unique_ptr<CPDF_AllStates> m_pCurStates; 217 std::stack<std::unique_ptr<CPDF_ContentMarks>> m_ContentMarksStack; 218 std::vector<std::unique_ptr<CPDF_TextObject>> m_ClipTextList; 219 UnownedPtr<CPDF_TextObject> m_pLastTextObject; 220 std::vector<FX_PATHPOINT> m_PathPoints; 221 float m_PathStartX = 0.0f; 222 float m_PathStartY = 0.0f; 223 float m_PathCurrentX = 0.0f; 224 float m_PathCurrentY = 0.0f; 225 uint8_t m_PathClipType = 0; 226 ByteString m_LastImageName; 227 RetainPtr<CPDF_Image> m_pLastImage; 228 bool m_bColored = false; 229 bool m_bResourceMissing = false; 230 std::vector<std::unique_ptr<CPDF_AllStates>> m_StateStack; 231 float m_Type3Data[6] = {0.0f}; 232 ContentParam m_ParamBuf[kParamBufSize]; 233 234 // The merged stream offsets at which a content stream ends and another 235 // begins. 236 std::vector<uint32_t> m_StreamStartOffsets; 237 238 // The merged stream offset at which the last |m_pSyntax| started parsing. 239 uint32_t m_StartParseOffset = 0; 240 }; 241 242 #endif // CORE_FPDFAPI_PAGE_CPDF_STREAMCONTENTPARSER_H_ 243