// 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

#ifndef _PDF_VT_H_
#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;
    }

    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							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_fFontSize;

private:
    FX_BOOL									m_bInitial;
    FX_BOOL									m_bRichText;
    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;
};

#endif  // _PDF_VT_H_
