// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#define _PDF_VT_H_
class CPVT_Size;
class CPVT_FloatRect;
struct CPVT_SectionInfo;
struct CPVT_LineInfo;
struct CPVT_WordInfo;
class CLine;
class CLines;
class CSection;
class CTypeset;
class CPDF_EditContainer;
class CPDF_VariableText;
class CPDF_VariableText_Iterator;
#define IsFloatZero(f)						((f) < 0.0001 && (f) > -0.0001)
#define IsFloatBigger(fa,fb)				((fa) > (fb) && !IsFloatZero((fa) - (fb)))
#define IsFloatSmaller(fa,fb)				((fa) < (fb) && !IsFloatZero((fa) - (fb)))
template<class T> T FPDF_MIN (const T & i, const T & j)
{
    return ((i < j) ? i : j);
}
template<class T> T FPDF_MAX (const T & i, const T & j)
{
    return ((i > j) ? i : j);
}
class CPVT_Size
{
public:
    CPVT_Size() : x(0.0f), y(0.0f)
    {
    }
    CPVT_Size(FX_FLOAT x, FX_FLOAT y)
    {
        this->x = x;
        this->y = y;
    }
    FX_FLOAT x, y;
};
class CPVT_FloatRect : public CFX_FloatRect
{
public:
    CPVT_FloatRect()
    {
        left = top = right = bottom = 0.0f;
    }
    CPVT_FloatRect(FX_FLOAT left, FX_FLOAT top,
                   FX_FLOAT right, FX_FLOAT bottom)
    {
        this->left = left;
        this->top = top;
        this->right = right;
        this->bottom = bottom;
    }
    CPVT_FloatRect(const CPDF_Rect & rect)
    {
        this->left = rect.left;
        this->top = rect.top;
        this->right = rect.right;
        this->bottom = rect.bottom;
    }
    void Default()
    {
        left = top = right = bottom = 0.0f;
    }
    FX_FLOAT Height() const
    {
        if(this->top > this->bottom) {
            return this->top - this->bottom;
        } else {
            return this->bottom - this->top;
        }
    }
};
struct CPVT_SectionInfo {
    CPVT_SectionInfo() : rcSection(), nTotalLine(0), pSecProps(NULL), pWordProps(NULL)
    {
    }
    virtual ~CPVT_SectionInfo()
    {
        if (pSecProps) {
            delete pSecProps;
        }
        if (pWordProps) {
            delete pWordProps;
        }
    }
    CPVT_SectionInfo(const CPVT_SectionInfo & other): rcSection(), nTotalLine(0), pSecProps(NULL), pWordProps(NULL)
    {
        operator = (other);
    }
    void operator = (const CPVT_SectionInfo & other)
    {
        if (this == &other) {
            return;
        }
        this->rcSection = other.rcSection;
        this->nTotalLine = other.nTotalLine;
        if (other.pSecProps) {
            if (pSecProps) {
                *pSecProps = *other.pSecProps;
            } else {
                pSecProps = FX_NEW CPVT_SecProps(*other.pSecProps);
            }
        }
        if (other.pWordProps) {
            if (pWordProps) {
                *pWordProps = *other.pWordProps;
            } else {
                pWordProps = FX_NEW CPVT_WordProps(*other.pWordProps);
            }
        }
    }
    CPVT_FloatRect				rcSection;
    FX_INT32					nTotalLine;
    CPVT_SecProps*				pSecProps;
    CPVT_WordProps*				pWordProps;
};
struct CPVT_LineInfo {
    CPVT_LineInfo() : nTotalWord(0), nBeginWordIndex(-1), nEndWordIndex(-1),
        fLineX(0.0f), fLineY(0.0f), fLineWidth(0.0f), fLineAscent(0.0f), fLineDescent(0.0f)
    {
    }
    FX_INT32					nTotalWord;
    FX_INT32					nBeginWordIndex;
    FX_INT32					nEndWordIndex;
    FX_FLOAT					fLineX;
    FX_FLOAT					fLineY;
    FX_FLOAT					fLineWidth;
    FX_FLOAT					fLineAscent;
    FX_FLOAT					fLineDescent;
};
struct CPVT_WordInfo : public CFX_Object {
    CPVT_WordInfo() : Word(0), nCharset(0),
        fWordX(0.0f), fWordY(0.0f), fWordTail(0.0f), nFontIndex(-1), pWordProps(NULL)
    {
    }
    CPVT_WordInfo(FX_WORD word, FX_INT32 charset, FX_INT32 fontIndex, CPVT_WordProps * pProps):
        Word(word), nCharset(charset), fWordX(0.0f), fWordY(0.0f), fWordTail(0.0f),
        nFontIndex(fontIndex), pWordProps(pProps)
    {
    }
    virtual ~CPVT_WordInfo()
    {
        if (pWordProps) {
            delete pWordProps;
        }
    }
    CPVT_WordInfo(const CPVT_WordInfo & word): Word(0), nCharset(0),
        fWordX(0.0f), fWordY(0.0f), fWordTail(0.0f), nFontIndex(-1), pWordProps(NULL)
    {
        operator = (word);
    }
    void operator = (const CPVT_WordInfo & word)
    {
        if (this == &word) {
            return;
        }
        this->Word = word.Word;
        this->nCharset = word.nCharset;
        this->nFontIndex = word.nFontIndex;
        if (word.pWordProps) {
            if (pWordProps) {
                *pWordProps = *word.pWordProps;
            } else {
                pWordProps = FX_NEW CPVT_WordProps(*word.pWordProps);
            }
        }
    }
    FX_WORD						Word;
    FX_INT32					nCharset;
    FX_FLOAT					fWordX;
    FX_FLOAT					fWordY;
    FX_FLOAT					fWordTail;
    FX_INT32					nFontIndex;
    CPVT_WordProps*				pWordProps;
};
struct CPVT_FloatRange {
    CPVT_FloatRange() : fMin(0.0f), fMax(0.0f)
    {
    }
    CPVT_FloatRange(FX_FLOAT min, FX_FLOAT max) : fMin(min), fMax(max)
    {
    }
    FX_FLOAT Range() const
    {
        return fMax - fMin;
    }
    FX_FLOAT fMin, fMax;
};
template<class TYPE> class CPVT_ArrayTemplate : public CFX_ArrayTemplate<TYPE>
{
public:
    FX_BOOL IsEmpty()
    {
        return CFX_ArrayTemplate<TYPE>::GetSize() <= 0;
    }
    TYPE GetAt(int nIndex) const
    {
        if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize()) {
            return CFX_ArrayTemplate<TYPE>::GetAt(nIndex);
        }
        return NULL;
    }
    void RemoveAt(int nIndex)
    {
        if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize()) {
            CFX_ArrayTemplate<TYPE>::RemoveAt(nIndex);
        }
    }
};
class CLine : public CFX_Object
{
public:
    CLine();
    virtual ~CLine();
    CPVT_WordPlace							GetBeginWordPlace() const;
    CPVT_WordPlace							GetEndWordPlace() const;
    CPVT_WordPlace							GetPrevWordPlace(const CPVT_WordPlace & place) const;
    CPVT_WordPlace							GetNextWordPlace(const CPVT_WordPlace & place) const;
    CPVT_WordPlace							LinePlace;
    CPVT_LineInfo							m_LineInfo;
};
class CLines
{
public:
    CLines() : m_nTotal(0) {}
    virtual ~CLines()
    {
        RemoveAll();
    }
    FX_INT32								GetSize() const
    {
        return m_Lines.GetSize();
    }
    CLine *									GetAt(FX_INT32 nIndex) const
    {
        return m_Lines.GetAt(nIndex);
    }
    void									Empty()
    {
        m_nTotal = 0;
    }
    void									RemoveAll()
    {
        for (FX_INT32 i = 0, sz = GetSize(); i < sz; i++) {
            delete GetAt(i);
        }
        m_Lines.RemoveAll();
        m_nTotal = 0;
    }
    FX_INT32								Add(const CPVT_LineInfo & lineinfo)
    {
        if (m_nTotal >= GetSize()) {
            if (CLine * pLine = FX_NEW CLine) {
                pLine->m_LineInfo = lineinfo;
                m_Lines.Add(pLine);
                return m_nTotal++;
            }
            return m_nTotal;
        } else {
            if (CLine * pLine = GetAt(m_nTotal)) {
                pLine->m_LineInfo = lineinfo;
            }
            return m_nTotal++;
        }
    }
    void									Clear()
    {
        for (FX_INT32 i = GetSize() - 1; i >= m_nTotal; i--) {
            delete GetAt(i);
            m_Lines.RemoveAt(i);
        }
    }
private:
    CPVT_ArrayTemplate<CLine*>				m_Lines;
    FX_INT32								m_nTotal;
};
class CSection : public CFX_Object
{
    friend class CTypeset;
public:
    CSection(CPDF_VariableText * pVT);
    virtual ~CSection();
    void									ResetAll();
    void									ResetLineArray();
    void									ResetWordArray();
    void									ResetLinePlace();
    CPVT_WordPlace							AddWord(const CPVT_WordPlace & place, const CPVT_WordInfo & wordinfo);
    CPVT_WordPlace							AddLine(const CPVT_LineInfo & lineinfo);
    void									ClearWords(const CPVT_WordRange & PlaceRange);
    void									ClearWord(const CPVT_WordPlace & place);
    CPVT_FloatRect							Rearrange();
    CPVT_Size								GetSectionSize(FX_FLOAT fFontSize);
    CPVT_WordPlace							GetBeginWordPlace() const;
    CPVT_WordPlace							GetEndWordPlace() const;
    CPVT_WordPlace							GetPrevWordPlace(const CPVT_WordPlace & place) const;
    CPVT_WordPlace							GetNextWordPlace(const CPVT_WordPlace & place) const;
    void									UpdateWordPlace(CPVT_WordPlace & place) const;
    CPVT_WordPlace							SearchWordPlace(const CPDF_Point & point) const;
    CPVT_WordPlace							SearchWordPlace(FX_FLOAT fx, const CPVT_WordPlace & lineplace) const;
    CPVT_WordPlace							SearchWordPlace(FX_FLOAT fx, const CPVT_WordRange & range) const;
public:
    CPVT_WordPlace							SecPlace;
    CPVT_SectionInfo						m_SecInfo;
    CLines									m_LineArray;
    CPVT_ArrayTemplate<CPVT_WordInfo*>		m_WordArray;
private:
    void									ClearLeftWords(FX_INT32 nWordIndex);
    void									ClearRightWords(FX_INT32 nWordIndex);
    void									ClearMidWords(FX_INT32 nBeginIndex, FX_INT32 nEndIndex);

