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) )
13 class CRF_Data;
14 class CRF_LineData;
15 class CRF_CharData;
16 class CRF_PathData;
17 class CRF_ImageData;
18 class CRF_Table;
19 class CRF_AttrOperation;
20 class CRF_OperationDate;
21 class CPDF_ReflowedPage;
22 class CPDF_Rect;
23 typedef CFX_SegmentedArray<CRF_Data*> CRF_DataPtrArray;
24 class CRF_CharState;
25 typedef 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
30 class CPDF_LayoutProcessor_Reflow : public IPDF_LayoutProcessor
31 {
32 public:
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();
40 protected:
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 };
96 struct 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 };
109 typedef CFX_ArrayTemplate<RF_TableCell*> CRF_TableCellArray;
110 class CRF_Table
111 {
112 public:
CRF_Table()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 };
124 class CRF_CharState
125 {
126 public:
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 };
136 class CRF_PageInfo
137 {
138 public:
139     CRF_PageInfo(CPDF_PageObject* pPageObj, CRF_PageInfo* pParent = NULL)
m_pPageObj(pPageObj)140         : m_pPageObj(pPageObj) , m_pParent(pParent)
141     {
142     }
GetPageObj()143     CPDF_PageObject* GetPageObj()
144     {
145         return m_pPageObj;
146     }
GetFormDict()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     }
158 protected:
159     CPDF_PageObject*		m_pPageObj;
160     CRF_PageInfo*			m_pParent;
161 };
162 class CPDF_ReflowedPage : public IPDF_ReflowedPage, public CFX_PrivateData
163 {
164 public:
165 
166     CPDF_ReflowedPage(CFX_GrowOnlyPool*	pMemoryPool);
167     ~CPDF_ReflowedPage();
GetPrivateDataCtrl()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() ;
GetPageWidth()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 };
196 class CPDF_ProgressiveReflowPageParser : public IPDF_ProgressiveReflowPageParser
197 {
198 public:
199     CPDF_ProgressiveReflowPageParser();
200     ~CPDF_ProgressiveReflowPageParser() ;
201     void			Init();
202 
GetStatus()203     ParseStatus		GetStatus()
204     {
205         return m_Status;
206     };
207 
SetParserStyle(RF_ParseStyle style)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;
218 protected:
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 };
231 class CPDF_ProgressiveReflowPageRender : public IPDF_ProgressiveReflowPageRender
232 {
233 public:
234     CPDF_ProgressiveReflowPageRender();
235     ~CPDF_ProgressiveReflowPageRender() ;
236 
GetStatus()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();
250 protected:
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 {
CRF_TextDataAttCRF_TextDataAtt261         CRF_TextDataAtt()
262         {
263             pFont = NULL;
264             fFontSize = 0.0f;
265             Color = 0;
266         }
CRF_TextDataAttCRF_TextDataAtt267         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;
isTextDataAttSame(CRF_TEXTDATAATT data1,CRF_TEXTDATAATT data2)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
296 class CRF_Data
297 {
298 public:
299     typedef enum {Unknow, Text, Image, Path, Line, paragraph} RF_DataType;
CRF_Data()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     }
GetType()308     RF_DataType	GetType()
309     {
310         return m_Type;
311     }
~CRF_Data()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 };
319 class CRF_LineData : public CRF_Data
320 {
321 public:
CRF_LineData()322     CRF_LineData()
323     {
324         m_Type = Line;
325     }
326 };
327 class CRF_CharData : public CRF_Data
328 {
329 public:
CRF_CharData()330     CRF_CharData()
331     {
332         m_Type = Text;
333         m_CharCode = -1;
334     }
335     CRF_CharState*	m_pCharState;
336     FX_DWORD		m_CharCode;
337 };
338 class CRF_ImageData : public CRF_Data
339 {
340 public:
CRF_ImageData()341     CRF_ImageData()
342     {
343         m_Type = Image;
344         m_pBitmap = NULL;
345     }
~CRF_ImageData()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 };
356 class CRF_PathData : public CRF_Data
357 {
358 public:
CRF_PathData()359     CRF_PathData()
360     {
361         m_Type = Path;
362         m_bDecoration = FALSE;
363     }
~CRF_PathData()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