Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: xfa/src/fde/tto/fde_textout.cpp

Issue 1803723002: Move xfa/src up to xfa/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase to master Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « xfa/src/fde/tto/fde_textout.h ('k') | xfa/src/fde/xml/fde_xml.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "xfa/src/fde/tto/fde_textout.h"
8
9 #include <algorithm>
10
11 #include "core/include/fxcrt/fx_coordinates.h"
12 #include "core/include/fxcrt/fx_system.h"
13 #include "xfa/src/fde/fde_brush.h"
14 #include "xfa/src/fde/fde_pen.h"
15 #include "xfa/src/fde/fde_renderdevice.h"
16 #include "xfa/src/fgas/crt/fgas_memory.h"
17 #include "xfa/src/fgas/crt/fgas_utils.h"
18 #include "xfa/src/fgas/layout/fgas_textbreak.h"
19
20 namespace {
21
22 struct FDE_TTOPIECE {
23 public:
24 int32_t iStartChar;
25 int32_t iChars;
26 FX_DWORD dwCharStyles;
27 CFX_RectF rtPiece;
28 };
29 typedef FDE_TTOPIECE* FDE_LPTTOPIECE;
30 typedef CFX_MassArrayTemplate<FDE_TTOPIECE> CFDE_TTOPieceArray;
31
32 class CFDE_TTOLine : public CFX_Target {
33 public:
34 CFDE_TTOLine();
35 CFDE_TTOLine(const CFDE_TTOLine& ttoLine);
36 ~CFDE_TTOLine();
37 int32_t AddPiece(int32_t index, const FDE_TTOPIECE& ttoPiece);
38 int32_t GetSize() const;
39 FDE_LPTTOPIECE GetPtrAt(int32_t index);
40 void RemoveLast(int32_t iCount);
41 void RemoveAll(FX_BOOL bLeaveMemory);
42 FX_BOOL m_bNewReload;
43 CFDE_TTOPieceArray m_pieces;
44
45 protected:
46 int32_t m_iPieceCount;
47 };
48 typedef CFX_ObjectMassArrayTemplate<CFDE_TTOLine> CFDE_TTOLineArray;
49
50 class CFDE_TextOut : public IFDE_TextOut, public CFX_Target {
51 public:
52 CFDE_TextOut();
53 ~CFDE_TextOut();
54 virtual void Release() { delete this; }
55 virtual void SetFont(IFX_Font* pFont);
56 virtual void SetFontSize(FX_FLOAT fFontSize);
57 virtual void SetTextColor(FX_ARGB color);
58 virtual void SetStyles(FX_DWORD dwStyles);
59 virtual void SetTabWidth(FX_FLOAT fTabWidth);
60 virtual void SetEllipsisString(const CFX_WideString& wsEllipsis);
61 virtual void SetParagraphBreakChar(FX_WCHAR wch);
62 virtual void SetAlignment(int32_t iAlignment);
63 virtual void SetLineSpace(FX_FLOAT fLineSpace);
64 virtual void SetDIBitmap(CFX_DIBitmap* pDIB);
65 virtual void SetRenderDevice(CFX_RenderDevice* pDevice);
66 virtual void SetClipRect(const CFX_Rect& rtClip);
67 virtual void SetClipRect(const CFX_RectF& rtClip);
68 virtual void SetMatrix(const CFX_Matrix& matrix);
69 virtual void SetLineBreakTolerance(FX_FLOAT fTolerance);
70 virtual void CalcSize(const FX_WCHAR* pwsStr,
71 int32_t iLength,
72 CFX_Size& size);
73 virtual void CalcSize(const FX_WCHAR* pwsStr,
74 int32_t iLength,
75 CFX_SizeF& size);
76 virtual void CalcSize(const FX_WCHAR* pwsStr,
77 int32_t iLength,
78 CFX_Rect& rect);
79 virtual void CalcSize(const FX_WCHAR* pwsStr,
80 int32_t iLength,
81 CFX_RectF& rect);
82
83 virtual void DrawText(const FX_WCHAR* pwsStr,
84 int32_t iLength,
85 int32_t x,
86 int32_t y);
87 virtual void DrawText(const FX_WCHAR* pwsStr,
88 int32_t iLength,
89 FX_FLOAT x,
90 FX_FLOAT y);
91 virtual void DrawText(const FX_WCHAR* pwsStr,
92 int32_t iLength,
93 const CFX_Rect& rect);
94 virtual void DrawText(const FX_WCHAR* pwsStr,
95 int32_t iLength,
96 const CFX_RectF& rect);
97
98 virtual void SetLogicClipRect(const CFX_RectF& rtClip);
99 virtual void CalcLogicSize(const FX_WCHAR* pwsStr,
100 int32_t iLength,
101 CFX_SizeF& size);
102 virtual void CalcLogicSize(const FX_WCHAR* pwsStr,
103 int32_t iLength,
104 CFX_RectF& rect);
105 virtual void DrawLogicText(const FX_WCHAR* pwsStr,
106 int32_t iLength,
107 FX_FLOAT x,
108 FX_FLOAT y);
109 virtual void DrawLogicText(const FX_WCHAR* pwsStr,
110 int32_t iLength,
111 const CFX_RectF& rect);
112 virtual int32_t GetTotalLines();
113
114 protected:
115 void CalcTextSize(const FX_WCHAR* pwsStr, int32_t iLength, CFX_RectF& rect);
116 FX_BOOL RetrieveLineWidth(FX_DWORD dwBreakStatus,
117 FX_FLOAT& fStartPos,
118 FX_FLOAT& fWidth,
119 FX_FLOAT& fHeight);
120 void SetLineWidth(CFX_RectF& rect);
121 void DrawText(const FX_WCHAR* pwsStr,
122 int32_t iLength,
123 const CFX_RectF& rect,
124 const CFX_RectF& rtClip);
125 void LoadText(const FX_WCHAR* pwsStr, int32_t iLength, const CFX_RectF& rect);
126 void LoadEllipsis();
127 void ExpandBuffer(int32_t iSize, int32_t iType);
128 void RetrieveEllPieces(int32_t*& pCharWidths);
129
130 void Reload(const CFX_RectF& rect);
131 void ReloadLinePiece(CFDE_TTOLine* pLine, const CFX_RectF& rect);
132 FX_BOOL RetriecePieces(FX_DWORD dwBreakStatus,
133 int32_t& iStartChar,
134 int32_t& iPieceWidths,
135 FX_BOOL bReload,
136 const CFX_RectF& rect);
137 void AppendPiece(const FDE_TTOPIECE& ttoPiece,
138 FX_BOOL bNeedReload,
139 FX_BOOL bEnd);
140 void ReplaceWidthEllipsis();
141 void DoAlignment(const CFX_RectF& rect);
142 void OnDraw(const CFX_RectF& rtClip);
143 int32_t GetDisplayPos(FDE_LPTTOPIECE pPiece);
144 int32_t GetCharRects(FDE_LPTTOPIECE pPiece);
145
146 void ToTextRun(const FDE_LPTTOPIECE pPiece, FX_TXTRUN& tr);
147 void DrawLine(const FDE_LPTTOPIECE pPiece, IFDE_Pen*& pPen);
148
149 IFX_TxtBreak* m_pTxtBreak;
150 IFX_Font* m_pFont;
151 FX_FLOAT m_fFontSize;
152 FX_FLOAT m_fLineSpace;
153 FX_FLOAT m_fLinePos;
154 FX_FLOAT m_fTolerance;
155 int32_t m_iAlignment;
156 int32_t m_iTxtBkAlignment;
157 int32_t* m_pCharWidths;
158 int32_t m_iChars;
159 int32_t* m_pEllCharWidths;
160 int32_t m_iEllChars;
161 FX_WCHAR m_wParagraphBkChar;
162 FX_ARGB m_TxtColor;
163 FX_DWORD m_dwStyles;
164 FX_DWORD m_dwTxtBkStyles;
165 CFX_WideString m_wsEllipsis;
166 FX_BOOL m_bElliChanged;
167 int32_t m_iEllipsisWidth;
168 CFX_WideString m_wsText;
169 CFX_RectF m_rtClip;
170 CFX_RectF m_rtLogicClip;
171 CFX_Matrix m_Matrix;
172 CFDE_TTOLineArray m_ttoLines;
173 int32_t m_iCurLine;
174 int32_t m_iCurPiece;
175 int32_t m_iTotalLines;
176 FXTEXT_CHARPOS* m_pCharPos;
177 int32_t m_iCharPosSize;
178 IFDE_RenderDevice* m_pRenderDevice;
179 CFX_Int32Array m_hotKeys;
180 CFX_RectFArray m_rectArray;
181 };
182
183 } // namespace
184
185 IFDE_TextOut* IFDE_TextOut::Create() {
186 return new CFDE_TextOut;
187 }
188 CFDE_TextOut::CFDE_TextOut()
189 : m_pFont(NULL),
190 m_fFontSize(12.0f),
191 m_fLineSpace(m_fFontSize),
192 m_fLinePos(0.0f),
193 m_fTolerance(0.0f),
194 m_iAlignment(0),
195 m_iTxtBkAlignment(0),
196 m_pCharWidths(NULL),
197 m_iChars(0),
198 m_pEllCharWidths(NULL),
199 m_iEllChars(0),
200 m_wParagraphBkChar(L'\n'),
201 m_TxtColor(0xFF000000),
202 m_dwStyles(0),
203 m_dwTxtBkStyles(0),
204 m_bElliChanged(FALSE),
205 m_iEllipsisWidth(0),
206 m_ttoLines(5),
207 m_iCurLine(0),
208 m_iCurPiece(0),
209 m_iTotalLines(0),
210 m_pCharPos(NULL),
211 m_iCharPosSize(0),
212 m_pRenderDevice(NULL) {
213 m_pTxtBreak = IFX_TxtBreak::Create(FX_TXTBREAKPOLICY_None);
214 FXSYS_assert(m_pTxtBreak != NULL);
215 m_Matrix.SetIdentity();
216 m_rtClip.Reset();
217 m_rtLogicClip.Reset();
218 }
219 CFDE_TextOut::~CFDE_TextOut() {
220 if (m_pTxtBreak) {
221 m_pTxtBreak->Release();
222 }
223 FX_Free(m_pCharWidths);
224 FX_Free(m_pEllCharWidths);
225 if (m_pRenderDevice) {
226 m_pRenderDevice->Release();
227 }
228 FX_Free(m_pCharPos);
229 m_ttoLines.RemoveAll();
230 }
231 void CFDE_TextOut::SetFont(IFX_Font* pFont) {
232 FXSYS_assert(pFont);
233 m_pFont = pFont;
234 m_pTxtBreak->SetFont(pFont);
235 }
236 void CFDE_TextOut::SetFontSize(FX_FLOAT fFontSize) {
237 FXSYS_assert(fFontSize > 0);
238 m_fFontSize = fFontSize;
239 m_pTxtBreak->SetFontSize(fFontSize);
240 }
241 void CFDE_TextOut::SetTextColor(FX_ARGB color) {
242 m_TxtColor = color;
243 }
244 void CFDE_TextOut::SetStyles(FX_DWORD dwStyles) {
245 m_dwStyles = dwStyles;
246 m_dwTxtBkStyles = 0;
247 if (dwStyles & FDE_TTOSTYLE_SingleLine) {
248 m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_SingleLine;
249 }
250 if (dwStyles & FDE_TTOSTYLE_ExpandTab) {
251 m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_ExpandTab;
252 }
253 if (dwStyles & FDE_TTOSTYLE_ArabicShapes) {
254 m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_ArabicShapes;
255 }
256 if (dwStyles & FDE_TTOSTYLE_RTL) {
257 m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_RTLReadingOrder;
258 }
259 if (dwStyles & FDE_TTOSTYLE_ArabicContext) {
260 m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_ArabicContext;
261 }
262 if (dwStyles & FDE_TTOSTYLE_VerticalLayout) {
263 m_dwTxtBkStyles |=
264 (FX_TXTLAYOUTSTYLE_VerticalChars | FX_TXTLAYOUTSTYLE_VerticalLayout);
265 }
266 m_pTxtBreak->SetLayoutStyles(m_dwTxtBkStyles);
267 }
268 void CFDE_TextOut::SetTabWidth(FX_FLOAT fTabWidth) {
269 FXSYS_assert(fTabWidth > 1.0f);
270 m_pTxtBreak->SetTabWidth(fTabWidth, FALSE);
271 }
272 void CFDE_TextOut::SetEllipsisString(const CFX_WideString& wsEllipsis) {
273 m_bElliChanged = TRUE;
274 m_wsEllipsis = wsEllipsis;
275 }
276 void CFDE_TextOut::SetParagraphBreakChar(FX_WCHAR wch) {
277 m_wParagraphBkChar = wch;
278 m_pTxtBreak->SetParagraphBreakChar(wch);
279 }
280 void CFDE_TextOut::SetAlignment(int32_t iAlignment) {
281 m_iAlignment = iAlignment;
282 switch (m_iAlignment) {
283 case FDE_TTOALIGNMENT_TopCenter:
284 case FDE_TTOALIGNMENT_Center:
285 case FDE_TTOALIGNMENT_BottomCenter:
286 m_iTxtBkAlignment = FX_TXTLINEALIGNMENT_Center;
287 break;
288 case FDE_TTOALIGNMENT_TopRight:
289 case FDE_TTOALIGNMENT_CenterRight:
290 case FDE_TTOALIGNMENT_BottomRight:
291 m_iTxtBkAlignment = FX_TXTLINEALIGNMENT_Right;
292 break;
293 default:
294 m_iTxtBkAlignment = FX_TXTLINEALIGNMENT_Left;
295 break;
296 }
297 m_pTxtBreak->SetAlignment(m_iTxtBkAlignment);
298 }
299 void CFDE_TextOut::SetLineSpace(FX_FLOAT fLineSpace) {
300 FXSYS_assert(fLineSpace > 1.0f);
301 m_fLineSpace = fLineSpace;
302 }
303 void CFDE_TextOut::SetDIBitmap(CFX_DIBitmap* pDIB) {
304 FXSYS_assert(pDIB != NULL);
305 if (m_pRenderDevice != NULL) {
306 m_pRenderDevice->Release();
307 }
308 m_pRenderDevice = IFDE_RenderDevice::Create(pDIB);
309 }
310 void CFDE_TextOut::SetRenderDevice(CFX_RenderDevice* pDevice) {
311 FXSYS_assert(pDevice != NULL);
312 if (m_pRenderDevice != NULL) {
313 m_pRenderDevice->Release();
314 }
315 m_pRenderDevice = IFDE_RenderDevice::Create(pDevice);
316 }
317 void CFDE_TextOut::SetClipRect(const CFX_Rect& rtClip) {
318 m_rtClip.Set((FX_FLOAT)rtClip.left, (FX_FLOAT)rtClip.top,
319 (FX_FLOAT)rtClip.Width(), (FX_FLOAT)rtClip.Height());
320 }
321 void CFDE_TextOut::SetClipRect(const CFX_RectF& rtClip) {
322 m_rtClip = rtClip;
323 }
324 void CFDE_TextOut::SetLogicClipRect(const CFX_RectF& rtClip) {
325 m_rtLogicClip = rtClip;
326 }
327 void CFDE_TextOut::SetMatrix(const CFX_Matrix& matrix) {
328 m_Matrix = matrix;
329 }
330 void CFDE_TextOut::SetLineBreakTolerance(FX_FLOAT fTolerance) {
331 m_fTolerance = fTolerance;
332 m_pTxtBreak->SetLineBreakTolerance(m_fTolerance);
333 }
334 int32_t CFDE_TextOut::GetTotalLines() {
335 return m_iTotalLines;
336 }
337 void CFDE_TextOut::CalcSize(const FX_WCHAR* pwsStr,
338 int32_t iLength,
339 CFX_Size& size) {
340 CFX_RectF rtText;
341 rtText.Set(0.0f, 0.0f, (FX_FLOAT)size.x, (FX_FLOAT)size.y);
342 CalcSize(pwsStr, iLength, rtText);
343 size.x = (int32_t)rtText.Width();
344 size.y = (int32_t)rtText.Height();
345 }
346 void CFDE_TextOut::CalcSize(const FX_WCHAR* pwsStr,
347 int32_t iLength,
348 CFX_SizeF& size) {
349 CFX_RectF rtText;
350 rtText.Set(0.0f, 0.0f, size.x, size.y);
351 CalcSize(pwsStr, iLength, rtText);
352 size.x = rtText.Width();
353 size.y = rtText.Height();
354 }
355 void CFDE_TextOut::CalcSize(const FX_WCHAR* pwsStr,
356 int32_t iLength,
357 CFX_Rect& rect) {
358 CFX_RectF rtText;
359 rtText.Set((FX_FLOAT)rect.left, (FX_FLOAT)rect.top, (FX_FLOAT)rect.Width(),
360 (FX_FLOAT)rect.Height());
361 CalcSize(pwsStr, iLength, rtText);
362 rect.Set((int32_t)rtText.left, (int32_t)rtText.top, (int32_t)rtText.Width(),
363 (int32_t)rtText.Height());
364 }
365 void CFDE_TextOut::CalcSize(const FX_WCHAR* pwsStr,
366 int32_t iLength,
367 CFX_RectF& rect) {
368 if (pwsStr == NULL || iLength < 1) {
369 rect.width = 0.0f;
370 rect.height = 0.0f;
371 } else {
372 CFX_Matrix rm;
373 rm.SetReverse(m_Matrix);
374 rm.TransformRect(rect);
375 CalcTextSize(pwsStr, iLength, rect);
376 m_Matrix.TransformRect(rect);
377 }
378 }
379 void CFDE_TextOut::CalcLogicSize(const FX_WCHAR* pwsStr,
380 int32_t iLength,
381 CFX_SizeF& size) {
382 CFX_RectF rtText;
383 rtText.Set(0.0f, 0.0f, size.x, size.y);
384 CalcLogicSize(pwsStr, iLength, rtText);
385 size.x = rtText.Width();
386 size.y = rtText.Height();
387 }
388 void CFDE_TextOut::CalcLogicSize(const FX_WCHAR* pwsStr,
389 int32_t iLength,
390 CFX_RectF& rect) {
391 if (pwsStr == NULL || iLength < 1) {
392 rect.width = 0.0f;
393 rect.height = 0.0f;
394 } else {
395 CalcTextSize(pwsStr, iLength, rect);
396 }
397 }
398 void CFDE_TextOut::CalcTextSize(const FX_WCHAR* pwsStr,
399 int32_t iLength,
400 CFX_RectF& rect) {
401 FXSYS_assert(m_pFont != NULL && m_fFontSize >= 1.0f);
402 SetLineWidth(rect);
403 m_iTotalLines = 0;
404 const FX_WCHAR* pStr = pwsStr;
405 FX_BOOL bHotKey = !!(m_dwStyles & FDE_TTOSTYLE_HotKey);
406 FX_BOOL bVertical = !!(m_dwStyles & FDE_TTOSTYLE_VerticalLayout);
407 FX_FLOAT fWidth = 0.0f;
408 FX_FLOAT fHeight = 0.0f;
409 FX_FLOAT fStartPos = bVertical ? rect.bottom() : rect.right();
410 FX_DWORD dwBreakStatus = 0;
411 FX_WCHAR wPreChar = 0;
412 FX_WCHAR wch;
413 FX_WCHAR wBreak = 0;
414 while (iLength-- > 0) {
415 wch = *pStr++;
416 if (wBreak == 0 && (wch == L'\n' || wch == L'\r')) {
417 wBreak = wch;
418 m_pTxtBreak->SetParagraphBreakChar(wch);
419 }
420 if (bHotKey && wch == L'&' && wPreChar != L'&') {
421 wPreChar = wch;
422 continue;
423 }
424 dwBreakStatus = m_pTxtBreak->AppendChar(wch);
425 if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
426 RetrieveLineWidth(dwBreakStatus, fStartPos, fWidth, fHeight);
427 }
428 wPreChar = 0;
429 }
430 dwBreakStatus = m_pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
431 if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
432 RetrieveLineWidth(dwBreakStatus, fStartPos, fWidth, fHeight);
433 }
434 m_pTxtBreak->Reset();
435 FX_FLOAT fInc = rect.Height() - fHeight;
436 if (bVertical) {
437 fInc = rect.Width() - fHeight;
438 }
439 if (m_iAlignment >= FDE_TTOALIGNMENT_CenterLeft &&
440 m_iAlignment < FDE_TTOALIGNMENT_BottomLeft) {
441 fInc /= 2.0f;
442 } else if (m_iAlignment < FDE_TTOALIGNMENT_CenterLeft) {
443 fInc = 0.0f;
444 }
445 if (bVertical) {
446 rect.top += fStartPos;
447 rect.left += fInc;
448 rect.width = fHeight;
449 rect.height = std::min(fWidth, rect.Height());
450 } else {
451 rect.left += fStartPos;
452 rect.top += fInc;
453 rect.width = std::min(fWidth, rect.Width());
454 rect.height = fHeight;
455 if (m_dwStyles & FDE_TTOSTYLE_LastLineHeight) {
456 rect.height -= m_fLineSpace - m_fFontSize;
457 }
458 }
459 }
460 void CFDE_TextOut::SetLineWidth(CFX_RectF& rect) {
461 if ((m_dwStyles & FDE_TTOSTYLE_SingleLine) == 0) {
462 FX_FLOAT fLineWidth = 0.0f;
463 if (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) {
464 if (rect.Height() < 1.0f) {
465 rect.height = m_fFontSize * 1000.0f;
466 }
467 fLineWidth = rect.Height();
468 } else {
469 if (rect.Width() < 1.0f) {
470 rect.width = m_fFontSize * 1000.0f;
471 }
472 fLineWidth = rect.Width();
473 }
474 m_pTxtBreak->SetLineWidth(fLineWidth);
475 }
476 }
477 FX_BOOL CFDE_TextOut::RetrieveLineWidth(FX_DWORD dwBreakStatus,
478 FX_FLOAT& fStartPos,
479 FX_FLOAT& fWidth,
480 FX_FLOAT& fHeight) {
481 if (dwBreakStatus <= FX_TXTBREAK_PieceBreak) {
482 return FALSE;
483 }
484 FX_FLOAT fLineStep =
485 (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize;
486 FX_BOOL bLineWrap = !!(m_dwStyles & FDE_TTOSTYLE_LineWrap);
487 FX_FLOAT fLineWidth = 0.0f;
488 int32_t iCount = m_pTxtBreak->CountBreakPieces();
489 for (int32_t i = 0; i < iCount; i++) {
490 const CFX_TxtPiece* pPiece = m_pTxtBreak->GetBreakPiece(i);
491 fLineWidth += (FX_FLOAT)pPiece->m_iWidth / 20000.0f;
492 fStartPos = std::min(fStartPos, (FX_FLOAT)pPiece->m_iStartPos / 20000.0f);
493 }
494 m_pTxtBreak->ClearBreakPieces();
495 if (dwBreakStatus == FX_TXTBREAK_ParagraphBreak) {
496 m_pTxtBreak->Reset();
497 }
498 if (!bLineWrap && dwBreakStatus == FX_TXTBREAK_LineBreak) {
499 fWidth += fLineWidth;
500 } else {
501 fWidth = std::max(fWidth, fLineWidth);
502 fHeight += fLineStep;
503 }
504 m_iTotalLines++;
505 return TRUE;
506 }
507 void CFDE_TextOut::DrawText(const FX_WCHAR* pwsStr,
508 int32_t iLength,
509 int32_t x,
510 int32_t y) {
511 CFX_RectF rtText;
512 rtText.Set((FX_FLOAT)x, (FX_FLOAT)y, m_fFontSize * 1000.0f,
513 m_fFontSize * 1000.0f);
514 DrawText(pwsStr, iLength, rtText);
515 }
516 void CFDE_TextOut::DrawText(const FX_WCHAR* pwsStr,
517 int32_t iLength,
518 FX_FLOAT x,
519 FX_FLOAT y) {
520 CFX_RectF rtText;
521 rtText.Set(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f);
522 DrawText(pwsStr, iLength, rtText);
523 }
524 void CFDE_TextOut::DrawText(const FX_WCHAR* pwsStr,
525 int32_t iLength,
526 const CFX_Rect& rect) {
527 CFX_RectF rtText;
528 rtText.Set((FX_FLOAT)rect.left, (FX_FLOAT)rect.top, (FX_FLOAT)rect.width,
529 (FX_FLOAT)rect.height);
530 DrawText(pwsStr, iLength, rtText);
531 }
532 void CFDE_TextOut::DrawText(const FX_WCHAR* pwsStr,
533 int32_t iLength,
534 const CFX_RectF& rect) {
535 CFX_RectF rtText;
536 rtText.Set(rect.left, rect.top, rect.width, rect.height);
537 CFX_Matrix rm;
538 rm.SetReverse(m_Matrix);
539 rm.TransformRect(rtText);
540 DrawText(pwsStr, iLength, rtText, m_rtClip);
541 }
542 void CFDE_TextOut::DrawLogicText(const FX_WCHAR* pwsStr,
543 int32_t iLength,
544 FX_FLOAT x,
545 FX_FLOAT y) {
546 CFX_RectF rtText;
547 rtText.Set(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f);
548 DrawLogicText(pwsStr, iLength, rtText);
549 }
550 void CFDE_TextOut::DrawLogicText(const FX_WCHAR* pwsStr,
551 int32_t iLength,
552 const CFX_RectF& rect) {
553 CFX_RectF rtClip;
554 rtClip.Set(m_rtLogicClip.left, m_rtLogicClip.top, m_rtLogicClip.width,
555 m_rtLogicClip.height);
556 m_Matrix.TransformRect(rtClip);
557 DrawText(pwsStr, iLength, rect, rtClip);
558 }
559 void CFDE_TextOut::DrawText(const FX_WCHAR* pwsStr,
560 int32_t iLength,
561 const CFX_RectF& rect,
562 const CFX_RectF& rtClip) {
563 FXSYS_assert(m_pFont != NULL && m_fFontSize >= 1.0f);
564 if (pwsStr == NULL || iLength < 1) {
565 return;
566 }
567 if (rect.width < m_fFontSize || rect.height < m_fFontSize) {
568 return;
569 }
570 FX_FLOAT fLineWidth = rect.width;
571 if (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) {
572 fLineWidth = rect.height;
573 }
574 m_pTxtBreak->SetLineWidth(fLineWidth);
575 m_ttoLines.RemoveAll(TRUE);
576 m_wsText.Empty();
577 LoadText(pwsStr, iLength, rect);
578 if (m_dwStyles & FDE_TTOSTYLE_Ellipsis) {
579 ReplaceWidthEllipsis();
580 }
581 Reload(rect);
582 DoAlignment(rect);
583 OnDraw(rtClip);
584 }
585 void CFDE_TextOut::ExpandBuffer(int32_t iSize, int32_t iType) {
586 switch (iType) {
587 case 0:
588 if (!m_pCharWidths) {
589 m_pCharWidths = FX_Alloc(int32_t, iSize);
590 m_iChars = iSize;
591 } else if (m_iChars < iSize) {
592 m_pCharWidths = FX_Realloc(int32_t, m_pCharWidths, iSize);
593 m_iChars = iSize;
594 }
595 FXSYS_memset(m_pCharWidths, 0, iSize * sizeof(int32_t));
596 break;
597 case 1:
598 if (!m_pEllCharWidths) {
599 m_pEllCharWidths = FX_Alloc(int32_t, iSize);
600 m_iEllChars = iSize;
601 } else if (m_iEllChars < iSize) {
602 m_pEllCharWidths = FX_Realloc(int32_t, m_pEllCharWidths, iSize);
603 m_iEllChars = iSize;
604 }
605 FXSYS_memset(m_pEllCharWidths, 0, iSize * sizeof(int32_t));
606 break;
607 case 2:
608 if (m_pCharPos == NULL) {
609 m_pCharPos = FX_Alloc(FXTEXT_CHARPOS, iSize);
610 m_iCharPosSize = iSize;
611 } else if (m_iCharPosSize < iSize) {
612 m_pCharPos = FX_Realloc(FXTEXT_CHARPOS, m_pCharPos, iSize);
613 m_iCharPosSize = iSize;
614 }
615 break;
616 }
617 }
618 void CFDE_TextOut::LoadEllipsis() {
619 if (!m_bElliChanged) {
620 return;
621 }
622 m_bElliChanged = FALSE;
623 m_iEllipsisWidth = 0;
624 int32_t iLength = m_wsEllipsis.GetLength();
625 if (iLength < 1) {
626 return;
627 }
628 ExpandBuffer(iLength, 1);
629 const FX_WCHAR* pStr = (const FX_WCHAR*)m_wsEllipsis;
630 int32_t* pCharWidths = m_pEllCharWidths;
631 FX_DWORD dwBreakStatus;
632 FX_WCHAR wch;
633 while (iLength-- > 0) {
634 wch = *pStr++;
635 dwBreakStatus = m_pTxtBreak->AppendChar(wch);
636 if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
637 RetrieveEllPieces(pCharWidths);
638 }
639 }
640 dwBreakStatus = m_pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
641 if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
642 RetrieveEllPieces(pCharWidths);
643 }
644 m_pTxtBreak->Reset();
645 }
646 void CFDE_TextOut::RetrieveEllPieces(int32_t*& pCharWidths) {
647 int32_t iCount = m_pTxtBreak->CountBreakPieces();
648 CFX_Char* pTC;
649 for (int32_t i = 0; i < iCount; i++) {
650 const CFX_TxtPiece* pPiece = m_pTxtBreak->GetBreakPiece(i);
651 int32_t iPieceChars = pPiece->GetLength();
652 for (int32_t j = 0; j < iPieceChars; j++) {
653 pTC = pPiece->GetCharPtr(j);
654 if (pTC->m_iCharWidth <= 0) {
655 *pCharWidths = 0;
656 } else {
657 *pCharWidths = pTC->m_iCharWidth;
658 }
659 m_iEllipsisWidth += *pCharWidths;
660 pCharWidths++;
661 }
662 }
663 m_pTxtBreak->ClearBreakPieces();
664 }
665 void CFDE_TextOut::LoadText(const FX_WCHAR* pwsStr,
666 int32_t iLength,
667 const CFX_RectF& rect) {
668 FX_WCHAR* pStr = m_wsText.GetBuffer(iLength);
669 int32_t iTxtLength = iLength;
670 ExpandBuffer(iTxtLength, 0);
671 FX_BOOL bHotKey = !!(m_dwStyles & FDE_TTOSTYLE_HotKey);
672 FX_BOOL bVertical = !!(m_dwStyles & FDE_TTOSTYLE_VerticalLayout);
673 FX_BOOL bLineWrap = !!(m_dwStyles & FDE_TTOSTYLE_LineWrap);
674 FX_FLOAT fLineStep =
675 (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize;
676 FX_FLOAT fLineStop = bVertical ? rect.left : rect.bottom();
677 m_fLinePos = bVertical ? rect.right() : rect.top;
678 if (bVertical) {
679 fLineStep = -fLineStep;
680 }
681 m_hotKeys.RemoveAll();
682 int32_t iStartChar = 0;
683 int32_t iChars = 0;
684 int32_t iPieceWidths = 0;
685 FX_DWORD dwBreakStatus;
686 FX_WCHAR wch;
687 FX_BOOL bRet = FALSE;
688 while (iTxtLength-- > 0) {
689 wch = *pwsStr++;
690 if (wch == L'&' && bHotKey && (pStr - 1) != NULL && *(pStr - 1) != L'&') {
691 if (iTxtLength > 0) {
692 m_hotKeys.Add(iChars);
693 }
694 continue;
695 }
696 *pStr++ = wch;
697 iChars++;
698 dwBreakStatus = m_pTxtBreak->AppendChar(wch);
699 if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
700 FX_BOOL bEndofLine =
701 RetriecePieces(dwBreakStatus, iStartChar, iPieceWidths, FALSE, rect);
702 if (bEndofLine && (bLineWrap || (dwBreakStatus > FX_TXTBREAK_LineBreak &&
703 !bLineWrap))) {
704 iPieceWidths = 0;
705 m_iCurLine++;
706 m_fLinePos += fLineStep;
707 }
708 if ((bVertical && m_fLinePos + fLineStep < fLineStop) ||
709 (!bVertical && m_fLinePos + fLineStep > fLineStop)) {
710 int32_t iCurLine = m_iCurLine;
711 if (bEndofLine) {
712 iCurLine--;
713 }
714 CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(iCurLine);
715 pLine->m_bNewReload = TRUE;
716 bRet = TRUE;
717 break;
718 }
719 }
720 }
721 dwBreakStatus = m_pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
722 if (dwBreakStatus > FX_TXTBREAK_PieceBreak && !bRet) {
723 RetriecePieces(dwBreakStatus, iStartChar, iPieceWidths, FALSE, rect);
724 }
725 m_pTxtBreak->ClearBreakPieces();
726 m_pTxtBreak->Reset();
727 m_wsText.ReleaseBuffer(iLength);
728 }
729 FX_BOOL CFDE_TextOut::RetriecePieces(FX_DWORD dwBreakStatus,
730 int32_t& iStartChar,
731 int32_t& iPieceWidths,
732 FX_BOOL bReload,
733 const CFX_RectF& rect) {
734 FX_BOOL bSingleLine = !!(m_dwStyles & FDE_TTOSTYLE_SingleLine);
735 FX_BOOL bLineWrap = !!(m_dwStyles & FDE_TTOSTYLE_LineWrap);
736 FX_BOOL bVertical = !!(m_dwStyles & FDE_TTOSTYLE_VerticalLayout);
737 FX_FLOAT fLineStep =
738 (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize;
739 if (bVertical) {
740 fLineStep = -fLineStep;
741 }
742 CFX_Char* pTC = NULL;
743 FX_BOOL bNeedReload = FALSE;
744 FX_FLOAT fLineWidth = bVertical ? rect.Height() : rect.Width();
745 int32_t iLineWidth = FXSYS_round(fLineWidth * 20000.0f);
746 int32_t iCount = m_pTxtBreak->CountBreakPieces();
747 for (int32_t i = 0; i < iCount; i++) {
748 const CFX_TxtPiece* pPiece = m_pTxtBreak->GetBreakPiece(i);
749 int32_t iPieceChars = pPiece->GetLength();
750 int32_t iChar = iStartChar;
751 int32_t iWidth = 0;
752 int32_t j = 0;
753 for (; j < iPieceChars; j++) {
754 pTC = pPiece->GetCharPtr(j);
755 int32_t iCurCharWidth = pTC->m_iCharWidth > 0 ? pTC->m_iCharWidth : 0;
756 if (bSingleLine || !bLineWrap) {
757 if (iLineWidth - iPieceWidths - iWidth < iCurCharWidth) {
758 bNeedReload = TRUE;
759 break;
760 }
761 }
762 iWidth += iCurCharWidth;
763 m_pCharWidths[iChar++] = iCurCharWidth;
764 }
765 if (j == 0 && !bReload) {
766 CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(m_iCurLine);
767 pLine->m_bNewReload = TRUE;
768 } else if (j > 0) {
769 CFX_RectF rtPiece;
770 if (bVertical) {
771 rtPiece.left = m_fLinePos;
772 rtPiece.top = rect.top + (FX_FLOAT)pPiece->m_iStartPos / 20000.0f;
773 rtPiece.width = fLineStep;
774 rtPiece.height = iWidth / 20000.0f;
775 } else {
776 rtPiece.left = rect.left + (FX_FLOAT)pPiece->m_iStartPos / 20000.0f;
777 rtPiece.top = m_fLinePos;
778 rtPiece.width = iWidth / 20000.0f;
779 rtPiece.height = fLineStep;
780 }
781 FDE_TTOPIECE ttoPiece;
782 ttoPiece.iStartChar = iStartChar;
783 ttoPiece.iChars = j;
784 ttoPiece.rtPiece = rtPiece;
785 ttoPiece.dwCharStyles = pPiece->m_dwCharStyles;
786 if (FX_IsOdd(pPiece->m_iBidiLevel)) {
787 ttoPiece.dwCharStyles |= FX_TXTCHARSTYLE_OddBidiLevel;
788 }
789 AppendPiece(ttoPiece, bNeedReload, (bReload && i == iCount - 1));
790 }
791 iStartChar += iPieceChars;
792 iPieceWidths += iWidth;
793 }
794 m_pTxtBreak->ClearBreakPieces();
795 FX_BOOL bRet = bSingleLine || bLineWrap || (!bLineWrap && bNeedReload) ||
796 dwBreakStatus == FX_TXTBREAK_ParagraphBreak;
797 return bRet;
798 }
799 void CFDE_TextOut::AppendPiece(const FDE_TTOPIECE& ttoPiece,
800 FX_BOOL bNeedReload,
801 FX_BOOL bEnd) {
802 if (m_iCurLine >= m_ttoLines.GetSize()) {
803 CFDE_TTOLine ttoLine;
804 ttoLine.m_bNewReload = bNeedReload;
805 m_iCurPiece = ttoLine.AddPiece(m_iCurPiece, ttoPiece);
806 m_iCurLine = m_ttoLines.Add(ttoLine);
807 } else {
808 CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(m_iCurLine);
809 pLine->m_bNewReload = bNeedReload;
810 m_iCurPiece = pLine->AddPiece(m_iCurPiece, ttoPiece);
811 if (bEnd) {
812 int32_t iPieces = pLine->GetSize();
813 if (m_iCurPiece < iPieces) {
814 pLine->RemoveLast(iPieces - m_iCurPiece - 1);
815 }
816 }
817 }
818 if (!bEnd && bNeedReload) {
819 m_iCurPiece = 0;
820 }
821 }
822 void CFDE_TextOut::ReplaceWidthEllipsis() {
823 LoadEllipsis();
824 int32_t iLength = m_wsEllipsis.GetLength();
825 if (iLength < 1) {
826 return;
827 }
828 int32_t iLines = m_ttoLines.GetSize();
829 for (int32_t i = 0; i < iLines; i++) {
830 CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(i);
831 if (!pLine->m_bNewReload) {
832 continue;
833 }
834 int32_t iEllipsisCharIndex = iLength - 1;
835 int32_t iCharWidth = 0;
836 int32_t iCharCount = 0;
837 int32_t iPiece = pLine->GetSize();
838 while (iPiece-- > 0) {
839 FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(iPiece);
840 if (pPiece == NULL) {
841 break;
842 }
843 for (int32_t j = pPiece->iChars - 1; j >= 0; j--) {
844 if (iEllipsisCharIndex < 0) {
845 break;
846 }
847 int32_t index = pPiece->iStartChar + j;
848 iCharWidth += m_pCharWidths[index];
849 iCharCount++;
850 if (iCharCount <= iLength) {
851 m_wsText.SetAt(index, m_wsEllipsis.GetAt(iEllipsisCharIndex));
852 m_pCharWidths[index] = m_pEllCharWidths[iEllipsisCharIndex];
853 } else if (iCharWidth <= m_iEllipsisWidth) {
854 m_wsText.SetAt(index, 0);
855 m_pCharWidths[index] = 0;
856 }
857 iEllipsisCharIndex--;
858 }
859 if (iEllipsisCharIndex < 0) {
860 break;
861 }
862 }
863 }
864 }
865 void CFDE_TextOut::Reload(const CFX_RectF& rect) {
866 int32_t iCount = m_ttoLines.GetSize();
867 for (int32_t i = 0; i < iCount; i++) {
868 CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(i);
869 if (pLine == NULL || !pLine->m_bNewReload) {
870 continue;
871 }
872 m_iCurLine = i;
873 m_iCurPiece = 0;
874 ReloadLinePiece(pLine, rect);
875 }
876 }
877 void CFDE_TextOut::ReloadLinePiece(CFDE_TTOLine* pLine, const CFX_RectF& rect) {
878 const FX_WCHAR* pwsStr = (const FX_WCHAR*)m_wsText;
879 FX_BOOL bVertical = !!(m_dwStyles & FDE_TTOSTYLE_VerticalLayout);
880 int32_t iPieceWidths = 0;
881 FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(0);
882 int32_t iStartChar = pPiece->iStartChar;
883 m_fLinePos = bVertical ? pPiece->rtPiece.left : pPiece->rtPiece.top;
884 int32_t iPieceCount = pLine->GetSize();
885 int32_t iPieceIndex = 0;
886 FX_DWORD dwBreakStatus = 0;
887 FX_WCHAR wch;
888 while (iPieceIndex < iPieceCount) {
889 int32_t iStar = iStartChar;
890 int32_t iEnd = pPiece->iChars + iStar;
891 while (iStar < iEnd) {
892 wch = *(pwsStr + iStar);
893 dwBreakStatus = m_pTxtBreak->AppendChar(wch);
894 if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
895 RetriecePieces(dwBreakStatus, iStartChar, iPieceWidths, TRUE, rect);
896 }
897 iStar++;
898 }
899 iPieceIndex++;
900 pPiece = pLine->GetPtrAt(iPieceIndex);
901 }
902 dwBreakStatus = m_pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
903 if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
904 RetriecePieces(dwBreakStatus, iStartChar, iPieceWidths, TRUE, rect);
905 }
906 m_pTxtBreak->Reset();
907 }
908 void CFDE_TextOut::DoAlignment(const CFX_RectF& rect) {
909 FX_BOOL bVertical = !!(m_dwStyles & FDE_TTOSTYLE_VerticalLayout);
910 FX_FLOAT fLineStopS = bVertical ? rect.right() : rect.bottom();
911 int32_t iLines = m_ttoLines.GetSize();
912 if (iLines < 1) {
913 return;
914 }
915 CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(iLines - 1);
916 FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(0);
917 if (pPiece == NULL) {
918 return;
919 }
920 FX_FLOAT fLineStopD =
921 bVertical ? pPiece->rtPiece.right() : pPiece->rtPiece.bottom();
922 FX_FLOAT fInc = fLineStopS - fLineStopD;
923 if (m_iAlignment >= FDE_TTOALIGNMENT_CenterLeft &&
924 m_iAlignment < FDE_TTOALIGNMENT_BottomLeft) {
925 fInc /= 2.0f;
926 } else if (m_iAlignment < FDE_TTOALIGNMENT_CenterLeft) {
927 fInc = 0.0f;
928 }
929 if (fInc < 1.0f) {
930 return;
931 }
932 for (int32_t i = 0; i < iLines; i++) {
933 CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(i);
934 int32_t iPieces = pLine->GetSize();
935 for (int32_t j = 0; j < iPieces; j++) {
936 FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(j);
937 if (bVertical) {
938 pPiece->rtPiece.left += fInc;
939 } else {
940 pPiece->rtPiece.top += fInc;
941 }
942 }
943 }
944 }
945 void CFDE_TextOut::OnDraw(const CFX_RectF& rtClip) {
946 if (m_pRenderDevice == NULL) {
947 return;
948 }
949 int32_t iLines = m_ttoLines.GetSize();
950 if (iLines < 1) {
951 return;
952 }
953 IFDE_SolidBrush* pBrush =
954 (IFDE_SolidBrush*)IFDE_Brush::Create(FDE_BRUSHTYPE_Solid);
955 pBrush->SetColor(m_TxtColor);
956 IFDE_Pen* pPen = NULL;
957 FDE_HDEVICESTATE hDev = m_pRenderDevice->SaveState();
958 if (rtClip.Width() > 0.0f && rtClip.Height() > 0.0f) {
959 m_pRenderDevice->SetClipRect(rtClip);
960 }
961 for (int32_t i = 0; i < iLines; i++) {
962 CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(i);
963 int32_t iPieces = pLine->GetSize();
964 for (int32_t j = 0; j < iPieces; j++) {
965 FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(j);
966 if (pPiece == NULL) {
967 continue;
968 }
969 int32_t iCount = GetDisplayPos(pPiece);
970 if (iCount > 0) {
971 m_pRenderDevice->DrawString(pBrush, m_pFont, m_pCharPos, iCount,
972 m_fFontSize, &m_Matrix);
973 }
974 DrawLine(pPiece, pPen);
975 }
976 }
977 m_pRenderDevice->RestoreState(hDev);
978 if (pBrush) {
979 pBrush->Release();
980 }
981 if (pPen) {
982 pPen->Release();
983 }
984 }
985 int32_t CFDE_TextOut::GetDisplayPos(FDE_LPTTOPIECE pPiece) {
986 FX_TXTRUN tr;
987 ToTextRun(pPiece, tr);
988 ExpandBuffer(tr.iLength, 2);
989 return m_pTxtBreak->GetDisplayPos(&tr, m_pCharPos);
990 }
991 int32_t CFDE_TextOut::GetCharRects(FDE_LPTTOPIECE pPiece) {
992 FX_TXTRUN tr;
993 ToTextRun(pPiece, tr);
994 m_rectArray.RemoveAll();
995 return m_pTxtBreak->GetCharRects(&tr, m_rectArray);
996 }
997 void CFDE_TextOut::ToTextRun(const FDE_LPTTOPIECE pPiece, FX_TXTRUN& tr) {
998 tr.pAccess = NULL;
999 tr.pIdentity = NULL;
1000 tr.pStr = (const FX_WCHAR*)m_wsText + pPiece->iStartChar;
1001 tr.pWidths = m_pCharWidths + pPiece->iStartChar;
1002 tr.iLength = pPiece->iChars;
1003 tr.pFont = m_pFont;
1004 tr.fFontSize = m_fFontSize;
1005 tr.dwStyles = m_dwTxtBkStyles;
1006 tr.iCharRotation = 0;
1007 tr.dwCharStyles = pPiece->dwCharStyles;
1008 tr.wLineBreakChar = m_wParagraphBkChar;
1009 tr.pRect = &pPiece->rtPiece;
1010 }
1011 void CFDE_TextOut::DrawLine(const FDE_LPTTOPIECE pPiece, IFDE_Pen*& pPen) {
1012 FX_BOOL bUnderLine = !!(m_dwStyles & FDE_TTOSTYLE_Underline);
1013 FX_BOOL bStrikeOut = !!(m_dwStyles & FDE_TTOSTYLE_Strikeout);
1014 FX_BOOL bHotKey = !!(m_dwStyles & FDE_TTOSTYLE_HotKey);
1015 FX_BOOL bVertical = !!(m_dwStyles & FDE_TTOSTYLE_VerticalLayout);
1016 if (!bUnderLine && !bStrikeOut && !bHotKey) {
1017 return;
1018 }
1019 if (pPen == NULL) {
1020 pPen = IFDE_Pen::Create();
1021 pPen->SetColor(m_TxtColor);
1022 }
1023 IFDE_Path* pPath = IFDE_Path::Create();
1024 int32_t iLineCount = 0;
1025 CFX_RectF rtText = pPiece->rtPiece;
1026 CFX_PointF pt1, pt2;
1027 if (bUnderLine) {
1028 if (bVertical) {
1029 pt1.x = rtText.left;
1030 pt1.y = rtText.top;
1031 pt2.x = rtText.left;
1032 pt2.y = rtText.bottom();
1033 } else {
1034 pt1.x = rtText.left;
1035 pt1.y = rtText.bottom();
1036 pt2.x = rtText.right();
1037 pt2.y = rtText.bottom();
1038 }
1039 pPath->AddLine(pt1, pt2);
1040 iLineCount++;
1041 }
1042 if (bStrikeOut) {
1043 if (bVertical) {
1044 pt1.x = rtText.left + rtText.width * 2.0f / 5.0f;
1045 pt1.y = rtText.top;
1046 pt2.x = pt1.x;
1047 pt2.y = rtText.bottom();
1048 } else {
1049 pt1.x = rtText.left;
1050 pt1.y = rtText.bottom() - rtText.height * 2.0f / 5.0f;
1051 pt2.x = rtText.right();
1052 pt2.y = pt1.y;
1053 }
1054 pPath->AddLine(pt1, pt2);
1055 iLineCount++;
1056 }
1057 if (bHotKey) {
1058 int32_t iHotKeys = m_hotKeys.GetSize();
1059 int32_t iCount = GetCharRects(pPiece);
1060 if (iCount > 0) {
1061 for (int32_t i = 0; i < iHotKeys; i++) {
1062 int32_t iCharIndex = m_hotKeys.GetAt(i);
1063 if (iCharIndex >= pPiece->iStartChar &&
1064 iCharIndex < pPiece->iStartChar + pPiece->iChars) {
1065 CFX_RectF rect = m_rectArray.GetAt(iCharIndex - pPiece->iStartChar);
1066 if (bVertical) {
1067 pt1.x = rect.left;
1068 pt1.y = rect.top;
1069 pt2.x = rect.left;
1070 pt2.y = rect.bottom();
1071 } else {
1072 pt1.x = rect.left;
1073 pt1.y = rect.bottom();
1074 pt2.x = rect.right();
1075 pt2.y = rect.bottom();
1076 }
1077 pPath->AddLine(pt1, pt2);
1078 iLineCount++;
1079 }
1080 }
1081 }
1082 }
1083 if (iLineCount > 0) {
1084 m_pRenderDevice->DrawPath(pPen, 1, pPath, &m_Matrix);
1085 }
1086 pPath->Release();
1087 }
1088 CFDE_TTOLine::CFDE_TTOLine()
1089 : m_bNewReload(FALSE), m_pieces(5), m_iPieceCount(0) {}
1090 CFDE_TTOLine::CFDE_TTOLine(const CFDE_TTOLine& ttoLine) : m_pieces(5) {
1091 m_bNewReload = ttoLine.m_bNewReload;
1092 m_iPieceCount = ttoLine.m_iPieceCount;
1093 m_pieces.Copy(ttoLine.m_pieces);
1094 }
1095 CFDE_TTOLine::~CFDE_TTOLine() {}
1096 int32_t CFDE_TTOLine::AddPiece(int32_t index, const FDE_TTOPIECE& ttoPiece) {
1097 if (index >= m_iPieceCount) {
1098 index = m_pieces.Add(ttoPiece) + 1;
1099 m_iPieceCount++;
1100 } else {
1101 FDE_TTOPIECE& piece = m_pieces.GetAt(index);
1102 piece = ttoPiece;
1103 }
1104 return index;
1105 }
1106 int32_t CFDE_TTOLine::GetSize() const {
1107 return m_iPieceCount;
1108 }
1109 FDE_LPTTOPIECE CFDE_TTOLine::GetPtrAt(int32_t index) {
1110 if (index >= m_iPieceCount) {
1111 return NULL;
1112 }
1113 return m_pieces.GetPtrAt(index);
1114 }
1115 void CFDE_TTOLine::RemoveLast(int32_t iCount) {
1116 m_pieces.RemoveLast(iCount);
1117 }
1118 void CFDE_TTOLine::RemoveAll(FX_BOOL bLeaveMemory) {
1119 m_pieces.RemoveAll(bLeaveMemory);
1120 }
OLDNEW
« no previous file with comments | « xfa/src/fde/tto/fde_textout.h ('k') | xfa/src/fde/xml/fde_xml.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698