    CPDF_VariableText						*m_pVT;
};
class CTypeset
{
public:
    CTypeset(CSection * pSection);
    virtual ~CTypeset();
    CPVT_Size								GetEditSize(FX_FLOAT fFontSize);
    CPVT_FloatRect							Typeset();
    CPVT_FloatRect							CharArray();
private:
    void									SplitLines(FX_BOOL bTypeset, FX_FLOAT fFontSize);
    void									OutputLines();

    CPVT_FloatRect							m_rcRet;
    CPDF_VariableText						* m_pVT;
    CSection								* m_pSection;
};
class CPDF_EditContainer
{
public:
    CPDF_EditContainer(): m_rcPlate(0, 0, 0, 0), m_rcContent(0, 0, 0, 0) {};
    virtual ~CPDF_EditContainer() {};
    virtual void							SetPlateRect(const CPDF_Rect & rect)
    {
        m_rcPlate = rect;
    };
    virtual const CPDF_Rect &				GetPlateRect() const
    {
        return m_rcPlate;
    };
    virtual void							SetContentRect(const CPVT_FloatRect & rect)
    {
        m_rcContent = rect;
    };
    virtual CPDF_Rect 						GetContentRect() const
    {
        return m_rcContent;
    };
    FX_FLOAT								GetPlateWidth() const
    {
        return m_rcPlate.right - m_rcPlate.left;
    };
    FX_FLOAT								GetPlateHeight() const
    {
        return m_rcPlate.top - m_rcPlate.bottom;
    };
    CPVT_Size								GetPlateSize() const
    {
        return CPVT_Size(GetPlateWidth(), GetPlateHeight());
    };
    CPDF_Point								GetBTPoint() const
    {
        return CPDF_Point(m_rcPlate.left, m_rcPlate.top);
    };
    CPDF_Point								GetETPoint() const
    {
        return CPDF_Point(m_rcPlate.right, m_rcPlate.bottom);
    };
    inline CPDF_Point						InToOut(const CPDF_Point & point) const
    {
        return CPDF_Point(point.x + GetBTPoint().x, GetBTPoint().y - point.y);
    };
    inline CPDF_Point						OutToIn(const CPDF_Point & point) const
    {
        return CPDF_Point(point.x - GetBTPoint().x, GetBTPoint().y - point.y);
    };
    inline CPDF_Rect						InToOut(const CPVT_FloatRect & rect) const
    {
        CPDF_Point ptLeftTop = InToOut(CPDF_Point(rect.left, rect.top));
        CPDF_Point ptRightBottom = InToOut(CPDF_Point(rect.right, rect.bottom));
        return CPDF_Rect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x, ptLeftTop.y);
    };
    inline CPVT_FloatRect					OutToIn(const CPDF_Rect & rect) const
    {
        CPDF_Point ptLeftTop = OutToIn(CPDF_Point(rect.left, rect.top));
        CPDF_Point ptRightBottom = OutToIn(CPDF_Point(rect.right, rect.bottom));
        return CPVT_FloatRect(ptLeftTop.x, ptLeftTop.y, ptRightBottom.x, ptRightBottom.y);
    };

