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.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
7 #include "../../include/fpdfdoc/fpdf_doc.h"
8 #include "../../include/fpdfdoc/fpdf_vt.h"
10 const FX_BYTE gFontSizeSteps[] = { 4, 6, 8, 9, 10, 12, 14, 18, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, 90, 100, 110, 120, 130, 144};
11 #define PVT_RETURN_LENGTH 1
12 #define PVT_DEFAULT_FONTSIZE 18.0f
13 #define PVTWORD_SCRIPT_NORMAL 0
14 #define PVTWORD_SCRIPT_SUPER 1
15 #define PVTWORD_SCRIPT_SUB 2
16 #define PVT_FONTSCALE 0.001f
17 #define PVT_PERCENT 0.01f
25 CPVT_WordPlace CLine::GetBeginWordPlace() const
27 return CPVT_WordPlace(LinePlace.nSecIndex, LinePlace.nLineIndex, -1);
29 CPVT_WordPlace CLine::GetEndWordPlace() const
31 return CPVT_WordPlace(LinePlace.nSecIndex, LinePlace.nLineIndex, m_LineInfo.nEndWordIndex);
33 CPVT_WordPlace CLine::GetPrevWordPlace(const CPVT_WordPlace & place) const
35 if (place.nWordIndex > m_LineInfo.nEndWordIndex) {
36 return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, m_LineInfo.nEndWordIndex);
38 return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, place.nWordIndex - 1);
40 CPVT_WordPlace CLine::GetNextWordPlace(const CPVT_WordPlace & place) const
42 if (place.nWordIndex < m_LineInfo.nBeginWordIndex) {
43 return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, m_LineInfo.nBeginWordIndex);
45 return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, place.nWordIndex + 1);
47 CSection::CSection(CPDF_VariableText * pVT) : m_pVT(pVT)
54 void CSection::ResetAll()
59 void CSection::ResetLineArray()
61 m_LineArray.RemoveAll();
63 void CSection::ResetWordArray()
65 for (FX_INT32 i = 0, sz = m_WordArray.GetSize(); i < sz; i++) {
66 delete m_WordArray.GetAt(i);
68 m_WordArray.RemoveAll();
70 void CSection::ResetLinePlace()
72 for (FX_INT32 i = 0, sz = m_LineArray.GetSize(); i < sz; i++) {
73 if (CLine * pLine = m_LineArray.GetAt(i)) {
74 pLine->LinePlace = CPVT_WordPlace(SecPlace.nSecIndex, i, -1);
78 CPVT_WordPlace CSection::AddWord(const CPVT_WordPlace & place, const CPVT_WordInfo & wordinfo)
80 if (CPVT_WordInfo * pWord = FX_NEW CPVT_WordInfo(wordinfo)) {
81 FX_INT32 nWordIndex = FPDF_MAX(FPDF_MIN(place.nWordIndex, this->m_WordArray.GetSize()), 0);
82 if (nWordIndex == m_WordArray.GetSize()) {
83 m_WordArray.Add(pWord);
85 m_WordArray.InsertAt(nWordIndex, pWord);
90 CPVT_WordPlace CSection::AddLine(const CPVT_LineInfo & lineinfo)
92 return CPVT_WordPlace(SecPlace.nSecIndex, m_LineArray.Add(lineinfo), -1);
94 CPVT_FloatRect CSection::Rearrange()
96 ASSERT(m_pVT != NULL);
97 if (m_pVT->m_nCharArray > 0) {
98 return CTypeset(this).CharArray();
100 return CTypeset(this).Typeset();
103 CPVT_Size CSection::GetSectionSize(FX_FLOAT fFontSize)
105 return CTypeset(this).GetEditSize(fFontSize);
107 CPVT_WordPlace CSection::GetBeginWordPlace() const
109 if (CLine * pLine = m_LineArray.GetAt(0)) {
110 return pLine->GetBeginWordPlace();
115 CPVT_WordPlace CSection::GetEndWordPlace() const
117 if (CLine * pLine = m_LineArray.GetAt(m_LineArray.GetSize() - 1)) {
118 return pLine->GetEndWordPlace();
120 return this->SecPlace;
123 CPVT_WordPlace CSection::GetPrevWordPlace(const CPVT_WordPlace & place) const
125 if (place.nLineIndex < 0) {
126 return GetBeginWordPlace();
128 if (place.nLineIndex >= m_LineArray.GetSize()) {
129 return GetEndWordPlace();
131 if (CLine * pLine = m_LineArray.GetAt(place.nLineIndex)) {
132 if (place.nWordIndex == pLine->m_LineInfo.nBeginWordIndex) {
133 return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, -1);
134 } else if (place.nWordIndex < pLine->m_LineInfo.nBeginWordIndex) {
135 if (CLine * pPrevLine = m_LineArray.GetAt(place.nLineIndex - 1)) {
136 return pPrevLine->GetEndWordPlace();
139 return pLine->GetPrevWordPlace(place);
144 CPVT_WordPlace CSection::GetNextWordPlace(const CPVT_WordPlace & place) const
146 if (place.nLineIndex < 0) {
147 return GetBeginWordPlace();
149 if (place.nLineIndex >= m_LineArray.GetSize()) {
150 return GetEndWordPlace();
152 if (CLine * pLine = m_LineArray.GetAt(place.nLineIndex)) {
153 if (place.nWordIndex >= pLine->m_LineInfo.nEndWordIndex) {
154 if (CLine * pNextLine = m_LineArray.GetAt(place.nLineIndex + 1)) {
155 return pNextLine->GetBeginWordPlace();
158 return pLine->GetNextWordPlace(place);
163 void CSection::UpdateWordPlace(CPVT_WordPlace & place) const
166 FX_INT32 nRight = m_LineArray.GetSize() - 1;
167 FX_INT32 nMid = (nLeft + nRight) / 2;
168 while (nLeft <= nRight) {
169 if (CLine * pLine = m_LineArray.GetAt(nMid)) {
170 if (place.nWordIndex < pLine->m_LineInfo.nBeginWordIndex) {
172 nMid = (nLeft + nRight) / 2;
173 } else if (place.nWordIndex > pLine->m_LineInfo.nEndWordIndex) {
175 nMid = (nLeft + nRight) / 2;
177 place.nLineIndex = nMid;
185 CPVT_WordPlace CSection::SearchWordPlace(const CPDF_Point & point) const
187 ASSERT(m_pVT != NULL);
188 CPVT_WordPlace place = GetBeginWordPlace();
190 FX_BOOL bDown = TRUE;
192 FX_INT32 nRight = m_LineArray.GetSize() - 1;
193 FX_INT32 nMid = m_LineArray.GetSize() / 2;
195 FX_FLOAT fBottom = 0;
196 while (nLeft <= nRight) {
197 if (CLine * pLine = m_LineArray.GetAt(nMid)) {
198 fTop = pLine->m_LineInfo.fLineY - pLine->m_LineInfo.fLineAscent - m_pVT->GetLineLeading(m_SecInfo);
199 fBottom = pLine->m_LineInfo.fLineY - pLine->m_LineInfo.fLineDescent;
200 if (IsFloatBigger(point.y, fTop)) {
203 if (IsFloatSmaller(point.y, fBottom)) {
206 if (IsFloatSmaller(point.y, fTop)) {
208 nMid = (nLeft + nRight) / 2;
210 } else if (IsFloatBigger(point.y, fBottom)) {
212 nMid = (nLeft + nRight) / 2;
215 place = SearchWordPlace(point.x,
216 CPVT_WordRange(pLine->GetNextWordPlace(pLine->GetBeginWordPlace()), pLine->GetEndWordPlace())
218 place.nLineIndex = nMid;
224 place = GetBeginWordPlace();
227 place = GetEndWordPlace();
231 CPVT_WordPlace CSection::SearchWordPlace(FX_FLOAT fx, const CPVT_WordPlace & lineplace) const
233 if (CLine * pLine = m_LineArray.GetAt(lineplace.nLineIndex)) {
234 return SearchWordPlace(fx - m_SecInfo.rcSection.left,
235 CPVT_WordRange(pLine->GetNextWordPlace(pLine->GetBeginWordPlace()), pLine->GetEndWordPlace()));
237 return GetBeginWordPlace();
239 CPVT_WordPlace CSection::SearchWordPlace(FX_FLOAT fx, const CPVT_WordRange & range) const
241 CPVT_WordPlace wordplace = range.BeginPos;
242 wordplace.nWordIndex = -1;
246 FX_INT32 nLeft = range.BeginPos.nWordIndex;
247 FX_INT32 nRight = range.EndPos.nWordIndex + 1;
248 FX_INT32 nMid = (nLeft + nRight) / 2;
249 while (nLeft < nRight) {
253 if (nMid == nRight) {
257 if (CPVT_WordInfo * pWord = m_WordArray.GetAt(nMid)) {
258 if (fx > pWord->fWordX + m_pVT->GetWordWidth(*pWord) * PVT_HALF) {
260 nMid = (nLeft + nRight) / 2;
264 nMid = (nLeft + nRight) / 2;
271 if (CPVT_WordInfo * pWord = m_WordArray.GetAt(nMid)) {
272 if (fx > pWord->fWordX + m_pVT->GetWordWidth(*pWord) * PVT_HALF) {
273 wordplace.nWordIndex = nMid;
278 void CSection::ClearLeftWords(FX_INT32 nWordIndex)
280 for (FX_INT32 i = nWordIndex; i >= 0; i--) {
281 delete m_WordArray.GetAt(i);
282 m_WordArray.RemoveAt(i);
285 void CSection::ClearRightWords(FX_INT32 nWordIndex)
287 for (FX_INT32 i = m_WordArray.GetSize() - 1; i > nWordIndex; i--) {
288 delete m_WordArray.GetAt(i);
289 m_WordArray.RemoveAt(i);
292 void CSection::ClearMidWords(FX_INT32 nBeginIndex, FX_INT32 nEndIndex)
294 for (FX_INT32 i = nEndIndex; i > nBeginIndex; i--) {
295 delete m_WordArray.GetAt(i);
296 m_WordArray.RemoveAt(i);
299 void CSection::ClearWords(const CPVT_WordRange & PlaceRange)
301 CPVT_WordPlace SecBeginPos = GetBeginWordPlace();
302 CPVT_WordPlace SecEndPos = GetEndWordPlace();
303 if (PlaceRange.BeginPos.WordCmp(SecBeginPos) >= 0) {
304 if (PlaceRange.EndPos.WordCmp(SecEndPos) <= 0) {
305 ClearMidWords(PlaceRange.BeginPos.nWordIndex, PlaceRange.EndPos.nWordIndex);
307 ClearRightWords(PlaceRange.BeginPos.nWordIndex);
309 } else if (PlaceRange.EndPos.WordCmp(SecEndPos) <= 0) {
310 ClearLeftWords(PlaceRange.EndPos.nWordIndex);
315 void CSection::ClearWord(const CPVT_WordPlace & place)
317 delete m_WordArray.GetAt(place.nWordIndex);
318 m_WordArray.RemoveAt(place.nWordIndex);
320 CTypeset::CTypeset(CSection * pSection) : m_pSection(pSection), m_pVT(pSection->m_pVT), m_rcRet(0.0f, 0.0f, 0.0f, 0.0f)
323 CTypeset::~CTypeset()
326 CPVT_FloatRect CTypeset::CharArray()
328 ASSERT(m_pSection != NULL);
329 ASSERT(m_pVT != NULL);
330 FX_FLOAT fLineAscent = m_pVT->GetFontAscent(m_pVT->GetDefaultFontIndex(), m_pVT->GetFontSize());
331 FX_FLOAT fLineDescent = m_pVT->GetFontDescent(m_pVT->GetDefaultFontIndex(), m_pVT->GetFontSize());
333 FX_FLOAT x = 0.0f, y = 0.0f;
336 FX_FLOAT fNodeWidth = m_pVT->GetPlateWidth() / (m_pVT->m_nCharArray <= 0 ? 1 : m_pVT->m_nCharArray);
337 if (CLine * pLine = m_pSection->m_LineArray.GetAt(0)) {
339 y += m_pVT->GetLineLeading(m_pSection->m_SecInfo);
342 switch (m_pVT->GetAlignment(m_pSection->m_SecInfo)) {
344 pLine->m_LineInfo.fLineX = fNodeWidth * PVT_HALF;
347 nStart = (m_pVT->m_nCharArray - m_pSection->m_WordArray.GetSize()) / 2;
348 pLine->m_LineInfo.fLineX = fNodeWidth * nStart - fNodeWidth * PVT_HALF;
351 nStart = m_pVT->m_nCharArray - m_pSection->m_WordArray.GetSize();
352 pLine->m_LineInfo.fLineX = fNodeWidth * nStart - fNodeWidth * PVT_HALF;
355 for (FX_INT32 w = 0, sz = m_pSection->m_WordArray.GetSize(); w < sz; w++) {
356 if (w >= m_pVT->m_nCharArray) {
360 if (CPVT_WordInfo * pNextWord = (CPVT_WordInfo *)m_pSection->m_WordArray.GetAt(w + 1)) {
361 pNextWord->fWordTail = 0;
362 fNextWidth = m_pVT->GetWordWidth(*pNextWord);
364 if (CPVT_WordInfo * pWord = (CPVT_WordInfo *)m_pSection->m_WordArray.GetAt(w)) {
365 pWord->fWordTail = 0;
366 FX_FLOAT fWordWidth = m_pVT->GetWordWidth(*pWord);
367 FX_FLOAT fWordAscent = m_pVT->GetWordAscent(*pWord);
368 FX_FLOAT fWordDescent = m_pVT->GetWordDescent(*pWord);
369 x = (FX_FLOAT)(fNodeWidth * (w + nStart + 0.5) - fWordWidth * PVT_HALF);
373 pLine->m_LineInfo.fLineX = x;
375 if (w != m_pSection->m_WordArray.GetSize() - 1)
376 pWord->fWordTail = (fNodeWidth - (fWordWidth + fNextWidth) * PVT_HALF > 0 ?
377 fNodeWidth - (fWordWidth + fNextWidth) * PVT_HALF : 0);
379 pWord->fWordTail = 0;
382 fLineAscent = FPDF_MAX(fLineAscent, fWordAscent);
383 fLineDescent = FPDF_MIN(fLineDescent, fWordDescent);
386 pLine->m_LineInfo.nBeginWordIndex = 0;
387 pLine->m_LineInfo.nEndWordIndex = m_pSection->m_WordArray.GetSize() - 1;
388 pLine->m_LineInfo.fLineY = y;
389 pLine->m_LineInfo.fLineWidth = x - pLine->m_LineInfo.fLineX;
390 pLine->m_LineInfo.fLineAscent = fLineAscent;
391 pLine->m_LineInfo.fLineDescent = fLineDescent;
392 y += (-fLineDescent);
394 return m_rcRet = CPVT_FloatRect(0, 0, x, y);
396 CPVT_Size CTypeset::GetEditSize(FX_FLOAT fFontSize)
398 ASSERT(m_pSection != NULL);
399 ASSERT(m_pVT != NULL);
400 SplitLines(FALSE, fFontSize);
401 return CPVT_Size(m_rcRet.Width(), m_rcRet.Height());
403 CPVT_FloatRect CTypeset::Typeset()
405 ASSERT(m_pSection != NULL);
406 ASSERT(m_pVT != NULL);
407 m_pSection->m_LineArray.Empty();
408 SplitLines(TRUE, 0.0f);
409 m_pSection->m_LineArray.Clear();
413 static int special_chars[128] = {
414 0x0000, 0x000C, 0x0008, 0x000C, 0x0008, 0x0000, 0x0020, 0x0000,
415 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
416 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
417 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
418 0x0000, 0x0008, 0x0008, 0x0000, 0x0010, 0x0000, 0x0000, 0x0028,
419 0x000C, 0x0008, 0x0000, 0x0000, 0x0028, 0x0028, 0x0028, 0x0028,
420 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
421 0x0002, 0x0002, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0008,
422 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
423 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
424 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
425 0x0001, 0x0001, 0x0001, 0x000C, 0x0000, 0x0008, 0x0000, 0x0000,
426 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
427 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
428 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
429 0x0001, 0x0001, 0x0001, 0x000C, 0x0000, 0x0008, 0x0000, 0x0000,
431 static FX_BOOL IsLatin(FX_WORD word)
433 if (word <= 0x007F) {
434 if (special_chars[word] & 0x0001) {
438 if ((word >= 0x00C0 && word <= 0x00FF) ||
439 (word >= 0x0100 && word <= 0x024F) ||
440 (word >= 0x1E00 && word <= 0x1EFF) ||
441 (word >= 0x2C60 && word <= 0x2C7F) ||
442 (word >= 0xA720 && word <= 0xA7FF) ||
443 (word >= 0xFF21 && word <= 0xFF3A) ||
444 (word >= 0xFF41 && word <= 0xFF5A)) {
449 static FX_BOOL IsDigit(FX_DWORD word)
451 return (word >= 0x0030 && word <= 0x0039) ? TRUE : FALSE;
453 static FX_BOOL IsCJK(FX_DWORD word)
455 if ((word >= 0x1100 && word <= 0x11FF) ||
456 (word >= 0x2E80 && word <= 0x2FFF) ||
457 (word >= 0x3040 && word <= 0x9FBF) ||
458 (word >= 0xAC00 && word <= 0xD7AF) ||
459 (word >= 0xF900 && word <= 0xFAFF) ||
460 (word >= 0xFE30 && word <= 0xFE4F) ||
461 (word >= 0x20000 && word <= 0x2A6DF) ||
462 (word >= 0x2F800 && word <= 0x2FA1F)) {
465 if (word >= 0x3000 && word <= 0x303F) {
466 if (word == 0x3005 || word == 0x3006 || word == 0x3021 || word == 0x3022 ||
467 word == 0x3023 || word == 0x3024 || word == 0x3025 || word == 0x3026 ||
468 word == 0x3027 || word == 0x3028 || word == 0x3029 || word == 0x3031 ||
469 word == 0x3032 || word == 0x3033 || word == 0x3034 || word == 0x3035) {
474 if (word >= 0xFF66 && word <= 0xFF9D) {
479 static FX_BOOL IsPunctuation(FX_DWORD word)
481 if (word <= 0x007F) {
482 if ((special_chars[word] >> 3) & 1) {
485 } else if (word >= 0x0080 && word <= 0x00FF) {
486 if (word == 0x0082 || word == 0x0084 || word == 0x0085 || word == 0x0091 ||
487 word == 0x0092 || word == 0x0093 || word <= 0x0094 || word == 0x0096 ||
488 word == 0x00B4 || word == 0x00B8) {
491 } else if (word >= 0x2000 && word <= 0x206F) {
492 if (word == 0x2010 || word == 0x2011 || word == 0x2012 || word == 0x2013 ||
493 word == 0x2018 || word == 0x2019 || word == 0x201A || word == 0x201B ||
494 word == 0x201C || word == 0x201D || word == 0x201E || word == 0x201F ||
495 word == 0x2032 || word == 0x2033 || word == 0x2034 || word == 0x2035 ||
496 word == 0x2036 || word == 0x2037 || word == 0x203C || word == 0x203D ||
497 word == 0x203E || word == 0x2044) {
500 } else if (word >= 0x3000 && word <= 0x303F) {
501 if (word == 0x3001 || word == 0x3002 || word == 0x3003 || word == 0x3005 ||
502 word == 0x3009 || word == 0x300A || word == 0x300B || word == 0x300C ||
503 word == 0x300D || word == 0x300F || word == 0x300E || word == 0x3010 ||
504 word == 0x3011 || word == 0x3014 || word == 0x3015 || word == 0x3016 ||
505 word == 0x3017 || word == 0x3018 || word == 0x3019 || word == 0x301A ||
506 word == 0x301B || word == 0x301D || word == 0x301E || word == 0x301F) {
509 } else if (word >= 0xFE50 && word <= 0xFE6F) {
510 if ((word >= 0xFE50 && word <= 0xFE5E) || word == 0xFE63) {
513 } else if (word >= 0xFF00 && word <= 0xFFEF) {
514 if (word == 0xFF01 || word == 0xFF02 || word == 0xFF07 || word == 0xFF08 ||
515 word == 0xFF09 || word == 0xFF0C || word == 0xFF0E || word == 0xFF0F ||
516 word == 0xFF1A || word == 0xFF1B || word == 0xFF1F || word == 0xFF3B ||
517 word == 0xFF3D || word == 0xFF40 || word == 0xFF5B || word == 0xFF5C ||
518 word == 0xFF5D || word == 0xFF61 || word == 0xFF62 || word == 0xFF63 ||
519 word == 0xFF64 || word == 0xFF65 || word == 0xFF9E || word == 0xFF9F) {
525 static FX_BOOL IsConnectiveSymbol(FX_DWORD word)
527 if (word <= 0x007F) {
528 if ((special_chars[word] >> 5) & 1) {
534 static FX_BOOL IsOpenStylePunctuation(FX_DWORD word)
536 if (word <= 0x007F) {
537 if ((special_chars[word] >> 2) & 1) {
540 } else if (word == 0x300A || word == 0x300C || word == 0x300E || word == 0x3010 ||
541 word == 0x3014 || word == 0x3016 || word == 0x3018 || word == 0x301A ||
542 word == 0xFF08 || word == 0xFF3B || word == 0xFF5B || word == 0xFF62) {
547 static FX_BOOL IsCurrencySymbol(FX_WORD word)
549 if (word == 0x0024 || word == 0x0080 || word == 0x00A2 || word == 0x00A3 ||
550 word == 0x00A4 || word == 0x00A5 || (word >= 0x20A0 && word <= 0x20CF) ||
551 word == 0xFE69 || word == 0xFF04 || word == 0xFFE0 || word == 0xFFE1 ||
552 word == 0xFFE5 || word == 0xFFE6) {
557 static FX_BOOL IsPrefixSymbol(FX_WORD word)
559 if (IsCurrencySymbol(word)) {
562 if (word == 0x2116) {
567 static FX_BOOL IsSpace(FX_WORD word)
569 return (word == 0x0020 || word == 0x3000) ? TRUE : FALSE;
571 static FX_BOOL NeedDivision(FX_WORD prevWord, FX_WORD curWord)
573 if ((IsLatin(prevWord) || IsDigit(prevWord)) && (IsLatin(curWord) || IsDigit(curWord))) {
575 } else if (IsSpace(curWord) || IsPunctuation(curWord)) {
577 } else if (IsConnectiveSymbol(prevWord) || IsConnectiveSymbol(curWord)) {
579 } else if (IsSpace(prevWord) || IsPunctuation(prevWord)) {
581 } else if (IsPrefixSymbol(prevWord)) {
583 } else if (IsPrefixSymbol(curWord) || IsCJK(curWord)) {
585 } else if (IsCJK(prevWord)) {
590 void CTypeset::SplitLines(FX_BOOL bTypeset, FX_FLOAT fFontSize)
592 ASSERT(m_pVT != NULL);
593 ASSERT(m_pSection != NULL);
594 FX_INT32 nLineHead = 0;
595 FX_INT32 nLineTail = 0;
596 FX_FLOAT fMaxX = 0.0f, fMaxY = 0.0f;
597 FX_FLOAT fLineWidth = 0.0f, fBackupLineWidth = 0.0f;
598 FX_FLOAT fLineAscent = 0.0f, fBackupLineAscent = 0.0f;
599 FX_FLOAT fLineDescent = 0.0f, fBackupLineDescent = 0.0f;
600 FX_INT32 nWordStartPos = 0;
601 FX_BOOL bFullWord = FALSE;
602 FX_INT32 nLineFullWordIndex = 0;
603 FX_INT32 nCharIndex = 0;
605 FX_FLOAT fWordWidth = 0;
606 FX_FLOAT fTypesetWidth = FPDF_MAX(m_pVT->GetPlateWidth() - m_pVT->GetLineIndent(m_pSection->m_SecInfo), 0.0f);
607 FX_INT32 nTotalWords = m_pSection->m_WordArray.GetSize();
608 FX_BOOL bOpened = FALSE;
609 if (nTotalWords > 0) {
611 while (i < nTotalWords) {
612 CPVT_WordInfo * pWord = m_pSection->m_WordArray.GetAt(i);
613 CPVT_WordInfo* pOldWord = pWord;
615 pOldWord = m_pSection->m_WordArray.GetAt(i - 1);
619 fLineAscent = FPDF_MAX(fLineAscent, m_pVT->GetWordAscent(*pWord, TRUE));
620 fLineDescent = FPDF_MIN(fLineDescent, m_pVT->GetWordDescent(*pWord, TRUE));
621 fWordWidth = m_pVT->GetWordWidth(*pWord);
623 fLineAscent = FPDF_MAX(fLineAscent, m_pVT->GetWordAscent(*pWord, fFontSize));
624 fLineDescent = FPDF_MIN(fLineDescent, m_pVT->GetWordDescent(*pWord, fFontSize));
625 fWordWidth = m_pVT->GetWordWidth(pWord->nFontIndex,
635 if (IsOpenStylePunctuation(pWord->Word)) {
638 } else if (pOldWord != NULL) {
639 if (NeedDivision(pOldWord->Word, pWord->Word)) {
644 if (!IsSpace(pWord->Word) && !IsOpenStylePunctuation(pWord->Word)) {
650 if (nCharIndex > 0) {
651 nLineFullWordIndex ++;
654 fBackupLineWidth = fLineWidth;
655 fBackupLineAscent = fLineAscent;
656 fBackupLineDescent = fLineDescent;
660 if (m_pVT->m_bLimitWidth && fTypesetWidth > 0 &&
661 fLineWidth + fWordWidth > fTypesetWidth) {
662 if (nLineFullWordIndex > 0) {
664 fLineWidth = fBackupLineWidth;
665 fLineAscent = fBackupLineAscent;
666 fLineDescent = fBackupLineDescent;
668 if (nCharIndex == 1) {
669 fLineWidth = fWordWidth;
674 line.nBeginWordIndex = nLineHead;
675 line.nEndWordIndex = nLineTail;
676 line.nTotalWord = nLineTail - nLineHead + 1;
677 line.fLineWidth = fLineWidth;
678 line.fLineAscent = fLineAscent;
679 line.fLineDescent = fLineDescent;
680 m_pSection->AddLine(line);
682 fMaxY += (fLineAscent + m_pVT->GetLineLeading(m_pSection->m_SecInfo));
683 fMaxY += (-fLineDescent);
684 fMaxX = FPDF_MAX(fLineWidth, fMaxX);
690 nLineFullWordIndex = 0;
693 fLineWidth += fWordWidth;
697 if (nLineHead <= nTotalWords - 1) {
698 nLineTail = nTotalWords - 1;
700 line.nBeginWordIndex = nLineHead;
701 line.nEndWordIndex = nLineTail;
702 line.nTotalWord = nLineTail - nLineHead + 1;
703 line.fLineWidth = fLineWidth;
704 line.fLineAscent = fLineAscent;
705 line.fLineDescent = fLineDescent;
706 m_pSection->AddLine(line);
708 fMaxY += (fLineAscent + m_pVT->GetLineLeading(m_pSection->m_SecInfo));
709 fMaxY += (-fLineDescent);
710 fMaxX = FPDF_MAX(fLineWidth, fMaxX);
714 fLineAscent = m_pVT->GetLineAscent(m_pSection->m_SecInfo);
715 fLineDescent = m_pVT->GetLineDescent(m_pSection->m_SecInfo);
717 fLineAscent = m_pVT->GetFontAscent(m_pVT->GetDefaultFontIndex(), fFontSize);
718 fLineDescent = m_pVT->GetFontDescent(m_pVT->GetDefaultFontIndex(), fFontSize);
721 line.nBeginWordIndex = -1;
722 line.nEndWordIndex = -1;
725 line.fLineAscent = fLineAscent;
726 line.fLineDescent = fLineDescent;
727 m_pSection->AddLine(line);
729 fMaxY += (m_pVT->GetLineLeading(m_pSection->m_SecInfo) + fLineAscent + (-fLineDescent));
731 m_rcRet = CPVT_FloatRect(0, 0, fMaxX, fMaxY);
733 void CTypeset::OutputLines()
735 ASSERT(m_pVT != NULL);
736 ASSERT(m_pSection != NULL);
737 FX_FLOAT fMinX = 0.0f, fMinY = 0.0f, fMaxX = 0.0f, fMaxY = 0.0f;
738 FX_FLOAT fPosX = 0.0f, fPosY = 0.0f;
739 FX_FLOAT fLineIndent = m_pVT->GetLineIndent(m_pSection->m_SecInfo);
740 FX_FLOAT fTypesetWidth = FPDF_MAX(m_pVT->GetPlateWidth() - fLineIndent, 0.0f);
741 switch (m_pVT->GetAlignment(m_pSection->m_SecInfo)) {
747 fMinX = (fTypesetWidth - m_rcRet.Width()) * PVT_HALF;
750 fMinX = fTypesetWidth - m_rcRet.Width();
753 fMaxX = fMinX + m_rcRet.Width();
755 fMaxY = m_rcRet.Height();
756 FX_INT32 nTotalLines = m_pSection->m_LineArray.GetSize();
757 if (nTotalLines > 0) {
758 m_pSection->m_SecInfo.nTotalLine = nTotalLines;
759 for (FX_INT32 l = 0; l < nTotalLines; l++) {
760 if (CLine * pLine = m_pSection->m_LineArray.GetAt(l)) {
761 switch (m_pVT->GetAlignment(m_pSection->m_SecInfo)) {
767 fPosX = (fTypesetWidth - pLine->m_LineInfo.fLineWidth) * PVT_HALF;
770 fPosX = fTypesetWidth - pLine->m_LineInfo.fLineWidth;
773 fPosX += fLineIndent;
774 fPosY += m_pVT->GetLineLeading(m_pSection->m_SecInfo);
775 fPosY += pLine->m_LineInfo.fLineAscent;
776 pLine->m_LineInfo.fLineX = fPosX - fMinX;
777 pLine->m_LineInfo.fLineY = fPosY - fMinY;
778 for (FX_INT32 w = pLine->m_LineInfo.nBeginWordIndex; w <= pLine->m_LineInfo.nEndWordIndex; w++) {
779 if (CPVT_WordInfo * pWord = m_pSection->m_WordArray.GetAt(w)) {
780 pWord->fWordX = fPosX - fMinX;
781 if (pWord->pWordProps) {
782 switch (pWord->pWordProps->nScriptType) {
784 case PVTWORD_SCRIPT_NORMAL:
785 pWord->fWordY = fPosY - fMinY;
787 case PVTWORD_SCRIPT_SUPER:
788 pWord->fWordY = fPosY - m_pVT->GetWordAscent(*pWord) - fMinY;
790 case PVTWORD_SCRIPT_SUB:
791 pWord->fWordY = fPosY - m_pVT->GetWordDescent(*pWord) - fMinY;
795 pWord->fWordY = fPosY - fMinY;
797 fPosX += m_pVT->GetWordWidth(*pWord);
800 fPosY += (-pLine->m_LineInfo.fLineDescent);
804 m_rcRet = CPVT_FloatRect(fMinX, fMinY, fMaxX, fMaxY);
806 CPDF_VariableText::CPDF_VariableText() :
812 m_bLimitWidth(FALSE),
813 m_bAutoFontSize(FALSE),
824 CPDF_VariableText::~CPDF_VariableText()
827 delete m_pVTIterator;
828 m_pVTIterator = NULL;
832 void CPDF_VariableText::Initialize()
835 CPVT_SectionInfo secinfo;
837 secinfo.pSecProps = FX_NEW CPVT_SecProps(0.0f, 0.0f, 0);
838 secinfo.pWordProps = FX_NEW CPVT_WordProps(GetDefaultFontIndex(), PVT_DEFAULT_FONTSIZE, 0, 0, 0);
840 CPVT_WordPlace place;
842 AddSection(place, secinfo);
843 CPVT_LineInfo lineinfo;
844 lineinfo.fLineAscent = GetFontAscent(GetDefaultFontIndex(), GetFontSize());
845 lineinfo.fLineDescent = GetFontDescent(GetDefaultFontIndex(), GetFontSize());
846 AddLine(place, lineinfo);
847 if (CSection * pSection = m_SectionArray.GetAt(0)) {
848 pSection->ResetLinePlace();
853 void CPDF_VariableText::ResetAll()
858 CPVT_WordPlace CPDF_VariableText::InsertWord(const CPVT_WordPlace & place, FX_WORD word, FX_INT32 charset,
859 const CPVT_WordProps * pWordProps)
861 FX_INT32 nTotlaWords = this->GetTotalWords();
862 if (m_nLimitChar > 0 && nTotlaWords >= m_nLimitChar) {
865 if (m_nCharArray > 0 && nTotlaWords >= m_nCharArray) {
868 CPVT_WordPlace newplace = place;
869 newplace.nWordIndex ++;
871 CPVT_WordProps * pNewProps = pWordProps ? FX_NEW CPVT_WordProps(*pWordProps) : FX_NEW CPVT_WordProps();
873 pNewProps->nFontIndex = GetWordFontIndex(word, charset, pWordProps->nFontIndex);
874 return AddWord(newplace, CPVT_WordInfo(word, charset, -1, pNewProps));
877 FX_INT32 nFontIndex = GetSubWord() > 0 ? GetDefaultFontIndex() : GetWordFontIndex(word, charset, GetDefaultFontIndex());
878 return AddWord(newplace, CPVT_WordInfo(word, charset, nFontIndex, NULL));
882 CPVT_WordPlace CPDF_VariableText::InsertSection(const CPVT_WordPlace & place, const CPVT_SecProps * pSecProps,
883 const CPVT_WordProps * pWordProps)
885 FX_INT32 nTotlaWords = this->GetTotalWords();
886 if (m_nLimitChar > 0 && nTotlaWords >= m_nLimitChar) {
889 if (m_nCharArray > 0 && nTotlaWords >= m_nCharArray) {
895 CPVT_WordPlace wordplace = place;
896 UpdateWordPlace(wordplace);
897 CPVT_WordPlace newplace = place;
898 if (CSection * pSection = m_SectionArray.GetAt(wordplace.nSecIndex)) {
899 CPVT_WordPlace NewPlace(wordplace.nSecIndex + 1, 0, -1);
900 CPVT_SectionInfo secinfo;
903 secinfo.pSecProps = FX_NEW CPVT_SecProps(*pSecProps);
906 secinfo.pWordProps = FX_NEW CPVT_WordProps(*pWordProps);
909 AddSection(NewPlace, secinfo);
911 if (CSection * pNewSection = m_SectionArray.GetAt(NewPlace.nSecIndex)) {
912 for (FX_INT32 w = wordplace.nWordIndex + 1, sz = pSection->m_WordArray.GetSize(); w < sz; w++) {
913 if (CPVT_WordInfo * pWord = pSection->m_WordArray.GetAt(w)) {
914 NewPlace.nWordIndex++;
915 pNewSection->AddWord(NewPlace, *pWord);
919 ClearSectionRightWords(wordplace);
923 CPVT_WordPlace CPDF_VariableText::InsertText(const CPVT_WordPlace & place, FX_LPCWSTR text, FX_INT32 charset,
924 const CPVT_SecProps * pSecProps, const CPVT_WordProps * pProps)
926 CFX_WideString swText = text;
927 CPVT_WordPlace wp = place;
928 for (FX_INT32 i = 0, sz = swText.GetLength(); i < sz; i++) {
929 CPVT_WordPlace oldwp = wp;
930 FX_WORD word = swText.GetAt(i);
934 if (swText.GetAt(i + 1) == 0x0A) {
937 wp = InsertSection(wp, pSecProps, pProps);
942 if (swText.GetAt(i + 1) == 0x0D) {
945 wp = InsertSection(wp, pSecProps, pProps);
951 wp = InsertWord(wp, word, charset, pProps);
960 CPVT_WordPlace CPDF_VariableText::DeleteWords(const CPVT_WordRange & PlaceRange)
962 FX_BOOL bLastSecPos = FALSE;
963 if (CSection * pSection = m_SectionArray.GetAt(PlaceRange.EndPos.nSecIndex)) {
964 bLastSecPos = (PlaceRange.EndPos == pSection->GetEndWordPlace());
966 ClearWords(PlaceRange);
967 if (PlaceRange.BeginPos.nSecIndex != PlaceRange.EndPos.nSecIndex) {
968 ClearEmptySections(PlaceRange);
970 LinkLatterSection(PlaceRange.BeginPos);
973 return PlaceRange.BeginPos;
975 CPVT_WordPlace CPDF_VariableText::DeleteWord(const CPVT_WordPlace & place)
977 return ClearRightWord(AjustLineHeader(place, TRUE));
979 CPVT_WordPlace CPDF_VariableText::BackSpaceWord(const CPVT_WordPlace & place)
981 return ClearLeftWord(AjustLineHeader(place, TRUE));
983 void CPDF_VariableText::SetText(FX_LPCWSTR text, FX_INT32 charset, const CPVT_SecProps * pSecProps,
984 const CPVT_WordProps * pWordProps)
986 DeleteWords(CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
987 CFX_WideString swText = text;
988 CPVT_WordPlace wp(0, 0, -1);
989 CPVT_SectionInfo secinfo;
992 secinfo.pSecProps = FX_NEW CPVT_SecProps(*pSecProps);
995 secinfo.pWordProps = FX_NEW CPVT_WordProps(*pWordProps);
998 if (CSection * pSection = m_SectionArray.GetAt(0)) {
999 pSection->m_SecInfo = secinfo;
1001 FX_INT32 nCharCount = 0;
1002 for (FX_INT32 i = 0, sz = swText.GetLength(); i < sz; i++) {
1003 if (m_nLimitChar > 0 && nCharCount >= m_nLimitChar) {
1006 if (m_nCharArray > 0 && nCharCount >= m_nCharArray) {
1009 FX_WORD word = swText.GetAt(i);
1013 if (swText.GetAt(i + 1) == 0x0A) {
1019 AddSection(wp, secinfo);
1024 if (swText.GetAt(i + 1) == 0x0D) {
1030 AddSection(wp, secinfo);
1036 wp = InsertWord(wp, word, charset, pWordProps);
1042 void CPDF_VariableText::UpdateWordPlace(CPVT_WordPlace & place) const
1044 if (place.nSecIndex < 0) {
1045 place = GetBeginWordPlace();
1047 if (place.nSecIndex >= m_SectionArray.GetSize()) {
1048 place = GetEndWordPlace();
1050 place = AjustLineHeader(place, TRUE);
1051 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1052 pSection->UpdateWordPlace(place);
1055 FX_INT32 CPDF_VariableText::WordPlaceToWordIndex(const CPVT_WordPlace & place) const
1057 CPVT_WordPlace newplace = place;
1058 UpdateWordPlace(newplace);
1059 FX_INT32 nIndex = 0;
1062 for (i = 0, sz = m_SectionArray.GetSize(); i < sz && i < newplace.nSecIndex; i++) {
1063 if (CSection * pSection = m_SectionArray.GetAt(i)) {
1064 nIndex += pSection->m_WordArray.GetSize();
1065 if (i != m_SectionArray.GetSize() - 1) {
1066 nIndex += PVT_RETURN_LENGTH;
1070 if (i >= 0 && i < m_SectionArray.GetSize()) {
1071 nIndex += newplace.nWordIndex + PVT_RETURN_LENGTH;
1075 CPVT_WordPlace CPDF_VariableText::WordIndexToWordPlace(FX_INT32 index) const
1077 CPVT_WordPlace place = GetBeginWordPlace();
1078 FX_INT32 nOldIndex = 0 , nIndex = 0;
1079 FX_BOOL bFind = FALSE;
1080 for (FX_INT32 i = 0, sz = m_SectionArray.GetSize(); i < sz; i++) {
1081 if (CSection * pSection = m_SectionArray.GetAt(i)) {
1082 nIndex += pSection->m_WordArray.GetSize();
1083 if (nIndex == index) {
1084 place = pSection->GetEndWordPlace();
1087 } else if (nIndex > index) {
1088 place.nSecIndex = i;
1089 place.nWordIndex = index - nOldIndex - 1;
1090 pSection->UpdateWordPlace(place);
1094 if (i != m_SectionArray.GetSize() - 1) {
1095 nIndex += PVT_RETURN_LENGTH;
1101 place = GetEndWordPlace();
1105 CPVT_WordPlace CPDF_VariableText::GetBeginWordPlace() const
1107 return m_bInitial ? CPVT_WordPlace(0, 0, -1) : CPVT_WordPlace();
1109 CPVT_WordPlace CPDF_VariableText::GetEndWordPlace() const
1111 if (CSection * pSection = m_SectionArray.GetAt(m_SectionArray.GetSize() - 1)) {
1112 return pSection->GetEndWordPlace();
1114 return CPVT_WordPlace();
1116 CPVT_WordPlace CPDF_VariableText::GetPrevWordPlace(const CPVT_WordPlace & place) const
1118 if( place.nSecIndex < 0) {
1119 return GetBeginWordPlace();
1121 if (place.nSecIndex >= m_SectionArray.GetSize()) {
1122 return GetEndWordPlace();
1124 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1125 if (place.WordCmp(pSection->GetBeginWordPlace()) <= 0) {
1126 if (CSection * pPrevSection = m_SectionArray.GetAt(place.nSecIndex - 1)) {
1127 return pPrevSection->GetEndWordPlace();
1129 return GetBeginWordPlace();
1132 return pSection->GetPrevWordPlace(place);
1137 CPVT_WordPlace CPDF_VariableText::GetNextWordPlace(const CPVT_WordPlace & place) const
1139 if (place.nSecIndex < 0) {
1140 return GetBeginWordPlace();
1142 if (place.nSecIndex >= m_SectionArray.GetSize()) {
1143 return GetEndWordPlace();
1145 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1146 if (place.WordCmp(pSection->GetEndWordPlace()) >= 0) {
1147 if (CSection * pNextSection = m_SectionArray.GetAt(place.nSecIndex + 1)) {
1148 return pNextSection->GetBeginWordPlace();
1150 return GetEndWordPlace();
1153 return pSection->GetNextWordPlace(place);
1158 CPVT_WordPlace CPDF_VariableText::SearchWordPlace(const CPDF_Point & point) const
1160 CPDF_Point pt = OutToIn(point);
1161 CPVT_WordPlace place = GetBeginWordPlace();
1163 FX_INT32 nRight = m_SectionArray.GetSize() - 1;
1164 FX_INT32 nMid = m_SectionArray.GetSize() / 2;
1166 FX_BOOL bDown = TRUE;
1167 while (nLeft <= nRight) {
1168 if (CSection * pSection = m_SectionArray.GetAt(nMid)) {
1169 if (IsFloatBigger(pt.y, pSection->m_SecInfo.rcSection.top)) {
1172 if (IsFloatBigger(pSection->m_SecInfo.rcSection.bottom, pt.y)) {
1175 if (IsFloatSmaller(pt.y, pSection->m_SecInfo.rcSection.top)) {
1177 nMid = (nLeft + nRight) / 2;
1179 } else if (IsFloatBigger(pt.y, pSection->m_SecInfo.rcSection.bottom)) {
1181 nMid = (nLeft + nRight) / 2;
1184 place = pSection->SearchWordPlace(
1185 CPDF_Point(pt.x - pSection->m_SecInfo.rcSection.left, pt.y - pSection->m_SecInfo.rcSection.top)
1187 place.nSecIndex = nMid;
1195 place = GetBeginWordPlace();
1198 place = GetEndWordPlace();
1202 CPVT_WordPlace CPDF_VariableText::GetUpWordPlace(const CPVT_WordPlace & place, const CPDF_Point & point) const
1204 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1205 CPVT_WordPlace temp = place;
1206 CPDF_Point pt = OutToIn(point);
1207 if (temp.nLineIndex-- > 0) {
1208 return pSection->SearchWordPlace(pt.x - pSection->m_SecInfo.rcSection.left, temp);
1210 if (temp.nSecIndex-- > 0) {
1211 if (CSection * pLastSection = m_SectionArray.GetAt(temp.nSecIndex)) {
1212 temp.nLineIndex = pLastSection->m_LineArray.GetSize() - 1;
1213 return pLastSection->SearchWordPlace(pt.x - pLastSection->m_SecInfo.rcSection.left, temp);
1220 CPVT_WordPlace CPDF_VariableText::GetDownWordPlace(const CPVT_WordPlace & place, const CPDF_Point & point) const
1222 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1223 CPVT_WordPlace temp = place;
1224 CPDF_Point pt = OutToIn(point);
1225 if (temp.nLineIndex++ < pSection->m_LineArray.GetSize() - 1) {
1226 return pSection->SearchWordPlace(pt.x - pSection->m_SecInfo.rcSection.left, temp);
1228 if (temp.nSecIndex++ < m_SectionArray.GetSize() - 1) {
1229 if (CSection * pNextSection = m_SectionArray.GetAt(temp.nSecIndex)) {
1230 temp.nLineIndex = 0;
1231 return pNextSection->SearchWordPlace(pt.x - pSection->m_SecInfo.rcSection.left, temp);
1238 CPVT_WordPlace CPDF_VariableText::GetLineBeginPlace(const CPVT_WordPlace & place) const
1240 return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, -1);
1242 CPVT_WordPlace CPDF_VariableText::GetLineEndPlace(const CPVT_WordPlace & place) const
1244 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex))
1245 if (CLine * pLine = pSection->m_LineArray.GetAt(place.nLineIndex)) {
1246 return pLine->GetEndWordPlace();
1250 CPVT_WordPlace CPDF_VariableText::GetSectionBeginPlace(const CPVT_WordPlace & place) const
1252 return CPVT_WordPlace(place.nSecIndex, 0, -1);
1254 CPVT_WordPlace CPDF_VariableText::GetSectionEndPlace(const CPVT_WordPlace & place) const
1256 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1257 return pSection->GetEndWordPlace();
1261 FX_INT32 CPDF_VariableText::GetTotalWords() const
1263 FX_INT32 nTotal = 0;
1264 for (FX_INT32 i = 0, sz = m_SectionArray.GetSize(); i < sz; i++)
1265 if (CSection * pSection = m_SectionArray.GetAt(i)) {
1266 nTotal += (pSection->m_WordArray.GetSize() + PVT_RETURN_LENGTH);
1268 return nTotal - PVT_RETURN_LENGTH;
1270 void CPDF_VariableText::ResetSectionArray()
1272 for (FX_INT32 s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) {
1273 delete m_SectionArray.GetAt(s);
1275 m_SectionArray.RemoveAll();
1277 CPVT_WordPlace CPDF_VariableText::AddSection(const CPVT_WordPlace & place, const CPVT_SectionInfo & secinfo)
1279 if (IsValid() && !m_bMultiLine) {
1282 FX_INT32 nSecIndex = FPDF_MAX(FPDF_MIN(place.nSecIndex, m_SectionArray.GetSize()), 0);
1283 CSection * pSection = FX_NEW CSection(this);
1287 pSection->m_SecInfo = secinfo;
1288 pSection->SecPlace.nSecIndex = nSecIndex;
1289 if (nSecIndex == m_SectionArray.GetSize()) {
1290 m_SectionArray.Add(pSection);
1292 m_SectionArray.InsertAt(nSecIndex, pSection);
1296 CPVT_WordPlace CPDF_VariableText::AddLine(const CPVT_WordPlace & place, const CPVT_LineInfo & lineinfo)
1298 if (m_SectionArray.IsEmpty()) {
1301 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1302 return pSection->AddLine(lineinfo);
1306 CPVT_WordPlace CPDF_VariableText::AddWord(const CPVT_WordPlace & place, const CPVT_WordInfo & wordinfo)
1308 if (m_SectionArray.GetSize() <= 0) {
1311 CPVT_WordPlace newplace = place;
1312 newplace.nSecIndex = FPDF_MAX(FPDF_MIN(newplace.nSecIndex, m_SectionArray.GetSize() - 1), 0);
1313 if (CSection * pSection = m_SectionArray.GetAt(newplace.nSecIndex)) {
1314 return pSection->AddWord(newplace, wordinfo);
1318 FX_BOOL CPDF_VariableText::GetWordInfo(const CPVT_WordPlace & place, CPVT_WordInfo & wordinfo)
1320 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1321 if (CPVT_WordInfo * pWord = pSection->m_WordArray.GetAt(place.nWordIndex)) {
1328 FX_BOOL CPDF_VariableText::SetWordInfo(const CPVT_WordPlace & place, const CPVT_WordInfo & wordinfo)
1330 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1331 if (CPVT_WordInfo * pWord = pSection->m_WordArray.GetAt(place.nWordIndex)) {
1338 FX_BOOL CPDF_VariableText::GetLineInfo(const CPVT_WordPlace & place, CPVT_LineInfo & lineinfo)
1340 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1341 if (CLine * pLine = pSection->m_LineArray.GetAt(place.nLineIndex)) {
1342 lineinfo = pLine->m_LineInfo;
1348 FX_BOOL CPDF_VariableText::GetSectionInfo(const CPVT_WordPlace & place, CPVT_SectionInfo & secinfo)
1350 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1351 secinfo = pSection->m_SecInfo;
1356 CPDF_Rect CPDF_VariableText::GetContentRect() const
1358 return InToOut(CPDF_EditContainer::GetContentRect());
1360 FX_FLOAT CPDF_VariableText::GetWordFontSize(const CPVT_WordInfo & WordInfo, FX_BOOL bFactFontSize)
1362 return m_bRichText && WordInfo.pWordProps ? (WordInfo.pWordProps->nScriptType == PVTWORD_SCRIPT_NORMAL || bFactFontSize ? WordInfo.pWordProps->fFontSize : WordInfo.pWordProps->fFontSize * PVT_HALF) : GetFontSize();
1364 FX_INT32 CPDF_VariableText::GetWordFontIndex(const CPVT_WordInfo & WordInfo)
1366 return m_bRichText && WordInfo.pWordProps ? WordInfo.pWordProps->nFontIndex : WordInfo.nFontIndex;
1368 FX_FLOAT CPDF_VariableText::GetWordWidth(FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord,
1369 FX_FLOAT fCharSpace, FX_INT32 nHorzScale,
1370 FX_FLOAT fFontSize, FX_FLOAT fWordTail, FX_INT32 nWordStyle)
1372 return (GetCharWidth(nFontIndex, Word, SubWord, nWordStyle) * fFontSize * PVT_FONTSCALE + fCharSpace) * nHorzScale * PVT_PERCENT + fWordTail;
1374 FX_FLOAT CPDF_VariableText::GetWordWidth(const CPVT_WordInfo & WordInfo)
1376 return GetWordWidth(GetWordFontIndex(WordInfo), WordInfo.Word, GetSubWord(), GetCharSpace(WordInfo), GetHorzScale(WordInfo),
1377 GetWordFontSize(WordInfo), WordInfo.fWordTail,
1378 WordInfo.pWordProps ? WordInfo.pWordProps->nWordStyle : 0);
1380 FX_FLOAT CPDF_VariableText::GetLineAscent(const CPVT_SectionInfo & SecInfo)
1382 return m_bRichText && SecInfo.pWordProps ? GetFontAscent(SecInfo.pWordProps->nFontIndex, SecInfo.pWordProps->fFontSize) :
1383 GetFontAscent(GetDefaultFontIndex(), GetFontSize());
1385 FX_FLOAT CPDF_VariableText::GetLineDescent(const CPVT_SectionInfo & SecInfo)
1387 return m_bRichText && SecInfo.pWordProps ? GetFontDescent(SecInfo.pWordProps->nFontIndex, SecInfo.pWordProps->fFontSize) :
1388 GetFontDescent(GetDefaultFontIndex(), GetFontSize());
1390 FX_FLOAT CPDF_VariableText::GetFontAscent(FX_INT32 nFontIndex, FX_FLOAT fFontSize)
1392 return (FX_FLOAT)GetTypeAscent(nFontIndex) * fFontSize * PVT_FONTSCALE;
1394 FX_FLOAT CPDF_VariableText::GetFontDescent(FX_INT32 nFontIndex, FX_FLOAT fFontSize)
1396 return (FX_FLOAT)GetTypeDescent(nFontIndex) * fFontSize * PVT_FONTSCALE;
1398 FX_FLOAT CPDF_VariableText::GetWordAscent(const CPVT_WordInfo & WordInfo, FX_FLOAT fFontSize)
1400 return GetFontAscent(GetWordFontIndex(WordInfo), fFontSize);
1402 FX_FLOAT CPDF_VariableText::GetWordDescent(const CPVT_WordInfo & WordInfo, FX_FLOAT fFontSize)
1404 return GetFontDescent(GetWordFontIndex(WordInfo), fFontSize);
1406 FX_FLOAT CPDF_VariableText::GetWordAscent(const CPVT_WordInfo & WordInfo, FX_BOOL bFactFontSize)
1408 return GetFontAscent(GetWordFontIndex(WordInfo), GetWordFontSize(WordInfo, bFactFontSize));
1410 FX_FLOAT CPDF_VariableText::GetWordDescent(const CPVT_WordInfo & WordInfo, FX_BOOL bFactFontSize)
1412 return GetFontDescent(GetWordFontIndex(WordInfo), GetWordFontSize(WordInfo, bFactFontSize));
1414 FX_FLOAT CPDF_VariableText::GetLineLeading(const CPVT_SectionInfo & SecInfo)
1416 return m_bRichText && SecInfo.pSecProps ? SecInfo.pSecProps->fLineLeading : m_fLineLeading;
1418 FX_FLOAT CPDF_VariableText::GetLineIndent(const CPVT_SectionInfo & SecInfo)
1420 return m_bRichText && SecInfo.pSecProps ? SecInfo.pSecProps->fLineIndent : 0.0f;
1422 FX_INT32 CPDF_VariableText::GetAlignment(const CPVT_SectionInfo& SecInfo)
1424 return m_bRichText && SecInfo.pSecProps ? SecInfo.pSecProps->nAlignment : this->m_nAlignment;
1426 FX_FLOAT CPDF_VariableText::GetCharSpace(const CPVT_WordInfo & WordInfo)
1428 return m_bRichText && WordInfo.pWordProps ? WordInfo.pWordProps->fCharSpace : m_fCharSpace;
1430 FX_INT32 CPDF_VariableText::GetHorzScale(const CPVT_WordInfo & WordInfo)
1432 return m_bRichText && WordInfo.pWordProps ? WordInfo.pWordProps->nHorzScale : m_nHorzScale;
1434 void CPDF_VariableText::ClearSectionRightWords(const CPVT_WordPlace & place)
1436 CPVT_WordPlace wordplace = AjustLineHeader(place, TRUE);
1437 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1438 for (FX_INT32 w = pSection->m_WordArray.GetSize() - 1; w > wordplace.nWordIndex; w--) {
1439 delete pSection->m_WordArray.GetAt(w);
1440 pSection->m_WordArray.RemoveAt(w);
1444 CPVT_WordPlace CPDF_VariableText::AjustLineHeader(const CPVT_WordPlace & place, FX_BOOL bPrevOrNext) const
1446 if (place.nWordIndex < 0 && place.nLineIndex > 0) {
1448 return GetPrevWordPlace(place);
1450 return GetNextWordPlace(place);
1455 FX_BOOL CPDF_VariableText::ClearEmptySection(const CPVT_WordPlace & place)
1457 if (place.nSecIndex == 0 && m_SectionArray.GetSize() == 1) {
1460 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1461 if (pSection->m_WordArray.GetSize() == 0) {
1463 m_SectionArray.RemoveAt(place.nSecIndex);
1469 void CPDF_VariableText::ClearEmptySections(const CPVT_WordRange & PlaceRange)
1471 CPVT_WordPlace wordplace;
1472 for (FX_INT32 s = PlaceRange.EndPos.nSecIndex; s > PlaceRange.BeginPos.nSecIndex; s--) {
1473 wordplace.nSecIndex = s;
1474 ClearEmptySection(wordplace);
1477 void CPDF_VariableText::LinkLatterSection(const CPVT_WordPlace & place)
1479 CPVT_WordPlace oldplace = AjustLineHeader(place, TRUE);
1480 if (CSection * pNextSection = m_SectionArray.GetAt(place.nSecIndex + 1)) {
1481 if (CSection * pSection = m_SectionArray.GetAt(oldplace.nSecIndex)) {
1482 for (FX_INT32 w = 0, sz = pNextSection->m_WordArray.GetSize(); w < sz; w++) {
1483 if (CPVT_WordInfo * pWord = pNextSection->m_WordArray.GetAt(w)) {
1484 oldplace.nWordIndex ++;
1485 pSection->AddWord(oldplace, *pWord);
1489 delete pNextSection;
1490 m_SectionArray.RemoveAt(place.nSecIndex + 1);
1493 void CPDF_VariableText::ClearWords(const CPVT_WordRange & PlaceRange)
1495 CPVT_WordRange NewRange;
1496 NewRange.BeginPos = AjustLineHeader(PlaceRange.BeginPos, TRUE);
1497 NewRange.EndPos = AjustLineHeader(PlaceRange.EndPos, TRUE);
1498 for (FX_INT32 s = NewRange.EndPos.nSecIndex; s >= NewRange.BeginPos.nSecIndex; s--) {
1499 if (CSection * pSection = m_SectionArray.GetAt(s)) {
1500 pSection->ClearWords(NewRange);
1504 CPVT_WordPlace CPDF_VariableText::ClearLeftWord(const CPVT_WordPlace & place)
1506 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1507 CPVT_WordPlace leftplace = this->GetPrevWordPlace(place);
1508 if (leftplace != place) {
1509 if (leftplace.nSecIndex != place.nSecIndex) {
1510 if (pSection->m_WordArray.GetSize() == 0) {
1511 this->ClearEmptySection(place);
1513 this->LinkLatterSection(leftplace);
1516 pSection->ClearWord(place);
1523 CPVT_WordPlace CPDF_VariableText::ClearRightWord(const CPVT_WordPlace & place)
1525 if (CSection * pSection = m_SectionArray.GetAt(place.nSecIndex)) {
1526 CPVT_WordPlace rightplace = AjustLineHeader(this->GetNextWordPlace(place), FALSE);
1527 if (rightplace != place) {
1528 if(rightplace.nSecIndex != place.nSecIndex) {
1529 LinkLatterSection(place);
1531 pSection->ClearWord(rightplace);
1537 void CPDF_VariableText::RearrangeAll()
1539 Rearrange(CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
1541 void CPDF_VariableText::RearrangePart(const CPVT_WordRange & PlaceRange)
1543 Rearrange(PlaceRange);
1545 CPVT_FloatRect CPDF_VariableText::Rearrange(const CPVT_WordRange & PlaceRange)
1547 CPVT_FloatRect rcRet;
1549 if (m_bAutoFontSize) {
1550 SetFontSize(GetAutoFontSize());
1551 rcRet = RearrangeSections(CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
1553 rcRet = RearrangeSections(PlaceRange);
1556 SetContentRect(rcRet);
1559 FX_FLOAT CPDF_VariableText::GetAutoFontSize()
1561 FX_INT32 nTotal = sizeof(gFontSizeSteps) / sizeof(FX_BYTE);
1562 if (IsMultiLine()) {
1568 if (GetPlateWidth() <= 0) {
1572 FX_INT32 nRight = nTotal - 1;
1573 FX_INT32 nMid = nTotal / 2;
1574 while (nLeft <= nRight) {
1575 if (IsBigger(gFontSizeSteps[nMid])) {
1577 nMid = (nLeft + nRight) / 2;
1581 nMid = (nLeft + nRight) / 2;
1585 return (FX_FLOAT)gFontSizeSteps[nMid];
1587 FX_BOOL CPDF_VariableText::IsBigger(FX_FLOAT fFontSize)
1589 FX_BOOL bBigger = FALSE;
1591 for (FX_INT32 s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) {
1592 if (CSection * pSection = m_SectionArray.GetAt(s)) {
1593 CPVT_Size size = pSection->GetSectionSize(fFontSize);
1594 szTotal.x = FPDF_MAX(size.x, szTotal.x);
1595 szTotal.y += size.y;
1596 if (IsFloatBigger(szTotal.x, GetPlateWidth())
1597 || IsFloatBigger(szTotal.y, GetPlateHeight())
1606 CPVT_FloatRect CPDF_VariableText::RearrangeSections(const CPVT_WordRange & PlaceRange)
1608 CPVT_WordPlace place;
1610 FX_FLOAT fOldHeight;
1611 FX_INT32 nSSecIndex = PlaceRange.BeginPos.nSecIndex;
1612 FX_INT32 nESecIndex = PlaceRange.EndPos.nSecIndex;
1613 CPVT_FloatRect rcRet;
1614 for (FX_INT32 s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) {
1615 place.nSecIndex = s;
1616 if (CSection * pSection = m_SectionArray.GetAt(s)) {
1617 pSection->SecPlace = place;
1618 CPVT_FloatRect rcSec = pSection->m_SecInfo.rcSection;
1619 if (s >= nSSecIndex) {
1620 if (s <= nESecIndex) {
1621 rcSec = pSection->Rearrange();
1623 rcSec.bottom += fPosY;
1625 fOldHeight = pSection->m_SecInfo.rcSection.bottom - pSection->m_SecInfo.rcSection.top;
1627 rcSec.bottom = fPosY + fOldHeight;
1629 pSection->m_SecInfo.rcSection = rcSec;
1630 pSection->ResetLinePlace();
1635 rcRet.left = FPDF_MIN(rcSec.left, rcRet.left);
1636 rcRet.top = FPDF_MIN(rcSec.top, rcRet.top);
1637 rcRet.right = FPDF_MAX(rcSec.right, rcRet.right);
1638 rcRet.bottom = FPDF_MAX(rcSec.bottom, rcRet.bottom);
1640 fPosY += rcSec.Height();
1645 FX_INT32 CPDF_VariableText::GetCharWidth(FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord, FX_INT32 nWordStyle)
1647 if (m_pVTProvider) {
1649 return m_pVTProvider->GetCharWidth(nFontIndex, SubWord, nWordStyle);
1651 return m_pVTProvider->GetCharWidth(nFontIndex, Word, nWordStyle);
1656 FX_INT32 CPDF_VariableText::GetTypeAscent(FX_INT32 nFontIndex)
1658 return m_pVTProvider ? m_pVTProvider->GetTypeAscent(nFontIndex) : 0;
1660 FX_INT32 CPDF_VariableText::GetTypeDescent(FX_INT32 nFontIndex)
1662 return m_pVTProvider ? m_pVTProvider->GetTypeDescent(nFontIndex) : 0;
1664 FX_INT32 CPDF_VariableText::GetWordFontIndex(FX_WORD word, FX_INT32 charset, FX_INT32 nFontIndex)
1666 return m_pVTProvider ? m_pVTProvider->GetWordFontIndex(word, charset, nFontIndex) : -1;
1668 FX_INT32 CPDF_VariableText::GetDefaultFontIndex()
1670 return m_pVTProvider ? m_pVTProvider->GetDefaultFontIndex() : -1;
1672 FX_BOOL CPDF_VariableText::IsLatinWord(FX_WORD word)
1674 return m_pVTProvider ? m_pVTProvider->IsLatinWord(word) : FALSE;
1676 IPDF_VariableText_Iterator * CPDF_VariableText::GetIterator()
1678 if (!m_pVTIterator) {
1679 return m_pVTIterator = FX_NEW CPDF_VariableText_Iterator(this);
1681 return m_pVTIterator;
1683 IPDF_VariableText_Provider* CPDF_VariableText::SetProvider(IPDF_VariableText_Provider * pProvider)
1685 IPDF_VariableText_Provider* pOld = m_pVTProvider;
1686 m_pVTProvider = pProvider;
1689 CPDF_VariableText_Iterator::CPDF_VariableText_Iterator(CPDF_VariableText * pVT):
1691 m_CurPos(-1, -1, -1)
1694 CPDF_VariableText_Iterator::~CPDF_VariableText_Iterator()
1697 void CPDF_VariableText_Iterator::SetAt(FX_INT32 nWordIndex)
1699 ASSERT(m_pVT != NULL);
1700 m_CurPos = m_pVT->WordIndexToWordPlace(nWordIndex);
1702 void CPDF_VariableText_Iterator::SetAt(const CPVT_WordPlace & place)
1704 ASSERT(m_pVT != NULL);
1707 FX_BOOL CPDF_VariableText_Iterator::NextWord()
1709 ASSERT(m_pVT != NULL);
1710 if (m_CurPos == m_pVT->GetEndWordPlace()) {
1713 m_CurPos = m_pVT->GetNextWordPlace(m_CurPos);
1716 FX_BOOL CPDF_VariableText_Iterator::PrevWord()
1718 ASSERT(m_pVT != NULL);
1719 if (m_CurPos == m_pVT->GetBeginWordPlace()) {
1722 m_CurPos = m_pVT->GetPrevWordPlace(m_CurPos);
1725 FX_BOOL CPDF_VariableText_Iterator::NextLine()
1727 ASSERT(m_pVT != NULL);
1728 if (CSection * pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
1729 if (m_CurPos.nLineIndex < pSection->m_LineArray.GetSize() - 1) {
1730 m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex + 1, -1);
1733 if (m_CurPos.nSecIndex < m_pVT->m_SectionArray.GetSize() - 1) {
1734 m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex + 1, 0, -1);
1741 FX_BOOL CPDF_VariableText_Iterator::PrevLine()
1743 ASSERT(m_pVT != NULL);
1744 if (m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
1745 if (m_CurPos.nLineIndex > 0) {
1746 m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex - 1, -1);
1749 if (m_CurPos.nSecIndex > 0) {
1750 if (CSection * pLastSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex - 1)) {
1751 m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex - 1, pLastSection->m_LineArray.GetSize() - 1, -1);
1759 FX_BOOL CPDF_VariableText_Iterator::NextSection()
1761 ASSERT(m_pVT != NULL);
1762 if (m_CurPos.nSecIndex < m_pVT->m_SectionArray.GetSize() - 1) {
1763 m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex + 1, 0, -1);
1768 FX_BOOL CPDF_VariableText_Iterator::PrevSection()
1770 ASSERT(m_pVT != NULL);
1771 if (m_CurPos.nSecIndex > 0) {
1772 m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex - 1, 0, -1);
1777 FX_BOOL CPDF_VariableText_Iterator::GetWord(CPVT_Word & word) const
1779 ASSERT(m_pVT != NULL);
1780 word.WordPlace = m_CurPos;
1781 if (CSection * pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
1782 if (pSection->m_LineArray.GetAt(m_CurPos.nLineIndex)) {
1783 if (CPVT_WordInfo * pWord = pSection->m_WordArray.GetAt(m_CurPos.nWordIndex)) {
1784 word.Word = pWord->Word;
1785 word.nCharset = pWord->nCharset;
1786 word.fWidth = m_pVT->GetWordWidth(*pWord);
1787 word.ptWord = m_pVT->InToOut(
1788 CPDF_Point(pWord->fWordX + pSection->m_SecInfo.rcSection.left,
1789 pWord->fWordY + pSection->m_SecInfo.rcSection.top) );
1790 word.fAscent = m_pVT->GetWordAscent(*pWord);
1791 word.fDescent = m_pVT->GetWordDescent(*pWord);
1792 if (pWord->pWordProps) {
1793 word.WordProps = *pWord->pWordProps;
1795 word.nFontIndex = m_pVT->GetWordFontIndex(*pWord);
1796 word.fFontSize = m_pVT->GetWordFontSize(*pWord);
1803 FX_BOOL CPDF_VariableText_Iterator::SetWord(const CPVT_Word & word)
1805 ASSERT(m_pVT != NULL);
1806 if (CSection * pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
1807 if (CPVT_WordInfo * pWord = pSection->m_WordArray.GetAt(m_CurPos.nWordIndex)) {
1808 if (pWord->pWordProps) {
1809 *pWord->pWordProps = word.WordProps;
1816 FX_BOOL CPDF_VariableText_Iterator::GetLine(CPVT_Line & line) const
1818 ASSERT(m_pVT != NULL);
1819 line.lineplace = CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex, -1);
1820 if (CSection * pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
1821 if (CLine * pLine = pSection->m_LineArray.GetAt(m_CurPos.nLineIndex)) {
1822 line.ptLine = m_pVT->InToOut(
1823 CPDF_Point(pLine->m_LineInfo.fLineX + pSection->m_SecInfo.rcSection.left,
1824 pLine->m_LineInfo.fLineY + pSection->m_SecInfo.rcSection.top) );
1825 line.fLineWidth = pLine->m_LineInfo.fLineWidth;
1826 line.fLineAscent = pLine->m_LineInfo.fLineAscent;
1827 line.fLineDescent = pLine->m_LineInfo.fLineDescent;
1828 line.lineEnd = pLine->GetEndWordPlace();
1834 FX_BOOL CPDF_VariableText_Iterator::GetSection(CPVT_Section & section) const
1836 ASSERT(m_pVT != NULL);
1837 section.secplace = CPVT_WordPlace(m_CurPos.nSecIndex, 0, -1);
1838 if (CSection * pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
1839 section.rcSection = m_pVT->InToOut(pSection->m_SecInfo.rcSection);
1840 if (pSection->m_SecInfo.pSecProps) {
1841 section.SecProps = *pSection->m_SecInfo.pSecProps;
1843 if (pSection->m_SecInfo.pWordProps) {
1844 section.WordProps = *pSection->m_SecInfo.pWordProps;
1850 FX_BOOL CPDF_VariableText_Iterator::SetSection(const CPVT_Section & section)
1852 ASSERT(m_pVT != NULL);
1853 if (CSection * pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
1854 if (pSection->m_SecInfo.pSecProps) {
1855 *pSection->m_SecInfo.pSecProps = section.SecProps;
1857 if (pSection->m_SecInfo.pWordProps) {
1858 *pSection->m_SecInfo.pWordProps = section.WordProps;