OLD | NEW |
| (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/fee/fde_txtedtpage.h" | |
8 | |
9 #include <algorithm> | |
10 | |
11 #include "xfa/src/fee/fx_wordbreak/fx_wordbreak.h" | |
12 #include "xfa/src/fee/fde_txtedtbuf.h" | |
13 #include "xfa/src/fee/fde_txtedtengine.h" | |
14 #include "xfa/src/fee/fde_txtedtparag.h" | |
15 #include "xfa/src/fee/ifde_txtedtbuf.h" | |
16 #include "xfa/src/fee/ifde_txtedtengine.h" | |
17 #include "xfa/src/fee/ifde_txtedtpage.h" | |
18 | |
19 #define FDE_TXTEDT_TOLERANCE 0.1f | |
20 | |
21 IFDE_TxtEdtPage* IFDE_TxtEdtPage::Create(IFDE_TxtEdtEngine* pEngine, | |
22 int32_t nIndex) { | |
23 return (IFDE_TxtEdtPage*)new CFDE_TxtEdtPage(pEngine, nIndex); | |
24 } | |
25 CFDE_TxtEdtTextSet::CFDE_TxtEdtTextSet(CFDE_TxtEdtPage* pPage) | |
26 : m_pPage(pPage) {} | |
27 CFDE_TxtEdtTextSet::~CFDE_TxtEdtTextSet() {} | |
28 FDE_VISUALOBJTYPE CFDE_TxtEdtTextSet::GetType() { | |
29 return FDE_VISUALOBJ_Text; | |
30 } | |
31 FX_BOOL CFDE_TxtEdtTextSet::GetBBox(FDE_HVISUALOBJ hVisualObj, | |
32 CFX_RectF& bbox) { | |
33 return FALSE; | |
34 } | |
35 FX_BOOL CFDE_TxtEdtTextSet::GetMatrix(FDE_HVISUALOBJ hVisualObj, | |
36 CFX_Matrix& matrix) { | |
37 return FALSE; | |
38 } | |
39 FX_BOOL CFDE_TxtEdtTextSet::GetRect(FDE_HVISUALOBJ hVisualObj, CFX_RectF& rt) { | |
40 rt = ((FDE_TEXTEDITPIECE*)(hVisualObj))->rtPiece; | |
41 return TRUE; | |
42 } | |
43 FX_BOOL CFDE_TxtEdtTextSet::GetClip(FDE_HVISUALOBJ hVisualObj, CFX_RectF& rt) { | |
44 return FALSE; | |
45 } | |
46 int32_t CFDE_TxtEdtTextSet::GetString(FDE_HVISUALOBJ hText, | |
47 CFX_WideString& wsText) { | |
48 FDE_TEXTEDITPIECE* pPiece = (FDE_TEXTEDITPIECE*)hText; | |
49 FX_WCHAR* pBuffer = wsText.GetBuffer(pPiece->nCount); | |
50 for (int32_t i = 0; i < pPiece->nCount; i++) { | |
51 pBuffer[i] = m_pPage->GetChar((void*)hText, i); | |
52 } | |
53 wsText.ReleaseBuffer(pPiece->nCount); | |
54 return pPiece->nCount; | |
55 } | |
56 IFX_Font* CFDE_TxtEdtTextSet::GetFont(FDE_HVISUALOBJ hText) { | |
57 return m_pPage->GetEngine()->GetEditParams()->pFont; | |
58 } | |
59 FX_FLOAT CFDE_TxtEdtTextSet::GetFontSize(FDE_HVISUALOBJ hText) { | |
60 return m_pPage->GetEngine()->GetEditParams()->fFontSize; | |
61 } | |
62 FX_ARGB CFDE_TxtEdtTextSet::GetFontColor(FDE_HVISUALOBJ hText) { | |
63 return m_pPage->GetEngine()->GetEditParams()->dwFontColor; | |
64 } | |
65 int32_t CFDE_TxtEdtTextSet::GetDisplayPos(FDE_HVISUALOBJ hText, | |
66 FXTEXT_CHARPOS* pCharPos, | |
67 FX_BOOL bCharCode, | |
68 CFX_WideString* pWSForms) { | |
69 if (hText == NULL) { | |
70 return 0; | |
71 } | |
72 FDE_TEXTEDITPIECE* pPiece = (FDE_TEXTEDITPIECE*)hText; | |
73 int32_t nLength = pPiece->nCount; | |
74 if (nLength < 1) { | |
75 return 0; | |
76 } | |
77 CFDE_TxtEdtEngine* pEngine = (CFDE_TxtEdtEngine*)(m_pPage->GetEngine()); | |
78 const FDE_TXTEDTPARAMS* pTextParams = pEngine->GetEditParams(); | |
79 IFX_TxtBreak* pBreak = pEngine->GetTextBreak(); | |
80 FX_DWORD dwLayoutStyle = pBreak->GetLayoutStyles(); | |
81 FX_TXTRUN tr; | |
82 tr.pAccess = m_pPage; | |
83 tr.pIdentity = (void*)hText; | |
84 tr.pStr = NULL; | |
85 tr.pWidths = NULL; | |
86 tr.iLength = nLength; | |
87 tr.pFont = pTextParams->pFont; | |
88 tr.fFontSize = pTextParams->fFontSize; | |
89 tr.dwStyles = dwLayoutStyle; | |
90 tr.iCharRotation = pTextParams->nCharRotation; | |
91 tr.dwCharStyles = pPiece->dwCharStyles; | |
92 tr.pRect = &(pPiece->rtPiece); | |
93 tr.wLineBreakChar = pTextParams->wLineBreakChar; | |
94 return pBreak->GetDisplayPos(&tr, pCharPos, bCharCode, pWSForms); | |
95 } | |
96 int32_t CFDE_TxtEdtTextSet::GetCharRects(FDE_HVISUALOBJ hText, | |
97 CFX_RectFArray& rtArray) { | |
98 return GetCharRects_Impl(hText, rtArray); | |
99 } | |
100 int32_t CFDE_TxtEdtTextSet::GetCharRects_Impl(FDE_HVISUALOBJ hText, | |
101 CFX_RectFArray& rtArray, | |
102 FX_BOOL bBBox) { | |
103 if (hText == NULL) { | |
104 return 0; | |
105 } | |
106 FDE_TEXTEDITPIECE* pPiece = (FDE_TEXTEDITPIECE*)hText; | |
107 CFDE_TxtEdtEngine* pEngine = (CFDE_TxtEdtEngine*)(m_pPage->GetEngine()); | |
108 int32_t nLength = pPiece->nCount; | |
109 if (nLength < 1) { | |
110 return 0; | |
111 } | |
112 const FDE_TXTEDTPARAMS* pTextParams = pEngine->GetEditParams(); | |
113 FX_DWORD dwLayoutStyle = pEngine->GetTextBreak()->GetLayoutStyles(); | |
114 FX_TXTRUN tr; | |
115 tr.pAccess = m_pPage; | |
116 tr.pIdentity = (void*)hText; | |
117 tr.pStr = NULL; | |
118 tr.pWidths = NULL; | |
119 tr.iLength = nLength; | |
120 tr.pFont = pTextParams->pFont; | |
121 tr.fFontSize = pTextParams->fFontSize; | |
122 tr.dwStyles = dwLayoutStyle; | |
123 tr.iCharRotation = pTextParams->nCharRotation; | |
124 tr.dwCharStyles = pPiece->dwCharStyles; | |
125 tr.pRect = &(pPiece->rtPiece); | |
126 tr.wLineBreakChar = pTextParams->wLineBreakChar; | |
127 return pEngine->GetTextBreak()->GetCharRects(&tr, rtArray, bBBox); | |
128 } | |
129 CFDE_TxtEdtPage::CFDE_TxtEdtPage(IFDE_TxtEdtEngine* pEngine, int32_t nPageIndex) | |
130 : m_pIter(nullptr), | |
131 m_pTextSet(nullptr), | |
132 m_pBgnParag(nullptr), | |
133 m_pEndParag(nullptr), | |
134 m_nRefCount(0), | |
135 m_nPageStart(-1), | |
136 m_nCharCount(0), | |
137 m_nPageIndex(nPageIndex), | |
138 m_bLoaded(FALSE), | |
139 m_pCharWidth(nullptr) { | |
140 FXSYS_memset(&m_rtPage, 0, sizeof(CFX_RectF)); | |
141 FXSYS_memset(&m_rtPageMargin, 0, sizeof(CFX_RectF)); | |
142 FXSYS_memset(&m_rtPageContents, 0, sizeof(CFX_RectF)); | |
143 FXSYS_memset(&m_rtPageCanvas, 0, sizeof(CFX_RectF)); | |
144 m_pEditEngine = (CFDE_TxtEdtEngine*)pEngine; | |
145 } | |
146 CFDE_TxtEdtPage::~CFDE_TxtEdtPage() { | |
147 m_PieceMassArr.RemoveAll(TRUE); | |
148 if (m_pTextSet) { | |
149 delete m_pTextSet; | |
150 m_pTextSet = NULL; | |
151 } | |
152 if (m_pCharWidth) { | |
153 delete[] m_pCharWidth; | |
154 m_pCharWidth = NULL; | |
155 } | |
156 if (m_pIter != NULL) { | |
157 m_pIter->Release(); | |
158 m_pIter = NULL; | |
159 } | |
160 } | |
161 void CFDE_TxtEdtPage::Release() { | |
162 delete this; | |
163 } | |
164 IFDE_TxtEdtEngine* CFDE_TxtEdtPage::GetEngine() const { | |
165 return (IFDE_TxtEdtEngine*)m_pEditEngine; | |
166 } | |
167 FDE_VISUALOBJTYPE CFDE_TxtEdtPage::GetType() { | |
168 return FDE_VISUALOBJ_Text; | |
169 } | |
170 FX_BOOL CFDE_TxtEdtPage::GetBBox(FDE_HVISUALOBJ hVisualObj, CFX_RectF& bbox) { | |
171 return FALSE; | |
172 } | |
173 FX_BOOL CFDE_TxtEdtPage::GetMatrix(FDE_HVISUALOBJ hVisualObj, | |
174 CFX_Matrix& matrix) { | |
175 return FALSE; | |
176 } | |
177 FX_BOOL CFDE_TxtEdtPage::GetRect(FDE_HVISUALOBJ hVisualObj, CFX_RectF& rt) { | |
178 return FALSE; | |
179 } | |
180 FX_BOOL CFDE_TxtEdtPage::GetClip(FDE_HVISUALOBJ hVisualObj, CFX_RectF& rt) { | |
181 return FALSE; | |
182 } | |
183 int32_t CFDE_TxtEdtPage::GetCharRect(int32_t nIndex, | |
184 CFX_RectF& rect, | |
185 FX_BOOL bBBox) const { | |
186 FXSYS_assert(m_nRefCount > 0); | |
187 FXSYS_assert(nIndex >= 0 && nIndex < m_nCharCount); | |
188 if (m_nRefCount < 1) { | |
189 return 0; | |
190 } | |
191 int32_t nCount = m_PieceMassArr.GetSize(); | |
192 for (int32_t i = 0; i < nCount; i++) { | |
193 const FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(i); | |
194 if (nIndex >= pPiece->nStart && | |
195 nIndex < (pPiece->nStart + pPiece->nCount)) { | |
196 CFX_RectFArray rectArr; | |
197 if (bBBox) { | |
198 m_pTextSet->GetCharRects_Impl((FDE_HVISUALOBJ)pPiece, rectArr, bBBox); | |
199 } else { | |
200 m_pTextSet->GetCharRects((FDE_HVISUALOBJ)pPiece, rectArr); | |
201 } | |
202 rect = rectArr[nIndex - pPiece->nStart]; | |
203 return pPiece->nBidiLevel; | |
204 } | |
205 } | |
206 FXSYS_assert(0); | |
207 return 0; | |
208 } | |
209 int32_t CFDE_TxtEdtPage::GetCharIndex(const CFX_PointF& fPoint, | |
210 FX_BOOL& bBefore) { | |
211 FX_BOOL bVertical = m_pEditEngine->GetEditParams()->dwLayoutStyles & | |
212 FDE_TEXTEDITLAYOUT_DocVertical; | |
213 CFX_PointF ptF = fPoint; | |
214 NormalizePt2Rect(ptF, m_rtPageContents, FDE_TXTEDT_TOLERANCE); | |
215 int32_t nCount = m_PieceMassArr.GetSize(); | |
216 CFX_RectF rtLine; | |
217 int32_t nBgn = 0; | |
218 int32_t nEnd = 0; | |
219 FX_BOOL bInLine = FALSE; | |
220 int32_t i = 0; | |
221 for (i = 0; i < nCount; i++) { | |
222 const FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(i); | |
223 if (!bInLine && (bVertical ? (pPiece->rtPiece.left <= ptF.x && | |
224 pPiece->rtPiece.right() > ptF.x) | |
225 : (pPiece->rtPiece.top <= ptF.y && | |
226 pPiece->rtPiece.bottom() > ptF.y))) { | |
227 nBgn = nEnd = i; | |
228 rtLine = pPiece->rtPiece; | |
229 bInLine = TRUE; | |
230 } else if (bInLine) { | |
231 if (bVertical ? (!(pPiece->rtPiece.left <= ptF.x && | |
232 pPiece->rtPiece.right() > ptF.x)) | |
233 : (pPiece->rtPiece.bottom() <= ptF.y || | |
234 pPiece->rtPiece.top > ptF.y)) { | |
235 nEnd = i - 1; | |
236 break; | |
237 } else { | |
238 rtLine.Union(pPiece->rtPiece); | |
239 } | |
240 } | |
241 } | |
242 NormalizePt2Rect(ptF, rtLine, FDE_TXTEDT_TOLERANCE); | |
243 int32_t nCaret = 0; | |
244 FDE_TEXTEDITPIECE* pPiece = NULL; | |
245 for (i = nBgn; i <= nEnd; i++) { | |
246 pPiece = m_PieceMassArr.GetPtrAt(i); | |
247 nCaret = m_nPageStart + pPiece->nStart; | |
248 if (pPiece->rtPiece.Contains(ptF)) { | |
249 CFX_RectFArray rectArr; | |
250 m_pTextSet->GetCharRects((FDE_HVISUALOBJ)pPiece, rectArr); | |
251 int32_t nRtCount = rectArr.GetSize(); | |
252 for (int32_t j = 0; j < nRtCount; j++) { | |
253 if (rectArr[j].Contains(ptF)) { | |
254 nCaret = m_nPageStart + pPiece->nStart + j; | |
255 if (nCaret >= m_pEditEngine->GetTextBufLength()) { | |
256 bBefore = TRUE; | |
257 return m_pEditEngine->GetTextBufLength(); | |
258 } | |
259 FX_WCHAR wChar = m_pEditEngine->GetTextBuf()->GetCharByIndex(nCaret); | |
260 if (wChar == L'\n' || wChar == L'\r') { | |
261 if (wChar == L'\n') { | |
262 if (m_pEditEngine->GetTextBuf()->GetCharByIndex(nCaret - 1) == | |
263 L'\r') { | |
264 nCaret--; | |
265 } | |
266 } | |
267 bBefore = TRUE; | |
268 return nCaret; | |
269 } | |
270 if (bVertical | |
271 ? (ptF.y > ((rectArr[j].top + rectArr[j].bottom()) / 2)) | |
272 : (ptF.x > ((rectArr[j].left + rectArr[j].right()) / 2))) { | |
273 bBefore = FX_IsOdd(pPiece->nBidiLevel); | |
274 } else { | |
275 bBefore = !FX_IsOdd(pPiece->nBidiLevel); | |
276 } | |
277 return nCaret; | |
278 } | |
279 } | |
280 } | |
281 } | |
282 bBefore = TRUE; | |
283 return nCaret; | |
284 } | |
285 int32_t CFDE_TxtEdtPage::GetCharStart() const { | |
286 return m_nPageStart; | |
287 } | |
288 int32_t CFDE_TxtEdtPage::GetCharCount() const { | |
289 return m_nCharCount; | |
290 } | |
291 int32_t CFDE_TxtEdtPage::GetDisplayPos(const CFX_RectF& rtClip, | |
292 FXTEXT_CHARPOS*& pCharPos, | |
293 CFX_RectF* pBBox) const { | |
294 pCharPos = FX_Alloc(FXTEXT_CHARPOS, m_nCharCount); | |
295 int32_t nCharPosCount = 0; | |
296 FDE_HVISUALOBJ hVisualObj = NULL; | |
297 int32_t nVisualObjCount = m_PieceMassArr.GetSize(); | |
298 FXTEXT_CHARPOS* pos = pCharPos; | |
299 CFX_RectF rtObj; | |
300 for (int32_t i = 0; i < nVisualObjCount; i++) { | |
301 hVisualObj = (FDE_HVISUALOBJ)m_PieceMassArr.GetPtrAt(i); | |
302 m_pTextSet->GetRect(hVisualObj, rtObj); | |
303 if (!rtClip.IntersectWith(rtObj)) { | |
304 continue; | |
305 } | |
306 int32_t nCount = m_pTextSet->GetDisplayPos(hVisualObj, pos, FALSE); | |
307 nCharPosCount += nCount; | |
308 pos += nCount; | |
309 } | |
310 if ((nCharPosCount * 5) < (m_nCharCount << 2)) { | |
311 FXTEXT_CHARPOS* pTemp = FX_Alloc(FXTEXT_CHARPOS, nCharPosCount); | |
312 FXSYS_memcpy(pTemp, pCharPos, sizeof(FXTEXT_CHARPOS) * nCharPosCount); | |
313 FX_Free(pCharPos); | |
314 pCharPos = pTemp; | |
315 } | |
316 return nCharPosCount; | |
317 } | |
318 void CFDE_TxtEdtPage::CalcRangeRectArray(int32_t nStart, | |
319 int32_t nCount, | |
320 CFX_RectFArray& RectFArr) const { | |
321 int32_t nPieceCount = m_PieceMassArr.GetSize(); | |
322 int32_t nEnd = nStart + nCount - 1; | |
323 FX_BOOL bInRange = FALSE; | |
324 for (int32_t i = 0; i < nPieceCount; i++) { | |
325 FDE_TEXTEDITPIECE* piece = m_PieceMassArr.GetPtrAt(i); | |
326 if (!bInRange) { | |
327 if (nStart >= piece->nStart && nStart < (piece->nStart + piece->nCount)) { | |
328 int32_t nRangeEnd = piece->nCount - 1; | |
329 FX_BOOL bEnd = FALSE; | |
330 if (nEnd >= piece->nStart && nEnd < (piece->nStart + piece->nCount)) { | |
331 nRangeEnd = nEnd - piece->nStart; | |
332 bEnd = TRUE; | |
333 } | |
334 CFX_RectFArray rcArr; | |
335 m_pTextSet->GetCharRects((FDE_HVISUALOBJ)piece, rcArr); | |
336 CFX_RectF rectPiece = rcArr[nStart - piece->nStart]; | |
337 rectPiece.Union(rcArr[nRangeEnd]); | |
338 RectFArr.Add(rectPiece); | |
339 if (bEnd) { | |
340 return; | |
341 } | |
342 bInRange = TRUE; | |
343 } | |
344 } else { | |
345 if (nEnd >= piece->nStart && nEnd < (piece->nStart + piece->nCount)) { | |
346 CFX_RectFArray rcArr; | |
347 m_pTextSet->GetCharRects((FDE_HVISUALOBJ)piece, rcArr); | |
348 CFX_RectF rectPiece = rcArr[0]; | |
349 rectPiece.Union(rcArr[nEnd - piece->nStart]); | |
350 RectFArr.Add(rectPiece); | |
351 return; | |
352 } | |
353 RectFArr.Add(piece->rtPiece); | |
354 } | |
355 } | |
356 } | |
357 | |
358 int32_t CFDE_TxtEdtPage::SelectWord(const CFX_PointF& fPoint, int32_t& nCount) { | |
359 if (m_nRefCount < 0) { | |
360 return -1; | |
361 } | |
362 IFDE_TxtEdtBuf* pBuf = m_pEditEngine->GetTextBuf(); | |
363 FX_BOOL bBefore; | |
364 int32_t nIndex = GetCharIndex(fPoint, bBefore); | |
365 if (nIndex == m_pEditEngine->GetTextBufLength()) { | |
366 nIndex = m_pEditEngine->GetTextBufLength() - 1; | |
367 } | |
368 if (nIndex < 0) { | |
369 return -1; | |
370 } | |
371 IFX_WordBreak* pIter = FX_WordBreak_Create(); | |
372 pIter->Attach(new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pBuf)); | |
373 pIter->SetAt(nIndex); | |
374 nCount = pIter->GetWordLength(); | |
375 int32_t nRet = pIter->GetWordPos(); | |
376 pIter->Release(); | |
377 return nRet; | |
378 } | |
379 FX_BOOL CFDE_TxtEdtPage::IsLoaded(const CFX_RectF* pClipBox) { | |
380 return m_bLoaded; | |
381 } | |
382 int32_t CFDE_TxtEdtPage::LoadPage(const CFX_RectF* pClipBox, | |
383 IFX_Pause* pPause) { | |
384 if (m_nRefCount > 0) { | |
385 m_nRefCount++; | |
386 return m_nRefCount; | |
387 } | |
388 IFDE_TxtEdtBuf* pBuf = m_pEditEngine->GetTextBuf(); | |
389 const FDE_TXTEDTPARAMS* pParams = m_pEditEngine->GetEditParams(); | |
390 if (m_pIter != NULL) { | |
391 m_pIter->Release(); | |
392 } | |
393 FX_WCHAR wcAlias = 0; | |
394 if (pParams->dwMode & FDE_TEXTEDITMODE_Password) { | |
395 wcAlias = m_pEditEngine->GetAliasChar(); | |
396 } | |
397 m_pIter = new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pBuf, wcAlias); | |
398 IFX_TxtBreak* pBreak = m_pEditEngine->GetTextBreak(); | |
399 pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); | |
400 pBreak->ClearBreakPieces(); | |
401 int32_t nPageLineCount = m_pEditEngine->GetPageLineCount(); | |
402 int32_t nStartLine = nPageLineCount * m_nPageIndex; | |
403 int32_t nEndLine = std::min((nStartLine + nPageLineCount - 1), | |
404 (m_pEditEngine->GetLineCount() - 1)); | |
405 int32_t nPageStart, nPageEnd, nTemp, nBgnParag, nStartLineInParag, nEndParag, | |
406 nEndLineInParag; | |
407 nBgnParag = m_pEditEngine->Line2Parag(0, 0, nStartLine, nStartLineInParag); | |
408 m_pBgnParag = (CFDE_TxtEdtParag*)m_pEditEngine->GetParag(nBgnParag); | |
409 m_pBgnParag->LoadParag(); | |
410 m_pBgnParag->GetLineRange(nStartLine - nStartLineInParag, nPageStart, nTemp); | |
411 nEndParag = m_pEditEngine->Line2Parag(nBgnParag, nStartLineInParag, nEndLine, | |
412 nEndLineInParag); | |
413 m_pEndParag = (CFDE_TxtEdtParag*)m_pEditEngine->GetParag(nEndParag); | |
414 m_pEndParag->LoadParag(); | |
415 m_pEndParag->GetLineRange(nEndLine - nEndLineInParag, nPageEnd, nTemp); | |
416 nPageEnd += (nTemp - 1); | |
417 FX_BOOL bVertial = pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical; | |
418 FX_BOOL bLineReserve = | |
419 pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve; | |
420 FX_FLOAT fLineStart = | |
421 bVertial | |
422 ? (bLineReserve ? (pParams->fPlateWidth - pParams->fLineSpace) : 0.0f) | |
423 : 0.0f; | |
424 FX_FLOAT fLineStep = | |
425 (bVertial && bLineReserve) ? (-pParams->fLineSpace) : pParams->fLineSpace; | |
426 FX_FLOAT fLinePos = fLineStart; | |
427 if (m_pTextSet == NULL) { | |
428 m_pTextSet = new CFDE_TxtEdtTextSet(this); | |
429 } | |
430 m_PieceMassArr.RemoveAll(TRUE); | |
431 FX_DWORD dwBreakStatus = FX_TXTBREAK_None; | |
432 int32_t nPieceStart = 0; | |
433 if (m_pCharWidth != NULL) { | |
434 delete[] m_pCharWidth; | |
435 } | |
436 m_pCharWidth = new int32_t[nPageEnd - nPageStart + 1]; | |
437 pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); | |
438 pBreak->ClearBreakPieces(); | |
439 m_nPageStart = nPageStart; | |
440 m_nCharCount = nPageEnd - nPageStart + 1; | |
441 FX_BOOL bReload = FALSE; | |
442 FX_FLOAT fDefCharWidth = 0; | |
443 IFX_CharIter* pIter = m_pIter->Clone(); | |
444 pIter->SetAt(nPageStart); | |
445 m_pIter->SetAt(nPageStart); | |
446 FX_BOOL bFirstPiece = TRUE; | |
447 do { | |
448 if (bReload) { | |
449 dwBreakStatus = pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); | |
450 } else { | |
451 FX_WCHAR wAppend = pIter->GetChar(); | |
452 dwBreakStatus = pBreak->AppendChar(wAppend); | |
453 } | |
454 if (pIter->GetAt() == nPageEnd && dwBreakStatus < FX_TXTBREAK_LineBreak) { | |
455 dwBreakStatus = pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak); | |
456 } | |
457 if (dwBreakStatus > FX_TXTBREAK_PieceBreak) { | |
458 int32_t nPieceCount = pBreak->CountBreakPieces(); | |
459 for (int32_t j = 0; j < nPieceCount; j++) { | |
460 const CFX_TxtPiece* pPiece = pBreak->GetBreakPiece(j); | |
461 FDE_TEXTEDITPIECE TxtEdtPiece; | |
462 FXSYS_memset(&TxtEdtPiece, 0, sizeof(FDE_TEXTEDITPIECE)); | |
463 TxtEdtPiece.nBidiLevel = pPiece->m_iBidiLevel; | |
464 TxtEdtPiece.nCount = pPiece->GetLength(); | |
465 TxtEdtPiece.nStart = nPieceStart; | |
466 TxtEdtPiece.dwCharStyles = pPiece->m_dwCharStyles; | |
467 if (FX_IsOdd(pPiece->m_iBidiLevel)) { | |
468 TxtEdtPiece.dwCharStyles |= FX_TXTCHARSTYLE_OddBidiLevel; | |
469 } | |
470 FX_FLOAT fParaBreakWidth = 0.0f; | |
471 if (pPiece->m_dwStatus > FX_TXTBREAK_PieceBreak) { | |
472 FX_WCHAR wRtChar = pParams->wLineBreakChar; | |
473 if (TxtEdtPiece.nCount >= 2) { | |
474 FX_WCHAR wChar = pBuf->GetCharByIndex( | |
475 m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 1); | |
476 FX_WCHAR wCharPre = pBuf->GetCharByIndex( | |
477 m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 2); | |
478 if (wChar == wRtChar) { | |
479 fParaBreakWidth += fDefCharWidth; | |
480 } | |
481 if (wCharPre == wRtChar) { | |
482 fParaBreakWidth += fDefCharWidth; | |
483 } | |
484 } else if (TxtEdtPiece.nCount >= 1) { | |
485 FX_WCHAR wChar = pBuf->GetCharByIndex( | |
486 m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 1); | |
487 if (wChar == wRtChar) { | |
488 fParaBreakWidth += fDefCharWidth; | |
489 } | |
490 } | |
491 } | |
492 if (pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) { | |
493 TxtEdtPiece.rtPiece.left = fLinePos; | |
494 TxtEdtPiece.rtPiece.top = (FX_FLOAT)pPiece->m_iStartPos / 20000.0f; | |
495 TxtEdtPiece.rtPiece.width = pParams->fLineSpace; | |
496 TxtEdtPiece.rtPiece.height = | |
497 (FX_FLOAT)pPiece->m_iWidth / 20000.0f + fParaBreakWidth; | |
498 } else { | |
499 TxtEdtPiece.rtPiece.left = (FX_FLOAT)pPiece->m_iStartPos / 20000.0f; | |
500 TxtEdtPiece.rtPiece.top = fLinePos; | |
501 TxtEdtPiece.rtPiece.width = | |
502 (FX_FLOAT)pPiece->m_iWidth / 20000.0f + fParaBreakWidth; | |
503 TxtEdtPiece.rtPiece.height = pParams->fLineSpace; | |
504 } | |
505 if (bFirstPiece) { | |
506 m_rtPageContents = TxtEdtPiece.rtPiece; | |
507 bFirstPiece = FALSE; | |
508 } else { | |
509 m_rtPageContents.Union(TxtEdtPiece.rtPiece); | |
510 } | |
511 nPieceStart += TxtEdtPiece.nCount; | |
512 m_PieceMassArr.Add(TxtEdtPiece); | |
513 for (int32_t k = 0; k < TxtEdtPiece.nCount; k++) { | |
514 CFX_Char* ptc = pPiece->GetCharPtr(k); | |
515 m_pCharWidth[TxtEdtPiece.nStart + k] = ptc->m_iCharWidth; | |
516 } | |
517 } | |
518 fLinePos += fLineStep; | |
519 pBreak->ClearBreakPieces(); | |
520 } | |
521 if (pIter->GetAt() == nPageEnd && dwBreakStatus == FX_TXTBREAK_LineBreak) { | |
522 bReload = TRUE; | |
523 pIter->Next(TRUE); | |
524 } | |
525 } while (pIter->Next(FALSE) && (pIter->GetAt() <= nPageEnd)); | |
526 if (m_rtPageContents.left != 0) { | |
527 FX_FLOAT fDelta = 0.0f; | |
528 if (m_rtPageContents.width < pParams->fPlateWidth) { | |
529 if (pParams->dwAlignment & FDE_TEXTEDITALIGN_Right) { | |
530 fDelta = pParams->fPlateWidth - m_rtPageContents.width; | |
531 } else if (pParams->dwAlignment & FDE_TEXTEDITALIGN_Center) { | |
532 if ((pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) && | |
533 m_nCharCount > 1) { | |
534 int32_t nCount = m_nCharCount - 1; | |
535 int32_t n = (m_pEditEngine->m_nLimit - nCount) / 2; | |
536 fDelta = (m_rtPageContents.width / nCount) * n; | |
537 } else { | |
538 fDelta = (pParams->fPlateWidth - m_rtPageContents.width) / 2; | |
539 } | |
540 } | |
541 } | |
542 FX_FLOAT fOffset = m_rtPageContents.left - fDelta; | |
543 int32_t nCount = m_PieceMassArr.GetSize(); | |
544 for (int32_t i = 0; i < nCount; i++) { | |
545 FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(i); | |
546 pPiece->rtPiece.Offset(-fOffset, 0.0f); | |
547 } | |
548 m_rtPageContents.Offset(-fOffset, 0.0f); | |
549 } | |
550 if (m_pEditEngine->GetEditParams()->dwLayoutStyles & | |
551 FDE_TEXTEDITLAYOUT_LastLineHeight) { | |
552 m_rtPageContents.height -= pParams->fLineSpace - pParams->fFontSize; | |
553 int32_t nCount = m_PieceMassArr.GetSize(); | |
554 FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(nCount - 1); | |
555 pPiece->rtPiece.height = pParams->fFontSize; | |
556 } | |
557 pIter->Release(); | |
558 m_nRefCount = 1; | |
559 m_bLoaded = TRUE; | |
560 return 0; | |
561 } | |
562 void CFDE_TxtEdtPage::UnloadPage(const CFX_RectF* pClipBox) { | |
563 FXSYS_assert(m_nRefCount > 0); | |
564 m_nRefCount--; | |
565 if (m_nRefCount == 0) { | |
566 m_PieceMassArr.RemoveAll(); | |
567 if (m_pTextSet) { | |
568 delete m_pTextSet; | |
569 m_pTextSet = NULL; | |
570 } | |
571 if (m_pCharWidth) { | |
572 delete[] m_pCharWidth; | |
573 m_pCharWidth = NULL; | |
574 } | |
575 if (m_pBgnParag) { | |
576 m_pBgnParag->UnloadParag(); | |
577 } | |
578 if (m_pEndParag) { | |
579 m_pEndParag->UnloadParag(); | |
580 } | |
581 if (m_pIter) { | |
582 m_pIter->Release(); | |
583 m_pIter = NULL; | |
584 } | |
585 m_pBgnParag = NULL; | |
586 m_pEndParag = NULL; | |
587 } | |
588 } | |
589 | |
590 const CFX_RectF& CFDE_TxtEdtPage::GetContentsBox() { | |
591 return m_rtPageContents; | |
592 } | |
593 FX_POSITION CFDE_TxtEdtPage::GetFirstPosition(FDE_HVISUALOBJ hCanvas) { | |
594 if (m_PieceMassArr.GetSize() < 1) { | |
595 return NULL; | |
596 } | |
597 return (FX_POSITION)1; | |
598 } | |
599 FDE_HVISUALOBJ CFDE_TxtEdtPage::GetNext(FDE_HVISUALOBJ hCanvas, | |
600 FX_POSITION& pos, | |
601 IFDE_VisualSet*& pVisualSet) { | |
602 if (m_pTextSet == NULL) { | |
603 pos = NULL; | |
604 return NULL; | |
605 } | |
606 int32_t nPos = (int32_t)(uintptr_t)pos; | |
607 pVisualSet = m_pTextSet; | |
608 if (nPos + 1 > m_PieceMassArr.GetSize()) { | |
609 pos = NULL; | |
610 } else { | |
611 pos = (FX_POSITION)(uintptr_t)(nPos + 1); | |
612 } | |
613 return (FDE_HVISUALOBJ)(m_PieceMassArr.GetPtrAt(nPos - 1)); | |
614 } | |
615 FDE_HVISUALOBJ CFDE_TxtEdtPage::GetParentCanvas(FDE_HVISUALOBJ hCanvas, | |
616 IFDE_VisualSet*& pVisualSet) { | |
617 return NULL; | |
618 } | |
619 FX_WCHAR CFDE_TxtEdtPage::GetChar(void* pIdentity, int32_t index) const { | |
620 int32_t nIndex = | |
621 m_nPageStart + ((FDE_TEXTEDITPIECE*)pIdentity)->nStart + index; | |
622 if (nIndex != m_pIter->GetAt()) { | |
623 m_pIter->SetAt(nIndex); | |
624 } | |
625 FX_WCHAR wChar = m_pIter->GetChar(); | |
626 m_pIter->Next(); | |
627 return wChar; | |
628 } | |
629 int32_t CFDE_TxtEdtPage::GetWidth(void* pIdentity, int32_t index) const { | |
630 int32_t nWidth = | |
631 m_pCharWidth[((FDE_TEXTEDITPIECE*)pIdentity)->nStart + index]; | |
632 return nWidth; | |
633 } | |
634 void CFDE_TxtEdtPage::NormalizePt2Rect(CFX_PointF& ptF, | |
635 const CFX_RectF& rtF, | |
636 FX_FLOAT fTolerance) const { | |
637 if (rtF.Contains(ptF.x, ptF.y)) { | |
638 return; | |
639 } | |
640 if (ptF.x < rtF.left) { | |
641 ptF.x = rtF.left; | |
642 } else if (ptF.x >= rtF.right()) { | |
643 ptF.x = rtF.right() - fTolerance; | |
644 } | |
645 if (ptF.y < rtF.top) { | |
646 ptF.y = rtF.top; | |
647 } else if (ptF.y >= rtF.bottom()) { | |
648 ptF.y = rtF.bottom() - fTolerance; | |
649 } | |
650 } | |
OLD | NEW |