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_REFLOW_REFLOWEDPAGE_H_
8#define CORE_SRC_REFLOW_REFLOWEDPAGE_H_
9
10#include "../../include/reflow/reflowengine.h"
11
12#define GET_SIGNED(a) ( (a)>0 ? a/a : (a==0 ? 0 : -a/a) )
13class CRF_Data;
14class CRF_LineData;
15class CRF_CharData;
16class CRF_PathData;
17class CRF_ImageData;
18class CRF_Table;
19class CRF_AttrOperation;
20class CRF_OperationDate;
21class CPDF_ReflowedPage;
22class CPDF_Rect;
23typedef CFX_SegmentedArray<CRF_Data*> CRF_DataPtrArray;
24class CRF_CharState;
25typedef CFX_SegmentedArray<CRF_CharState> CRF_CharStateArray;
26#define SST_GE		1
27#define SST_BLSE	2
28#define SST_ILSE	3
29#define SST_IE		4
30class CPDF_LayoutProcessor_Reflow : public IPDF_LayoutProcessor
31{
32public:
33    CPDF_LayoutProcessor_Reflow();
34    ~CPDF_LayoutProcessor_Reflow();
35    void Init(FX_FLOAT TopIndent, FX_FLOAT fWidth, FX_FLOAT fHeight, CPDF_ReflowedPage* pReflowedPage, int flags, FX_FLOAT lineSpace);
36
37    LayoutStatus	StartProcess(IPDF_LayoutElement* pElement, IFX_Pause* pPause, const CFX_AffineMatrix* pPDFMatrix = NULL);
38    LayoutStatus	Continue();
39    int				GetPosition();
40protected:
41    void	FitPageMode();
42    void	ProcessElement(IPDF_LayoutElement* pElement, FX_FLOAT reflowWidth);
43    FX_FLOAT GetElmWidth(IPDF_LayoutElement* pElement);
44    CFX_FloatRect GetElmBBox(IPDF_LayoutElement* pElement);
45    void	ProcessTable(FX_FLOAT dx);
46    void	ProcessObjs(IPDF_LayoutElement* pElement, FX_FLOAT reflowWidth);
47    void	ProcessObject(CPDF_PageObject* pObj, FX_FLOAT reflowWidth, CFX_AffineMatrix objMatrix);
48    void	ProcessTextObject(CPDF_TextObject *pObj, FX_FLOAT reflowWidth, CFX_AffineMatrix objMatrix);
49    void	ProcessPathObject(CPDF_PathObject *pObj, FX_FLOAT reflowWidth);
50    void	ProcessUnitaryObjs(CPDF_PageObjects *pObjs, FX_FLOAT reflowWidth, CFX_AffineMatrix objMatrix);
51    FX_INT32 LogicPreObj(CPDF_TextObject* pObj);
52    int ProcessInsertObject(CPDF_TextObject* pObj, CFX_AffineMatrix formMatrix);
53    FX_WCHAR GetPreChar();
54    FX_BOOL IsSameTextObject(CPDF_TextObject* pTextObj1, CPDF_TextObject* pTextObj2);
55    int GetCharWidth(FX_DWORD charCode, CPDF_Font* pFont) const;
56    FX_BOOL	IsCanBreakAfter(FX_DWORD unicode);
57    FX_BOOL	IsCanBreakBefore(FX_DWORD unicode);
58    FX_INT32 GetElementTypes(LayoutType layoutType);
59    void				CreateRFData(CPDF_PageObject* pObj, CFX_AffineMatrix* pMatrix = NULL);
60    CRF_CharState*		GetCharState(CPDF_TextObject* pObj, CPDF_Font* pFont, FX_FLOAT fHeight, FX_ARGB color);
61    FX_FLOAT		ConverWidth(FX_FLOAT width);
62    void	AddData2CurrLine(CRF_Data* pData);
63    void	AddTemp2CurrLine(int begin, int count );
64    void	Transform(const CFX_AffineMatrix* pMatrix, CRF_Data* pData);
65    void	Transform(const CFX_AffineMatrix* pMatrix, CRF_DataPtrArray* pDataArray, int beginPos, int count = 0);
66    FX_FLOAT GetDatasWidth( int beginPos, int endpos);
67    void	UpdateCurrLine();
68    FX_BOOL	FinishedCurrLine();
69    int m_flags;
70    CFX_AffineMatrix m_PDFMatrix;
71    LayoutStatus	m_Status;
72    CPDF_TextObject* m_pPreObj;
73    CFX_AffineMatrix m_perMatrix;
74    IPDF_LayoutElement*	m_pLayoutElement;
75    IPDF_LayoutElement* m_pRootElement;
76    FX_FLOAT		m_CurrRefWidth;
77    IFX_Pause*		m_pPause;
78    LayoutEnum		m_CurrWritingMode;
79    CPDF_ReflowedPage*	m_pReflowedPage;
80    FX_FLOAT		m_fRefWidth;
81    FX_FLOAT		m_TopIndent;
82    FX_FLOAT		m_fLineSpace;
83    FX_FLOAT		m_fScreenHeight;
84    FX_FLOAT		m_fCurrMaxWidth;
85    FX_FLOAT		m_fCurrLineWidth;
86    FX_FLOAT		m_fCurrLineHeight;
87    CRF_DataPtrArray*	m_pCurrLine;
88    CRF_DataPtrArray*	m_pTempLine;
89    FX_BOOL			m_bIllustration;
90    FX_FLOAT		m_fLineHeight;
91    LayoutEnum		m_TextAlign;
92    FX_FLOAT		m_StartIndent;
93    CFX_ArrayTemplate<CRF_Table*> m_TableArray;
94    int				m_PausePosition;
95};
96struct RF_TableCell {
97    int			m_BeginPos;
98    int			m_EndPos;
99    FX_FLOAT m_MaxWidth;
100    FX_FLOAT m_PosX;
101    FX_FLOAT	m_PosY;
102    FX_FLOAT	m_CellWidth;
103    FX_FLOAT m_CellHeight;
104    int			m_RowSpan;
105    int			m_ColSpan;
106    LayoutEnum	m_BlockAlign;
107    LayoutEnum	m_InlineAlign;
108};
109typedef CFX_ArrayTemplate<RF_TableCell*> CRF_TableCellArray;
110class CRF_Table
111{
112public:
113    CRF_Table()
114    {
115        m_TableWidth = 0;
116        m_nCol = 0;
117    }
118    CRF_TableCellArray  m_pCellArray;
119    CFX_WordArray		m_nCell;
120    int					m_nCol;
121    FX_FLOAT			m_TableWidth;
122    FX_FLOAT			m_ReflowPageHeight;
123};
124class CRF_CharState
125{
126public:
127    CPDF_Font*	m_pFont;
128    FX_ARGB		m_Color;
129    FX_BOOL		m_bVert;
130    FX_FLOAT m_fFontSize;
131    FX_FLOAT m_fAscent;
132    FX_FLOAT m_fDescent;
133
134    CPDF_TextObject*	m_pTextObj;
135};
136class CRF_PageInfo
137{
138public:
139    CRF_PageInfo(CPDF_PageObject* pPageObj, CRF_PageInfo* pParent = NULL)
140        : m_pPageObj(pPageObj) , m_pParent(pParent)
141    {
142    }
143    CPDF_PageObject* GetPageObj()
144    {
145        return m_pPageObj;
146    }
147    CPDF_Dictionary* GetFormDict()
148    {
149        if (NULL == m_pParent) {
150            return NULL;
151        }
152        CPDF_PageObject* pParentObj = m_pParent->GetPageObj();
153        if (NULL == pParentObj || PDFPAGE_FORM != pParentObj->m_Type) {
154            return NULL;
155        }
156        return ((CPDF_FormObject*)pParentObj)->m_pForm->m_pResources;
157    }
158protected:
159    CPDF_PageObject*		m_pPageObj;
160    CRF_PageInfo*			m_pParent;
161};
162class CPDF_ReflowedPage : public IPDF_ReflowedPage, public CFX_PrivateData
163{
164public:
165
166    CPDF_ReflowedPage(CFX_GrowOnlyPool*	pMemoryPool);
167    ~CPDF_ReflowedPage();
168    CFX_PrivateData*	GetPrivateDataCtrl()
169    {
170        return this;
171    };
172    void		GetDisplayMatrix(CFX_AffineMatrix& matrix, FX_INT32 xPos, FX_INT32 yPos, FX_INT32 xSize, FX_INT32 ySize, FX_INT32 iRotate, const CFX_AffineMatrix* pPageMatrix);
173
174    FX_FLOAT	GetPageHeight() ;
175    FX_FLOAT	GetPageWidth()
176    {
177        return m_PageWidth;
178    };
179    void		FocusGetData(const CFX_AffineMatrix matrix, FX_INT32 x, FX_INT32 y, CFX_ByteString& str);
180    FX_BOOL		FocusGetPosition(const CFX_AffineMatrix matrix, CFX_ByteString str, FX_INT32& x, FX_INT32& y);
181    CRF_DataPtrArray*	m_pReflowed;
182    FX_FLOAT			m_PageWidth;
183    FX_FLOAT			m_PageHeight;
184    FX_BOOL				m_bWaiting;
185    CRF_CharStateArray*	m_pCharState;
186    CFX_GrowOnlyPool*	m_pMemoryPool;
187    FX_BOOL				m_bCreateMemoryPool;
188    CPDF_Page*			m_pPDFPage;
189    FX_BOOL					RetainPageObjsMemberShip();
190    void					MarkPageObjMemberShip(CPDF_PageObject* pObj, CRF_PageInfo* pParent);
191    void					ReleasePageObjsMemberShip();
192    CPDF_Dictionary*		GetFormResDict(CPDF_PageObject* pObj);
193
194    CFX_MapPtrToPtr*		m_pPageInfos;
195};
196class CPDF_ProgressiveReflowPageParser : public IPDF_ProgressiveReflowPageParser
197{
198public:
199    CPDF_ProgressiveReflowPageParser();
200    ~CPDF_ProgressiveReflowPageParser() ;
201    void			Init();
202
203    ParseStatus		GetStatus()
204    {
205        return m_Status;
206    };
207
208    void			SetParserStyle(RF_ParseStyle style)
209    {
210        m_ParseStyle = style;
211    };
212    void			Start(IPDF_ReflowedPage* pReflowPage, CPDF_Page* pPage, FX_FLOAT TopIndent, FX_FLOAT fWidth, FX_FLOAT fHeight, IFX_Pause* pPause, int flags);
213    void			Continue(IFX_Pause* pPause);
214    int				GetPosition() ;
215
216    void			Clear();
217    ParseStatus		m_Status;
218protected:
219    RF_ParseStyle		m_ParseStyle;
220    CPDF_Page*			m_pPDFPage;
221    IFX_Pause*			m_pPause;
222    CPDF_ReflowedPage*	m_pReflowPage;
223    FX_FLOAT			m_TopIndent;
224    FX_FLOAT			m_ReflowedWidth;
225    FX_FLOAT			m_fScreenHeight;
226    IPDF_LayoutProvider*	m_pProvider;
227    IPDF_LayoutProcessor*	m_pReflowEngine;
228    int					m_nObjProcessed;
229    int m_flags;
230};
231class CPDF_ProgressiveReflowPageRender : public IPDF_ProgressiveReflowPageRender
232{
233public:
234    CPDF_ProgressiveReflowPageRender();
235    ~CPDF_ProgressiveReflowPageRender() ;
236
237    RenderStatus			GetStatus()
238    {
239        return m_Status;
240    };
241
242
243    void		SetDisplayColor(FX_COLORREF color);
244    void		Start(IPDF_ReflowedPage* pReflowPage, CFX_RenderDevice* pDevice, const CFX_AffineMatrix* pMatrix, IFX_Pause* pPause, int DitherBits);
245    void		Continue(IFX_Pause* pPause);
246    int			GetPosition();
247
248
249    void				Clear();
250protected:
251    void				Display(IFX_Pause* pPause);
252    RenderStatus m_Status;
253    CPDF_ReflowedPage*	m_pReflowPage;
254    CFX_AffineMatrix*	m_pDisplayMatrix;
255    int					m_CurrNum;
256    IFX_FontEncoding*	m_pFontEncoding;
257    CFX_RenderDevice*	m_pFXDevice;
258    int					m_DitherBits;
259    FX_COLORREF			m_DisplayColor;
260    typedef struct CRF_TextDataAtt {
261        CRF_TextDataAtt()
262        {
263            pFont = NULL;
264            fFontSize = 0.0f;
265            Color = 0;
266        }
267        CRF_TextDataAtt(CPDF_Font* font, FX_FLOAT fontSize, FX_ARGB color)
268        {
269            pFont = font;
270            fFontSize = fontSize;
271            Color = color;
272        }
273        CPDF_Font*  pFont;
274        FX_FLOAT    fFontSize;
275        FX_ARGB		Color;
276    } CRF_TEXTDATAATT;
277    inline bool isTextDataAttSame(CRF_TEXTDATAATT data1, CRF_TEXTDATAATT data2)
278    {
279        if (data1.pFont != data2.pFont) {
280            return false;
281        }
282        if (data1.Color != data2.Color) {
283            return false;
284        }
285        if (fabs(data1.fFontSize - data2.fFontSize) > 0.0f) {
286            return false;
287        }
288        return true;
289    };
290};
291#define TYPE_UNKNOW		0
292#define TYPE_TEXT		1
293#define TYPE_PATH		2
294#define TYPE_IMAGE		3
295#define TYPE_LINE		4
296class CRF_Data
297{
298public:
299    typedef enum {Unknow, Text, Image, Path, Line, paragraph} RF_DataType;
300    CRF_Data()
301    {
302        m_Type = Unknow;
303        m_Width = 0;
304        m_PosY = 0;
305        m_PosX = 0;
306        m_Height = 0;
307    }
308    RF_DataType	GetType()
309    {
310        return m_Type;
311    }
312    virtual		~CRF_Data() {}
313    RF_DataType 	m_Type;
314    FX_FLOAT	m_PosX;
315    FX_FLOAT	m_PosY;
316    FX_FLOAT	m_Width;
317    FX_FLOAT	m_Height;
318};
319class CRF_LineData : public CRF_Data
320{
321public:
322    CRF_LineData()
323    {
324        m_Type = Line;
325    }
326};
327class CRF_CharData : public CRF_Data
328{
329public:
330    CRF_CharData()
331    {
332        m_Type = Text;
333        m_CharCode = -1;
334    }
335    CRF_CharState*	m_pCharState;
336    FX_DWORD		m_CharCode;
337};
338class CRF_ImageData : public CRF_Data
339{
340public:
341    CRF_ImageData()
342    {
343        m_Type = Image;
344        m_pBitmap = NULL;
345    }
346    ~CRF_ImageData()
347    {
348        if(m_pBitmap) {
349            delete m_pBitmap;
350        }
351        m_pBitmap = NULL;
352    }
353    CFX_AffineMatrix m_Matrix;
354    CFX_DIBitmap*	m_pBitmap;
355};
356class CRF_PathData : public CRF_Data
357{
358public:
359    CRF_PathData()
360    {
361        m_Type = Path;
362        m_bDecoration = FALSE;
363    }
364    ~CRF_PathData() {};
365    FX_BOOL			m_bDecoration;
366    CPDF_Path			m_pPathData;
367    CFX_AffineMatrix	m_pPath2Device;
368    CPDF_GraphState		m_pGraphState;
369    FX_ARGB		m_fill_argb;
370    FX_ARGB		m_stroke_argb;
371    int			m_fill_mode;
372};
373
374#endif  // CORE_SRC_REFLOW_REFLOWEDPAGE_H_
375