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();
GetWordBuf()26 FX_LPBYTE GetWordBuf()
27 {
28 return m_WordBuffer;
29 }
GetWordSize()30 FX_DWORD GetWordSize()
31 {
32 return m_WordSize;
33 }
GetObject()34 CPDF_Object* GetObject()
35 {
36 CPDF_Object* pObj = m_pLastObj;
37 m_pLastObj = NULL;
38 return pObj;
39 }
GetPos()40 FX_DWORD GetPos()
41 {
42 return m_Pos;
43 }
SetPos(FX_DWORD pos)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);
GetInteger(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;
GetParsePos()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;
GetStatus()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>
PDF_DocPageData_FindValue(const CFX_MapPtrTemplate<KeyType,CPDF_CountedObject<ValueType> * > & map,ValueType findValue,CPDF_CountedObject<ValueType> * & findData)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);
IsForceClear()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;
CountInputs()403 int CountInputs()
404 {
405 return m_nInputs;
406 }
CountOutputs()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();
GetComponents()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;
GetBaseCS()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