private:
    CPDF_Rect								m_rcPlate;
    CPVT_FloatRect							m_rcContent;
};
class CPDF_VariableText : public IPDF_VariableText, public CFX_Object, private CPDF_EditContainer
{
    friend class CTypeset;
    friend class CSection;
    friend class CPDF_VariableText_Iterator;
public:
    CPDF_VariableText();
    virtual ~CPDF_VariableText();
    IPDF_VariableText_Provider*				SetProvider(IPDF_VariableText_Provider * pProvider);
    IPDF_VariableText_Iterator*				GetIterator();
    void									SetPlateRect(const CPDF_Rect & rect)
    {
        CPDF_EditContainer::SetPlateRect(rect);
    }
    void									SetAlignment(FX_INT32 nFormat = 0)
    {
        m_nAlignment = nFormat;
    }
    void									SetPasswordChar(FX_WORD wSubWord = '*')
    {
        m_wSubWord = wSubWord;
    }
    void									SetLimitChar(FX_INT32 nLimitChar = 0)
    {
        m_nLimitChar = nLimitChar;
    }
    void									SetCharSpace(FX_FLOAT fCharSpace = 0.0f)
    {
        m_fCharSpace = fCharSpace;
    }
    void									SetHorzScale(FX_INT32 nHorzScale = 100)
    {
        m_nHorzScale = nHorzScale;
    }
    void									SetMultiLine(FX_BOOL bMultiLine = TRUE)
    {
        m_bMultiLine = bMultiLine;
    }
    void									SetAutoReturn(FX_BOOL bAuto = TRUE)
    {
        m_bLimitWidth = bAuto;
    }
    void									SetFontSize(FX_FLOAT fFontSize)
    {
        m_fFontSize = fFontSize;
    }
    void									SetCharArray(FX_INT32 nCharArray = 0)
    {
        m_nCharArray = nCharArray;
    }
    void									SetAutoFontSize(FX_BOOL bAuto = TRUE)
    {
        m_bAutoFontSize = bAuto;
    }
    void									SetRichText(FX_BOOL bRichText)
    {
        m_bRichText = bRichText;
    }
    void									SetLineLeading(FX_FLOAT fLineLeading)
    {
        m_fLineLeading = fLineLeading;
    }
    void									Initialize();
    FX_BOOL									IsValid() const
    {
        return m_bInitial;
    }
    FX_BOOL									IsRichText() const
    {
        return m_bRichText;
    }
    void									RearrangeAll();
    void									RearrangePart(const CPVT_WordRange & PlaceRange);
    void									ResetAll();
    void									SetText(FX_LPCWSTR text, FX_INT32 charset = 1, const CPVT_SecProps * pSecProps = NULL,
            const CPVT_WordProps * pWordProps = NULL);
    CPVT_WordPlace							InsertWord(const CPVT_WordPlace & place, FX_WORD word, FX_INT32 charset = 1,
            const CPVT_WordProps * pWordProps = NULL);
    CPVT_WordPlace							InsertSection(const CPVT_WordPlace & place, const CPVT_SecProps * pSecProps = NULL,
            const CPVT_WordProps * pWordProps = NULL);
    CPVT_WordPlace							InsertText(const CPVT_WordPlace & place, FX_LPCWSTR text, FX_INT32 charset = 1,
            const CPVT_SecProps * pSecProps = NULL,	const CPVT_WordProps * pWordProps = NULL);
    CPVT_WordPlace							DeleteWords(const CPVT_WordRange & PlaceRange);
    CPVT_WordPlace							DeleteWord(const CPVT_WordPlace & place);
    CPVT_WordPlace							BackSpaceWord(const CPVT_WordPlace & place);
    const CPDF_Rect &						GetPlateRect() const
    {
        return CPDF_EditContainer::GetPlateRect();
    }
    CPDF_Rect								GetContentRect() const;
    FX_INT32								GetTotalWords() const;
    FX_FLOAT								GetFontSize() const
    {
        return m_fFontSize;
    }
    FX_INT32								GetAlignment() const
    {
        return m_nAlignment;
    }
    FX_INT32								GetCharArray() const
    {
        return m_nCharArray;
    }
    FX_INT32								GetLimitChar() const
    {
        return m_nLimitChar;
    }
    FX_BOOL									IsMultiLine() const
    {
        return m_bMultiLine;
    }
    FX_INT32								GetHorzScale() const
    {
        return m_nHorzScale;
    }
    FX_FLOAT								GetCharSpace() const
    {
        return m_fCharSpace;
    }

