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