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