    inline CPVT_WordPlace					GetBeginWordPlace() const;
    inline CPVT_WordPlace					GetEndWordPlace() const;
    CPVT_WordPlace							GetPrevWordPlace(const CPVT_WordPlace & place) const;
    CPVT_WordPlace							GetNextWordPlace(const CPVT_WordPlace & place) const;
    CPVT_WordPlace							SearchWordPlace(const CPDF_Point & point) const;
    CPVT_WordPlace							GetUpWordPlace(const CPVT_WordPlace & place, const CPDF_Point & point) const;
    CPVT_WordPlace							GetDownWordPlace(const CPVT_WordPlace & place, const CPDF_Point & point) const;
    CPVT_WordPlace							GetLineBeginPlace(const CPVT_WordPlace & place) const;
    CPVT_WordPlace							GetLineEndPlace(const CPVT_WordPlace & place) const;
    CPVT_WordPlace							GetSectionBeginPlace(const CPVT_WordPlace & place) const;
    CPVT_WordPlace							GetSectionEndPlace(const CPVT_WordPlace & place) const;
    void									UpdateWordPlace(CPVT_WordPlace & place) const;
    FX_INT32								WordPlaceToWordIndex(const CPVT_WordPlace & place) const;
    CPVT_WordPlace							WordIndexToWordPlace(FX_INT32 index) const;
    FX_WORD									GetPasswordChar() const
    {
        return GetSubWord();
    }
    FX_WORD									GetSubWord() const
    {
        return m_wSubWord;
    }
private:
    FX_INT32								GetCharWidth(FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord, FX_INT32 nWordStyle);
    FX_INT32								GetTypeAscent(FX_INT32 nFontIndex);
    FX_INT32								GetTypeDescent(FX_INT32 nFontIndex);
    FX_INT32								GetWordFontIndex(FX_WORD word, FX_INT32 charset, FX_INT32 nFontIndex);
    FX_INT32								GetDefaultFontIndex();
    FX_BOOL									IsLatinWord(FX_WORD word);
private:

