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 XFA_FGAS_LAYOUT_FGAS_RTFBREAK_H_
8 #define XFA_FGAS_LAYOUT_FGAS_RTFBREAK_H_
9 
10 #include <deque>
11 #include <vector>
12 
13 #include "core/fxcrt/cfx_retain_ptr.h"
14 #include "core/fxcrt/fx_basic.h"
15 #include "core/fxcrt/fx_ucd.h"
16 #include "xfa/fgas/crt/fgas_utils.h"
17 #include "xfa/fgas/layout/fgas_textbreak.h"
18 
19 class CFGAS_GEFont;
20 
21 #define FX_RTFLAYOUTSTYLE_Pagination 0x01
22 #define FX_RTFLAYOUTSTYLE_ExpandTab 0x10
23 
24 enum class CFX_RTFLineAlignment {
25   Left = 0,
26   Center,
27   Right,
28   Justified,
29   Distributed
30 };
31 
32 struct FX_RTFTEXTOBJ {
33   FX_RTFTEXTOBJ();
34   ~FX_RTFTEXTOBJ();
35 
36   CFX_WideString pStr;
37   std::vector<int32_t> pWidths;
38   CFX_RetainPtr<CFGAS_GEFont> pFont;
39   const CFX_RectF* pRect;
40   FX_WCHAR wLineBreakChar;
41   FX_FLOAT fFontSize;
42   int32_t iLength;
43   int32_t iBidiLevel;
44   int32_t iHorizontalScale;
45   int32_t iVerticalScale;
46 };
47 
48 class CFX_RTFPiece {
49  public:
50   CFX_RTFPiece();
51   ~CFX_RTFPiece();
52 
GetEndPos()53   int32_t GetEndPos() const {
54     return m_iWidth < 0 ? m_iStartPos : m_iStartPos + m_iWidth;
55   }
56 
GetChar(int32_t index)57   CFX_RTFChar& GetChar(int32_t index) {
58     ASSERT(index > -1 && index < m_iChars && m_pChars);
59     return (*m_pChars)[m_iStartChar + index];
60   }
61 
GetString()62   CFX_WideString GetString() const {
63     CFX_WideString ret;
64     ret.Reserve(m_iChars);
65     for (int32_t i = m_iStartChar; i < m_iStartChar + m_iChars; i++)
66       ret += static_cast<FX_WCHAR>((*m_pChars)[i].m_wCharCode);
67     return ret;
68   }
69 
GetWidths()70   std::vector<int32_t> GetWidths() const {
71     std::vector<int32_t> ret;
72     ret.reserve(m_iChars);
73     for (int32_t i = m_iStartChar; i < m_iStartChar + m_iChars; i++)
74       ret.push_back((*m_pChars)[i].m_iCharWidth);
75     return ret;
76   }
77 
Reset()78   void Reset() {
79     m_dwStatus = CFX_RTFBreakType::Piece;
80     if (m_iWidth > -1)
81       m_iStartPos += m_iWidth;
82 
83     m_iWidth = -1;
84     m_iStartChar += m_iChars;
85     m_iChars = 0;
86     m_iBidiLevel = 0;
87     m_iBidiPos = 0;
88     m_iHorizontalScale = 100;
89     m_iVerticalScale = 100;
90   }
91 
92   CFX_RTFBreakType m_dwStatus;
93   int32_t m_iStartPos;
94   int32_t m_iWidth;
95   int32_t m_iStartChar;
96   int32_t m_iChars;
97   int32_t m_iBidiLevel;
98   int32_t m_iBidiPos;
99   int32_t m_iFontSize;
100   int32_t m_iFontHeight;
101   int32_t m_iHorizontalScale;
102   int32_t m_iVerticalScale;
103   uint32_t m_dwIdentity;
104   std::vector<CFX_RTFChar>* m_pChars;  // not owned.
105   CFX_RetainPtr<CFX_Retainable> m_pUserData;
106 };
107 
108 typedef CFX_BaseArrayTemplate<CFX_RTFPiece> CFX_RTFPieceArray;
109 
110 class CFX_RTFLine {
111  public:
112   CFX_RTFLine();
113   ~CFX_RTFLine();
114 
CountChars()115   int32_t CountChars() const {
116     return pdfium::CollectionSize<int32_t>(m_LineChars);
117   }
118 
GetChar(int32_t index)119   CFX_RTFChar& GetChar(int32_t index) {
120     ASSERT(index >= 0 && index < pdfium::CollectionSize<int32_t>(m_LineChars));
121     return m_LineChars[index];
122   }
123 
GetLineEnd()124   int32_t GetLineEnd() const { return m_iStart + m_iWidth; }
RemoveAll(bool bLeaveMemory)125   void RemoveAll(bool bLeaveMemory) {
126     m_LineChars.clear();
127     m_LinePieces.RemoveAll(bLeaveMemory);
128     m_iWidth = 0;
129     m_iArabicChars = 0;
130     m_iMBCSChars = 0;
131   }
132 
133   std::vector<CFX_RTFChar> m_LineChars;
134   CFX_RTFPieceArray m_LinePieces;
135   int32_t m_iStart;
136   int32_t m_iWidth;
137   int32_t m_iArabicChars;
138   int32_t m_iMBCSChars;
139 };
140 
141 class CFX_RTFBreak {
142  public:
143   explicit CFX_RTFBreak(uint32_t dwLayoutStyles);
144   ~CFX_RTFBreak();
145 
146   void SetLineBoundary(FX_FLOAT fLineStart, FX_FLOAT fLineEnd);
147   void SetLineStartPos(FX_FLOAT fLinePos);
148   void SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont);
149   void SetFontSize(FX_FLOAT fFontSize);
150   void SetTabWidth(FX_FLOAT fTabWidth);
151   void SetLineBreakTolerance(FX_FLOAT fTolerance);
152   void SetHorizontalScale(int32_t iScale);
153   void SetVerticalScale(int32_t iScale);
154   void SetCharSpace(FX_FLOAT fCharSpace);
SetAlignment(CFX_RTFLineAlignment align)155   void SetAlignment(CFX_RTFLineAlignment align) { m_iAlignment = align; }
156   void SetUserData(const CFX_RetainPtr<CFX_Retainable>& pUserData);
157 
158   void AddPositionedTab(FX_FLOAT fTabPos);
159 
160   CFX_RTFBreakType EndBreak(CFX_RTFBreakType dwStatus);
161   int32_t CountBreakPieces() const;
162   const CFX_RTFPiece* GetBreakPiece(int32_t index) const;
163   void ClearBreakPieces();
164 
165   void Reset();
166 
167   int32_t GetDisplayPos(const FX_RTFTEXTOBJ* pText,
168                         FXTEXT_CHARPOS* pCharPos,
169                         bool bCharCode) const;
170 
171   CFX_RTFBreakType AppendChar(FX_WCHAR wch);
172   CFX_RTFBreakType AppendChar_Combination(CFX_RTFChar* pCurChar);
173   CFX_RTFBreakType AppendChar_Tab(CFX_RTFChar* pCurChar);
174   CFX_RTFBreakType AppendChar_Control(CFX_RTFChar* pCurChar);
175   CFX_RTFBreakType AppendChar_Arabic(CFX_RTFChar* pCurChar);
176   CFX_RTFBreakType AppendChar_Others(CFX_RTFChar* pCurChar);
177 
178  private:
179   void FontChanged();
180   void SetBreakStatus();
181   CFX_RTFChar* GetLastChar(int32_t index) const;
182   const CFX_RTFLine* GetRTFLine() const;
183   const CFX_RTFPieceArray* GetRTFPieces() const;
184   FX_CHARTYPE GetUnifiedCharType(FX_CHARTYPE chartype) const;
185   int32_t GetLastPositionedTab() const;
186   bool GetPositionedTab(int32_t* iTabPos) const;
187 
188   int32_t GetBreakPos(std::vector<CFX_RTFChar>& tca,
189                       int32_t& iEndPos,
190                       bool bAllChars,
191                       bool bOnlyBrk);
192   void SplitTextLine(CFX_RTFLine* pCurLine,
193                      CFX_RTFLine* pNextLine,
194                      bool bAllChars);
195   bool EndBreak_SplitLine(CFX_RTFLine* pNextLine,
196                           bool bAllChars,
197                           CFX_RTFBreakType dwStatus);
198   void EndBreak_BidiLine(std::deque<FX_TPO>* tpos, CFX_RTFBreakType dwStatus);
199   void EndBreak_Alignment(const std::deque<FX_TPO>& tpos,
200                           bool bAllChars,
201                           CFX_RTFBreakType dwStatus);
202 
203   int32_t m_iBoundaryStart;
204   int32_t m_iBoundaryEnd;
205   uint32_t m_dwLayoutStyles;
206   bool m_bPagination;
207   CFX_RetainPtr<CFGAS_GEFont> m_pFont;
208   int32_t m_iFontHeight;
209   int32_t m_iFontSize;
210   int32_t m_iTabWidth;
211   std::vector<int32_t> m_PositionedTabs;
212   FX_WCHAR m_wDefChar;
213   int32_t m_iDefChar;
214   FX_WCHAR m_wLineBreakChar;
215   int32_t m_iHorizontalScale;
216   int32_t m_iVerticalScale;
217   int32_t m_iCharSpace;
218   CFX_RTFLineAlignment m_iAlignment;
219   CFX_RetainPtr<CFX_Retainable> m_pUserData;
220   FX_CHARTYPE m_eCharType;
221   uint32_t m_dwIdentity;
222   CFX_RTFLine m_RTFLine1;
223   CFX_RTFLine m_RTFLine2;
224   CFX_RTFLine* m_pCurLine;
225   int32_t m_iReady;
226   int32_t m_iTolerance;
227 };
228 
229 #endif  // XFA_FGAS_LAYOUT_FGAS_RTFBREAK_H_
230