diff options
author | dsinclair <dsinclair@chromium.org> | 2016-10-04 11:29:35 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-10-04 11:29:36 -0700 |
commit | 41872fa5ac7448a50f66ad56d7bde8d1aa77db4b (patch) | |
tree | 49f8162a8ed05ace693d7164f9ba116286427919 /core/fpdfapi/page/pageint.h | |
parent | bc5e6d289ed40efec2b0e03427e8fc2947bf53e3 (diff) | |
download | pdfium-41872fa5ac7448a50f66ad56d7bde8d1aa77db4b.tar.xz |
Move core/fpdfapi/fpdf_page to core/fpdfapi/page
BUG=pdfium:603
Review-Url: https://codereview.chromium.org/2386423004
Diffstat (limited to 'core/fpdfapi/page/pageint.h')
-rw-r--r-- | core/fpdfapi/page/pageint.h | 566 |
1 files changed, 566 insertions, 0 deletions
diff --git a/core/fpdfapi/page/pageint.h b/core/fpdfapi/page/pageint.h new file mode 100644 index 0000000000..2d3927d13d --- /dev/null +++ b/core/fpdfapi/page/pageint.h @@ -0,0 +1,566 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_PAGEINT_H_ +#define CORE_FPDFAPI_PAGE_PAGEINT_H_ + +#include <map> +#include <memory> +#include <set> +#include <unordered_map> +#include <vector> + +#include "core/fpdfapi/page/cpdf_contentmark.h" +#include "core/fpdfapi/page/cpdf_countedobject.h" +#include "core/fpdfapi/page/cpdf_pageobjectholder.h" +#include "core/fxcrt/cfx_string_pool_template.h" +#include "core/fxcrt/cfx_weak_ptr.h" +#include "core/fxge/cfx_pathdata.h" +#include "core/fxge/cfx_renderdevice.h" + +class CPDF_AllStates; +class CPDF_ColorSpace; +class CPDF_ExpIntFunc; +class CPDF_Font; +class CPDF_FontEncoding; +class CPDF_Form; +class CPDF_IccProfile; +class CPDF_Image; +class CPDF_ImageObject; +class CPDF_Page; +class CPDF_Pattern; +class CPDF_SampledFunc; +class CPDF_StitchFunc; +class CPDF_StreamAcc; +class CPDF_TextObject; +class CPDF_Type3Char; + +#define PARSE_STEP_LIMIT 100 + +class CPDF_StreamParser { + public: + enum SyntaxType { EndOfData, Number, Keyword, Name, Others }; + + CPDF_StreamParser(const uint8_t* pData, uint32_t dwSize); + CPDF_StreamParser(const uint8_t* pData, + uint32_t dwSize, + const CFX_WeakPtr<CFX_ByteStringPool>& pPool); + ~CPDF_StreamParser(); + + CPDF_Stream* ReadInlineStream(CPDF_Document* pDoc, + CPDF_Dictionary* pDict, + CPDF_Object* pCSObj); + SyntaxType ParseNextElement(); + uint8_t* GetWordBuf() { return m_WordBuffer; } + uint32_t GetWordSize() const { return m_WordSize; } + CPDF_Object* GetObject() { + CPDF_Object* pObj = m_pLastObj; + m_pLastObj = nullptr; + return pObj; + } + uint32_t GetPos() const { return m_Pos; } + void SetPos(uint32_t pos) { m_Pos = pos; } + CPDF_Object* ReadNextObject(bool bAllowNestedArray, uint32_t dwInArrayLevel); + + protected: + friend class fpdf_page_parser_old_ReadHexString_Test; + + void GetNextWord(FX_BOOL& bIsNumber); + CFX_ByteString ReadString(); + CFX_ByteString ReadHexString(); + + const uint8_t* m_pBuf; + uint32_t m_Size; // Length in bytes of m_pBuf. + uint32_t m_Pos; // Current byte position within m_pBuf. + uint8_t m_WordBuffer[256]; + uint32_t m_WordSize; + CPDF_Object* m_pLastObj; + CFX_WeakPtr<CFX_ByteStringPool> m_pPool; + + private: + bool PositionIsInBounds() const; +}; + +#define PARAM_BUF_SIZE 16 +struct ContentParam { + enum Type { OBJECT = 0, NUMBER, NAME }; + Type m_Type; + union { + struct { + bool m_bInteger; + union { + int m_Integer; + FX_FLOAT m_Float; + }; + } m_Number; + CPDF_Object* m_pObject; + struct { + int m_Len; + char m_Buffer[32]; + } m_Name; + }; +}; +#define _FPDF_MAX_FORM_LEVEL_ 30 +#define _FPDF_MAX_TYPE3_FORM_LEVEL_ 4 +class CPDF_StreamContentParser { + public: + CPDF_StreamContentParser(CPDF_Document* pDoc, + CPDF_Dictionary* pPageResources, + CPDF_Dictionary* pParentResources, + const CFX_Matrix* pmtContentToUser, + CPDF_PageObjectHolder* pObjectHolder, + CPDF_Dictionary* pResources, + CFX_FloatRect* pBBox, + CPDF_AllStates* pAllStates, + int level); + ~CPDF_StreamContentParser(); + + CPDF_PageObjectHolder* GetPageObjectHolder() const { return m_pObjectHolder; } + CPDF_AllStates* GetCurStates() const { return m_pCurStates.get(); } + FX_BOOL IsColored() const { return m_bColored; } + const FX_FLOAT* GetType3Data() const { return m_Type3Data; } + + void AddNumberParam(const FX_CHAR* str, int len); + void AddObjectParam(CPDF_Object* pObj); + void AddNameParam(const FX_CHAR* name, int size); + int GetNextParamPos(); + void ClearAllParams(); + CPDF_Object* GetObject(uint32_t index); + CFX_ByteString GetString(uint32_t index); + FX_FLOAT GetNumber(uint32_t index); + int GetInteger(uint32_t index) { return (int32_t)(GetNumber(index)); } + void OnOperator(const FX_CHAR* op); + void BigCaseCaller(int index); + uint32_t GetParsePos() { return m_pSyntax->GetPos(); } + void AddTextObject(CFX_ByteString* pText, + FX_FLOAT fInitKerning, + FX_FLOAT* pKerning, + int count); + + void ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y); + void ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y); + void OnChangeTextMatrix(); + uint32_t Parse(const uint8_t* pData, uint32_t dwSize, uint32_t max_cost); + void ParsePathObject(); + void AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag); + void AddPathRect(FX_FLOAT x, FX_FLOAT y, FX_FLOAT w, FX_FLOAT h); + void AddPathObject(int FillType, FX_BOOL bStroke); + CPDF_ImageObject* AddImage(CPDF_Stream* pStream, + CPDF_Image* pImage, + bool bInline); + void AddDuplicateImage(); + void AddForm(CPDF_Stream* pStream); + void SetGraphicStates(CPDF_PageObject* pObj, + FX_BOOL bColor, + FX_BOOL bText, + FX_BOOL bGraph); + void SaveStates(CPDF_AllStates* pState); + void RestoreStates(CPDF_AllStates* pState); + CPDF_Font* FindFont(const CFX_ByteString& name); + CPDF_ColorSpace* FindColorSpace(const CFX_ByteString& name); + CPDF_Pattern* FindPattern(const CFX_ByteString& name, bool bShading); + CPDF_Object* FindResourceObj(const CFX_ByteString& type, + const CFX_ByteString& name); + + protected: + using OpCodes = + std::unordered_map<uint32_t, void (CPDF_StreamContentParser::*)()>; + static OpCodes InitializeOpCodes(); + + void Handle_CloseFillStrokePath(); + void Handle_FillStrokePath(); + void Handle_CloseEOFillStrokePath(); + void Handle_EOFillStrokePath(); + void Handle_BeginMarkedContent_Dictionary(); + void Handle_BeginImage(); + void Handle_BeginMarkedContent(); + void Handle_BeginText(); + void Handle_CurveTo_123(); + void Handle_ConcatMatrix(); + void Handle_SetColorSpace_Fill(); + void Handle_SetColorSpace_Stroke(); + void Handle_SetDash(); + void Handle_SetCharWidth(); + void Handle_SetCachedDevice(); + void Handle_ExecuteXObject(); + void Handle_MarkPlace_Dictionary(); + void Handle_EndImage(); + void Handle_EndMarkedContent(); + void Handle_EndText(); + void Handle_FillPath(); + void Handle_FillPathOld(); + void Handle_EOFillPath(); + void Handle_SetGray_Fill(); + void Handle_SetGray_Stroke(); + void Handle_SetExtendGraphState(); + void Handle_ClosePath(); + void Handle_SetFlat(); + void Handle_BeginImageData(); + void Handle_SetLineJoin(); + void Handle_SetLineCap(); + void Handle_SetCMYKColor_Fill(); + void Handle_SetCMYKColor_Stroke(); + void Handle_LineTo(); + void Handle_MoveTo(); + void Handle_SetMiterLimit(); + void Handle_MarkPlace(); + void Handle_EndPath(); + void Handle_SaveGraphState(); + void Handle_RestoreGraphState(); + void Handle_Rectangle(); + void Handle_SetRGBColor_Fill(); + void Handle_SetRGBColor_Stroke(); + void Handle_SetRenderIntent(); + void Handle_CloseStrokePath(); + void Handle_StrokePath(); + void Handle_SetColor_Fill(); + void Handle_SetColor_Stroke(); + void Handle_SetColorPS_Fill(); + void Handle_SetColorPS_Stroke(); + void Handle_ShadeFill(); + void Handle_SetCharSpace(); + void Handle_MoveTextPoint(); + void Handle_MoveTextPoint_SetLeading(); + void Handle_SetFont(); + void Handle_ShowText(); + void Handle_ShowText_Positioning(); + void Handle_SetTextLeading(); + void Handle_SetTextMatrix(); + void Handle_SetTextRenderMode(); + void Handle_SetTextRise(); + void Handle_SetWordSpace(); + void Handle_SetHorzScale(); + void Handle_MoveToNextLine(); + void Handle_CurveTo_23(); + void Handle_SetLineWidth(); + void Handle_Clip(); + void Handle_EOClip(); + void Handle_CurveTo_13(); + void Handle_NextLineShowText(); + void Handle_NextLineShowText_Space(); + void Handle_Invalid(); + + CPDF_Document* const m_pDocument; + CPDF_Dictionary* m_pPageResources; + CPDF_Dictionary* m_pParentResources; + CPDF_Dictionary* m_pResources; + CPDF_PageObjectHolder* m_pObjectHolder; + int m_Level; + CFX_Matrix m_mtContentToUser; + CFX_FloatRect m_BBox; + ContentParam m_ParamBuf[PARAM_BUF_SIZE]; + uint32_t m_ParamStartPos; + uint32_t m_ParamCount; + CPDF_StreamParser* m_pSyntax; + std::unique_ptr<CPDF_AllStates> m_pCurStates; + CPDF_ContentMark m_CurContentMark; + std::vector<std::unique_ptr<CPDF_TextObject>> m_ClipTextList; + CPDF_TextObject* m_pLastTextObject; + FX_FLOAT m_DefFontSize; + FX_PATHPOINT* m_pPathPoints; + int m_PathPointCount; + int m_PathAllocSize; + FX_FLOAT m_PathStartX; + FX_FLOAT m_PathStartY; + FX_FLOAT m_PathCurrentX; + FX_FLOAT m_PathCurrentY; + uint8_t m_PathClipType; + CFX_ByteString m_LastImageName; + CPDF_Image* m_pLastImage; + CFX_BinaryBuf m_LastImageDict; + CFX_BinaryBuf m_LastImageData; + CPDF_Dictionary* m_pLastImageDict; + CPDF_Dictionary* m_pLastCloneImageDict; + FX_BOOL m_bReleaseLastDict; + FX_BOOL m_bSameLastDict; + FX_BOOL m_bColored; + FX_FLOAT m_Type3Data[6]; + FX_BOOL m_bResourceMissing; + std::vector<std::unique_ptr<CPDF_AllStates>> m_StateStack; +}; +class CPDF_ContentParser { + public: + enum ParseStatus { Ready, ToBeContinued, Done }; + + CPDF_ContentParser(); + ~CPDF_ContentParser(); + + ParseStatus GetStatus() const { return m_Status; } + void Start(CPDF_Page* pPage); + void Start(CPDF_Form* pForm, + CPDF_AllStates* pGraphicStates, + const CFX_Matrix* pParentMatrix, + CPDF_Type3Char* pType3Char, + int level); + void Continue(IFX_Pause* pPause); + + private: + enum InternalStage { + STAGE_GETCONTENT = 1, + STAGE_PARSE, + STAGE_CHECKCLIP, + }; + + ParseStatus m_Status; + InternalStage m_InternalStage; + CPDF_PageObjectHolder* m_pObjectHolder; + FX_BOOL m_bForm; + CPDF_Type3Char* m_pType3Char; + uint32_t m_nStreams; + std::unique_ptr<CPDF_StreamAcc> m_pSingleStream; + std::vector<std::unique_ptr<CPDF_StreamAcc>> m_StreamArray; + uint8_t* m_pData; + uint32_t m_Size; + uint32_t m_CurrentOffset; + std::unique_ptr<CPDF_StreamContentParser> m_pParser; +}; + +class CPDF_DocPageData { + public: + explicit CPDF_DocPageData(CPDF_Document* pPDFDoc); + ~CPDF_DocPageData(); + + void Clear(FX_BOOL bRelease = FALSE); + CPDF_Font* GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly); + CPDF_Font* GetStandardFont(const CFX_ByteString& fontName, + CPDF_FontEncoding* pEncoding); + void ReleaseFont(const CPDF_Dictionary* pFontDict); + CPDF_ColorSpace* GetColorSpace(CPDF_Object* pCSObj, + const CPDF_Dictionary* pResources); + CPDF_ColorSpace* GetCopiedColorSpace(CPDF_Object* pCSObj); + void ReleaseColorSpace(const CPDF_Object* pColorSpace); + CPDF_Pattern* GetPattern(CPDF_Object* pPatternObj, + FX_BOOL bShading, + const CFX_Matrix& matrix); + void ReleasePattern(const CPDF_Object* pPatternObj); + CPDF_Image* GetImage(CPDF_Object* pImageStream); + void ReleaseImage(const CPDF_Object* pImageStream); + CPDF_IccProfile* GetIccProfile(CPDF_Stream* pIccProfileStream); + void ReleaseIccProfile(const CPDF_IccProfile* pIccProfile); + CPDF_StreamAcc* GetFontFileStreamAcc(CPDF_Stream* pFontStream); + void ReleaseFontFileStreamAcc(const CPDF_Stream* pFontStream); + FX_BOOL IsForceClear() const { return m_bForceClear; } + CPDF_CountedColorSpace* FindColorSpacePtr(CPDF_Object* pCSObj) const; + CPDF_CountedPattern* FindPatternPtr(CPDF_Object* pPatternObj) const; + + private: + using CPDF_CountedFont = CPDF_CountedObject<CPDF_Font>; + using CPDF_CountedIccProfile = CPDF_CountedObject<CPDF_IccProfile>; + using CPDF_CountedImage = CPDF_CountedObject<CPDF_Image>; + using CPDF_CountedStreamAcc = CPDF_CountedObject<CPDF_StreamAcc>; + + using CPDF_ColorSpaceMap = + std::map<const CPDF_Object*, CPDF_CountedColorSpace*>; + using CPDF_FontFileMap = std::map<const CPDF_Stream*, CPDF_CountedStreamAcc*>; + using CPDF_FontMap = std::map<const CPDF_Dictionary*, CPDF_CountedFont*>; + using CPDF_IccProfileMap = + std::map<const CPDF_Stream*, CPDF_CountedIccProfile*>; + using CPDF_ImageMap = std::map<uint32_t, CPDF_CountedImage*>; + using CPDF_PatternMap = std::map<const CPDF_Object*, CPDF_CountedPattern*>; + + CPDF_ColorSpace* GetColorSpaceImpl(CPDF_Object* pCSObj, + const CPDF_Dictionary* pResources, + std::set<CPDF_Object*>* pVisited); + + CPDF_Document* const m_pPDFDoc; + FX_BOOL m_bForceClear; + std::map<CFX_ByteString, CPDF_Stream*> m_HashProfileMap; + CPDF_ColorSpaceMap m_ColorSpaceMap; + CPDF_FontFileMap m_FontFileMap; + CPDF_FontMap m_FontMap; + CPDF_IccProfileMap m_IccProfileMap; + CPDF_ImageMap m_ImageMap; + CPDF_PatternMap m_PatternMap; +}; + +class CPDF_Function { + public: + enum class Type { + kTypeInvalid = -1, + kType0Sampled = 0, + kType2ExpotentialInterpolation = 2, + kType3Stitching = 3, + kType4PostScript = 4, + }; + + static std::unique_ptr<CPDF_Function> Load(CPDF_Object* pFuncObj); + static Type IntegerToFunctionType(int iType); + + virtual ~CPDF_Function(); + FX_BOOL Call(FX_FLOAT* inputs, + uint32_t ninputs, + FX_FLOAT* results, + int& nresults) const; + uint32_t CountInputs() const { return m_nInputs; } + uint32_t CountOutputs() const { return m_nOutputs; } + FX_FLOAT GetDomain(int i) const { return m_pDomains[i]; } + FX_FLOAT GetRange(int i) const { return m_pRanges[i]; } + + const CPDF_SampledFunc* ToSampledFunc() const; + const CPDF_ExpIntFunc* ToExpIntFunc() const; + const CPDF_StitchFunc* ToStitchFunc() const; + + protected: + explicit CPDF_Function(Type type); + + FX_BOOL Init(CPDF_Object* pObj); + virtual FX_BOOL v_Init(CPDF_Object* pObj) = 0; + virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const = 0; + + uint32_t m_nInputs; + uint32_t m_nOutputs; + FX_FLOAT* m_pDomains; + FX_FLOAT* m_pRanges; + const Type m_Type; +}; + +class CPDF_ExpIntFunc : public CPDF_Function { + public: + CPDF_ExpIntFunc(); + ~CPDF_ExpIntFunc() override; + + // CPDF_Function + FX_BOOL v_Init(CPDF_Object* pObj) override; + FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; + + uint32_t m_nOrigOutputs; + FX_FLOAT m_Exponent; + FX_FLOAT* m_pBeginValues; + FX_FLOAT* m_pEndValues; +}; + +class CPDF_SampledFunc : public CPDF_Function { + public: + struct SampleEncodeInfo { + FX_FLOAT encode_max; + FX_FLOAT encode_min; + uint32_t sizes; + }; + + struct SampleDecodeInfo { + FX_FLOAT decode_max; + FX_FLOAT decode_min; + }; + + CPDF_SampledFunc(); + ~CPDF_SampledFunc() override; + + // CPDF_Function + FX_BOOL v_Init(CPDF_Object* pObj) override; + FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; + + const std::vector<SampleEncodeInfo>& GetEncodeInfo() const { + return m_EncodeInfo; + } + uint32_t GetBitsPerSample() const { return m_nBitsPerSample; } + const CPDF_StreamAcc* GetSampleStream() const { + return m_pSampleStream.get(); + } + + private: + std::vector<SampleEncodeInfo> m_EncodeInfo; + std::vector<SampleDecodeInfo> m_DecodeInfo; + uint32_t m_nBitsPerSample; + uint32_t m_SampleMax; + std::unique_ptr<CPDF_StreamAcc> m_pSampleStream; +}; + +class CPDF_StitchFunc : public CPDF_Function { + public: + CPDF_StitchFunc(); + ~CPDF_StitchFunc() override; + + // CPDF_Function + FX_BOOL v_Init(CPDF_Object* pObj) override; + FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; + + const std::vector<std::unique_ptr<CPDF_Function>>& GetSubFunctions() const { + return m_pSubFunctions; + } + FX_FLOAT GetBound(size_t i) const { return m_pBounds[i]; } + + private: + std::vector<std::unique_ptr<CPDF_Function>> m_pSubFunctions; + FX_FLOAT* m_pBounds; + FX_FLOAT* m_pEncode; + + static const uint32_t kRequiredNumInputs = 1; +}; + +class CPDF_IccProfile { + public: + CPDF_IccProfile(const uint8_t* pData, uint32_t dwSize); + ~CPDF_IccProfile(); + uint32_t GetComponents() const { return m_nSrcComponents; } + FX_BOOL m_bsRGB; + void* m_pTransform; + + private: + uint32_t m_nSrcComponents; +}; + +class CPDF_DeviceCS : public CPDF_ColorSpace { + public: + CPDF_DeviceCS(CPDF_Document* pDoc, int family); + + FX_BOOL GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const override; + FX_BOOL SetRGB(FX_FLOAT* pBuf, + FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B) const override; + FX_BOOL v_GetCMYK(FX_FLOAT* pBuf, + FX_FLOAT& c, + FX_FLOAT& m, + FX_FLOAT& y, + FX_FLOAT& k) const override; + FX_BOOL v_SetCMYK(FX_FLOAT* pBuf, + FX_FLOAT c, + FX_FLOAT m, + FX_FLOAT y, + FX_FLOAT k) const override; + void TranslateImageLine(uint8_t* pDestBuf, + const uint8_t* pSrcBuf, + int pixels, + int image_width, + int image_height, + FX_BOOL bTransMask = FALSE) const override; +}; + +class CPDF_PatternCS : public CPDF_ColorSpace { + public: + explicit CPDF_PatternCS(CPDF_Document* pDoc); + ~CPDF_PatternCS() override; + FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; + FX_BOOL GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const override; + CPDF_ColorSpace* GetBaseCS() const override; + + private: + CPDF_ColorSpace* m_pBaseCS; + CPDF_CountedColorSpace* m_pCountedBaseCS; +}; + +#define MAX_PATTERN_COLORCOMPS 16 +struct PatternValue { + CPDF_Pattern* m_pPattern; + CPDF_CountedPattern* m_pCountedPattern; + int m_nComps; + FX_FLOAT m_Comps[MAX_PATTERN_COLORCOMPS]; +}; + +CFX_ByteStringC PDF_FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr); +CFX_ByteStringC PDF_FindValueAbbreviationForTesting( + const CFX_ByteStringC& abbr); + +void PDF_ReplaceAbbr(CPDF_Object* pObj); +bool IsPathOperator(const uint8_t* buf, size_t len); + +#endif // CORE_FPDFAPI_PAGE_PAGEINT_H_ |