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