1 // Copyright 2014 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_SRC_FPDFAPI_FPDF_PAGE_PAGEINT_H_ 8 #define CORE_SRC_FPDFAPI_FPDF_PAGE_PAGEINT_H_ 9 10 #include <map> 11 #include <memory> 12 #include <vector> 13 14 #include "core/include/fpdfapi/fpdf_page.h" 15 #include "core/include/fpdfapi/fpdf_pageobj.h" 16 17 class CPDF_AllStates; 18 class CPDF_ParseOptions; 19 20 #define PARSE_STEP_LIMIT 100 21 22 class CPDF_StreamParser { 23 public: 24 enum SyntaxType { EndOfData, Number, Keyword, Name, Others }; 25 26 CPDF_StreamParser(const uint8_t* pData, FX_DWORD dwSize); 27 ~CPDF_StreamParser(); 28 29 CPDF_Stream* ReadInlineStream(CPDF_Document* pDoc, 30 CPDF_Dictionary* pDict, 31 CPDF_Object* pCSObj, 32 FX_BOOL bDecode); 33 SyntaxType ParseNextElement(); GetWordBuf()34 uint8_t* GetWordBuf() { return m_WordBuffer; } GetWordSize()35 FX_DWORD GetWordSize() const { return m_WordSize; } GetObject()36 CPDF_Object* GetObject() { 37 CPDF_Object* pObj = m_pLastObj; 38 m_pLastObj = NULL; 39 return pObj; 40 } GetPos()41 FX_DWORD GetPos() const { return m_Pos; } SetPos(FX_DWORD pos)42 void SetPos(FX_DWORD pos) { m_Pos = pos; } 43 CPDF_Object* ReadNextObject(FX_BOOL bAllowNestedArray = FALSE, 44 FX_BOOL bInArray = FALSE); 45 void SkipPathObject(); 46 47 protected: 48 friend class fpdf_page_parser_old_ReadHexString_Test; 49 50 void GetNextWord(FX_BOOL& bIsNumber); 51 CFX_ByteString ReadString(); 52 CFX_ByteString ReadHexString(); 53 const uint8_t* m_pBuf; 54 55 // Length in bytes of m_pBuf. 56 FX_DWORD m_Size; 57 58 // Current byte position within m_pBuf. 59 FX_DWORD m_Pos; 60 61 uint8_t m_WordBuffer[256]; 62 FX_DWORD m_WordSize; 63 CPDF_Object* m_pLastObj; 64 65 private: 66 bool PositionIsInBounds() const; 67 }; 68 69 #define PARAM_BUF_SIZE 16 70 struct ContentParam { 71 int m_Type; 72 union { 73 struct { 74 FX_BOOL m_bInteger; 75 union { 76 int m_Integer; 77 FX_FLOAT m_Float; 78 }; 79 } m_Number; 80 CPDF_Object* m_pObject; 81 struct { 82 int m_Len; 83 char m_Buffer[32]; 84 } m_Name; 85 }; 86 }; 87 #define _FPDF_MAX_FORM_LEVEL_ 30 88 #define _FPDF_MAX_TYPE3_FORM_LEVEL_ 4 89 #define _FPDF_MAX_OBJECT_STACK_SIZE_ 512 90 class CPDF_StreamContentParser { 91 public: 92 CPDF_StreamContentParser(CPDF_Document* pDoc, 93 CPDF_Dictionary* pPageResources, 94 CPDF_Dictionary* pParentResources, 95 CFX_Matrix* pmtContentToUser, 96 CPDF_PageObjects* pObjList, 97 CPDF_Dictionary* pResources, 98 CFX_FloatRect* pBBox, 99 CPDF_ParseOptions* pOptions, 100 CPDF_AllStates* pAllStates, 101 int level); 102 ~CPDF_StreamContentParser(); 103 GetObjectList()104 CPDF_PageObjects* GetObjectList() const { return m_pObjectList; } GetCurStates()105 CPDF_AllStates* GetCurStates() const { return m_pCurStates.get(); } IsColored()106 FX_BOOL IsColored() const { return m_bColored; } GetType3Data()107 const FX_FLOAT* GetType3Data() const { return m_Type3Data; } 108 109 void AddNumberParam(const FX_CHAR* str, int len); 110 void AddObjectParam(CPDF_Object* pObj); 111 void AddNameParam(const FX_CHAR* name, int size); 112 int GetNextParamPos(); 113 void ClearAllParams(); 114 CPDF_Object* GetObject(FX_DWORD index); 115 CFX_ByteString GetString(FX_DWORD index); 116 FX_FLOAT GetNumber(FX_DWORD index); 117 FX_FLOAT GetNumber16(FX_DWORD index); GetInteger(FX_DWORD index)118 int GetInteger(FX_DWORD index) { return (int32_t)(GetNumber(index)); } 119 FX_BOOL OnOperator(const FX_CHAR* op); 120 void BigCaseCaller(int index); GetParsePos()121 FX_DWORD GetParsePos() { return m_pSyntax->GetPos(); } 122 void AddTextObject(CFX_ByteString* pText, 123 FX_FLOAT fInitKerning, 124 FX_FLOAT* pKerning, 125 int count); 126 127 void ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y); 128 void ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y); 129 void OnChangeTextMatrix(); 130 FX_DWORD Parse(const uint8_t* pData, FX_DWORD dwSize, FX_DWORD max_cost); 131 void ParsePathObject(); 132 void AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag); 133 void AddPathRect(FX_FLOAT x, FX_FLOAT y, FX_FLOAT w, FX_FLOAT h); 134 void AddPathObject(int FillType, FX_BOOL bStroke); 135 CPDF_ImageObject* AddImage(CPDF_Stream* pStream, 136 CPDF_Image* pImage, 137 FX_BOOL bInline); 138 void AddDuplicateImage(); 139 void AddForm(CPDF_Stream*); 140 void SetGraphicStates(CPDF_PageObject* pObj, 141 FX_BOOL bColor, 142 FX_BOOL bText, 143 FX_BOOL bGraph); 144 void SaveStates(CPDF_AllStates*); 145 void RestoreStates(CPDF_AllStates*); 146 CPDF_Font* FindFont(const CFX_ByteString& name); 147 CPDF_ColorSpace* FindColorSpace(const CFX_ByteString& name); 148 CPDF_Pattern* FindPattern(const CFX_ByteString& name, FX_BOOL bShading); 149 CPDF_Object* FindResourceObj(const CFX_ByteStringC& type, 150 const CFX_ByteString& name); 151 152 protected: 153 struct OpCode { 154 FX_DWORD m_OpId; 155 void (CPDF_StreamContentParser::*m_OpHandler)(); 156 }; 157 static const OpCode g_OpCodes[]; 158 159 void Handle_CloseFillStrokePath(); 160 void Handle_FillStrokePath(); 161 void Handle_CloseEOFillStrokePath(); 162 void Handle_EOFillStrokePath(); 163 void Handle_BeginMarkedContent_Dictionary(); 164 void Handle_BeginImage(); 165 void Handle_BeginMarkedContent(); 166 void Handle_BeginText(); 167 void Handle_BeginSectionUndefined(); 168 void Handle_CurveTo_123(); 169 void Handle_ConcatMatrix(); 170 void Handle_SetColorSpace_Fill(); 171 void Handle_SetColorSpace_Stroke(); 172 void Handle_SetDash(); 173 void Handle_SetCharWidth(); 174 void Handle_SetCachedDevice(); 175 void Handle_ExecuteXObject(); 176 void Handle_MarkPlace_Dictionary(); 177 void Handle_EndImage(); 178 void Handle_EndMarkedContent(); 179 void Handle_EndText(); 180 void Handle_EndSectionUndefined(); 181 void Handle_FillPath(); 182 void Handle_FillPathOld(); 183 void Handle_EOFillPath(); 184 void Handle_SetGray_Fill(); 185 void Handle_SetGray_Stroke(); 186 void Handle_SetExtendGraphState(); 187 void Handle_ClosePath(); 188 void Handle_SetFlat(); 189 void Handle_BeginImageData(); 190 void Handle_SetLineJoin(); 191 void Handle_SetLineCap(); 192 void Handle_SetCMYKColor_Fill(); 193 void Handle_SetCMYKColor_Stroke(); 194 void Handle_LineTo(); 195 void Handle_MoveTo(); 196 void Handle_SetMiterLimit(); 197 void Handle_MarkPlace(); 198 void Handle_EndPath(); 199 void Handle_SaveGraphState(); 200 void Handle_RestoreGraphState(); 201 void Handle_Rectangle(); 202 void Handle_SetRGBColor_Fill(); 203 void Handle_SetRGBColor_Stroke(); 204 void Handle_SetRenderIntent(); 205 void Handle_CloseStrokePath(); 206 void Handle_StrokePath(); 207 void Handle_SetColor_Fill(); 208 void Handle_SetColor_Stroke(); 209 void Handle_SetColorPS_Fill(); 210 void Handle_SetColorPS_Stroke(); 211 void Handle_ShadeFill(); 212 void Handle_SetCharSpace(); 213 void Handle_MoveTextPoint(); 214 void Handle_MoveTextPoint_SetLeading(); 215 void Handle_SetFont(); 216 void Handle_ShowText(); 217 void Handle_ShowText_Positioning(); 218 void Handle_SetTextLeading(); 219 void Handle_SetTextMatrix(); 220 void Handle_SetTextRenderMode(); 221 void Handle_SetTextRise(); 222 void Handle_SetWordSpace(); 223 void Handle_SetHorzScale(); 224 void Handle_MoveToNextLine(); 225 void Handle_CurveTo_23(); 226 void Handle_SetLineWidth(); 227 void Handle_Clip(); 228 void Handle_EOClip(); 229 void Handle_CurveTo_13(); 230 void Handle_NextLineShowText(); 231 void Handle_NextLineShowText_Space(); 232 void Handle_Invalid(); 233 234 CPDF_Document* const m_pDocument; 235 CPDF_Dictionary* m_pPageResources; 236 CPDF_Dictionary* m_pParentResources; 237 CPDF_Dictionary* m_pResources; 238 CPDF_PageObjects* m_pObjectList; 239 int m_Level; 240 CFX_Matrix m_mtContentToUser; 241 CFX_FloatRect m_BBox; 242 CPDF_ParseOptions m_Options; 243 ContentParam m_ParamBuf1[PARAM_BUF_SIZE]; 244 FX_DWORD m_ParamStartPos; 245 FX_DWORD m_ParamCount; 246 CPDF_StreamParser* m_pSyntax; 247 std::unique_ptr<CPDF_AllStates> m_pCurStates; 248 CPDF_ContentMark m_CurContentMark; 249 CFX_ArrayTemplate<CPDF_TextObject*> m_ClipTextList; 250 CPDF_TextObject* m_pLastTextObject; 251 FX_FLOAT m_DefFontSize; 252 int m_CompatCount; 253 FX_PATHPOINT* m_pPathPoints; 254 int m_PathPointCount; 255 int m_PathAllocSize; 256 FX_FLOAT m_PathStartX; 257 FX_FLOAT m_PathStartY; 258 FX_FLOAT m_PathCurrentX; 259 FX_FLOAT m_PathCurrentY; 260 int m_PathClipType; 261 CFX_ByteString m_LastImageName; 262 CPDF_Image* m_pLastImage; 263 CFX_BinaryBuf m_LastImageDict; 264 CFX_BinaryBuf m_LastImageData; 265 CPDF_Dictionary* m_pLastImageDict; 266 CPDF_Dictionary* m_pLastCloneImageDict; 267 FX_BOOL m_bReleaseLastDict; 268 FX_BOOL m_bSameLastDict; 269 FX_BOOL m_bColored; 270 FX_FLOAT m_Type3Data[6]; 271 FX_BOOL m_bResourceMissing; 272 std::vector<std::unique_ptr<CPDF_AllStates>> m_StateStack; 273 }; 274 class CPDF_ContentParser { 275 public: 276 enum ParseStatus { Ready, ToBeContinued, Done }; 277 278 CPDF_ContentParser(); 279 ~CPDF_ContentParser(); 280 GetStatus()281 ParseStatus GetStatus() const { return m_Status; } 282 void Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions); 283 void Start(CPDF_Form* pForm, 284 CPDF_AllStates* pGraphicStates, 285 CFX_Matrix* pParentMatrix, 286 CPDF_Type3Char* pType3Char, 287 CPDF_ParseOptions* pOptions, 288 int level); 289 void Continue(IFX_Pause* pPause); 290 291 private: 292 enum InternalStage { 293 STAGE_GETCONTENT = 1, 294 STAGE_PARSE, 295 STAGE_CHECKCLIP, 296 }; 297 298 ParseStatus m_Status; 299 InternalStage m_InternalStage; 300 CPDF_PageObjects* m_pObjects; 301 FX_BOOL m_bForm; 302 CPDF_ParseOptions m_Options; 303 CPDF_Type3Char* m_pType3Char; 304 FX_DWORD m_nStreams; 305 std::unique_ptr<CPDF_StreamAcc> m_pSingleStream; 306 std::vector<std::unique_ptr<CPDF_StreamAcc>> m_StreamArray; 307 uint8_t* m_pData; 308 FX_DWORD m_Size; 309 FX_DWORD m_CurrentOffset; 310 std::unique_ptr<CPDF_StreamContentParser> m_pParser; 311 }; 312 class CPDF_AllStates : public CPDF_GraphicStates { 313 public: 314 CPDF_AllStates(); 315 ~CPDF_AllStates(); 316 void Copy(const CPDF_AllStates& src); 317 void ProcessExtGS(CPDF_Dictionary* pGS, CPDF_StreamContentParser* pParser); 318 void SetLineDash(CPDF_Array*, FX_FLOAT, FX_FLOAT scale); 319 CFX_Matrix m_TextMatrix, m_CTM, m_ParentMatrix; 320 FX_FLOAT m_TextX, m_TextY, m_TextLineX, m_TextLineY; 321 FX_FLOAT m_TextLeading, m_TextRise, m_TextHorzScale; 322 }; 323 324 class CPDF_DocPageData { 325 public: 326 explicit CPDF_DocPageData(CPDF_Document* pPDFDoc); 327 ~CPDF_DocPageData(); 328 329 void Clear(FX_BOOL bRelease = FALSE); 330 CPDF_Font* GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly); 331 CPDF_Font* GetStandardFont(const CFX_ByteStringC& fontName, 332 CPDF_FontEncoding* pEncoding); 333 void ReleaseFont(CPDF_Dictionary* pFontDict); 334 CPDF_ColorSpace* GetColorSpace(CPDF_Object* pCSObj, 335 const CPDF_Dictionary* pResources); 336 CPDF_ColorSpace* GetCopiedColorSpace(CPDF_Object* pCSObj); 337 void ReleaseColorSpace(CPDF_Object* pColorSpace); 338 CPDF_Pattern* GetPattern(CPDF_Object* pPatternObj, 339 FX_BOOL bShading, 340 const CFX_Matrix* matrix); 341 void ReleasePattern(CPDF_Object* pPatternObj); 342 CPDF_Image* GetImage(CPDF_Object* pImageStream); 343 void ReleaseImage(CPDF_Object* pImageStream); 344 CPDF_IccProfile* GetIccProfile(CPDF_Stream* pIccProfileStream); 345 void ReleaseIccProfile(CPDF_IccProfile* pIccProfile); 346 CPDF_StreamAcc* GetFontFileStreamAcc(CPDF_Stream* pFontStream); 347 void ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream, 348 FX_BOOL bForce = FALSE); IsForceClear()349 FX_BOOL IsForceClear() const { return m_bForceClear; } 350 CPDF_CountedColorSpace* FindColorSpacePtr(CPDF_Object* pCSObj) const; 351 CPDF_CountedPattern* FindPatternPtr(CPDF_Object* pPatternObj) const; 352 353 private: 354 using CPDF_CountedFont = CPDF_CountedObject<CPDF_Font>; 355 using CPDF_CountedIccProfile = CPDF_CountedObject<CPDF_IccProfile>; 356 using CPDF_CountedImage = CPDF_CountedObject<CPDF_Image>; 357 using CPDF_CountedStreamAcc = CPDF_CountedObject<CPDF_StreamAcc>; 358 359 using CPDF_ColorSpaceMap = std::map<CPDF_Object*, CPDF_CountedColorSpace*>; 360 using CPDF_FontFileMap = std::map<CPDF_Stream*, CPDF_CountedStreamAcc*>; 361 using CPDF_FontMap = std::map<CPDF_Dictionary*, CPDF_CountedFont*>; 362 using CPDF_IccProfileMap = std::map<CPDF_Stream*, CPDF_CountedIccProfile*>; 363 using CPDF_ImageMap = std::map<FX_DWORD, CPDF_CountedImage*>; 364 using CPDF_PatternMap = std::map<CPDF_Object*, CPDF_CountedPattern*>; 365 366 CPDF_Document* const m_pPDFDoc; 367 FX_BOOL m_bForceClear; 368 std::map<CFX_ByteString, CPDF_Stream*> m_HashProfileMap; 369 CPDF_ColorSpaceMap m_ColorSpaceMap; 370 CPDF_FontFileMap m_FontFileMap; 371 CPDF_FontMap m_FontMap; 372 CPDF_IccProfileMap m_IccProfileMap; 373 CPDF_ImageMap m_ImageMap; 374 CPDF_PatternMap m_PatternMap; 375 }; 376 377 class CPDF_Function { 378 public: 379 static CPDF_Function* Load(CPDF_Object* pFuncObj); 380 virtual ~CPDF_Function(); 381 FX_BOOL Call(FX_FLOAT* inputs, 382 int ninputs, 383 FX_FLOAT* results, 384 int& nresults) const; CountInputs()385 int CountInputs() { return m_nInputs; } CountOutputs()386 int CountOutputs() { return m_nOutputs; } 387 388 protected: 389 CPDF_Function(); 390 int m_nInputs, m_nOutputs; 391 FX_FLOAT* m_pDomains; 392 FX_FLOAT* m_pRanges; 393 FX_BOOL Init(CPDF_Object* pObj); 394 virtual FX_BOOL v_Init(CPDF_Object* pObj) = 0; 395 virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const = 0; 396 }; 397 class CPDF_IccProfile { 398 public: 399 CPDF_IccProfile(const uint8_t* pData, FX_DWORD dwSize); 400 ~CPDF_IccProfile(); GetComponents()401 int32_t GetComponents() const { return m_nSrcComponents; } 402 FX_BOOL m_bsRGB; 403 void* m_pTransform; 404 405 private: 406 int32_t m_nSrcComponents; 407 }; 408 409 class CPDF_DeviceCS : public CPDF_ColorSpace { 410 public: 411 CPDF_DeviceCS(CPDF_Document* pDoc, int family); 412 413 FX_BOOL GetRGB(FX_FLOAT* pBuf, 414 FX_FLOAT& R, 415 FX_FLOAT& G, 416 FX_FLOAT& B) const override; 417 FX_BOOL SetRGB(FX_FLOAT* pBuf, 418 FX_FLOAT R, 419 FX_FLOAT G, 420 FX_FLOAT B) const override; 421 FX_BOOL v_GetCMYK(FX_FLOAT* pBuf, 422 FX_FLOAT& c, 423 FX_FLOAT& m, 424 FX_FLOAT& y, 425 FX_FLOAT& k) const override; 426 FX_BOOL v_SetCMYK(FX_FLOAT* pBuf, 427 FX_FLOAT c, 428 FX_FLOAT m, 429 FX_FLOAT y, 430 FX_FLOAT k) const override; 431 void TranslateImageLine(uint8_t* pDestBuf, 432 const uint8_t* pSrcBuf, 433 int pixels, 434 int image_width, 435 int image_height, 436 FX_BOOL bTransMask = FALSE) const override; 437 }; 438 439 class CPDF_PatternCS : public CPDF_ColorSpace { 440 public: CPDF_PatternCS(CPDF_Document * pDoc)441 explicit CPDF_PatternCS(CPDF_Document* pDoc) 442 : CPDF_ColorSpace(pDoc, PDFCS_PATTERN, 1), 443 m_pBaseCS(nullptr), 444 m_pCountedBaseCS(nullptr) {} 445 ~CPDF_PatternCS() override; 446 FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; 447 FX_BOOL GetRGB(FX_FLOAT* pBuf, 448 FX_FLOAT& R, 449 FX_FLOAT& G, 450 FX_FLOAT& B) const override; 451 CPDF_ColorSpace* GetBaseCS() const override; 452 453 private: 454 CPDF_ColorSpace* m_pBaseCS; 455 CPDF_CountedColorSpace* m_pCountedBaseCS; 456 }; 457 458 void PDF_ReplaceAbbr(CPDF_Object* pObj); 459 460 #endif // CORE_SRC_FPDFAPI_FPDF_PAGE_PAGEINT_H_ 461