Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fxfa / src / app / xfa_textlayout.h
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #ifndef _FXFA_TEXTLAYOUT_H\r
8 #define _FXFA_TEXTLAYOUT_H\r
9 #define XFA_LOADERCNTXTFLG_FILTERSPACE                  0x001\r
10 class CXFA_TextTabstopsContext;\r
11 class IXFA_TextProvider\r
12 {\r
13 public:\r
14     virtual CXFA_Node*                  GetTextNode(FX_BOOL &bRichText) = 0;\r
15     virtual CXFA_Para                   GetParaNode() = 0;\r
16     virtual CXFA_Font                   GetFontNode() = 0;\r
17     virtual FX_BOOL                             IsCheckButtonAndAutoWidth() = 0;\r
18     virtual     CXFA_FFDoc*                     GetDocNode() = 0;\r
19     virtual FX_BOOL                             GetEmbbedObj(FX_BOOL bURI, FX_BOOL bRaw, const CFX_WideString &wsAttr, CFX_WideString &wsValue) = 0;\r
20 };\r
21 class CXFA_CSSTagProvider : public IFDE_CSSTagProvider, public CFX_Object\r
22 {\r
23 public:\r
24     CXFA_CSSTagProvider ()\r
25         : m_bTagAviliable(FALSE),\r
26           m_bContent(FALSE)\r
27     {}\r
28     virtual ~CXFA_CSSTagProvider();\r
29     virtual CFX_WideStringC             GetTagName()\r
30     {\r
31         return m_wsTagName;\r
32     }\r
33     virtual FX_POSITION                 GetFirstAttribute()\r
34     {\r
35         return m_Attributes.GetStartPosition();\r
36     }\r
37     virtual void                                GetNextAttribute(FX_POSITION &pos, CFX_WideStringC &wsAttr, CFX_WideStringC &wsValue);\r
38     void                                                SetTagNameObj(const CFX_WideString &wsName)\r
39     {\r
40         m_wsTagName = wsName;\r
41     }\r
42     void                                                SetAttribute(const CFX_WideString &wsAttr, const CFX_WideString &wsValue);\r
43     FX_BOOL                                     m_bTagAviliable;\r
44     FX_BOOL                                     m_bContent;\r
45 protected:\r
46     CFX_WideString                      m_wsTagName;\r
47     CFX_MapPtrToPtr                     m_Attributes;\r
48 };\r
49 class CXFA_TextParseContext : public CFX_Target\r
50 {\r
51 public:\r
52     CXFA_TextParseContext() : m_ppMatchedDecls(NULL), m_dwMatchedDecls(0), m_eDisplay(FDE_CSSDISPLAY_None), m_pParentStyle(NULL) {}\r
53     ~CXFA_TextParseContext()\r
54     {\r
55         if (m_ppMatchedDecls != NULL) {\r
56             FDE_Free(m_ppMatchedDecls);\r
57         }\r
58     }\r
59     void                                                SetDisplay(FDE_CSSDISPLAY eDisplay)\r
60     {\r
61         m_eDisplay = eDisplay;\r
62     }\r
63     FDE_CSSDISPLAY                              GetDisplay() const\r
64     {\r
65         return m_eDisplay;\r
66     }\r
67     void                                                SetDecls(const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount);\r
68     const IFDE_CSSDeclaration** GetDecls()\r
69     {\r
70         return (const IFDE_CSSDeclaration**)m_ppMatchedDecls;\r
71     }\r
72     FX_DWORD                                    CountDecls() const\r
73     {\r
74         return m_dwMatchedDecls;\r
75     }\r
76     IFDE_CSSComputedStyle *             m_pParentStyle;\r
77 protected:\r
78     IFDE_CSSDeclaration         **m_ppMatchedDecls;\r
79     FX_DWORD                            m_dwMatchedDecls : 28;\r
80     FDE_CSSDISPLAY                      m_eDisplay               : 4;\r
81 };\r
82 class CXFA_TextParser : public CFX_Object\r
83 {\r
84 public:\r
85     CXFA_TextParser() : m_pAllocator(NULL), m_pSelector(NULL), m_pUASheet(NULL) {}\r
86     virtual ~CXFA_TextParser();\r
87     void                                                Reset();\r
88     void                                                DoParse(IFDE_XMLNode *pXMLContainer, IXFA_TextProvider *pTextProvider);\r
89     IFDE_CSSComputedStyle*              CreateRootStyle(IXFA_TextProvider *pTextProvider);\r
90     IFDE_CSSComputedStyle*              ComputeStyle(IFDE_XMLNode *pXMLNode, IFDE_CSSComputedStyle *pParentStyle);\r
91     FX_BOOL                                             IsParsed() const\r
92     {\r
93         return m_pAllocator != NULL;\r
94     }\r
95 \r
96     FX_INT32                                    GetVAlgin(IXFA_TextProvider *pTextProvider) const;\r
97     FX_FLOAT                                    GetTabInterval(IFDE_CSSComputedStyle *pStyle) const;\r
98     FX_INT32                                    CountTabs(IFDE_CSSComputedStyle *pStyle) const;\r
99     FX_BOOL                                             IsSpaceRun(IFDE_CSSComputedStyle *pStyle) const;\r
100     FX_BOOL                                             GetTabstops(IFDE_CSSComputedStyle *pStyle, CXFA_TextTabstopsContext     *pTabstopContext);\r
101     IFX_Font*                                   GetFont(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const;\r
102     FX_FLOAT                                    GetFontSize(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const;\r
103     FX_INT32                                    GetHorScale(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle, IFDE_XMLNode *pXMLNode) const;\r
104     FX_INT32                                    GetVerScale(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const;\r
105     void                                                GetUnderline(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle, FX_INT32 &iUnderline, FX_INT32 &iPeriod) const;\r
106     void                                                GetLinethrough(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle, FX_INT32 &iLinethrough) const;\r
107     FX_ARGB                                             GetColor(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const;\r
108     FX_FLOAT                                    GetBaseline(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const;\r
109     FX_FLOAT                                    GetLineHeight(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle, FX_BOOL bFirst, FX_FLOAT fVerScale) const;\r
110     FX_BOOL                                             GetEmbbedObj(IXFA_TextProvider *pTextProvider, IFDE_XMLNode *pXMLNode, CFX_WideString &wsValue);\r
111     CXFA_TextParseContext*              GetParseContextFromMap(IFDE_XMLNode *pXMLNode);\r
112 private:\r
113     void                                                InitCSSData(IXFA_TextProvider *pTextProvider);\r
114     void                                                ParseRichText(IFDE_XMLNode *pXMLNode, IFDE_CSSComputedStyle *pParentStyle);\r
115     void                                                ParseTagInfo(IFDE_XMLNode *pXMLNode, CXFA_CSSTagProvider &tagProvider);\r
116     IFDE_CSSStyleSheet*                 LoadDefaultSheetStyle();\r
117     IFDE_CSSComputedStyle*              CreateStyle(IFDE_CSSComputedStyle *pParentStyle);\r
118     IFX_MEMAllocator            *m_pAllocator;\r
119     IFDE_CSSStyleSelector       *m_pSelector;\r
120     IFDE_CSSStyleSheet          *m_pUASheet;\r
121     CFX_MapPtrTemplate<IFDE_XMLNode*, CXFA_TextParseContext*>   m_mapXMLNodeToParseContext;\r
122 };\r
123 class CXFA_LoaderContext : public CFX_Object\r
124 {\r
125 public:\r
126     CXFA_LoaderContext() : m_bSaveLineHeight(FALSE)\r
127         , m_fWidth(0)\r
128         , m_fHeight(0)\r
129         , m_fLastPos(0)\r
130         , m_fStartLineOffset(0)\r
131         , m_iChar(0)\r
132         , m_iTotalLines(-1)\r
133         , m_pXMLNode(NULL)\r
134         , m_pNode(NULL)\r
135         , m_pParentStyle(NULL)\r
136         , m_dwFlags(0)\r
137     {}\r
138     FX_BOOL                             m_bSaveLineHeight;\r
139     FX_FLOAT                    m_fWidth;\r
140     FX_FLOAT                    m_fHeight;\r
141     FX_FLOAT                    m_fLastPos;\r
142     FX_FLOAT                    m_fStartLineOffset;\r
143     FX_INT32                    m_iChar;\r
144     FX_INT32                    m_iLines;\r
145     FX_INT32                    m_iTotalLines;\r
146     IFDE_XMLNode                *m_pXMLNode;\r
147     CXFA_Node                   *m_pNode;\r
148     IFDE_CSSComputedStyle               *m_pParentStyle;\r
149     CFX_ArrayTemplate<FX_FLOAT> m_lineHeights;\r
150     FX_DWORD                    m_dwFlags;\r
151     CFX_FloatArray              m_BlocksHeight;\r
152 };\r
153 class CXFA_LinkUserData : public IFX_Unknown, public CFX_Target\r
154 {\r
155 public:\r
156     CXFA_LinkUserData(IFX_MEMAllocator *pAllocator, FX_LPWSTR pszText)\r
157         : m_pAllocator(pAllocator)\r
158         , m_dwRefCount(1)\r
159     {\r
160         m_pszURLContent = pszText;\r
161     }\r
162     ~CXFA_LinkUserData() { }\r
163     virtual FX_DWORD    Release()\r
164     {\r
165         FX_DWORD dwRefCount = --m_dwRefCount;\r
166         if (dwRefCount <= 0) {\r
167             FDE_DeleteWith(CXFA_LinkUserData, m_pAllocator, this);\r
168         }\r
169         return dwRefCount;\r
170     }\r
171     virtual FX_DWORD    AddRef()\r
172     {\r
173         return ++m_dwRefCount;\r
174     }\r
175 public:\r
176     FX_LPCWSTR GetLinkURL()\r
177     {\r
178         return m_pszURLContent;\r
179     };\r
180 protected:\r
181     IFX_MEMAllocator            *m_pAllocator;\r
182     FX_DWORD                            m_dwRefCount;\r
183     CFX_WideString                      m_pszURLContent;\r
184 };\r
185 class CXFA_TextUserData : public IFX_Unknown, public CFX_Target\r
186 {\r
187 public:\r
188     CXFA_TextUserData(IFX_MEMAllocator *pAllocator, IFDE_CSSComputedStyle *pStyle)\r
189         : m_pStyle(pStyle)\r
190         , m_pAllocator(pAllocator)\r
191         , m_dwRefCount(0)\r
192         , m_pLinkData(NULL)\r
193     {\r
194         FXSYS_assert(m_pAllocator != NULL);\r
195         if (m_pStyle != NULL) {\r
196             m_pStyle->AddRef();\r
197         }\r
198     }\r
199     CXFA_TextUserData(IFX_MEMAllocator *pAllocator, IFDE_CSSComputedStyle *pStyle, CXFA_LinkUserData* pLinkData)\r
200         : m_pStyle(pStyle)\r
201         , m_pAllocator(pAllocator)\r
202         , m_dwRefCount(0)\r
203         , m_pLinkData(pLinkData)\r
204     {\r
205         FXSYS_assert(m_pAllocator != NULL);\r
206         if (m_pStyle != NULL) {\r
207             m_pStyle->AddRef();\r
208         }\r
209     }\r
210     ~CXFA_TextUserData()\r
211     {\r
212         if (m_pStyle != NULL) {\r
213             m_pStyle->Release();\r
214         }\r
215         if (m_pLinkData != NULL) {\r
216             m_pLinkData->Release();\r
217         }\r
218     }\r
219     virtual FX_DWORD    Release()\r
220     {\r
221         FX_DWORD dwRefCount = --m_dwRefCount;\r
222         if (dwRefCount == 0) {\r
223             FDE_DeleteWith(CXFA_TextUserData, m_pAllocator, this);\r
224         }\r
225         return dwRefCount;\r
226     }\r
227     virtual FX_DWORD    AddRef()\r
228     {\r
229         return ++m_dwRefCount;\r
230     }\r
231 \r
232     IFDE_CSSComputedStyle       *m_pStyle;\r
233     CXFA_LinkUserData           *m_pLinkData;\r
234 protected:\r
235     IFX_MEMAllocator                    *m_pAllocator;\r
236     FX_DWORD                            m_dwRefCount;\r
237 };\r
238 typedef struct _XFA_TEXTPIECE : public CFX_Target {\r
239     FX_LPWSTR           pszText;\r
240     FX_INT32            iChars;\r
241     FX_INT32            *pWidths;\r
242     FX_INT32            iHorScale;\r
243     FX_INT32            iVerScale;\r
244     FX_INT32            iBidiLevel;\r
245     FX_INT32            iUnderline;\r
246     FX_INT32            iPeriod;\r
247     FX_INT32            iLineThrough;\r
248     IFX_Font            *pFont;\r
249     FX_ARGB                     dwColor;\r
250     FX_FLOAT            fFontSize;\r
251     CFX_RectF           rtPiece;\r
252     CXFA_LinkUserData*  pLinkData;\r
253 \r
254     _XFA_TEXTPIECE() : pszText(NULL), pFont(NULL), pLinkData(NULL)\r
255     {\r
256         pszText = NULL;\r
257     }\r
258     ~_XFA_TEXTPIECE()\r
259     {\r
260         pszText = NULL;\r
261         if (NULL != pLinkData) {\r
262             pLinkData->Release();\r
263             pLinkData = NULL;\r
264         }\r
265     }\r
266 } XFA_TEXTPIECE, * XFA_LPTEXTPIECE;\r
267 typedef XFA_TEXTPIECE const * XFA_LPCTEXTPIECE;\r
268 typedef CFX_ArrayTemplate<XFA_LPTEXTPIECE>      CXFA_PieceArray;\r
269 class CXFA_PieceLine : public CFX_Target\r
270 {\r
271 public:\r
272     CXFA_PieceLine() {}\r
273     CXFA_PieceArray             m_textPieces;\r
274     CFX_Int32Array              m_charCounts;\r
275 };\r
276 typedef CFX_ArrayTemplate<CXFA_PieceLine*>      CXFA_PieceLineArray;\r
277 struct XFA_TABSTOPS {\r
278     FX_DWORD dwAlign;\r
279     FX_FLOAT fTabstops;\r
280 };\r
281 class CXFA_TextTabstopsContext : public CFX_Object\r
282 {\r
283 public:\r
284     CXFA_TextTabstopsContext() : m_iTabCount(0), m_iTabIndex(-1), m_bTabstops(FALSE), m_fTabWidth(0), m_fLeft(0) {}\r
285     void Append(FX_DWORD dwAlign, FX_FLOAT fTabstops)\r
286     {\r
287         FX_INT32 i = 0;\r
288         for (i = 0; i < m_iTabCount; i++) {\r
289             XFA_TABSTOPS *pTabstop = m_tabstops.GetDataPtr(i);\r
290             if (fTabstops < pTabstop->fTabstops) {\r
291                 break;\r
292             }\r
293         }\r
294         m_tabstops.InsertSpaceAt(i, 1);\r
295         XFA_TABSTOPS tabstop;\r
296         tabstop.dwAlign         = dwAlign;\r
297         tabstop.fTabstops       = fTabstops;\r
298         m_tabstops.SetAt(i, tabstop);\r
299         m_iTabCount++;\r
300     }\r
301     void RemoveAll()\r
302     {\r
303         m_tabstops.RemoveAll();\r
304         m_iTabCount = 0;\r
305     }\r
306     void Reset()\r
307     {\r
308         m_iTabIndex = -1;\r
309         m_bTabstops = FALSE;\r
310         m_fTabWidth = 0;\r
311         m_fLeft = 0;\r
312     }\r
313     CFX_ArrayTemplate<XFA_TABSTOPS>             m_tabstops;\r
314     FX_INT32            m_iTabCount;\r
315     FX_INT32            m_iTabIndex;\r
316     FX_BOOL                     m_bTabstops;\r
317     FX_FLOAT            m_fTabWidth;\r
318     FX_FLOAT            m_fLeft;\r
319 };\r
320 class CXFA_TextLayout : public CFX_Object\r
321 {\r
322 public:\r
323     CXFA_TextLayout(IXFA_TextProvider *pTextProvider);\r
324     virtual ~CXFA_TextLayout();\r
325     FX_INT32                    GetText(CFX_WideString &wsText);\r
326     FX_FLOAT                    GetLayoutHeight();\r
327     FX_FLOAT                    StartLayout(FX_FLOAT fWidth = -1);\r
328     FX_BOOL                             DoLayout(FX_INT32 iBlockIndex, FX_FLOAT &fCalcHeight, FX_FLOAT fContentAreaHeight = -1, FX_FLOAT fTextHeight = -1);\r
329 \r
330     FX_BOOL                             CalcSize(const CFX_SizeF &minSize, const CFX_SizeF &maxSize, CFX_SizeF &defaultSize);\r
331     FX_BOOL                             Layout(const CFX_SizeF &size, FX_FLOAT* fHeight = NULL);\r
332     void                                ItemBlocks(const CFX_RectF& rtText, FX_INT32 iBlockIndex);\r
333     FX_BOOL                             DrawString(CFX_RenderDevice *pFxDevice, const CFX_Matrix &tmDoc2Device, const CFX_RectF &rtClip, FX_INT32 iBlock = 0);\r
334 \r
335     FX_BOOL                             IsLoaded() const\r
336     {\r
337         return m_pieceLines.GetSize() > 0;\r
338     }\r
339     void                                Unload();\r
340     const CXFA_PieceLineArray*  GetPieceLines();\r
341 private:\r
342     void                                GetTextDataNode();\r
343     IFDE_XMLNode*               GetXMLContainerNode();\r
344     IFX_RTFBreak*               CreateBreak(FX_BOOL bDefault);\r
345     void                                InitBreak(FX_FLOAT fLineWidth);\r
346     void                                InitBreak(IFDE_CSSComputedStyle *pStyle, FDE_CSSDISPLAY eDisplay, FX_FLOAT fLineWidth, IFDE_XMLNode *pXMLNode, IFDE_CSSComputedStyle *pParentStyle = NULL);\r
347     FX_BOOL                             Loader(const CFX_SizeF &szText, FX_FLOAT &fLinePos, FX_BOOL bSavePieces = TRUE);\r
348 \r
349     void                                LoadText(CXFA_Node *pNode, const CFX_SizeF &szText, FX_FLOAT &fLinePos, FX_BOOL bSavePieces);\r
350     FX_BOOL                             LoadRichText(IFDE_XMLNode *pXMLNode, const CFX_SizeF &szText, FX_FLOAT &fLinePos, IFDE_CSSComputedStyle *pParentStyle, FX_BOOL bSavePieces, CXFA_LinkUserData* pLinkData = NULL, FX_BOOL bEndBreak = TRUE, FX_BOOL bIsOl = FALSE, FX_INT32 iLiCount = 0);\r
351 \r
352     FX_BOOL                             AppendChar(const CFX_WideString &wsText, FX_FLOAT &fLinePos,  FX_FLOAT fSpaceAbove, FX_BOOL bSavePieces);\r
353 \r
354     void                                AppendTextLine(FX_DWORD dwStatus, FX_FLOAT &fLinePos, FX_BOOL bSavePieces, FX_BOOL bEndBreak = FALSE);\r
355     void                                EndBreak(FX_DWORD dwStatus, FX_FLOAT &fLinePos, FX_BOOL bDefault);\r
356     FX_BOOL                             IsEnd(FX_BOOL bSavePieces);\r
357 \r
358     void                                ProcessText(CFX_WideString &wsText);\r
359     void                                UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom);\r
360 \r
361     void                                RenderString(IFDE_RenderDevice *pDevice, IFDE_SolidBrush *pBrush, CXFA_PieceLine *pPieceLine,\r
362                                      FX_INT32 iPiece, FXTEXT_CHARPOS *pCharPos, const CFX_Matrix &tmDoc2Device);\r
363     void                                RenderPath(IFDE_RenderDevice *pDevice, IFDE_Pen *pPen, CXFA_PieceLine *pPieceLine, FX_INT32 iPiece,\r
364                                    FXTEXT_CHARPOS *pCharPos, const CFX_Matrix &tmDoc2Device);\r
365 \r
366     FX_INT32                    GetDisplayPos(XFA_LPCTEXTPIECE pPiece, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode = FALSE);\r
367     FX_BOOL                             ToRun(XFA_LPCTEXTPIECE pPiece, FX_RTFTEXTOBJ &tr);\r
368 \r
369     void                                DoTabstops(IFDE_CSSComputedStyle *pStyle, CXFA_PieceLine *pPieceLine);\r
370     FX_BOOL                             Layout(FX_INT32 iBlock);\r
371     FX_INT32                    CountBlocks() const;\r
372     IXFA_TextProvider   *m_pTextProvider;\r
373     CXFA_Node                   *m_pTextDataNode;\r
374     FX_BOOL                             m_bRichText;\r
375     IFX_MEMAllocator    *m_pAllocator;\r
376     IFX_RTFBreak                *m_pBreak;\r
377     FX_DWORD                    m_dwTextData;\r
378 \r
379     CXFA_LoaderContext  *m_pLoader;\r
380     FX_INT32                    m_iLines;\r
381     FX_FLOAT                    m_fMaxWidth;\r
382 \r
383     CXFA_TextParser             m_textParser;\r
384     CXFA_PieceLineArray m_pieceLines;\r
385     CXFA_TextTabstopsContext    *m_pTabstopContext;\r
386     FX_BOOL                             m_bBlockContinue;\r
387 public:\r
388     FX_BOOL                             m_bHasBlock;\r
389     CFX_Int32Array              m_Blocks;\r
390 };\r
391 #endif\r