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