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