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