blob: df98312824882333a6e33c7879d14404999a35fc [file] [log] [blame]
// 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 _PAGEINT_H_
#define _PAGEINT_H_
#include "../../../include/fpdfapi/fpdf_pageobj.h"
#define PARSE_STEP_LIMIT 100
#define STREAM_PARSE_BUFSIZE 20480
class CPDF_QuickFontCache;
class CPDF_StreamParser
{
public:
CPDF_StreamParser(const FX_BYTE* pData, FX_DWORD dwSize);
~CPDF_StreamParser();
CPDF_Stream* ReadInlineStream(CPDF_Document* pDoc, CPDF_Dictionary* pDict, CPDF_Object* pCSObj, FX_BOOL bDecode);
typedef enum { EndOfData, Number, Keyword, Name, Others } SyntaxType;
SyntaxType ParseNextElement();
FX_LPBYTE GetWordBuf()
{
return m_WordBuffer;
}
FX_DWORD GetWordSize()
{
return m_WordSize;
}
CPDF_Object* GetObject()
{
CPDF_Object* pObj = m_pLastObj;
m_pLastObj = NULL;
return pObj;
}
FX_DWORD GetPos()
{
return m_Pos;
}
void SetPos(FX_DWORD pos)
{
m_Pos = pos;
}
CPDF_Object* ReadNextObject(FX_BOOL bAllowNestedArray = FALSE, FX_BOOL bInArray = FALSE);
void SkipPathObject();
protected:
void GetNextWord(FX_BOOL& bIsNumber);
CFX_ByteString ReadString();
CFX_ByteString ReadHexString();
const FX_BYTE* m_pBuf;
FX_DWORD m_Size;
FX_DWORD m_Pos;
FX_BYTE m_WordBuffer[256];
FX_DWORD m_WordSize;
CPDF_Object* m_pLastObj;
};
typedef enum {
PDFOP_CloseFillStrokePath = 0, PDFOP_FillStrokePath,
PDFOP_CloseEOFillStrokePath, PDFOP_EOFillStrokePath,
PDFOP_BeginMarkedContent_Dictionary, PDFOP_BeginImage,
PDFOP_BeginMarkedContent, PDFOP_BeginText,
PDFOP_BeginSectionUndefined, PDFOP_CurveTo_123,
PDFOP_ConcatMatrix, PDFOP_SetColorSpace_Fill,
PDFOP_SetColorSpace_Stroke, PDFOP_SetDash,
PDFOP_SetCharWidth, PDFOP_SetCachedDevice,
PDFOP_ExecuteXObject, PDFOP_MarkPlace_Dictionary,
PDFOP_EndImage, PDFOP_EndMarkedContent,
PDFOP_EndText, PDFOP_EndSectionUndefined,
PDFOP_FillPath, PDFOP_FillPathOld,
PDFOP_EOFillPath, PDFOP_SetGray_Fill,
PDFOP_SetGray_Stroke, PDFOP_SetExtendGraphState,
PDFOP_ClosePath, PDFOP_SetFlat,
PDFOP_BeginImageData, PDFOP_SetLineJoin,
PDFOP_SetLineCap, PDFOP_SetCMYKColor_Fill,
PDFOP_SetCMYKColor_Stroke, PDFOP_LineTo,
PDFOP_MoveTo, PDFOP_SetMiterLimit,
PDFOP_MarkPlace, PDFOP_EndPath,
PDFOP_SaveGraphState, PDFOP_RestoreGraphState,
PDFOP_Rectangle, PDFOP_SetRGBColor_Fill,
PDFOP_SetRGBColor_Stroke, PDFOP_SetRenderIntent,
PDFOP_CloseStrokePath, PDFOP_StrokePath,
PDFOP_SetColor_Fill, PDFOP_SetColor_Stroke,
PDFOP_SetColorPS_Fill, PDFOP_SetColorPS_Stroke,
PDFOP_ShadeFill, PDFOP_SetCharSpace,
PDFOP_MoveTextPoint, PDFOP_MoveTextPoint_SetLeading,
PDFOP_SetFont, PDFOP_ShowText,
PDFOP_ShowText_Positioning, PDFOP_SetTextLeading,
PDFOP_SetTextMatrix, PDFOP_SetTextRenderMode,
PDFOP_SetTextRise, PDFOP_SetWordSpace,
PDFOP_SetHorzScale, PDFOP_MoveToNextLine,
PDFOP_CurveTo_23, PDFOP_SetLineWidth,
PDFOP_Clip, PDFOP_EOClip,
PDFOP_CurveTo_13, PDFOP_NextLineShowText,
PDFOP_NextLineShowText_Space, PDFOP_Invalid
} PDFOP;
#define PARAM_BUF_SIZE 16
typedef struct {
int m_Type;
union {
struct {
FX_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;
};
} _ContentParam;
#define _FPDF_MAX_FORM_LEVEL_ 30
#define _FPDF_MAX_TYPE3_FORM_LEVEL_ 4
#define _FPDF_MAX_OBJECT_STACK_SIZE_ 512
class CPDF_StreamContentParser
{
public:
CPDF_StreamContentParser();
~CPDF_StreamContentParser();
FX_BOOL Initialize();
void PrepareParse(CPDF_Document* pDoc, CPDF_Dictionary* pPageResources, CPDF_Dictionary* pParentResources,
CFX_AffineMatrix* pmtContentToUser,
CPDF_PageObjects* pObjList, CPDF_Dictionary* pResources,
CFX_FloatRect* pBBox, CPDF_ParseOptions* pOptions,
CPDF_AllStates* pAllStates, int level);
CPDF_Document* m_pDocument;
CPDF_Dictionary* m_pPageResources;
CPDF_Dictionary* m_pParentResources;
CPDF_PageObjects* m_pObjectList;
CPDF_Dictionary* m_pResources;
int m_Level;
CFX_AffineMatrix m_mtContentToUser;
CFX_FloatRect m_BBox;
CPDF_ParseOptions m_Options;
_ContentParam m_ParamBuf1[PARAM_BUF_SIZE];
FX_DWORD m_ParamStartPos;
FX_DWORD m_ParamCount;
void AddNumberParam(FX_LPCSTR str, int len);
void AddObjectParam(CPDF_Object* pObj);
void AddNameParam(FX_LPCSTR name, int size);
int GetNextParamPos();
void ClearAllParams();
CPDF_Object* GetObject(FX_DWORD index);
CFX_ByteString GetString(FX_DWORD index);
FX_FLOAT GetNumber(FX_DWORD index);
FX_FLOAT GetNumber16(FX_DWORD index);
int GetInteger(FX_DWORD index)
{
return (FX_INT32)(GetNumber(index));
}
FX_BOOL OnOperator(FX_LPCSTR op);
void BigCaseCaller(int index);
FX_BOOL m_bAbort;
CPDF_StreamParser* m_pSyntax;
FX_DWORD GetParsePos()
{
return m_pSyntax->GetPos();
}
CPDF_AllStates* m_pCurStates;
CPDF_ContentMark m_CurContentMark;
CFX_PtrArray m_ClipTextList;
CPDF_TextObject* m_pLastTextObject;
FX_FLOAT m_DefFontSize;
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();
FX_DWORD Parse(FX_LPCBYTE pData, FX_DWORD dwSize, FX_DWORD max_cost);
void ParsePathObject();
int m_CompatCount;
FX_PATHPOINT* m_pPathPoints;
int m_PathPointCount;
int m_PathAllocSize;
FX_FLOAT m_PathStartX, m_PathStartY;
FX_FLOAT m_PathCurrentX, m_PathCurrentY;
int m_PathClipType;
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, FX_BOOL bInline);
void AddDuplicateImage();
void AddForm(CPDF_Stream*);
CFX_ByteString m_LastImageName;
CPDF_Image* m_pLastImage;
CFX_BinaryBuf m_LastImageDict, m_LastImageData;
CPDF_Dictionary* m_pLastImageDict;
CPDF_Dictionary* m_pLastCloneImageDict;
FX_BOOL m_bReleaseLastDict;
FX_BOOL m_bSameLastDict;
void SetGraphicStates(CPDF_PageObject* pObj, FX_BOOL bColor, FX_BOOL bText, FX_BOOL bGraph);
FX_BOOL m_bColored;
FX_FLOAT m_Type3Data[6];
FX_BOOL m_bResourceMissing;
CFX_PtrArray m_StateStack;
void SaveStates(CPDF_AllStates*);
void RestoreStates(CPDF_AllStates*);
CPDF_Font* FindFont(const CFX_ByteString& name);
CPDF_ColorSpace* FindColorSpace(const CFX_ByteString& name);
CPDF_Pattern* FindPattern(const CFX_ByteString& name, FX_BOOL bShading);
CPDF_Object* FindResourceObj(FX_BSTR type, const CFX_ByteString& name);
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_BeginSectionUndefined();
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_EndSectionUndefined();
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();
};
class CPDF_ContentParser
{
public:
CPDF_ContentParser();
~CPDF_ContentParser();
typedef enum { Ready, ToBeContinued, Done } ParseStatus;
ParseStatus GetStatus()
{
return m_Status;
}
void Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions);
void Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates, CFX_AffineMatrix* pParentMatrix,
CPDF_Type3Char* pType3Char, CPDF_ParseOptions* pOptions, int level);
void Continue(IFX_Pause* pPause);
int EstimateProgress();
protected:
void Clear();
ParseStatus m_Status;
CPDF_PageObjects* m_pObjects;
FX_BOOL m_bForm;
CPDF_ParseOptions m_Options;
CPDF_Type3Char* m_pType3Char;
int m_InternalStage;
CPDF_StreamAcc* m_pSingleStream;
CPDF_StreamAcc** m_pStreamArray;
FX_DWORD m_nStreams;
FX_LPBYTE m_pData;
FX_DWORD m_Size;
class CPDF_StreamContentParser* m_pParser;
FX_DWORD m_CurrentOffset;
CPDF_StreamFilter* m_pStreamFilter;
};
class CPDF_AllStates : public CPDF_GraphicStates
{
public:
CPDF_AllStates();
~CPDF_AllStates();
void Copy(const CPDF_AllStates& src);
void ProcessExtGS(CPDF_Dictionary* pGS, CPDF_StreamContentParser* pParser);
void SetLineDash(CPDF_Array*, FX_FLOAT, FX_FLOAT scale);
CFX_AffineMatrix m_TextMatrix, m_CTM, m_ParentMatrix;
FX_FLOAT m_TextX, m_TextY, m_TextLineX, m_TextLineY;
FX_FLOAT m_TextLeading, m_TextRise, m_TextHorzScale;
};
template <class KeyType, class ValueType>
KeyType PDF_DocPageData_FindValue(const CFX_MapPtrTemplate<KeyType, CPDF_CountedObject<ValueType>*> &map, ValueType findValue, CPDF_CountedObject<ValueType>*& findData)
{
FX_POSITION pos = map.GetStartPosition();
while (pos) {
KeyType findKey;
map.GetNextAssoc(pos, findKey, findData);
if (findData->m_Obj == findValue) {
return findKey;
}
}
findData = NULL;
return (KeyType)(FX_UINTPTR)NULL;
}
template <class KeyType, class ValueType>
FX_BOOL PDF_DocPageData_Release(CFX_MapPtrTemplate<KeyType, CPDF_CountedObject<ValueType>*> &map, KeyType findKey, ValueType findValue, FX_BOOL bForce = FALSE)
{
if (!findKey && !findValue) {
return FALSE;
}
CPDF_CountedObject<ValueType>* findData = NULL;
if (!findKey) {
findKey = PDF_DocPageData_FindValue<KeyType, ValueType>(map, findValue, findData);
} else if (!map.Lookup(findKey, findData)) {
return FALSE;
}
if (findData && ((-- findData->m_nCount) == 0 || bForce)) {
delete findData->m_Obj;
delete findData;
map.RemoveKey(findKey);
return TRUE;
}
return FALSE;
}
class CPDF_DocPageData
{
public:
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(FX_BSTR fontName, CPDF_FontEncoding* pEncoding);
void ReleaseFont(CPDF_Dictionary* pFontDict);
CPDF_ColorSpace* GetColorSpace(CPDF_Object* pCSObj, CPDF_Dictionary* pResources);
CPDF_ColorSpace* GetCopiedColorSpace(CPDF_Object* pCSObj);
void ReleaseColorSpace(CPDF_Object* pColorSpace);
CPDF_Pattern* GetPattern(CPDF_Object* pPatternObj, FX_BOOL bShading, const CFX_AffineMatrix* matrix);
void ReleasePattern(CPDF_Object* pPatternObj);
CPDF_Image* GetImage(CPDF_Object* pImageStream);
void ReleaseImage(CPDF_Object* pImageStream);
CPDF_IccProfile* GetIccProfile(CPDF_Stream* pIccProfileStream);
void ReleaseIccProfile(CPDF_Stream* pIccProfileStream, CPDF_IccProfile* pIccProfile);
CPDF_StreamAcc* GetFontFileStreamAcc(CPDF_Stream* pFontStream);
void ReleaseFontFileStreamAcc(CPDF_Stream* pFontStream, FX_BOOL bForce = FALSE);
FX_BOOL IsForceClear() const {return m_bForceClear;}
CPDF_CountedColorSpace* FindColorSpacePtr(CPDF_Object* pCSObj) const;
CPDF_CountedPattern* FindPatternPtr(CPDF_Object* pPatternObj) const;
CPDF_Document* m_pPDFDoc;
CPDF_FontMap m_FontMap;
CPDF_ColorSpaceMap m_ColorSpaceMap;
CPDF_PatternMap m_PatternMap;
CPDF_ImageMap m_ImageMap;
CPDF_IccProfileMap m_IccProfileMap;
CFX_MapByteStringToPtr m_HashProfileMap;
CPDF_FontFileMap m_FontFileMap;
FX_BOOL m_bForceClear;
};
class CPDF_Function
{
public:
static CPDF_Function* Load(CPDF_Object* pFuncObj);
virtual ~CPDF_Function();
FX_BOOL Call(FX_FLOAT* inputs, int ninputs, FX_FLOAT* results, int& nresults) const;
int CountInputs()
{
return m_nInputs;
}
int CountOutputs()
{
return m_nOutputs;
}
protected:
CPDF_Function();
int m_nInputs, m_nOutputs;
FX_FLOAT* m_pDomains;
FX_FLOAT* m_pRanges;
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;
};
class CPDF_IccProfile
{
public:
CPDF_IccProfile(FX_LPCBYTE pData, FX_DWORD dwSize);
~CPDF_IccProfile();
FX_INT32 GetComponents() const { return m_nSrcComponents; }
FX_BOOL m_bsRGB;
FX_LPVOID m_pTransform;
private:
FX_INT32 m_nSrcComponents;
};
class CPDF_DeviceCS : public CPDF_ColorSpace
{
public:
CPDF_DeviceCS(int family);
virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
FX_BOOL SetRGB(FX_FLOAT* pBuf, FX_FLOAT R, FX_FLOAT G, FX_FLOAT B) const;
FX_BOOL v_GetCMYK(FX_FLOAT* pBuf, FX_FLOAT& c, FX_FLOAT& m, FX_FLOAT& y, FX_FLOAT& k) const;
FX_BOOL v_SetCMYK(FX_FLOAT* pBuf, FX_FLOAT c, FX_FLOAT m, FX_FLOAT y, FX_FLOAT k) const;
virtual void TranslateImageLine(FX_LPBYTE pDestBuf, FX_LPCBYTE pSrcBuf, int pixels, int image_width, int image_height, FX_BOOL bTransMask = FALSE) const;
};
class CPDF_PatternCS : public CPDF_ColorSpace
{
public:
CPDF_PatternCS();
~CPDF_PatternCS();
virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray);
virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B) const;
virtual CPDF_ColorSpace* GetBaseCS() const
{
return m_pBaseCS;
}
CPDF_ColorSpace* m_pBaseCS;
CPDF_CountedColorSpace* m_pCountedBaseCS;
};
#define MAX_PAGE_OBJECTS_UNIFY_NAMING 4096
class CPDF_ResourceNaming
{
public:
struct _NamingState {
CFX_ByteString m_Prefix;
int m_nIndex;
};
~CPDF_ResourceNaming();
CFX_ByteString GetName(const CPDF_Dictionary* pResList, FX_LPCSTR szType);
protected:
CFX_MapByteStringToPtr m_NamingCache;
};
#endif // _PAGEINT_H_