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
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
\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
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
21 class CXFA_CSSTagProvider : public IFDE_CSSTagProvider, public CFX_Object
\r
24 CXFA_CSSTagProvider ()
\r
25 : m_bTagAviliable(FALSE),
\r
28 virtual ~CXFA_CSSTagProvider();
\r
29 virtual CFX_WideStringC GetTagName()
\r
33 virtual FX_POSITION GetFirstAttribute()
\r
35 return m_Attributes.GetStartPosition();
\r
37 virtual void GetNextAttribute(FX_POSITION &pos, CFX_WideStringC &wsAttr, CFX_WideStringC &wsValue);
\r
38 void SetTagNameObj(const CFX_WideString &wsName)
\r
40 m_wsTagName = wsName;
\r
42 void SetAttribute(const CFX_WideString &wsAttr, const CFX_WideString &wsValue);
\r
43 FX_BOOL m_bTagAviliable;
\r
46 CFX_WideString m_wsTagName;
\r
47 CFX_MapPtrToPtr m_Attributes;
\r
49 class CXFA_TextParseContext : public CFX_Target
\r
52 CXFA_TextParseContext() : m_ppMatchedDecls(NULL), m_dwMatchedDecls(0), m_eDisplay(FDE_CSSDISPLAY_None), m_pParentStyle(NULL) {}
\r
53 ~CXFA_TextParseContext()
\r
55 if (m_ppMatchedDecls != NULL) {
\r
56 FDE_Free(m_ppMatchedDecls);
\r
59 void SetDisplay(FDE_CSSDISPLAY eDisplay)
\r
61 m_eDisplay = eDisplay;
\r
63 FDE_CSSDISPLAY GetDisplay() const
\r
67 void SetDecls(const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount);
\r
68 const IFDE_CSSDeclaration** GetDecls()
\r
70 return (const IFDE_CSSDeclaration**)m_ppMatchedDecls;
\r
72 FX_DWORD CountDecls() const
\r
74 return m_dwMatchedDecls;
\r
76 IFDE_CSSComputedStyle * m_pParentStyle;
\r
78 IFDE_CSSDeclaration **m_ppMatchedDecls;
\r
79 FX_DWORD m_dwMatchedDecls : 28;
\r
80 FDE_CSSDISPLAY m_eDisplay : 4;
\r
82 class CXFA_TextParser : public CFX_Object
\r
85 CXFA_TextParser() : m_pAllocator(NULL), m_pSelector(NULL), m_pUASheet(NULL) {}
\r
86 virtual ~CXFA_TextParser();
\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
93 return m_pAllocator != NULL;
\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
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
123 class CXFA_LoaderContext : public CFX_Object
\r
126 CXFA_LoaderContext() : m_bSaveLineHeight(FALSE)
\r
130 , m_fStartLineOffset(0)
\r
132 , m_iTotalLines(-1)
\r
135 , m_pParentStyle(NULL)
\r
138 FX_BOOL m_bSaveLineHeight;
\r
140 FX_FLOAT m_fHeight;
\r
141 FX_FLOAT m_fLastPos;
\r
142 FX_FLOAT m_fStartLineOffset;
\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
153 class CXFA_LinkUserData : public IFX_Unknown, public CFX_Target
\r
156 CXFA_LinkUserData(IFX_MEMAllocator *pAllocator, FX_LPWSTR pszText)
\r
157 : m_pAllocator(pAllocator)
\r
160 m_pszURLContent = pszText;
\r
162 ~CXFA_LinkUserData() { }
\r
163 virtual FX_DWORD Release()
\r
165 FX_DWORD dwRefCount = --m_dwRefCount;
\r
166 if (dwRefCount <= 0) {
\r
167 FDE_DeleteWith(CXFA_LinkUserData, m_pAllocator, this);
\r
171 virtual FX_DWORD AddRef()
\r
173 return ++m_dwRefCount;
\r
176 FX_LPCWSTR GetLinkURL()
\r
178 return m_pszURLContent;
\r
181 IFX_MEMAllocator *m_pAllocator;
\r
182 FX_DWORD m_dwRefCount;
\r
183 CFX_WideString m_pszURLContent;
\r
185 class CXFA_TextUserData : public IFX_Unknown, public CFX_Target
\r
188 CXFA_TextUserData(IFX_MEMAllocator *pAllocator, IFDE_CSSComputedStyle *pStyle)
\r
190 , m_pAllocator(pAllocator)
\r
192 , m_pLinkData(NULL)
\r
194 FXSYS_assert(m_pAllocator != NULL);
\r
195 if (m_pStyle != NULL) {
\r
196 m_pStyle->AddRef();
\r
199 CXFA_TextUserData(IFX_MEMAllocator *pAllocator, IFDE_CSSComputedStyle *pStyle, CXFA_LinkUserData* pLinkData)
\r
201 , m_pAllocator(pAllocator)
\r
203 , m_pLinkData(pLinkData)
\r
205 FXSYS_assert(m_pAllocator != NULL);
\r
206 if (m_pStyle != NULL) {
\r
207 m_pStyle->AddRef();
\r
210 ~CXFA_TextUserData()
\r
212 if (m_pStyle != NULL) {
\r
213 m_pStyle->Release();
\r
215 if (m_pLinkData != NULL) {
\r
216 m_pLinkData->Release();
\r
219 virtual FX_DWORD Release()
\r
221 FX_DWORD dwRefCount = --m_dwRefCount;
\r
222 if (dwRefCount == 0) {
\r
223 FDE_DeleteWith(CXFA_TextUserData, m_pAllocator, this);
\r
227 virtual FX_DWORD AddRef()
\r
229 return ++m_dwRefCount;
\r
232 IFDE_CSSComputedStyle *m_pStyle;
\r
233 CXFA_LinkUserData *m_pLinkData;
\r
235 IFX_MEMAllocator *m_pAllocator;
\r
236 FX_DWORD m_dwRefCount;
\r
238 typedef struct _XFA_TEXTPIECE : public CFX_Target {
\r
242 FX_INT32 iHorScale;
\r
243 FX_INT32 iVerScale;
\r
244 FX_INT32 iBidiLevel;
\r
245 FX_INT32 iUnderline;
\r
247 FX_INT32 iLineThrough;
\r
250 FX_FLOAT fFontSize;
\r
252 CXFA_LinkUserData* pLinkData;
\r
254 _XFA_TEXTPIECE() : pszText(NULL), pFont(NULL), pLinkData(NULL)
\r
261 if (NULL != pLinkData) {
\r
262 pLinkData->Release();
\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
272 CXFA_PieceLine() {}
\r
273 CXFA_PieceArray m_textPieces;
\r
274 CFX_Int32Array m_charCounts;
\r
276 typedef CFX_ArrayTemplate<CXFA_PieceLine*> CXFA_PieceLineArray;
\r
277 struct XFA_TABSTOPS {
\r
279 FX_FLOAT fTabstops;
\r
281 class CXFA_TextTabstopsContext : public CFX_Object
\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
288 for (i = 0; i < m_iTabCount; i++) {
\r
289 XFA_TABSTOPS *pTabstop = m_tabstops.GetDataPtr(i);
\r
290 if (fTabstops < pTabstop->fTabstops) {
\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
303 m_tabstops.RemoveAll();
\r
309 m_bTabstops = FALSE;
\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
320 class CXFA_TextLayout : public CFX_Object
\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
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
335 FX_BOOL IsLoaded() const
\r
337 return m_pieceLines.GetSize() > 0;
\r
340 const CXFA_PieceLineArray* GetPieceLines();
\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
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
352 FX_BOOL AppendChar(const CFX_WideString &wsText, FX_FLOAT &fLinePos, FX_FLOAT fSpaceAbove, FX_BOOL bSavePieces);
\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
358 void ProcessText(CFX_WideString &wsText);
\r
359 void UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom);
\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
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
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
379 CXFA_LoaderContext *m_pLoader;
\r
381 FX_FLOAT m_fMaxWidth;
\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
388 FX_BOOL m_bHasBlock;
\r
389 CFX_Int32Array m_Blocks;
\r