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
14class CPDF_QuickFontCache;
15class CPDF_StreamParser
16{
17public:
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();
51protected:
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};
62typedef 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
102typedef 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
122class CPDF_StreamContentParser
123{
124public:
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};
284class CPDF_ContentParser
285{
286public:
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();
299protected:
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};
316class CPDF_AllStates : public CPDF_GraphicStates
317{
318public:
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
329template <class KeyType, class ValueType>
330KeyType 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}
343template <class KeyType, class ValueType>
344FX_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}
363class CPDF_DocPageData
364{
365public:
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};
397class CPDF_Function
398{
399public:
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    }
411protected:
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};
420class CPDF_IccProfile
421{
422public:
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;
428private:
429    FX_INT32                m_nSrcComponents;
430};
431class CPDF_DeviceCS : public CPDF_ColorSpace
432{
433public:
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};
441class CPDF_PatternCS : public CPDF_ColorSpace
442{
443public:
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
456class CPDF_ResourceNaming
457{
458public:
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);
465protected:
466    CFX_MapByteStringToPtr	m_NamingCache;
467};
468
469#endif  // CORE_SRC_FPDFAPI_FPDF_PAGE_PAGEINT_H_
470