    CPVT_WordPlace							AddSection(const CPVT_WordPlace & place, const CPVT_SectionInfo & secinfo);
    CPVT_WordPlace							AddLine(const CPVT_WordPlace & place, const CPVT_LineInfo & lineinfo);
    CPVT_WordPlace							AddWord(const CPVT_WordPlace & place, const CPVT_WordInfo & wordinfo);
    FX_BOOL									GetWordInfo(const CPVT_WordPlace & place, CPVT_WordInfo & wordinfo);
    FX_BOOL									SetWordInfo(const CPVT_WordPlace & place, const CPVT_WordInfo & wordinfo);
    FX_BOOL									GetLineInfo(const CPVT_WordPlace & place, CPVT_LineInfo & lineinfo);
    FX_BOOL									GetSectionInfo(const CPVT_WordPlace & place, CPVT_SectionInfo & secinfo);
    FX_FLOAT								GetWordFontSize(const CPVT_WordInfo & WordInfo, FX_BOOL bFactFontSize = FALSE);
    FX_FLOAT								GetWordWidth(FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord,
            FX_FLOAT fCharSpace, FX_INT32 nHorzScale,
            FX_FLOAT fFontSize, FX_FLOAT fWordTail, FX_INT32 nWordStyle);
    FX_FLOAT								GetWordWidth(const CPVT_WordInfo & WordInfo);
    FX_FLOAT								GetWordAscent(const CPVT_WordInfo & WordInfo, FX_FLOAT fFontSize);
    FX_FLOAT								GetWordDescent(const CPVT_WordInfo & WordInfo, FX_FLOAT fFontSize);
    FX_FLOAT								GetWordAscent(const CPVT_WordInfo & WordInfo, FX_BOOL bFactFontSize = FALSE);
    FX_FLOAT								GetWordDescent(const CPVT_WordInfo & WordInfo, FX_BOOL bFactFontSize = FALSE);
    FX_FLOAT								GetLineAscent(const CPVT_SectionInfo & SecInfo);
    FX_FLOAT								GetLineDescent(const CPVT_SectionInfo & SecInfo);
    FX_FLOAT								GetFontAscent(FX_INT32 nFontIndex, FX_FLOAT fFontSize);
    FX_FLOAT								GetFontDescent(FX_INT32 nFontIndex, FX_FLOAT fFontSize);
    FX_INT32								GetWordFontIndex(const CPVT_WordInfo & WordInfo);
    FX_FLOAT								GetCharSpace(const CPVT_WordInfo & WordInfo);
    FX_INT32								GetHorzScale(const CPVT_WordInfo & WordInfo);
    FX_FLOAT								GetLineLeading(const CPVT_SectionInfo & SecInfo);
    FX_FLOAT								GetLineIndent(const CPVT_SectionInfo & SecInfo);
    FX_INT32								GetAlignment(const CPVT_SectionInfo& SecInfo);

