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#define _PDF_VT_H_
8class CPVT_Size;
9class CPVT_FloatRect;
10struct CPVT_SectionInfo;
11struct CPVT_LineInfo;
12struct CPVT_WordInfo;
13class CLine;
14class CLines;
15class CSection;
16class CTypeset;
17class CPDF_EditContainer;
18class CPDF_VariableText;
19class CPDF_VariableText_Iterator;
20#define IsFloatZero(f)						((f) < 0.0001 && (f) > -0.0001)
21#define IsFloatBigger(fa,fb)				((fa) > (fb) && !IsFloatZero((fa) - (fb)))
22#define IsFloatSmaller(fa,fb)				((fa) < (fb) && !IsFloatZero((fa) - (fb)))
23template<class T> T FPDF_MIN (const T & i, const T & j)
24{
25    return ((i < j) ? i : j);
26}
27template<class T> T FPDF_MAX (const T & i, const T & j)
28{
29    return ((i > j) ? i : j);
30}
31class CPVT_Size
32{
33public:
34    CPVT_Size() : x(0.0f), y(0.0f)
35    {
36    }
37    CPVT_Size(FX_FLOAT x, FX_FLOAT y)
38    {
39        this->x = x;
40        this->y = y;
41    }
42    FX_FLOAT x, y;
43};
44class CPVT_FloatRect : public CFX_FloatRect
45{
46public:
47    CPVT_FloatRect()
48    {
49        left = top = right = bottom = 0.0f;
50    }
51    CPVT_FloatRect(FX_FLOAT left, FX_FLOAT top,
52                   FX_FLOAT right, FX_FLOAT bottom)
53    {
54        this->left = left;
55        this->top = top;
56        this->right = right;
57        this->bottom = bottom;
58    }
59    CPVT_FloatRect(const CPDF_Rect & rect)
60    {
61        this->left = rect.left;
62        this->top = rect.top;
63        this->right = rect.right;
64        this->bottom = rect.bottom;
65    }
66    void Default()
67    {
68        left = top = right = bottom = 0.0f;
69    }
70    FX_FLOAT Height() const
71    {
72        if(this->top > this->bottom) {
73            return this->top - this->bottom;
74        } else {
75            return this->bottom - this->top;
76        }
77    }
78};
79struct CPVT_SectionInfo {
80    CPVT_SectionInfo() : rcSection(), nTotalLine(0), pSecProps(NULL), pWordProps(NULL)
81    {
82    }
83    virtual ~CPVT_SectionInfo()
84    {
85        if (pSecProps) {
86            delete pSecProps;
87        }
88        if (pWordProps) {
89            delete pWordProps;
90        }
91    }
92    CPVT_SectionInfo(const CPVT_SectionInfo & other): rcSection(), nTotalLine(0), pSecProps(NULL), pWordProps(NULL)
93    {
94        operator = (other);
95    }
96    void operator = (const CPVT_SectionInfo & other)
97    {
98        if (this == &other) {
99            return;
100        }
101        this->rcSection = other.rcSection;
102        this->nTotalLine = other.nTotalLine;
103        if (other.pSecProps) {
104            if (pSecProps) {
105                *pSecProps = *other.pSecProps;
106            } else {
107                pSecProps = FX_NEW CPVT_SecProps(*other.pSecProps);
108            }
109        }
110        if (other.pWordProps) {
111            if (pWordProps) {
112                *pWordProps = *other.pWordProps;
113            } else {
114                pWordProps = FX_NEW CPVT_WordProps(*other.pWordProps);
115            }
116        }
117    }
118    CPVT_FloatRect				rcSection;
119    FX_INT32					nTotalLine;
120    CPVT_SecProps*				pSecProps;
121    CPVT_WordProps*				pWordProps;
122};
123struct CPVT_LineInfo {
124    CPVT_LineInfo() : nTotalWord(0), nBeginWordIndex(-1), nEndWordIndex(-1),
125        fLineX(0.0f), fLineY(0.0f), fLineWidth(0.0f), fLineAscent(0.0f), fLineDescent(0.0f)
126    {
127    }
128    FX_INT32					nTotalWord;
129    FX_INT32					nBeginWordIndex;
130    FX_INT32					nEndWordIndex;
131    FX_FLOAT					fLineX;
132    FX_FLOAT					fLineY;
133    FX_FLOAT					fLineWidth;
134    FX_FLOAT					fLineAscent;
135    FX_FLOAT					fLineDescent;
136};
137struct CPVT_WordInfo : public CFX_Object {
138    CPVT_WordInfo() : Word(0), nCharset(0),
139        fWordX(0.0f), fWordY(0.0f), fWordTail(0.0f), nFontIndex(-1), pWordProps(NULL)
140    {
141    }
142    CPVT_WordInfo(FX_WORD word, FX_INT32 charset, FX_INT32 fontIndex, CPVT_WordProps * pProps):
143        Word(word), nCharset(charset), fWordX(0.0f), fWordY(0.0f), fWordTail(0.0f),
144        nFontIndex(fontIndex), pWordProps(pProps)
145    {
146    }
147    virtual ~CPVT_WordInfo()
148    {
149        if (pWordProps) {
150            delete pWordProps;
151        }
152    }
153    CPVT_WordInfo(const CPVT_WordInfo & word): Word(0), nCharset(0),
154        fWordX(0.0f), fWordY(0.0f), fWordTail(0.0f), nFontIndex(-1), pWordProps(NULL)
155    {
156        operator = (word);
157    }
158    void operator = (const CPVT_WordInfo & word)
159    {
160        if (this == &word) {
161            return;
162        }
163        this->Word = word.Word;
164        this->nCharset = word.nCharset;
165        this->nFontIndex = word.nFontIndex;
166        if (word.pWordProps) {
167            if (pWordProps) {
168                *pWordProps = *word.pWordProps;
169            } else {
170                pWordProps = FX_NEW CPVT_WordProps(*word.pWordProps);
171            }
172        }
173    }
174    FX_WORD						Word;
175    FX_INT32					nCharset;
176    FX_FLOAT					fWordX;
177    FX_FLOAT					fWordY;
178    FX_FLOAT					fWordTail;
179    FX_INT32					nFontIndex;
180    CPVT_WordProps*				pWordProps;
181};
182struct CPVT_FloatRange {
183    CPVT_FloatRange() : fMin(0.0f), fMax(0.0f)
184    {
185    }
186    CPVT_FloatRange(FX_FLOAT min, FX_FLOAT max) : fMin(min), fMax(max)
187    {
188    }
189    FX_FLOAT Range() const
190    {
191        return fMax - fMin;
192    }
193    FX_FLOAT fMin, fMax;
194};
195template<class TYPE> class CPVT_ArrayTemplate : public CFX_ArrayTemplate<TYPE>
196{
197public:
198    FX_BOOL IsEmpty()
199    {
200        return CFX_ArrayTemplate<TYPE>::GetSize() <= 0;
201    }
202    TYPE GetAt(int nIndex) const
203    {
204        if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize()) {
205            return CFX_ArrayTemplate<TYPE>::GetAt(nIndex);
206        }
207        return NULL;
208    }
209    void RemoveAt(int nIndex)
210    {
211        if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize()) {
212            CFX_ArrayTemplate<TYPE>::RemoveAt(nIndex);
213        }
214    }
215};
216class CLine : public CFX_Object
217{
218public:
219    CLine();
220    virtual ~CLine();
221    CPVT_WordPlace							GetBeginWordPlace() const;
222    CPVT_WordPlace							GetEndWordPlace() const;
223    CPVT_WordPlace							GetPrevWordPlace(const CPVT_WordPlace & place) const;
224    CPVT_WordPlace							GetNextWordPlace(const CPVT_WordPlace & place) const;
225    CPVT_WordPlace							LinePlace;
226    CPVT_LineInfo							m_LineInfo;
227};
228class CLines
229{
230public:
231    CLines() : m_nTotal(0) {}
232    virtual ~CLines()
233    {
234        RemoveAll();
235    }
236    FX_INT32								GetSize() const
237    {
238        return m_Lines.GetSize();
239    }
240    CLine *									GetAt(FX_INT32 nIndex) const
241    {
242        return m_Lines.GetAt(nIndex);
243    }
244    void									Empty()
245    {
246        m_nTotal = 0;
247    }
248    void									RemoveAll()
249    {
250        for (FX_INT32 i = 0, sz = GetSize(); i < sz; i++) {
251            delete GetAt(i);
252        }
253        m_Lines.RemoveAll();
254        m_nTotal = 0;
255    }
256    FX_INT32								Add(const CPVT_LineInfo & lineinfo)
257    {
258        if (m_nTotal >= GetSize()) {
259            if (CLine * pLine = FX_NEW CLine) {
260                pLine->m_LineInfo = lineinfo;
261                m_Lines.Add(pLine);
262                return m_nTotal++;
263            }
264            return m_nTotal;
265        } else {
266            if (CLine * pLine = GetAt(m_nTotal)) {
267                pLine->m_LineInfo = lineinfo;
268            }
269            return m_nTotal++;
270        }
271    }
272    void									Clear()
273    {
274        for (FX_INT32 i = GetSize() - 1; i >= m_nTotal; i--) {
275            delete GetAt(i);
276            m_Lines.RemoveAt(i);
277        }
278    }
279private:
280    CPVT_ArrayTemplate<CLine*>				m_Lines;
281    FX_INT32								m_nTotal;
282};
283class CSection : public CFX_Object
284{
285    friend class CTypeset;
286public:
287    CSection(CPDF_VariableText * pVT);
288    virtual ~CSection();
289    void									ResetAll();
290    void									ResetLineArray();
291    void									ResetWordArray();
292    void									ResetLinePlace();
293    CPVT_WordPlace							AddWord(const CPVT_WordPlace & place, const CPVT_WordInfo & wordinfo);
294    CPVT_WordPlace							AddLine(const CPVT_LineInfo & lineinfo);
295    void									ClearWords(const CPVT_WordRange & PlaceRange);
296    void									ClearWord(const CPVT_WordPlace & place);
297    CPVT_FloatRect							Rearrange();
298    CPVT_Size								GetSectionSize(FX_FLOAT fFontSize);
299    CPVT_WordPlace							GetBeginWordPlace() const;
300    CPVT_WordPlace							GetEndWordPlace() const;
301    CPVT_WordPlace							GetPrevWordPlace(const CPVT_WordPlace & place) const;
302    CPVT_WordPlace							GetNextWordPlace(const CPVT_WordPlace & place) const;
303    void									UpdateWordPlace(CPVT_WordPlace & place) const;
304    CPVT_WordPlace							SearchWordPlace(const CPDF_Point & point) const;
305    CPVT_WordPlace							SearchWordPlace(FX_FLOAT fx, const CPVT_WordPlace & lineplace) const;
306    CPVT_WordPlace							SearchWordPlace(FX_FLOAT fx, const CPVT_WordRange & range) const;
307public:
308    CPVT_WordPlace							SecPlace;
309    CPVT_SectionInfo						m_SecInfo;
310    CLines									m_LineArray;
311    CPVT_ArrayTemplate<CPVT_WordInfo*>		m_WordArray;
312private:
313    void									ClearLeftWords(FX_INT32 nWordIndex);
314    void									ClearRightWords(FX_INT32 nWordIndex);
315    void									ClearMidWords(FX_INT32 nBeginIndex, FX_INT32 nEndIndex);
316
317    CPDF_VariableText						*m_pVT;
318};
319class CTypeset
320{
321public:
322    CTypeset(CSection * pSection);
323    virtual ~CTypeset();
324    CPVT_Size								GetEditSize(FX_FLOAT fFontSize);
325    CPVT_FloatRect							Typeset();
326    CPVT_FloatRect							CharArray();
327private:
328    void									SplitLines(FX_BOOL bTypeset, FX_FLOAT fFontSize);
329    void									OutputLines();
330
331    CPVT_FloatRect							m_rcRet;
332    CPDF_VariableText						* m_pVT;
333    CSection								* m_pSection;
334};
335class CPDF_EditContainer
336{
337public:
338    CPDF_EditContainer(): m_rcPlate(0, 0, 0, 0), m_rcContent(0, 0, 0, 0) {};
339    virtual ~CPDF_EditContainer() {};
340    virtual void							SetPlateRect(const CPDF_Rect & rect)
341    {
342        m_rcPlate = rect;
343    };
344    virtual const CPDF_Rect &				GetPlateRect() const
345    {
346        return m_rcPlate;
347    };
348    virtual void							SetContentRect(const CPVT_FloatRect & rect)
349    {
350        m_rcContent = rect;
351    };
352    virtual CPDF_Rect 						GetContentRect() const
353    {
354        return m_rcContent;
355    };
356    FX_FLOAT								GetPlateWidth() const
357    {
358        return m_rcPlate.right - m_rcPlate.left;
359    };
360    FX_FLOAT								GetPlateHeight() const
361    {
362        return m_rcPlate.top - m_rcPlate.bottom;
363    };
364    CPVT_Size								GetPlateSize() const
365    {
366        return CPVT_Size(GetPlateWidth(), GetPlateHeight());
367    };
368    CPDF_Point								GetBTPoint() const
369    {
370        return CPDF_Point(m_rcPlate.left, m_rcPlate.top);
371    };
372    CPDF_Point								GetETPoint() const
373    {
374        return CPDF_Point(m_rcPlate.right, m_rcPlate.bottom);
375    };
376    inline CPDF_Point						InToOut(const CPDF_Point & point) const
377    {
378        return CPDF_Point(point.x + GetBTPoint().x, GetBTPoint().y - point.y);
379    };
380    inline CPDF_Point						OutToIn(const CPDF_Point & point) const
381    {
382        return CPDF_Point(point.x - GetBTPoint().x, GetBTPoint().y - point.y);
383    };
384    inline CPDF_Rect						InToOut(const CPVT_FloatRect & rect) const
385    {
386        CPDF_Point ptLeftTop = InToOut(CPDF_Point(rect.left, rect.top));
387        CPDF_Point ptRightBottom = InToOut(CPDF_Point(rect.right, rect.bottom));
388        return CPDF_Rect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x, ptLeftTop.y);
389    };
390    inline CPVT_FloatRect					OutToIn(const CPDF_Rect & rect) const
391    {
392        CPDF_Point ptLeftTop = OutToIn(CPDF_Point(rect.left, rect.top));
393        CPDF_Point ptRightBottom = OutToIn(CPDF_Point(rect.right, rect.bottom));
394        return CPVT_FloatRect(ptLeftTop.x, ptLeftTop.y, ptRightBottom.x, ptRightBottom.y);
395    };
396
397private:
398    CPDF_Rect								m_rcPlate;
399    CPVT_FloatRect							m_rcContent;
400};
401class CPDF_VariableText : public IPDF_VariableText, public CFX_Object, private CPDF_EditContainer
402{
403    friend class CTypeset;
404    friend class CSection;
405    friend class CPDF_VariableText_Iterator;
406public:
407    CPDF_VariableText();
408    virtual ~CPDF_VariableText();
409    IPDF_VariableText_Provider*				SetProvider(IPDF_VariableText_Provider * pProvider);
410    IPDF_VariableText_Iterator*				GetIterator();
411    void									SetPlateRect(const CPDF_Rect & rect)
412    {
413        CPDF_EditContainer::SetPlateRect(rect);
414    }
415    void									SetAlignment(FX_INT32 nFormat = 0)
416    {
417        m_nAlignment = nFormat;
418    }
419    void									SetPasswordChar(FX_WORD wSubWord = '*')
420    {
421        m_wSubWord = wSubWord;
422    }
423    void									SetLimitChar(FX_INT32 nLimitChar = 0)
424    {
425        m_nLimitChar = nLimitChar;
426    }
427    void									SetCharSpace(FX_FLOAT fCharSpace = 0.0f)
428    {
429        m_fCharSpace = fCharSpace;
430    }
431    void									SetHorzScale(FX_INT32 nHorzScale = 100)
432    {
433        m_nHorzScale = nHorzScale;
434    }
435    void									SetMultiLine(FX_BOOL bMultiLine = TRUE)
436    {
437        m_bMultiLine = bMultiLine;
438    }
439    void									SetAutoReturn(FX_BOOL bAuto = TRUE)
440    {
441        m_bLimitWidth = bAuto;
442    }
443    void									SetFontSize(FX_FLOAT fFontSize)
444    {
445        m_fFontSize = fFontSize;
446    }
447    void									SetCharArray(FX_INT32 nCharArray = 0)
448    {
449        m_nCharArray = nCharArray;
450    }
451    void									SetAutoFontSize(FX_BOOL bAuto = TRUE)
452    {
453        m_bAutoFontSize = bAuto;
454    }
455    void									SetRichText(FX_BOOL bRichText)
456    {
457        m_bRichText = bRichText;
458    }
459    void									SetLineLeading(FX_FLOAT fLineLeading)
460    {
461        m_fLineLeading = fLineLeading;
462    }
463    void									Initialize();
464    FX_BOOL									IsValid() const
465    {
466        return m_bInitial;
467    }
468    FX_BOOL									IsRichText() const
469    {
470        return m_bRichText;
471    }
472    void									RearrangeAll();
473    void									RearrangePart(const CPVT_WordRange & PlaceRange);
474    void									ResetAll();
475    void									SetText(FX_LPCWSTR text, FX_INT32 charset = 1, const CPVT_SecProps * pSecProps = NULL,
476            const CPVT_WordProps * pWordProps = NULL);
477    CPVT_WordPlace							InsertWord(const CPVT_WordPlace & place, FX_WORD word, FX_INT32 charset = 1,
478            const CPVT_WordProps * pWordProps = NULL);
479    CPVT_WordPlace							InsertSection(const CPVT_WordPlace & place, const CPVT_SecProps * pSecProps = NULL,
480            const CPVT_WordProps * pWordProps = NULL);
481    CPVT_WordPlace							InsertText(const CPVT_WordPlace & place, FX_LPCWSTR text, FX_INT32 charset = 1,
482            const CPVT_SecProps * pSecProps = NULL,	const CPVT_WordProps * pWordProps = NULL);
483    CPVT_WordPlace							DeleteWords(const CPVT_WordRange & PlaceRange);
484    CPVT_WordPlace							DeleteWord(const CPVT_WordPlace & place);
485    CPVT_WordPlace							BackSpaceWord(const CPVT_WordPlace & place);
486    const CPDF_Rect &						GetPlateRect() const
487    {
488        return CPDF_EditContainer::GetPlateRect();
489    }
490    CPDF_Rect								GetContentRect() const;
491    FX_INT32								GetTotalWords() const;
492    FX_FLOAT								GetFontSize() const
493    {
494        return m_fFontSize;
495    }
496    FX_INT32								GetAlignment() const
497    {
498        return m_nAlignment;
499    }
500    FX_INT32								GetCharArray() const
501    {
502        return m_nCharArray;
503    }
504    FX_INT32								GetLimitChar() const
505    {
506        return m_nLimitChar;
507    }
508    FX_BOOL									IsMultiLine() const
509    {
510        return m_bMultiLine;
511    }
512    FX_INT32								GetHorzScale() const
513    {
514        return m_nHorzScale;
515    }
516    FX_FLOAT								GetCharSpace() const
517    {
518        return m_fCharSpace;
519    }
520
521    inline CPVT_WordPlace					GetBeginWordPlace() const;
522    inline CPVT_WordPlace					GetEndWordPlace() const;
523    CPVT_WordPlace							GetPrevWordPlace(const CPVT_WordPlace & place) const;
524    CPVT_WordPlace							GetNextWordPlace(const CPVT_WordPlace & place) const;
525    CPVT_WordPlace							SearchWordPlace(const CPDF_Point & point) const;
526    CPVT_WordPlace							GetUpWordPlace(const CPVT_WordPlace & place, const CPDF_Point & point) const;
527    CPVT_WordPlace							GetDownWordPlace(const CPVT_WordPlace & place, const CPDF_Point & point) const;
528    CPVT_WordPlace							GetLineBeginPlace(const CPVT_WordPlace & place) const;
529    CPVT_WordPlace							GetLineEndPlace(const CPVT_WordPlace & place) const;
530    CPVT_WordPlace							GetSectionBeginPlace(const CPVT_WordPlace & place) const;
531    CPVT_WordPlace							GetSectionEndPlace(const CPVT_WordPlace & place) const;
532    void									UpdateWordPlace(CPVT_WordPlace & place) const;
533    FX_INT32								WordPlaceToWordIndex(const CPVT_WordPlace & place) const;
534    CPVT_WordPlace							WordIndexToWordPlace(FX_INT32 index) const;
535    FX_WORD									GetPasswordChar() const
536    {
537        return GetSubWord();
538    }
539    FX_WORD									GetSubWord() const
540    {
541        return m_wSubWord;
542    }
543private:
544    FX_INT32								GetCharWidth(FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord, FX_INT32 nWordStyle);
545    FX_INT32								GetTypeAscent(FX_INT32 nFontIndex);
546    FX_INT32								GetTypeDescent(FX_INT32 nFontIndex);
547    FX_INT32								GetWordFontIndex(FX_WORD word, FX_INT32 charset, FX_INT32 nFontIndex);
548    FX_INT32								GetDefaultFontIndex();
549    FX_BOOL									IsLatinWord(FX_WORD word);
550private:
551
552    CPVT_WordPlace							AddSection(const CPVT_WordPlace & place, const CPVT_SectionInfo & secinfo);
553    CPVT_WordPlace							AddLine(const CPVT_WordPlace & place, const CPVT_LineInfo & lineinfo);
554    CPVT_WordPlace							AddWord(const CPVT_WordPlace & place, const CPVT_WordInfo & wordinfo);
555    FX_BOOL									GetWordInfo(const CPVT_WordPlace & place, CPVT_WordInfo & wordinfo);
556    FX_BOOL									SetWordInfo(const CPVT_WordPlace & place, const CPVT_WordInfo & wordinfo);
557    FX_BOOL									GetLineInfo(const CPVT_WordPlace & place, CPVT_LineInfo & lineinfo);
558    FX_BOOL									GetSectionInfo(const CPVT_WordPlace & place, CPVT_SectionInfo & secinfo);
559    FX_FLOAT								GetWordFontSize(const CPVT_WordInfo & WordInfo, FX_BOOL bFactFontSize = FALSE);
560    FX_FLOAT								GetWordWidth(FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord,
561            FX_FLOAT fCharSpace, FX_INT32 nHorzScale,
562            FX_FLOAT fFontSize, FX_FLOAT fWordTail, FX_INT32 nWordStyle);
563    FX_FLOAT								GetWordWidth(const CPVT_WordInfo & WordInfo);
564    FX_FLOAT								GetWordAscent(const CPVT_WordInfo & WordInfo, FX_FLOAT fFontSize);
565    FX_FLOAT								GetWordDescent(const CPVT_WordInfo & WordInfo, FX_FLOAT fFontSize);
566    FX_FLOAT								GetWordAscent(const CPVT_WordInfo & WordInfo, FX_BOOL bFactFontSize = FALSE);
567    FX_FLOAT								GetWordDescent(const CPVT_WordInfo & WordInfo, FX_BOOL bFactFontSize = FALSE);
568    FX_FLOAT								GetLineAscent(const CPVT_SectionInfo & SecInfo);
569    FX_FLOAT								GetLineDescent(const CPVT_SectionInfo & SecInfo);
570    FX_FLOAT								GetFontAscent(FX_INT32 nFontIndex, FX_FLOAT fFontSize);
571    FX_FLOAT								GetFontDescent(FX_INT32 nFontIndex, FX_FLOAT fFontSize);
572    FX_INT32								GetWordFontIndex(const CPVT_WordInfo & WordInfo);
573    FX_FLOAT								GetCharSpace(const CPVT_WordInfo & WordInfo);
574    FX_INT32								GetHorzScale(const CPVT_WordInfo & WordInfo);
575    FX_FLOAT								GetLineLeading(const CPVT_SectionInfo & SecInfo);
576    FX_FLOAT								GetLineIndent(const CPVT_SectionInfo & SecInfo);
577    FX_INT32								GetAlignment(const CPVT_SectionInfo& SecInfo);
578
579    void									ClearSectionRightWords(const CPVT_WordPlace & place);
580    CPVT_WordPlace							AjustLineHeader(const CPVT_WordPlace & place, FX_BOOL bPrevOrNext) const;
581    FX_BOOL									ClearEmptySection(const CPVT_WordPlace & place);
582    void									ClearEmptySections(const CPVT_WordRange & PlaceRange);
583    void									LinkLatterSection(const CPVT_WordPlace & place);
584    void									ClearWords(const CPVT_WordRange & PlaceRange);
585    CPVT_WordPlace							ClearLeftWord(const CPVT_WordPlace & place);
586    CPVT_WordPlace							ClearRightWord(const CPVT_WordPlace & place);
587private:
588    CPVT_FloatRect							Rearrange(const CPVT_WordRange & PlaceRange);
589    FX_FLOAT								GetAutoFontSize();
590    FX_BOOL									IsBigger(FX_FLOAT fFontSize);
591    CPVT_FloatRect							RearrangeSections(const CPVT_WordRange & PlaceRange);
592private:
593    void									ResetSectionArray();
594private:
595    CPVT_ArrayTemplate<CSection*>			m_SectionArray;
596    FX_INT32								m_nLimitChar;
597    FX_INT32								m_nCharArray;
598    FX_BOOL									m_bMultiLine;
599    FX_BOOL									m_bLimitWidth;
600    FX_BOOL									m_bAutoFontSize;
601    FX_INT32								m_nAlignment;
602    FX_FLOAT								m_fLineLeading;
603    FX_FLOAT								m_fCharSpace;
604    FX_INT32								m_nHorzScale;
605    FX_WORD									m_wSubWord;
606    FX_FLOAT								m_fWordSpace;
607    FX_FLOAT								m_fFontSize;
608
609private:
610    FX_BOOL									m_bInitial;
611    FX_BOOL									m_bRichText;
612    FX_FLOAT								m_fCaretOriginX;
613    FX_INT32								m_nCurFontIndex;
614    IPDF_VariableText_Provider *			m_pVTProvider;
615    CPDF_VariableText_Iterator *			m_pVTIterator;
616};
617class CPDF_VariableText_Iterator : public IPDF_VariableText_Iterator, public CFX_Object
618{
619public:
620    CPDF_VariableText_Iterator(CPDF_VariableText * pVT);
621    virtual ~CPDF_VariableText_Iterator();
622    FX_BOOL									NextWord();
623    FX_BOOL									PrevWord();
624    FX_BOOL									NextLine();
625    FX_BOOL									PrevLine();
626    FX_BOOL									NextSection();
627    FX_BOOL									PrevSection();
628    FX_BOOL									SetWord(const CPVT_Word & word);
629    FX_BOOL									GetWord(CPVT_Word & word) const;
630    FX_BOOL									GetLine(CPVT_Line & line) const;
631    FX_BOOL									GetSection(CPVT_Section & section) const;
632    FX_BOOL									SetSection(const CPVT_Section & section);
633    void									SetAt(FX_INT32 nWordIndex);
634    void									SetAt(const CPVT_WordPlace & place);
635    const CPVT_WordPlace &					GetAt() const
636    {
637        return m_CurPos;
638    };
639private:
640    CPVT_WordPlace							m_CurPos;
641    CPDF_VariableText *						m_pVT;
642};
643