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