    void									ClearSectionRightWords(const CPVT_WordPlace & place);
    CPVT_WordPlace							AjustLineHeader(const CPVT_WordPlace & place, FX_BOOL bPrevOrNext) const;
    FX_BOOL									ClearEmptySection(const CPVT_WordPlace & place);
    void									ClearEmptySections(const CPVT_WordRange & PlaceRange);
    void									LinkLatterSection(const CPVT_WordPlace & place);
    void									ClearWords(const CPVT_WordRange & PlaceRange);
    CPVT_WordPlace							ClearLeftWord(const CPVT_WordPlace & place);
    CPVT_WordPlace							ClearRightWord(const CPVT_WordPlace & place);
private:
    CPVT_FloatRect							Rearrange(const CPVT_WordRange & PlaceRange);
    FX_FLOAT								GetAutoFontSize();
    FX_BOOL									IsBigger(FX_FLOAT fFontSize);
    CPVT_FloatRect							RearrangeSections(const CPVT_WordRange & PlaceRange);
private:
    void									ResetSectionArray();
private:
    CPVT_ArrayTemplate<CSection*>			m_SectionArray;
    FX_INT32								m_nLimitChar;
    FX_INT32								m_nCharArray;
    FX_BOOL									m_bMultiLine;
    FX_BOOL									m_bLimitWidth;
    FX_BOOL									m_bAutoFontSize;
    FX_INT32								m_nAlignment;
    FX_FLOAT								m_fLineLeading;
    FX_FLOAT								m_fCharSpace;
    FX_INT32								m_nHorzScale;
    FX_WORD									m_wSubWord;
    FX_FLOAT								m_fWordSpace;
    FX_FLOAT								m_fFontSize;

private:
    FX_BOOL									m_bInitial;
    FX_BOOL									m_bRichText;
    FX_FLOAT								m_fCaretOriginX;
    FX_INT32								m_nCurFontIndex;
    IPDF_VariableText_Provider *			m_pVTProvider;
    CPDF_VariableText_Iterator *			m_pVTIterator;
};
class CPDF_VariableText_Iterator : public IPDF_VariableText_Iterator, public CFX_Object
{
public:
    CPDF_VariableText_Iterator(CPDF_VariableText * pVT);
    virtual ~CPDF_VariableText_Iterator();
    FX_BOOL									NextWord();
    FX_BOOL									PrevWord();
    FX_BOOL									NextLine();
    FX_BOOL									PrevLine();
    FX_BOOL									NextSection();
    FX_BOOL									PrevSection();
    FX_BOOL									SetWord(const CPVT_Word & word);
    FX_BOOL									GetWord(CPVT_Word & word) const;
    FX_BOOL									GetLine(CPVT_Line & line) const;
    FX_BOOL									GetSection(CPVT_Section & section) const;
    FX_BOOL									SetSection(const CPVT_Section & section);
    void									SetAt(FX_INT32 nWordIndex);
    void									SetAt(const CPVT_WordPlace & place);
    const CPVT_WordPlace &					GetAt() const
    {
        return m_CurPos;
    };
private:
    CPVT_WordPlace							m_CurPos;
    CPDF_VariableText *						m_pVT;
};
