// 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_SRC_REFLOW_REFLOWEDPAGE_H_ #define CORE_SRC_REFLOW_REFLOWEDPAGE_H_ #include "../../include/reflow/reflowengine.h" #define GET_SIGNED(a) ( (a)>0 ? a/a : (a==0 ? 0 : -a/a) ) class CRF_Data; class CRF_LineData; class CRF_CharData; class CRF_PathData; class CRF_ImageData; class CRF_Table; class CRF_AttrOperation; class CRF_OperationDate; class CPDF_ReflowedPage; class CPDF_Rect; typedef CFX_SegmentedArray<CRF_Data*> CRF_DataPtrArray; class CRF_CharState; typedef CFX_SegmentedArray<CRF_CharState> CRF_CharStateArray; #define SST_GE 1 #define SST_BLSE 2 #define SST_ILSE 3 #define SST_IE 4 class CPDF_LayoutProcessor_Reflow : public IPDF_LayoutProcessor { public: CPDF_LayoutProcessor_Reflow(); ~CPDF_LayoutProcessor_Reflow(); void Init(FX_FLOAT TopIndent, FX_FLOAT fWidth, FX_FLOAT fHeight, CPDF_ReflowedPage* pReflowedPage, int flags, FX_FLOAT lineSpace); LayoutStatus StartProcess(IPDF_LayoutElement* pElement, IFX_Pause* pPause, const CFX_AffineMatrix* pPDFMatrix = NULL); LayoutStatus Continue(); int GetPosition(); protected: void FitPageMode(); void ProcessElement(IPDF_LayoutElement* pElement, FX_FLOAT reflowWidth); FX_FLOAT GetElmWidth(IPDF_LayoutElement* pElement); CFX_FloatRect GetElmBBox(IPDF_LayoutElement* pElement); void ProcessTable(FX_FLOAT dx); void ProcessObjs(IPDF_LayoutElement* pElement, FX_FLOAT reflowWidth); void ProcessObject(CPDF_PageObject* pObj, FX_FLOAT reflowWidth, CFX_AffineMatrix objMatrix); void ProcessTextObject(CPDF_TextObject *pObj, FX_FLOAT reflowWidth, CFX_AffineMatrix objMatrix); void ProcessPathObject(CPDF_PathObject *pObj, FX_FLOAT reflowWidth); void ProcessUnitaryObjs(CPDF_PageObjects *pObjs, FX_FLOAT reflowWidth, CFX_AffineMatrix objMatrix); FX_INT32 LogicPreObj(CPDF_TextObject* pObj); int ProcessInsertObject(CPDF_TextObject* pObj, CFX_AffineMatrix formMatrix); FX_WCHAR GetPreChar(); FX_BOOL IsSameTextObject(CPDF_TextObject* pTextObj1, CPDF_TextObject* pTextObj2); int GetCharWidth(FX_DWORD charCode, CPDF_Font* pFont) const; FX_BOOL IsCanBreakAfter(FX_DWORD unicode); FX_BOOL IsCanBreakBefore(FX_DWORD unicode); FX_INT32 GetElementTypes(LayoutType layoutType); void CreateRFData(CPDF_PageObject* pObj, CFX_AffineMatrix* pMatrix = NULL); CRF_CharState* GetCharState(CPDF_TextObject* pObj, CPDF_Font* pFont, FX_FLOAT fHeight, FX_ARGB color); FX_FLOAT ConverWidth(FX_FLOAT width); void AddData2CurrLine(CRF_Data* pData); void AddTemp2CurrLine(int begin, int count ); void Transform(const CFX_AffineMatrix* pMatrix, CRF_Data* pData); void Transform(const CFX_AffineMatrix* pMatrix, CRF_DataPtrArray* pDataArray, int beginPos, int count = 0); FX_FLOAT GetDatasWidth( int beginPos, int endpos); void UpdateCurrLine(); FX_BOOL FinishedCurrLine(); int m_flags; CFX_AffineMatrix m_PDFMatrix; LayoutStatus m_Status; CPDF_TextObject* m_pPreObj; CFX_AffineMatrix m_perMatrix; IPDF_LayoutElement* m_pLayoutElement; IPDF_LayoutElement* m_pRootElement; FX_FLOAT m_CurrRefWidth; IFX_Pause* m_pPause; LayoutEnum m_CurrWritingMode; CPDF_ReflowedPage* m_pReflowedPage; FX_FLOAT m_fRefWidth; FX_FLOAT m_TopIndent; FX_FLOAT m_fLineSpace; FX_FLOAT m_fScreenHeight; FX_FLOAT m_fCurrMaxWidth; FX_FLOAT m_fCurrLineWidth; FX_FLOAT m_fCurrLineHeight; CRF_DataPtrArray* m_pCurrLine; CRF_DataPtrArray* m_pTempLine; FX_BOOL m_bIllustration; FX_FLOAT m_fLineHeight; LayoutEnum m_TextAlign; FX_FLOAT m_StartIndent; CFX_ArrayTemplate<CRF_Table*> m_TableArray; int m_PausePosition; }; struct RF_TableCell { int m_BeginPos; int m_EndPos; FX_FLOAT m_MaxWidth; FX_FLOAT m_PosX; FX_FLOAT m_PosY; FX_FLOAT m_CellWidth; FX_FLOAT m_CellHeight; int m_RowSpan; int m_ColSpan; LayoutEnum m_BlockAlign; LayoutEnum m_InlineAlign; }; typedef CFX_ArrayTemplate<RF_TableCell*> CRF_TableCellArray; class CRF_Table { public: CRF_Table() { m_TableWidth = 0; m_nCol = 0; } CRF_TableCellArray m_pCellArray; CFX_WordArray m_nCell; int m_nCol; FX_FLOAT m_TableWidth; FX_FLOAT m_ReflowPageHeight; }; class CRF_CharState { public: CPDF_Font* m_pFont; FX_ARGB m_Color; FX_BOOL m_bVert; FX_FLOAT m_fFontSize; FX_FLOAT m_fAscent; FX_FLOAT m_fDescent; CPDF_TextObject* m_pTextObj; }; class CRF_PageInfo { public: CRF_PageInfo(CPDF_PageObject* pPageObj, CRF_PageInfo* pParent = NULL) : m_pPageObj(pPageObj) , m_pParent(pParent) { } CPDF_PageObject* GetPageObj() { return m_pPageObj; } CPDF_Dictionary* GetFormDict() { if (NULL == m_pParent) { return NULL; } CPDF_PageObject* pParentObj = m_pParent->GetPageObj(); if (NULL == pParentObj || PDFPAGE_FORM != pParentObj->m_Type) { return NULL; } return ((CPDF_FormObject*)pParentObj)->m_pForm->m_pResources; } protected: CPDF_PageObject* m_pPageObj; CRF_PageInfo* m_pParent; }; class CPDF_ReflowedPage : public IPDF_ReflowedPage, public CFX_PrivateData { public: CPDF_ReflowedPage(CFX_GrowOnlyPool* pMemoryPool); ~CPDF_ReflowedPage(); CFX_PrivateData* GetPrivateDataCtrl() { return this; }; void GetDisplayMatrix(CFX_AffineMatrix& matrix, FX_INT32 xPos, FX_INT32 yPos, FX_INT32 xSize, FX_INT32 ySize, FX_INT32 iRotate, const CFX_AffineMatrix* pPageMatrix); FX_FLOAT GetPageHeight() ; FX_FLOAT GetPageWidth() { return m_PageWidth; }; void FocusGetData(const CFX_AffineMatrix matrix, FX_INT32 x, FX_INT32 y, CFX_ByteString& str); FX_BOOL FocusGetPosition(const CFX_AffineMatrix matrix, CFX_ByteString str, FX_INT32& x, FX_INT32& y); CRF_DataPtrArray* m_pReflowed; FX_FLOAT m_PageWidth; FX_FLOAT m_PageHeight; FX_BOOL m_bWaiting; CRF_CharStateArray* m_pCharState; CFX_GrowOnlyPool* m_pMemoryPool; FX_BOOL m_bCreateMemoryPool; CPDF_Page* m_pPDFPage; FX_BOOL RetainPageObjsMemberShip(); void MarkPageObjMemberShip(CPDF_PageObject* pObj, CRF_PageInfo* pParent); void ReleasePageObjsMemberShip(); CPDF_Dictionary* GetFormResDict(CPDF_PageObject* pObj); CFX_MapPtrToPtr* m_pPageInfos; }; class CPDF_ProgressiveReflowPageParser : public IPDF_ProgressiveReflowPageParser { public: CPDF_ProgressiveReflowPageParser(); ~CPDF_ProgressiveReflowPageParser() ; void Init(); ParseStatus GetStatus() { return m_Status; }; void SetParserStyle(RF_ParseStyle style) { m_ParseStyle = style; }; void Start(IPDF_ReflowedPage* pReflowPage, CPDF_Page* pPage, FX_FLOAT TopIndent, FX_FLOAT fWidth, FX_FLOAT fHeight, IFX_Pause* pPause, int flags); void Continue(IFX_Pause* pPause); int GetPosition() ; void Clear(); ParseStatus m_Status; protected: RF_ParseStyle m_ParseStyle; CPDF_Page* m_pPDFPage; IFX_Pause* m_pPause; CPDF_ReflowedPage* m_pReflowPage; FX_FLOAT m_TopIndent; FX_FLOAT m_ReflowedWidth; FX_FLOAT m_fScreenHeight; IPDF_LayoutProvider* m_pProvider; IPDF_LayoutProcessor* m_pReflowEngine; int m_nObjProcessed; int m_flags; }; class CPDF_ProgressiveReflowPageRender : public IPDF_ProgressiveReflowPageRender { public: CPDF_ProgressiveReflowPageRender(); ~CPDF_ProgressiveReflowPageRender() ; RenderStatus GetStatus() { return m_Status; }; void SetDisplayColor(FX_COLORREF color); void Start(IPDF_ReflowedPage* pReflowPage, CFX_RenderDevice* pDevice, const CFX_AffineMatrix* pMatrix, IFX_Pause* pPause, int DitherBits); void Continue(IFX_Pause* pPause); int GetPosition(); void Clear(); protected: void Display(IFX_Pause* pPause); RenderStatus m_Status; CPDF_ReflowedPage* m_pReflowPage; CFX_AffineMatrix* m_pDisplayMatrix; int m_CurrNum; IFX_FontEncoding* m_pFontEncoding; CFX_RenderDevice* m_pFXDevice; int m_DitherBits; FX_COLORREF m_DisplayColor; typedef struct CRF_TextDataAtt { CRF_TextDataAtt() { pFont = NULL; fFontSize = 0.0f; Color = 0; } CRF_TextDataAtt(CPDF_Font* font, FX_FLOAT fontSize, FX_ARGB color) { pFont = font; fFontSize = fontSize; Color = color; } CPDF_Font* pFont; FX_FLOAT fFontSize; FX_ARGB Color; } CRF_TEXTDATAATT; inline bool isTextDataAttSame(CRF_TEXTDATAATT data1, CRF_TEXTDATAATT data2) { if (data1.pFont != data2.pFont) { return false; } if (data1.Color != data2.Color) { return false; } if (fabs(data1.fFontSize - data2.fFontSize) > 0.0f) { return false; } return true; }; }; #define TYPE_UNKNOW 0 #define TYPE_TEXT 1 #define TYPE_PATH 2 #define TYPE_IMAGE 3 #define TYPE_LINE 4 class CRF_Data { public: typedef enum {Unknow, Text, Image, Path, Line, paragraph} RF_DataType; CRF_Data() { m_Type = Unknow; m_Width = 0; m_PosY = 0; m_PosX = 0; m_Height = 0; } RF_DataType GetType() { return m_Type; } virtual ~CRF_Data() {} RF_DataType m_Type; FX_FLOAT m_PosX; FX_FLOAT m_PosY; FX_FLOAT m_Width; FX_FLOAT m_Height; }; class CRF_LineData : public CRF_Data { public: CRF_LineData() { m_Type = Line; } }; class CRF_CharData : public CRF_Data { public: CRF_CharData() { m_Type = Text; m_CharCode = -1; } CRF_CharState* m_pCharState; FX_DWORD m_CharCode; }; class CRF_ImageData : public CRF_Data { public: CRF_ImageData() { m_Type = Image; m_pBitmap = NULL; } ~CRF_ImageData() { if(m_pBitmap) { delete m_pBitmap; } m_pBitmap = NULL; } CFX_AffineMatrix m_Matrix; CFX_DIBitmap* m_pBitmap; }; class CRF_PathData : public CRF_Data { public: CRF_PathData() { m_Type = Path; m_bDecoration = FALSE; } ~CRF_PathData() {}; FX_BOOL m_bDecoration; CPDF_Path m_pPathData; CFX_AffineMatrix m_pPath2Device; CPDF_GraphState m_pGraphState; FX_ARGB m_fill_argb; FX_ARGB m_stroke_argb; int m_fill_mode; }; #endif // CORE_SRC_REFLOW_REFLOWEDPAGE_H_