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

#include "../../include/fxedit/fxet_stub.h"
#include "../../include/fxedit/fxet_edit.h"

#define FX_EDIT_UNDO_MAXITEM                10000

/* ---------------------------- CFX_Edit_Iterator ---------------------------- */

CFX_Edit_Iterator::CFX_Edit_Iterator(CFX_Edit * pEdit,IPDF_VariableText_Iterator * pVTIterator) :
    m_pEdit(pEdit),
    m_pVTIterator(pVTIterator)
{
}

CFX_Edit_Iterator::~CFX_Edit_Iterator()
{
}

bool CFX_Edit_Iterator::NextWord()
{
    return m_pVTIterator->NextWord();
}

bool CFX_Edit_Iterator::NextLine()
{
    return m_pVTIterator->NextLine();
}

bool CFX_Edit_Iterator::NextSection()
{
    return m_pVTIterator->NextSection();
}

bool CFX_Edit_Iterator::PrevWord()
{
    return m_pVTIterator->PrevWord();
}

bool CFX_Edit_Iterator::PrevLine()
{
    return m_pVTIterator->PrevLine();
}

bool CFX_Edit_Iterator::PrevSection()
{
    return m_pVTIterator->PrevSection();
}

bool CFX_Edit_Iterator::GetWord(CPVT_Word & word) const
{
    ASSERT(m_pEdit);

    if (m_pVTIterator->GetWord(word))
    {
        word.ptWord = m_pEdit->VTToEdit(word.ptWord);
        return true;
    }
    return false;
}

bool CFX_Edit_Iterator::GetLine(CPVT_Line & line) const
{
    ASSERT(m_pEdit);

    if (m_pVTIterator->GetLine(line))
    {
        line.ptLine = m_pEdit->VTToEdit(line.ptLine);
        return true;
    }
    return false;
}

bool CFX_Edit_Iterator::GetSection(CPVT_Section & section) const
{
    ASSERT(m_pEdit);

    if (m_pVTIterator->GetSection(section))
    {
        section.rcSection = m_pEdit->VTToEdit(section.rcSection);
        return true;
    }
    return false;
}

void CFX_Edit_Iterator::SetAt(int32_t nWordIndex)
{
    m_pVTIterator->SetAt(nWordIndex);
}

void CFX_Edit_Iterator::SetAt(const CPVT_WordPlace & place)
{
    m_pVTIterator->SetAt(place);
}

const CPVT_WordPlace & CFX_Edit_Iterator::GetAt() const
{
    return m_pVTIterator->GetAt();
}

IFX_Edit* CFX_Edit_Iterator::GetEdit() const
{
    return m_pEdit;
}

/* --------------------------- CFX_Edit_Provider ------------------------------- */

CFX_Edit_Provider::CFX_Edit_Provider(IFX_Edit_FontMap * pFontMap) : m_pFontMap(pFontMap)
{
    ASSERT(m_pFontMap != NULL);
}

CFX_Edit_Provider::~CFX_Edit_Provider()
{
}

IFX_Edit_FontMap* CFX_Edit_Provider::GetFontMap()
{
    return m_pFontMap;
}

int32_t CFX_Edit_Provider::GetCharWidth(int32_t nFontIndex, FX_WORD word, int32_t nWordStyle)
{
    if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
    {
        FX_DWORD charcode = word;

        if (pPDFFont->IsUnicodeCompatible())
            charcode = pPDFFont->CharCodeFromUnicode(word);
        else
            charcode = m_pFontMap->CharCodeFromUnicode(nFontIndex, word);

        if (charcode != -1)
            return pPDFFont->GetCharWidthF(charcode);
    }

    return 0;
}

int32_t CFX_Edit_Provider::GetTypeAscent(int32_t nFontIndex)
{
    if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
        return pPDFFont->GetTypeAscent();

    return 0;
}

int32_t CFX_Edit_Provider::GetTypeDescent(int32_t nFontIndex)
{
    if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
        return pPDFFont->GetTypeDescent();

    return 0;
}

int32_t CFX_Edit_Provider::GetWordFontIndex(FX_WORD word, int32_t charset, int32_t nFontIndex)
{
    return m_pFontMap->GetWordFontIndex(word,charset,nFontIndex);
}

int32_t CFX_Edit_Provider::GetDefaultFontIndex()
{
    return 0;
}

bool CFX_Edit_Provider::IsLatinWord(FX_WORD word)
{
    return FX_EDIT_ISLATINWORD(word);
}

/* --------------------------------- CFX_Edit_Refresh --------------------------------- */

CFX_Edit_Refresh::CFX_Edit_Refresh()
{
}

CFX_Edit_Refresh::~CFX_Edit_Refresh()
{
}

void CFX_Edit_Refresh::BeginRefresh()
{
    m_RefreshRects.Empty();
    m_OldLineRects = m_NewLineRects;
}

void CFX_Edit_Refresh::Push(const CPVT_WordRange & linerange,const CPDF_Rect & rect)
{
    m_NewLineRects.Add(linerange,rect);
}

void CFX_Edit_Refresh::NoAnalyse()
{
    {
        for (int32_t i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++)
            if (CFX_Edit_LineRect * pOldRect = m_OldLineRects.GetAt(i))
                m_RefreshRects.Add(pOldRect->m_rcLine);
    }

    {
        for (int32_t i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++)
            if (CFX_Edit_LineRect * pNewRect = m_NewLineRects.GetAt(i))
                m_RefreshRects.Add(pNewRect->m_rcLine);
    }
}

void CFX_Edit_Refresh::Analyse(int32_t nAlignment)
{
    bool bLineTopChanged = false;
    CPDF_Rect rcResult;
    FX_FLOAT fWidthDiff;

    int32_t szMax = FX_EDIT_MAX(m_OldLineRects.GetSize(),m_NewLineRects.GetSize());
    int32_t i = 0;

    while (i < szMax)
    {
        CFX_Edit_LineRect * pOldRect = m_OldLineRects.GetAt(i);
        CFX_Edit_LineRect * pNewRect = m_NewLineRects.GetAt(i);

        if (pOldRect)
        {
            if (pNewRect)
            {
                if (bLineTopChanged)
                {
                    rcResult = pOldRect->m_rcLine;
                    rcResult.Union(pNewRect->m_rcLine);
                    m_RefreshRects.Add(rcResult);
                }
                else
                {
                    if (*pNewRect != *pOldRect)
                    {
                        if (!pNewRect->IsSameTop(*pOldRect) || !pNewRect->IsSameHeight(*pOldRect))
                        {
                            bLineTopChanged = true;
                            continue;
                        }

                        if (nAlignment == 0)
                        {
                            if (pNewRect->m_wrLine.BeginPos != pOldRect->m_wrLine.BeginPos)
                            {
                                rcResult = pOldRect->m_rcLine;
                                rcResult.Union(pNewRect->m_rcLine);
                                m_RefreshRects.Add(rcResult);
                            }
                            else
                            {
                                if (!pNewRect->IsSameLeft(*pOldRect))
                                {
                                    rcResult = pOldRect->m_rcLine;
                                    rcResult.Union(pNewRect->m_rcLine);
                                }
                                else
                                {
                                    fWidthDiff = pNewRect->m_rcLine.Width() - pOldRect->m_rcLine.Width();
                                    rcResult = pNewRect->m_rcLine;
                                    if (fWidthDiff > 0.0f)
                                        rcResult.left = rcResult.right - fWidthDiff;
                                    else
                                    {
                                        rcResult.left = rcResult.right;
                                        rcResult.right += (-fWidthDiff);
                                    }
                                }
                                m_RefreshRects.Add(rcResult);
                            }
                        }
                        else
                        {
                            rcResult = pOldRect->m_rcLine;
                            rcResult.Union(pNewRect->m_rcLine);
                            m_RefreshRects.Add(rcResult);
                        }
                    }
                    else
                    {
                        //don't need to do anything
                    }
                }
            }
            else
            {
                m_RefreshRects.Add(pOldRect->m_rcLine);
            }
        }
        else
        {
            if (pNewRect)
            {
                m_RefreshRects.Add(pNewRect->m_rcLine);
            }
            else
            {
                //error
            }
        }
        i++;
    }
}

void CFX_Edit_Refresh::AddRefresh(const CPDF_Rect & rect)
{
    m_RefreshRects.Add(rect);
}

const CFX_Edit_RectArray * CFX_Edit_Refresh::GetRefreshRects() const
{
    return &m_RefreshRects;
}

void CFX_Edit_Refresh::EndRefresh()
{
    m_RefreshRects.Empty();
}

/* ------------------------------------- CFX_Edit_Undo ------------------------------------- */

CFX_Edit_Undo::CFX_Edit_Undo(int32_t nBufsize) : m_nCurUndoPos(0),
    m_nBufSize(nBufsize),
    m_bModified(false),
    m_bVirgin(true),
    m_bWorking(false)
{
}

CFX_Edit_Undo::~CFX_Edit_Undo()
{
    Reset();
}

bool CFX_Edit_Undo::CanUndo() const
{
    return m_nCurUndoPos > 0;
}

void CFX_Edit_Undo::Undo()
{
    m_bWorking = true;

    if (m_nCurUndoPos > 0)
    {
        IFX_Edit_UndoItem * pItem = m_UndoItemStack.GetAt(m_nCurUndoPos-1);
        ASSERT(pItem != NULL);

        pItem->Undo();

        m_nCurUndoPos--;
        m_bModified = (m_nCurUndoPos != 0);
    }

    m_bWorking = false;
}

bool CFX_Edit_Undo::CanRedo() const
{
    return m_nCurUndoPos < m_UndoItemStack.GetSize();
}

void CFX_Edit_Undo::Redo()
{
    m_bWorking = true;

    int32_t nStackSize = m_UndoItemStack.GetSize();

    if (m_nCurUndoPos < nStackSize)
    {
        IFX_Edit_UndoItem * pItem = m_UndoItemStack.GetAt(m_nCurUndoPos);
        ASSERT(pItem != NULL);

        pItem->Redo();

        m_nCurUndoPos++;
        m_bModified = (m_nCurUndoPos != 0);
    }

    m_bWorking = false;
}

bool CFX_Edit_Undo::IsWorking() const
{
    return m_bWorking;
}

void CFX_Edit_Undo::AddItem(IFX_Edit_UndoItem* pItem)
{
    ASSERT(!m_bWorking);
    ASSERT(pItem != NULL);
    ASSERT(m_nBufSize > 1);

    if (m_nCurUndoPos < m_UndoItemStack.GetSize())
        RemoveTails();

    if (m_UndoItemStack.GetSize() >= m_nBufSize)
    {
        RemoveHeads();
        m_bVirgin = false;
    }

    m_UndoItemStack.Add(pItem);
    m_nCurUndoPos = m_UndoItemStack.GetSize();

    m_bModified = (m_nCurUndoPos != 0);
}

bool CFX_Edit_Undo::IsModified() const
{
    return m_bVirgin ? m_bModified : true;
}

IFX_Edit_UndoItem* CFX_Edit_Undo::GetItem(int32_t nIndex)
{
    if (nIndex>=0 && nIndex < m_UndoItemStack.GetSize())
        return m_UndoItemStack.GetAt(nIndex);

    return NULL;
}

void CFX_Edit_Undo::RemoveHeads()
{
    ASSERT(m_UndoItemStack.GetSize() > 1);

    delete m_UndoItemStack.GetAt(0);
    m_UndoItemStack.RemoveAt(0);
}

void CFX_Edit_Undo::RemoveTails()
{
    for (int32_t i = m_UndoItemStack.GetSize()-1; i >= m_nCurUndoPos; i--)
    {
        delete m_UndoItemStack.GetAt(i);
        m_UndoItemStack.RemoveAt(i);
    }
}

void CFX_Edit_Undo::Reset()
{
    for (int32_t i=0, sz=m_UndoItemStack.GetSize(); i < sz; i++)
    {
        delete m_UndoItemStack.GetAt(i);
    }
    m_nCurUndoPos = 0;
    m_UndoItemStack.RemoveAll();
}

/* -------------------------------- CFX_Edit_GroupUndoItem -------------------------------- */

CFX_Edit_GroupUndoItem::CFX_Edit_GroupUndoItem(const CFX_WideString& sTitle) : m_sTitle(sTitle)
{
}

CFX_Edit_GroupUndoItem::~CFX_Edit_GroupUndoItem()
{
    for (int i=0,sz=m_Items.GetSize(); i<sz; i++)
    {
        delete m_Items[i];
    }

    m_Items.RemoveAll();
}

void CFX_Edit_GroupUndoItem::AddUndoItem(CFX_Edit_UndoItem* pUndoItem)
{
    ASSERT(pUndoItem != NULL);

    pUndoItem->SetFirst(false);
    pUndoItem->SetLast(false);

    m_Items.Add(pUndoItem);

    if (m_sTitle.IsEmpty())
        m_sTitle = pUndoItem->GetUndoTitle();
}

void CFX_Edit_GroupUndoItem::UpdateItems()
{
    if (m_Items.GetSize() > 0)
    {
        CFX_Edit_UndoItem* pFirstItem = m_Items[0];
        ASSERT(pFirstItem != NULL);
        pFirstItem->SetFirst(true);

        CFX_Edit_UndoItem* pLastItem = m_Items[m_Items.GetSize() - 1];
        ASSERT(pLastItem != NULL);
        pLastItem->SetLast(true);
    }
}

void CFX_Edit_GroupUndoItem::Undo()
{
    for (int i=m_Items.GetSize()-1; i>=0; i--)
    {
        CFX_Edit_UndoItem* pUndoItem = m_Items[i];
        ASSERT(pUndoItem != NULL);

        pUndoItem->Undo();
    }
}

void CFX_Edit_GroupUndoItem::Redo()
{
    for (int i=0,sz=m_Items.GetSize(); i<sz; i++)
    {
        CFX_Edit_UndoItem* pUndoItem = m_Items[i];
        ASSERT(pUndoItem != NULL);

        pUndoItem->Redo();
    }
}

CFX_WideString CFX_Edit_GroupUndoItem::GetUndoTitle()
{
    return m_sTitle;
}

/* ------------------------------------- CFX_Edit_UndoItem derived classes ------------------------------------- */

CFXEU_InsertWord::CFXEU_InsertWord(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
                                 FX_WORD word, int32_t charset, const CPVT_WordProps * pWordProps)
    : m_pEdit(pEdit), m_wpOld(wpOldPlace), m_wpNew(wpNewPlace), m_Word(word), m_nCharset(charset), m_WordProps()
{
    if (pWordProps)
        m_WordProps = *pWordProps;
}

CFXEU_InsertWord::~CFXEU_InsertWord()
{
}

void CFXEU_InsertWord::Redo()
{
    if (m_pEdit)
    {
        m_pEdit->SelectNone();
        m_pEdit->SetCaret(m_wpOld);
        m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,false,true);
    }
}

void CFXEU_InsertWord::Undo()
{
    if (m_pEdit)
    {
        m_pEdit->SelectNone();
        m_pEdit->SetCaret(m_wpNew);
        m_pEdit->Backspace(false,true);
    }
}

/* -------------------------------------------------------------------------- */

CFXEU_InsertReturn::CFXEU_InsertReturn(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
             const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps) :
            m_pEdit(pEdit),
            m_wpOld(wpOldPlace),
            m_wpNew(wpNewPlace),
            m_SecProps(),
            m_WordProps()
{
    if (pSecProps)
        m_SecProps = *pSecProps;
    if (pWordProps)
        m_WordProps = *pWordProps;
}

CFXEU_InsertReturn::~CFXEU_InsertReturn()
{
}

void CFXEU_InsertReturn::Redo()
{
    if (m_pEdit)
    {
        m_pEdit->SelectNone();
        m_pEdit->SetCaret(m_wpOld);
        m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,false,true);
    }
}

void CFXEU_InsertReturn::Undo()
{
    if (m_pEdit)
    {
        m_pEdit->SelectNone();
        m_pEdit->SetCaret(m_wpNew);
        m_pEdit->Backspace(false,true);
    }
}

/* -------------------------------------------------------------------------- */
//CFXEU_Backspace

CFXEU_Backspace::CFXEU_Backspace(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
                               FX_WORD word, int32_t charset,
                               const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps) :
            m_pEdit(pEdit),
            m_wpOld(wpOldPlace),
            m_wpNew(wpNewPlace),
            m_Word(word),
            m_nCharset(charset),
            m_SecProps(SecProps),
            m_WordProps(WordProps)
{
}

CFXEU_Backspace::~CFXEU_Backspace()
{
}

void CFXEU_Backspace::Redo()
{
    if (m_pEdit)
    {
        m_pEdit->SelectNone();
        m_pEdit->SetCaret(m_wpOld);
        m_pEdit->Backspace(false,true);
    }
}

void CFXEU_Backspace::Undo()
{
    if (m_pEdit)
    {
        m_pEdit->SelectNone();
        m_pEdit->SetCaret(m_wpNew);
        if (m_wpNew.SecCmp(m_wpOld) != 0)
        {
            m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,false,true);
        }
        else
        {
            m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,false,true);
        }
    }
}

/* -------------------------------------------------------------------------- */
//CFXEU_Delete

CFXEU_Delete::CFXEU_Delete(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
                               FX_WORD word, int32_t charset,
                               const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps, bool bSecEnd) :
            m_pEdit(pEdit),
            m_wpOld(wpOldPlace),
            m_wpNew(wpNewPlace),
            m_Word(word),
            m_nCharset(charset),
            m_SecProps(SecProps),
            m_WordProps(WordProps),
            m_bSecEnd(bSecEnd)
{
}

CFXEU_Delete::~CFXEU_Delete()
{
}

void CFXEU_Delete::Redo()
{
    if (m_pEdit)
    {
        m_pEdit->SelectNone();
        m_pEdit->SetCaret(m_wpOld);
        m_pEdit->Delete(false,true);
    }
}

void CFXEU_Delete::Undo()
{
    if (m_pEdit)
    {
        m_pEdit->SelectNone();
        m_pEdit->SetCaret(m_wpNew);
        if (m_bSecEnd)
        {
            m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,false,true);
        }
        else
        {
            m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,false,true);
        }
    }
}

/* -------------------------------------------------------------------------- */
//CFXEU_Clear

CFXEU_Clear::CFXEU_Clear(CFX_Edit * pEdit,  const CPVT_WordRange & wrSel, const CFX_WideString & swText) :
            m_pEdit(pEdit),
            m_wrSel(wrSel),
            m_swText(swText)
{
}

CFXEU_Clear::~CFXEU_Clear()
{
}

void CFXEU_Clear::Redo()
{
    if (m_pEdit)
    {
        m_pEdit->SelectNone();
        m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
        m_pEdit->Clear(false,true);
    }
}

void CFXEU_Clear::Undo()
{
    if (m_pEdit)
    {
        m_pEdit->SelectNone();
        m_pEdit->SetCaret(m_wrSel.BeginPos);
        m_pEdit->InsertText(m_swText.c_str(), DEFAULT_CHARSET, NULL, NULL, false, true);
        m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
    }
}

/* -------------------------------------------------------------------------- */
//CFXEU_ClearRich

CFXEU_ClearRich::CFXEU_ClearRich(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
                               const CPVT_WordRange & wrSel, FX_WORD word, int32_t charset,
                               const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps) :
            m_pEdit(pEdit),
            m_wpOld(wpOldPlace),
            m_wpNew(wpNewPlace),
            m_wrSel(wrSel),
            m_Word(word),
            m_nCharset(charset),
            m_SecProps(SecProps),
            m_WordProps(WordProps)
{
}

CFXEU_ClearRich::~CFXEU_ClearRich()
{
}

void CFXEU_ClearRich::Redo()
{
    if (m_pEdit && IsLast())
    {
        m_pEdit->SelectNone();
        m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
        m_pEdit->Clear(false,true);
    }
}

void CFXEU_ClearRich::Undo()
{
    if (m_pEdit)
    {
        m_pEdit->SelectNone();
        m_pEdit->SetCaret(m_wpOld);
        if (m_wpNew.SecCmp(m_wpOld) != 0)
        {
            m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,false,false);
        }
        else
        {
            m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,false,false);
        }

        if (IsFirst())
        {
            m_pEdit->PaintInsertText(m_wrSel.BeginPos,m_wrSel.EndPos);
            m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
        }
    }
}
/* -------------------------------------------------------------------------- */
//CFXEU_InsertText

CFXEU_InsertText::CFXEU_InsertText(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
                               const CFX_WideString & swText, int32_t charset,
                               const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps) :
            m_pEdit(pEdit),
            m_wpOld(wpOldPlace),
            m_wpNew(wpNewPlace),
            m_swText(swText),
            m_nCharset(charset),
            m_SecProps(),
            m_WordProps()
{
    if (pSecProps)
        m_SecProps = *pSecProps;
    if (pWordProps)
        m_WordProps = *pWordProps;
}

CFXEU_InsertText::~CFXEU_InsertText()
{
}

void CFXEU_InsertText::Redo()
{
    if (m_pEdit && IsLast())
    {
        m_pEdit->SelectNone();
        m_pEdit->SetCaret(m_wpOld);
        m_pEdit->InsertText(m_swText.c_str(), m_nCharset, &m_SecProps, &m_WordProps, false, true);
    }
}

void CFXEU_InsertText::Undo()
{
    if (m_pEdit)
    {
        m_pEdit->SelectNone();
        m_pEdit->SetSel(m_wpOld,m_wpNew);
        m_pEdit->Clear(false,true);
    }
}

/* -------------------------------------------------------------------------- */

CFXEU_SetSecProps::CFXEU_SetSecProps(CFX_Edit * pEdit, const CPVT_WordPlace & place, EDIT_PROPS_E ep,
        const CPVT_SecProps & oldsecprops, const CPVT_WordProps & oldwordprops,
        const CPVT_SecProps & newsecprops, const CPVT_WordProps & newwordprops, const CPVT_WordRange & range)
        : m_pEdit(pEdit),
        m_wpPlace(place),
        m_wrPlace(range),
        m_eProps(ep),
        m_OldSecProps(oldsecprops),
        m_NewSecProps(newsecprops),
        m_OldWordProps(oldwordprops),
        m_NewWordProps(newwordprops)
{
}

CFXEU_SetSecProps::~CFXEU_SetSecProps()
{
}

void CFXEU_SetSecProps::Redo()
{
    if (m_pEdit)
    {
        m_pEdit->SetSecProps(m_eProps,m_wpPlace,&m_NewSecProps,&m_NewWordProps,m_wrPlace,false);
        if (IsLast())
        {
            m_pEdit->SelectNone();
            m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
            m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
        }
    }
}

void CFXEU_SetSecProps::Undo()
{
    if (m_pEdit)
    {
        m_pEdit->SetSecProps(m_eProps,m_wpPlace,&m_OldSecProps,&m_OldWordProps,m_wrPlace,false);
        if (IsFirst())
        {
            m_pEdit->SelectNone();
            m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
            m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
        }
    }
}

/* -------------------------------------------------------------------------- */

CFXEU_SetWordProps::CFXEU_SetWordProps(CFX_Edit * pEdit, const CPVT_WordPlace & place, EDIT_PROPS_E ep,
        const CPVT_WordProps & oldprops, const CPVT_WordProps & newprops, const CPVT_WordRange & range)
        : m_pEdit(pEdit),
        m_wpPlace(place),
        m_wrPlace(range),
        m_eProps(ep),
        m_OldWordProps(oldprops),
        m_NewWordProps(newprops)
{
}

CFXEU_SetWordProps::~CFXEU_SetWordProps()
{
}

void CFXEU_SetWordProps::Redo()
{
    if (m_pEdit)
    {
        m_pEdit->SetWordProps(m_eProps,m_wpPlace,&m_NewWordProps,m_wrPlace,false);
        if (IsLast())
        {
            m_pEdit->SelectNone();
            m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
            m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
        }
    }
}

void CFXEU_SetWordProps::Undo()
{
    if (m_pEdit)
    {
        m_pEdit->SetWordProps(m_eProps,m_wpPlace,&m_OldWordProps,m_wrPlace,false);
        if (IsFirst())
        {
            m_pEdit->SelectNone();
            m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
            m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
        }
    }
}

/* ------------------------------------- CFX_Edit ------------------------------------- */

CFX_Edit::CFX_Edit(IPDF_VariableText * pVT) :
    m_pVT(pVT),
    m_pNotify(NULL),
    m_pOprNotify(NULL),
    m_pVTProvide(NULL),
    m_wpCaret(-1,-1,-1),
    m_wpOldCaret(-1,-1,-1),
    m_SelState(),
    m_ptScrollPos(0,0),
    m_ptRefreshScrollPos(0,0),
    m_bEnableScroll(false),
    m_pIterator(NULL),
    m_ptCaret(0.0f,0.0f),
    m_Undo(FX_EDIT_UNDO_MAXITEM),
    m_nAlignment(0),
    m_bNotifyFlag(false),
    m_bEnableOverflow(false),
    m_bEnableRefresh(true),
    m_rcOldContent(0.0f,0.0f,0.0f,0.0f),
    m_bEnableUndo(true),
    m_bNotify(true),
    m_bOprNotify(false),
    m_pGroupUndoItem(NULL)
{
    ASSERT(pVT != NULL);
}

CFX_Edit::~CFX_Edit()
{
    delete m_pVTProvide;
    m_pVTProvide = NULL;
    delete m_pIterator;
    m_pIterator = NULL;
    ASSERT(m_pGroupUndoItem == NULL);
}

// public methods

void CFX_Edit::Initialize()
{
    m_pVT->Initialize();
    SetCaret(m_pVT->GetBeginWordPlace());
    SetCaretOrigin();
}

void CFX_Edit::SetFontMap(IFX_Edit_FontMap * pFontMap)
{
    delete m_pVTProvide;
    m_pVT->SetProvider(m_pVTProvide = new CFX_Edit_Provider(pFontMap));
}

void CFX_Edit::SetVTProvider(IPDF_VariableText_Provider* pProvider)
{
    m_pVT->SetProvider(pProvider);
}

void CFX_Edit::SetNotify(IFX_Edit_Notify* pNotify)
{
    m_pNotify = pNotify;
}

void CFX_Edit::SetOprNotify(IFX_Edit_OprNotify* pOprNotify)
{
    m_pOprNotify = pOprNotify;
}

IFX_Edit_Iterator * CFX_Edit::GetIterator()
{
    if (!m_pIterator)
        m_pIterator = new CFX_Edit_Iterator(this,m_pVT->GetIterator());

    return m_pIterator;
}

IPDF_VariableText * CFX_Edit::GetVariableText()
{
    return m_pVT;
}

IFX_Edit_FontMap* CFX_Edit::GetFontMap()
{
    if (m_pVTProvide)
        return m_pVTProvide->GetFontMap();

    return NULL;
}

void CFX_Edit::SetPlateRect(const CPDF_Rect & rect, bool bPaint/* = true*/)
{
    m_pVT->SetPlateRect(rect);
    m_ptScrollPos = CPDF_Point(rect.left,rect.top);
    if (bPaint) Paint();
}

void CFX_Edit::SetAlignmentH(int32_t nFormat/* =0 */, bool bPaint/* = true*/)
{
    m_pVT->SetAlignment(nFormat);
    if (bPaint) Paint();
}

void CFX_Edit::SetAlignmentV(int32_t nFormat/* =0 */, bool bPaint/* = true*/)
{
    m_nAlignment = nFormat;
    if (bPaint) Paint();
}

void CFX_Edit::SetPasswordChar(FX_WORD wSubWord/* ='*' */, bool bPaint/* = true*/)
{
    m_pVT->SetPasswordChar(wSubWord);
    if (bPaint) Paint();
}

void CFX_Edit::SetLimitChar(int32_t nLimitChar/* =0 */, bool bPaint/* = true*/)
{
    m_pVT->SetLimitChar(nLimitChar);
    if (bPaint) Paint();
}

void CFX_Edit::SetCharArray(int32_t nCharArray/* =0 */, bool bPaint/* = true*/)
{
    m_pVT->SetCharArray(nCharArray);
    if (bPaint) Paint();
}

void CFX_Edit::SetCharSpace(FX_FLOAT fCharSpace/* =0.0f */, bool bPaint/* = true*/)
{
    m_pVT->SetCharSpace(fCharSpace);
    if (bPaint) Paint();
}

void CFX_Edit::SetHorzScale(int32_t nHorzScale/* =100 */, bool bPaint/* = true*/)
{
    m_pVT->SetHorzScale(nHorzScale);
    if (bPaint) Paint();
}

void CFX_Edit::SetMultiLine(bool bMultiLine/* =true */, bool bPaint/* = true*/)
{
    m_pVT->SetMultiLine(bMultiLine);
    if (bPaint) Paint();
}

void CFX_Edit::SetAutoReturn(bool bAuto/* =true */, bool bPaint/* = true*/)
{
    m_pVT->SetAutoReturn(bAuto);
    if (bPaint) Paint();
}

void CFX_Edit::SetLineLeading(FX_FLOAT fLineLeading/* =true */, bool bPaint/* = true*/)
{
    m_pVT->SetLineLeading(fLineLeading);
    if (bPaint) Paint();
}

void CFX_Edit::SetAutoFontSize(bool bAuto/* =true */, bool bPaint/* = true*/)
{
    m_pVT->SetAutoFontSize(bAuto);
    if (bPaint) Paint();
}

void CFX_Edit::SetFontSize(FX_FLOAT fFontSize, bool bPaint/* = true*/)
{
    m_pVT->SetFontSize(fFontSize);
    if (bPaint) Paint();
}

void CFX_Edit::SetAutoScroll(bool bAuto/* =true */, bool bPaint/* = true*/)
{
    m_bEnableScroll = bAuto;
    if (bPaint) Paint();
}

void CFX_Edit::SetTextOverflow(bool bAllowed /*= false*/, bool bPaint/* = true*/)
{
    m_bEnableOverflow = bAllowed;
    if (bPaint) Paint();
}

void CFX_Edit::SetSel(int32_t nStartChar,int32_t nEndChar)
{
    if (m_pVT->IsValid())
    {
        if (nStartChar == 0 && nEndChar < 0)
        {
            SelectAll();
        }
        else if (nStartChar < 0)
        {
            SelectNone();
        }
        else
        {
            if (nStartChar < nEndChar)
            {
                SetSel(m_pVT->WordIndexToWordPlace(nStartChar),m_pVT->WordIndexToWordPlace(nEndChar));
            }
            else
            {
                SetSel(m_pVT->WordIndexToWordPlace(nEndChar),m_pVT->WordIndexToWordPlace(nStartChar));
            }
        }
    }
}

void CFX_Edit::SetSel(const CPVT_WordPlace & begin,const CPVT_WordPlace & end)
{
    if (m_pVT->IsValid())
    {
        SelectNone();

        m_SelState.Set(begin,end);

        SetCaret(m_SelState.EndPos);

        if (m_SelState.IsExist())
        {
            ScrollToCaret();
            CPVT_WordRange wr(m_SelState.BeginPos,m_SelState.EndPos);
            Refresh(RP_OPTIONAL,&wr);
            SetCaretInfo();
        }
        else
        {
            ScrollToCaret();
            SetCaretInfo();
        }
    }
}

void CFX_Edit::GetSel(int32_t & nStartChar, int32_t & nEndChar) const
{
    nStartChar = -1;
    nEndChar = -1;

    if (m_pVT->IsValid())
    {
        if (m_SelState.IsExist())
        {
            if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
            {
                nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
                nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
            }
            else
            {
                nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
                nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
            }
        }
        else
        {
            nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
            nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
        }
    }
}

int32_t CFX_Edit::GetCaret() const
{
    if (m_pVT->IsValid())
        return m_pVT->WordPlaceToWordIndex(m_wpCaret);

    return -1;
}

CPVT_WordPlace CFX_Edit::GetCaretWordPlace() const
{
    return m_wpCaret;
}

CFX_WideString CFX_Edit::GetText() const
{
    CFX_WideString swRet;

    if (m_pVT->IsValid())
    {
        if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
        {
            bool bRich = m_pVT->IsRichText();

            pIterator->SetAt(0);

            CPVT_Word wordinfo;
            CPVT_WordPlace oldplace = pIterator->GetAt();
            while (pIterator->NextWord())
            {
                CPVT_WordPlace place = pIterator->GetAt();

                if (pIterator->GetWord(wordinfo))
                {
                    if (bRich)
                    {
                        swRet += wordinfo.Word;
                    }
                    else
                    {
                        swRet += wordinfo.Word;
                    }
                }

                if (oldplace.SecCmp(place) != 0)
                {
                    swRet += 0x0D;
                    swRet += 0x0A;
                }

                oldplace = place;
            }
        }
    }

    return swRet;
}

CFX_WideString CFX_Edit::GetRangeText(const CPVT_WordRange & range) const
{
    CFX_WideString swRet;

    if (m_pVT->IsValid())
    {
        bool bRich = m_pVT->IsRichText();

        if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
        {
            CPVT_WordRange wrTemp = range;
            m_pVT->UpdateWordPlace(wrTemp.BeginPos);
            m_pVT->UpdateWordPlace(wrTemp.EndPos);
            pIterator->SetAt(wrTemp.BeginPos);

            CPVT_Word wordinfo;
            CPVT_WordPlace oldplace = wrTemp.BeginPos;
            while (pIterator->NextWord())
            {
                CPVT_WordPlace place = pIterator->GetAt();
                if (place.WordCmp(wrTemp.EndPos) > 0)break;

                if (pIterator->GetWord(wordinfo))
                {
                    if (bRich)
                    {
                        swRet += wordinfo.Word;
                    }
                    else
                    {
                        swRet += wordinfo.Word;
                    }
                }

                if (oldplace.SecCmp(place) != 0)
                {
                    swRet += 0x0D;
                    swRet += 0x0A;
                }

                oldplace = place;
            }
        }
    }

    return swRet;
}

CFX_WideString CFX_Edit::GetSelText() const
{
    return GetRangeText(m_SelState.ConvertToWordRange());
}

int32_t CFX_Edit::GetTotalWords() const
{
    return m_pVT->GetTotalWords();
}

int32_t CFX_Edit::GetTotalLines() const
{
    int32_t nLines = 0;

    if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
    {
        pIterator->SetAt(0);
        while (pIterator->NextLine())
            nLines++;
    }

    return nLines+1;
}

CPVT_WordRange CFX_Edit::GetSelectWordRange() const
{
    return m_SelState.ConvertToWordRange();
}

CPVT_WordRange CFX_Edit::CombineWordRange(const CPVT_WordRange & wr1, const CPVT_WordRange & wr2)
{
    CPVT_WordRange wrRet;

    if (wr1.BeginPos.WordCmp(wr2.BeginPos) < 0)
    {
        wrRet.BeginPos = wr1.BeginPos;
    }
    else
    {
        wrRet.BeginPos = wr2.BeginPos;
    }

    if (wr1.EndPos.WordCmp(wr2.EndPos) < 0)
    {
        wrRet.EndPos = wr2.EndPos;
    }
    else
    {
        wrRet.EndPos = wr1.EndPos;
    }

    return wrRet;
}

bool CFX_Edit::IsRichText() const
{
    return m_pVT->IsRichText();
}

void CFX_Edit::SetRichText(bool bRichText/* =true */, bool bPaint/* = true*/)
{
    m_pVT->SetRichText(bRichText);
    if (bPaint) Paint();
}

bool CFX_Edit::SetRichFontIndex(int32_t nFontIndex)
{
    CPVT_WordProps WordProps;
    WordProps.nFontIndex = nFontIndex;
    return SetRichTextProps(EP_FONTINDEX,NULL,&WordProps);
}

bool CFX_Edit::SetRichFontSize(FX_FLOAT fFontSize)
{
    CPVT_WordProps WordProps;
    WordProps.fFontSize = fFontSize;
    return SetRichTextProps(EP_FONTSIZE,NULL,&WordProps);
}

bool CFX_Edit::SetRichTextColor(FX_COLORREF dwColor)
{
    CPVT_WordProps WordProps;
    WordProps.dwWordColor = dwColor;
    return SetRichTextProps(EP_WORDCOLOR,NULL,&WordProps);
}

bool CFX_Edit::SetRichTextScript(int32_t nScriptType)
{
    CPVT_WordProps WordProps;
    WordProps.nScriptType = nScriptType;
    return SetRichTextProps(EP_SCRIPTTYPE,NULL,&WordProps);
}

bool CFX_Edit::SetRichTextBold(bool bBold)
{
    CPVT_WordProps WordProps;
    if (bBold)
        WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
    return SetRichTextProps(EP_BOLD,NULL,&WordProps);
}

bool CFX_Edit::SetRichTextItalic(bool bItalic)
{
    CPVT_WordProps WordProps;
    if (bItalic)
        WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
    return SetRichTextProps(EP_ITALIC,NULL,&WordProps);
}

bool CFX_Edit::SetRichTextUnderline(bool bUnderline)
{
    CPVT_WordProps WordProps;
    if (bUnderline)
        WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
    return SetRichTextProps(EP_UNDERLINE,NULL,&WordProps);
}

bool CFX_Edit::SetRichTextCrossout(bool bCrossout)
{
    CPVT_WordProps WordProps;
    if (bCrossout)
        WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
    return SetRichTextProps(EP_CROSSOUT,NULL,&WordProps);
}

bool CFX_Edit::SetRichTextCharSpace(FX_FLOAT fCharSpace)
{
    CPVT_WordProps WordProps;
    WordProps.fCharSpace = fCharSpace;
    return SetRichTextProps(EP_CHARSPACE,NULL,&WordProps);
}

bool CFX_Edit::SetRichTextHorzScale(int32_t nHorzScale /*= 100*/)
{
    CPVT_WordProps WordProps;
    WordProps.nHorzScale = nHorzScale;
    return SetRichTextProps(EP_HORZSCALE,NULL,&WordProps);
}

bool CFX_Edit::SetRichTextLineLeading(FX_FLOAT fLineLeading)
{
    CPVT_SecProps SecProps;
    SecProps.fLineLeading = fLineLeading;
    return SetRichTextProps(EP_LINELEADING,&SecProps,NULL);
}

bool CFX_Edit::SetRichTextLineIndent(FX_FLOAT fLineIndent)
{
    CPVT_SecProps SecProps;
    SecProps.fLineIndent = fLineIndent;
    return SetRichTextProps(EP_LINEINDENT,&SecProps,NULL);
}

bool CFX_Edit::SetRichTextAlignment(int32_t nAlignment)
{
    CPVT_SecProps SecProps;
    SecProps.nAlignment = nAlignment;
    return SetRichTextProps(EP_ALIGNMENT,&SecProps,NULL);
}

bool CFX_Edit::SetRichTextProps(EDIT_PROPS_E eProps, const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps)
{
    bool bSet = false;
    bool bSet1,bSet2;
    if (m_pVT->IsValid() && m_pVT->IsRichText())
    {
        if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
        {
            CPVT_WordRange wrTemp = m_SelState.ConvertToWordRange();

            m_pVT->UpdateWordPlace(wrTemp.BeginPos);
            m_pVT->UpdateWordPlace(wrTemp.EndPos);
            pIterator->SetAt(wrTemp.BeginPos);

            BeginGroupUndo(L"");;

            bSet = SetSecProps(eProps,wrTemp.BeginPos,pSecProps,pWordProps,wrTemp,true);

            while (pIterator->NextWord())
            {
                CPVT_WordPlace place = pIterator->GetAt();
                if (place.WordCmp(wrTemp.EndPos) > 0) break;
                bSet1 = SetSecProps(eProps,place,pSecProps,pWordProps,wrTemp,true);
                bSet2 = SetWordProps(eProps,place,pWordProps,wrTemp,true);

                if (!bSet)
                    bSet = (bSet1 || bSet2);
            }

            EndGroupUndo();

            if (bSet)
            {
                PaintSetProps(eProps,wrTemp);
            }
        }
    }

    return bSet;
}

void CFX_Edit::PaintSetProps(EDIT_PROPS_E eProps, const CPVT_WordRange & wr)
{
    switch(eProps)
    {
    case EP_LINELEADING:
    case EP_LINEINDENT:
    case EP_ALIGNMENT:
        RearrangePart(wr);
        ScrollToCaret();
        Refresh(RP_ANALYSE);
        SetCaretOrigin();
        SetCaretInfo();
        break;
    case EP_WORDCOLOR:
    case EP_UNDERLINE:
    case EP_CROSSOUT:
        Refresh(RP_OPTIONAL,&wr);
        break;
    case EP_FONTINDEX:
    case EP_FONTSIZE:
    case EP_SCRIPTTYPE:
    case EP_CHARSPACE:
    case EP_HORZSCALE:
    case EP_BOLD:
    case EP_ITALIC:
        RearrangePart(wr);
        ScrollToCaret();

        CPVT_WordRange wrRefresh(m_pVT->GetSectionBeginPlace(wr.BeginPos),
            m_pVT->GetSectionEndPlace(wr.EndPos));
        Refresh(RP_ANALYSE,&wrRefresh);

        SetCaretOrigin();
        SetCaretInfo();
        break;
    }
}

bool CFX_Edit::SetSecProps(EDIT_PROPS_E eProps, const CPVT_WordPlace & place,
                               const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps,
                               const CPVT_WordRange & wr, bool bAddUndo)
{
    if (m_pVT->IsValid() && m_pVT->IsRichText())
    {
        if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
        {
            bool bSet = false;
            CPVT_Section secinfo;
            CPVT_Section OldSecinfo;

            CPVT_WordPlace oldplace = pIterator->GetAt();

            if (eProps == EP_LINELEADING || eProps == EP_LINEINDENT || eProps == EP_ALIGNMENT)
            {
                if (pSecProps)
                {
                    pIterator->SetAt(place);
                    if (pIterator->GetSection(secinfo))
                    {
                        if (bAddUndo) OldSecinfo = secinfo;

                        switch(eProps)
                        {
                        case EP_LINELEADING:
                            if (!FX_EDIT_IsFloatEqual(secinfo.SecProps.fLineLeading,pSecProps->fLineLeading))
                            {
                                secinfo.SecProps.fLineLeading = pSecProps->fLineLeading;
                                bSet = true;
                            }
                            break;
                        case EP_LINEINDENT:
                            if (!FX_EDIT_IsFloatEqual(secinfo.SecProps.fLineIndent,pSecProps->fLineIndent))
                            {
                                secinfo.SecProps.fLineIndent = pSecProps->fLineIndent;
                                bSet = true;
                            }
                            break;
                        case EP_ALIGNMENT:
                            if (secinfo.SecProps.nAlignment != pSecProps->nAlignment)
                            {
                                secinfo.SecProps.nAlignment = pSecProps->nAlignment;
                                bSet = true;
                            }
                            break;
                        default:
                            break;
                        }
                    }
                }
            }
            else
            {
                if (pWordProps && place == m_pVT->GetSectionBeginPlace(place))
                {
                    pIterator->SetAt(place);
                    if (pIterator->GetSection(secinfo))
                    {
                        if (bAddUndo) OldSecinfo = secinfo;

                        switch(eProps)
                        {
                        case EP_FONTINDEX:
                            if (secinfo.WordProps.nFontIndex != pWordProps->nFontIndex)
                            {
                                secinfo.WordProps.nFontIndex = pWordProps->nFontIndex;
                                bSet = true;
                            }
                            break;
                        case EP_FONTSIZE:
                            if (!FX_EDIT_IsFloatEqual(secinfo.WordProps.fFontSize,pWordProps->fFontSize))
                            {
                                secinfo.WordProps.fFontSize = pWordProps->fFontSize;
                                bSet = true;
                            }
                            break;
                        case EP_WORDCOLOR:
                            if (secinfo.WordProps.dwWordColor != pWordProps->dwWordColor)
                            {
                                secinfo.WordProps.dwWordColor = pWordProps->dwWordColor;
                                bSet = true;
                            }
                            break;
                        case EP_SCRIPTTYPE:
                            if (secinfo.WordProps.nScriptType != pWordProps->nScriptType)
                            {
                                secinfo.WordProps.nScriptType = pWordProps->nScriptType;
                                bSet = true;
                            }
                            break;
                        case EP_CHARSPACE:
                            if (!FX_EDIT_IsFloatEqual(secinfo.WordProps.fCharSpace,pWordProps->fCharSpace))
                            {
                                secinfo.WordProps.fCharSpace = pWordProps->fCharSpace;
                                bSet = true;
                            }
                            break;
                        case EP_HORZSCALE:
                            if (secinfo.WordProps.nHorzScale != pWordProps->nHorzScale)
                            {
                                secinfo.WordProps.nHorzScale = pWordProps->nHorzScale;
                                bSet = true;
                            }
                            break;
                        case EP_UNDERLINE:
                            if (pWordProps->nWordStyle & PVTWORD_STYLE_UNDERLINE)
                            {
                                if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) == 0)
                                {
                                    secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
                                    bSet = true;
                                }
                            }
                            else
                            {
                                if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) != 0)
                                {
                                    secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_UNDERLINE;
                                    bSet = true;
                                }
                            }
                            break;
                        case EP_CROSSOUT:
                            if (pWordProps->nWordStyle & PVTWORD_STYLE_CROSSOUT)
                            {
                                if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) == 0)
                                {
                                    secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
                                    bSet = true;
                                }
                            }
                            else
                            {
                                if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) != 0)
                                {
                                    secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_CROSSOUT;
                                    bSet = true;
                                }
                            }
                            break;
                        case EP_BOLD:
                            if (pWordProps->nWordStyle & PVTWORD_STYLE_BOLD)
                            {
                                if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) == 0)
                                {
                                    secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
                                    bSet = true;
                                }
                            }
                            else
                            {
                                if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) != 0)
                                {
                                    secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_BOLD;
                                    bSet = true;
                                }
                            }
                            break;
                        case EP_ITALIC:
                            if (pWordProps->nWordStyle & PVTWORD_STYLE_ITALIC)
                            {
                                if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) == 0)
                                {
                                    secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
                                    bSet = true;
                                }
                            }
                            else
                            {
                                if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) != 0)
                                {
                                    secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_ITALIC;
                                    bSet = true;
                                }
                            }
                            break;
                        default:
                            break;
                        }
                    }
                }
            }

            if (bSet)
            {
                pIterator->SetSection(secinfo);

                if (bAddUndo && m_bEnableUndo)
                {
                    AddEditUndoItem(new CFXEU_SetSecProps
                        (this,place,eProps,OldSecinfo.SecProps,OldSecinfo.WordProps,secinfo.SecProps,secinfo.WordProps,wr));
                }
            }

            pIterator->SetAt(oldplace);

            return bSet;
        }
    }

    return false;
}

bool CFX_Edit::SetWordProps(EDIT_PROPS_E eProps, const CPVT_WordPlace & place,
                                const CPVT_WordProps * pWordProps, const CPVT_WordRange & wr, bool bAddUndo)
{
    if (m_pVT->IsValid() && m_pVT->IsRichText())
    {
        if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
        {
            bool bSet = false;
            CPVT_Word wordinfo;
            CPVT_Word OldWordinfo;

            CPVT_WordPlace oldplace = pIterator->GetAt();

            if (pWordProps)
            {
                pIterator->SetAt(place);
                if (pIterator->GetWord(wordinfo))
                {
                    if (bAddUndo) OldWordinfo = wordinfo;

                    switch(eProps)
                    {
                    case EP_FONTINDEX:
                        if (wordinfo.WordProps.nFontIndex != pWordProps->nFontIndex)
                        {
                            if (IFX_Edit_FontMap* pFontMap = GetFontMap())
                            {
                                wordinfo.WordProps.nFontIndex = pFontMap->GetWordFontIndex(wordinfo.Word,wordinfo.nCharset,pWordProps->nFontIndex);
                            }
                            bSet = true;
                        }
                        break;
                    case EP_FONTSIZE:
                        if (!FX_EDIT_IsFloatEqual(wordinfo.WordProps.fFontSize,pWordProps->fFontSize))
                        {
                            wordinfo.WordProps.fFontSize = pWordProps->fFontSize;
                            bSet = true;
                        }
                        break;
                    case EP_WORDCOLOR:
                        if (wordinfo.WordProps.dwWordColor != pWordProps->dwWordColor)
                        {
                            wordinfo.WordProps.dwWordColor = pWordProps->dwWordColor;
                            bSet = true;
                        }
                        break;
                    case EP_SCRIPTTYPE:
                        if (wordinfo.WordProps.nScriptType != pWordProps->nScriptType)
                        {
                            wordinfo.WordProps.nScriptType = pWordProps->nScriptType;
                            bSet = true;
                        }
                        break;
                    case EP_CHARSPACE:
                        if (!FX_EDIT_IsFloatEqual(wordinfo.WordProps.fCharSpace,pWordProps->fCharSpace))
                        {
                            wordinfo.WordProps.fCharSpace = pWordProps->fCharSpace;
                            bSet = true;
                        }
                        break;
                    case EP_HORZSCALE:
                        if (wordinfo.WordProps.nHorzScale != pWordProps->nHorzScale)
                        {
                            wordinfo.WordProps.nHorzScale = pWordProps->nHorzScale;
                            bSet = true;
                        }
                        break;
                    case EP_UNDERLINE:
                        if (pWordProps->nWordStyle & PVTWORD_STYLE_UNDERLINE)
                        {
                            if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) == 0)
                            {
                                wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
                                bSet = true;
                            }
                        }
                        else
                        {
                            if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) != 0)
                            {
                                wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_UNDERLINE;
                                bSet = true;
                            }
                        }
                        break;
                    case EP_CROSSOUT:
                        if (pWordProps->nWordStyle & PVTWORD_STYLE_CROSSOUT)
                        {
                            if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) == 0)
                            {
                                wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
                                bSet = true;
                            }
                        }
                        else
                        {
                            if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) != 0)
                            {
                                wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_CROSSOUT;
                                bSet = true;
                            }
                        }
                        break;
                    case EP_BOLD:
                        if (pWordProps->nWordStyle & PVTWORD_STYLE_BOLD)
                        {
                            if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) == 0)
                            {
                                wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
                                bSet = true;
                            }
                        }
                        else
                        {
                            if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) != 0)
                            {
                                wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_BOLD;
                                bSet = true;
                            }
                        }
                        break;
                    case EP_ITALIC:
                        if (pWordProps->nWordStyle & PVTWORD_STYLE_ITALIC)
                        {
                            if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) == 0)
                            {
                                wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
                                bSet = true;
                            }
                        }
                        else
                        {
                            if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) != 0)
                            {
                                wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_ITALIC;
                                bSet = true;
                            }
                        }
                        break;
                    default:
                        break;
                    }
                }
            }

            if (bSet)
            {
                pIterator->SetWord(wordinfo);

                if (bAddUndo && m_bEnableUndo)
                {
                    AddEditUndoItem(new CFXEU_SetWordProps
                        (this,place,eProps,OldWordinfo.WordProps,wordinfo.WordProps,wr));
                }
            }

            pIterator->SetAt(oldplace);
            return bSet;
        }
    }

    return false;
}

void CFX_Edit::SetText(const FX_WCHAR* text,int32_t charset /*= DEFAULT_CHARSET*/,
                        const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
{
    SetText(text,charset,pSecProps,pWordProps,true,true);
}

bool CFX_Edit::InsertWord(FX_WORD word, int32_t charset /*= DEFAULT_CHARSET*/, const CPVT_WordProps * pWordProps /*= NULL*/)
{
    return InsertWord(word,charset,pWordProps,true,true);
}

bool CFX_Edit::InsertReturn(const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
{
    return InsertReturn(pSecProps,pWordProps,true,true);
}

bool CFX_Edit::Backspace()
{
    return Backspace(true,true);
}

bool CFX_Edit::Delete()
{
    return Delete(true,true);
}

bool CFX_Edit::Clear()
{
    return Clear(true,true);
}

bool CFX_Edit::InsertText(const FX_WCHAR* text, int32_t charset /*= DEFAULT_CHARSET*/,
                                const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
{
    return InsertText(text,charset,pSecProps,pWordProps,true,true);
}

FX_FLOAT CFX_Edit::GetFontSize() const
{
    return m_pVT->GetFontSize();
}

FX_WORD CFX_Edit::GetPasswordChar() const
{
    return m_pVT->GetPasswordChar();
}

int32_t CFX_Edit::GetCharArray() const
{
    return m_pVT->GetCharArray();
}

CPDF_Rect CFX_Edit::GetPlateRect() const
{
    return m_pVT->GetPlateRect();
}

CPDF_Rect CFX_Edit::GetContentRect() const
{
    return VTToEdit(m_pVT->GetContentRect());
}

int32_t CFX_Edit::GetHorzScale() const
{
    return m_pVT->GetHorzScale();
}

FX_FLOAT CFX_Edit::GetCharSpace() const
{
    return m_pVT->GetCharSpace();
}

// inner methods

CPVT_WordRange CFX_Edit::GetWholeWordRange() const
{
    if (m_pVT->IsValid())
        return CPVT_WordRange(m_pVT->GetBeginWordPlace(),m_pVT->GetEndWordPlace());

    return CPVT_WordRange();
}

CPVT_WordRange CFX_Edit::GetVisibleWordRange() const
{
    if (m_bEnableOverflow) return GetWholeWordRange();

    if (m_pVT->IsValid())
    {
        CPDF_Rect rcPlate = m_pVT->GetPlateRect();

        CPVT_WordPlace place1 = m_pVT->SearchWordPlace(EditToVT(CPDF_Point(rcPlate.left,rcPlate.top)));
        CPVT_WordPlace place2 = m_pVT->SearchWordPlace(EditToVT(CPDF_Point(rcPlate.right,rcPlate.bottom)));

        return CPVT_WordRange(place1,place2);
    }

    return CPVT_WordRange();
}

CPVT_WordPlace CFX_Edit::SearchWordPlace(const CPDF_Point& point) const
{
    if (m_pVT->IsValid())
    {
        return m_pVT->SearchWordPlace(EditToVT(point));
    }

    return CPVT_WordPlace();
}

void CFX_Edit::Paint()
{
    if (m_pVT->IsValid())
    {
        RearrangeAll();
        ScrollToCaret();
        Refresh(RP_NOANALYSE);
        SetCaretOrigin();
        SetCaretInfo();
    }
}

void CFX_Edit::RearrangeAll()
{
    if (m_pVT->IsValid())
    {
        m_pVT->UpdateWordPlace(m_wpCaret);
        m_pVT->RearrangeAll();
        m_pVT->UpdateWordPlace(m_wpCaret);
        SetScrollInfo();
        SetContentChanged();
    }
}

void CFX_Edit::RearrangePart(const CPVT_WordRange & range)
{
    if (m_pVT->IsValid())
    {
        m_pVT->UpdateWordPlace(m_wpCaret);
        m_pVT->RearrangePart(range);
        m_pVT->UpdateWordPlace(m_wpCaret);
        SetScrollInfo();
        SetContentChanged();
    }
}

void CFX_Edit::SetContentChanged()
{
    if (m_bNotify && m_pNotify)
    {
        CPDF_Rect rcContent = m_pVT->GetContentRect();
        if (rcContent.Width() != m_rcOldContent.Width() ||
            rcContent.Height() != m_rcOldContent.Height())
        {
            if (!m_bNotifyFlag)
            {
                m_bNotifyFlag = true;
                m_pNotify->IOnContentChange(rcContent);
                m_bNotifyFlag = false;
            }
            m_rcOldContent = rcContent;
        }
    }
}

void CFX_Edit::SelectAll()
{
    if (m_pVT->IsValid())
    {
        m_SelState = GetWholeWordRange();
        SetCaret(m_SelState.EndPos);

        ScrollToCaret();
        CPVT_WordRange wrVisible = GetVisibleWordRange();
        Refresh(RP_OPTIONAL,&wrVisible);
        SetCaretInfo();
    }
}

void CFX_Edit::SelectNone()
{
    if (m_pVT->IsValid())
    {
        if (m_SelState.IsExist())
        {
            CPVT_WordRange wrTemp = m_SelState.ConvertToWordRange();
            m_SelState.Default();
            Refresh(RP_OPTIONAL,&wrTemp);
        }
    }
}

bool CFX_Edit::IsSelected() const
{
    return m_SelState.IsExist();
}

CPDF_Point CFX_Edit::VTToEdit(const CPDF_Point & point) const
{
    CPDF_Rect rcContent = m_pVT->GetContentRect();
    CPDF_Rect rcPlate = m_pVT->GetPlateRect();

    FX_FLOAT fPadding = 0.0f;

    switch (m_nAlignment)
    {
    case 0:
        fPadding = 0.0f;
        break;
    case 1:
        fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
        break;
    case 2:
        fPadding = rcPlate.Height() - rcContent.Height();
        break;
    }

    return CPDF_Point(point.x - (m_ptScrollPos.x - rcPlate.left),
        point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
}

CPDF_Point CFX_Edit::EditToVT(const CPDF_Point & point) const
{
    CPDF_Rect rcContent = m_pVT->GetContentRect();
    CPDF_Rect rcPlate = m_pVT->GetPlateRect();

    FX_FLOAT fPadding = 0.0f;

    switch (m_nAlignment)
    {
    case 0:
        fPadding = 0.0f;
        break;
    case 1:
        fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
        break;
    case 2:
        fPadding = rcPlate.Height() - rcContent.Height();
        break;
    }

    return CPDF_Point(point.x + (m_ptScrollPos.x - rcPlate.left),
        point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
}

CPDF_Rect CFX_Edit::VTToEdit(const CPDF_Rect & rect) const
{
    CPDF_Point ptLeftBottom = VTToEdit(CPDF_Point(rect.left,rect.bottom));
    CPDF_Point ptRightTop = VTToEdit(CPDF_Point(rect.right,rect.top));

    return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y);
}

CPDF_Rect CFX_Edit::EditToVT(const CPDF_Rect & rect) const
{
    CPDF_Point ptLeftBottom = EditToVT(CPDF_Point(rect.left,rect.bottom));
    CPDF_Point ptRightTop = EditToVT(CPDF_Point(rect.right,rect.top));

    return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y);
}

void CFX_Edit::SetScrollInfo()
{
    if (m_bNotify && m_pNotify)
    {
        CPDF_Rect rcPlate = m_pVT->GetPlateRect();
        CPDF_Rect rcContent = m_pVT->GetContentRect();

        if (!m_bNotifyFlag)
        {
            m_bNotifyFlag = true;
            m_pNotify->IOnSetScrollInfoX(rcPlate.left, rcPlate.right,
                                rcContent.left, rcContent.right, rcPlate.Width() / 3, rcPlate.Width());

            m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
                    rcContent.bottom, rcContent.top, rcPlate.Height() / 3, rcPlate.Height());
            m_bNotifyFlag = false;
        }
    }
}

void CFX_Edit::SetScrollPosX(FX_FLOAT fx)
{
    if (!m_bEnableScroll) return;

    if (m_pVT->IsValid())
    {
        if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.x,fx))
        {
            m_ptScrollPos.x = fx;
            Refresh(RP_NOANALYSE);

            if (m_bNotify && m_pNotify)
            {
                if (!m_bNotifyFlag)
                {
                    m_bNotifyFlag = true;
                    m_pNotify->IOnSetScrollPosX(fx);
                    m_bNotifyFlag = false;
                }
            }
        }
    }
}

void CFX_Edit::SetScrollPosY(FX_FLOAT fy)
{
    if (!m_bEnableScroll) return;

    if (m_pVT->IsValid())
    {
        if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y,fy))
        {
            m_ptScrollPos.y = fy;
            Refresh(RP_NOANALYSE);

            if (m_bNotify && m_pNotify)
            {
                if (!m_bNotifyFlag)
                {
                    m_bNotifyFlag = true;
                    m_pNotify->IOnSetScrollPosY(fy);
                    m_bNotifyFlag = false;
                }
            }
        }
    }
}

void CFX_Edit::SetScrollPos(const CPDF_Point & point)
{
    SetScrollPosX(point.x);
    SetScrollPosY(point.y);
    SetScrollLimit();
    SetCaretInfo();
}

CPDF_Point CFX_Edit::GetScrollPos() const
{
    return m_ptScrollPos;
}

void CFX_Edit::SetScrollLimit()
{
    if (m_pVT->IsValid())
    {
        CPDF_Rect rcContent = m_pVT->GetContentRect();
        CPDF_Rect rcPlate = m_pVT->GetPlateRect();

        if (rcPlate.Width() > rcContent.Width())
        {
            SetScrollPosX(rcPlate.left);
        }
        else
        {
            if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.x, rcContent.left))
            {
                SetScrollPosX(rcContent.left);
            }
            else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.x, rcContent.right - rcPlate.Width()))
            {
                SetScrollPosX(rcContent.right - rcPlate.Width());
            }
        }

        if (rcPlate.Height() > rcContent.Height())
        {
            SetScrollPosY(rcPlate.top);
        }
        else
        {
            if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.y, rcContent.bottom + rcPlate.Height()))
            {
                SetScrollPosY(rcContent.bottom + rcPlate.Height());
            }
            else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.y, rcContent.top))
            {
                SetScrollPosY(rcContent.top);
            }
        }
    }
}

void CFX_Edit::ScrollToCaret()
{
    SetScrollLimit();

    if (m_pVT->IsValid())
    {
        CPDF_Point ptHead(0,0);
        CPDF_Point ptFoot(0,0);

        if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
        {
            pIterator->SetAt(m_wpCaret);

            CPVT_Word word;
            CPVT_Line line;
            if (pIterator->GetWord(word))
            {
                ptHead.x = word.ptWord.x + word.fWidth;
                ptHead.y = word.ptWord.y + word.fAscent;
                ptFoot.x = word.ptWord.x + word.fWidth;
                ptFoot.y = word.ptWord.y + word.fDescent;
            }
            else if (pIterator->GetLine(line))
            {
                ptHead.x = line.ptLine.x;
                ptHead.y = line.ptLine.y + line.fLineAscent;
                ptFoot.x = line.ptLine.x;
                ptFoot.y = line.ptLine.y + line.fLineDescent;
            }
        }

        CPDF_Point ptHeadEdit = VTToEdit(ptHead);
        CPDF_Point ptFootEdit = VTToEdit(ptFoot);

        CPDF_Rect rcPlate = m_pVT->GetPlateRect();

        if (!FX_EDIT_IsFloatEqual(rcPlate.left,rcPlate.right))
        {
            if (FX_EDIT_IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
                FX_EDIT_IsFloatEqual(ptHeadEdit.x, rcPlate.left))
            {
                SetScrollPosX(ptHead.x);
            }
            else if (FX_EDIT_IsFloatBigger(ptHeadEdit.x, rcPlate.right))
            {
                SetScrollPosX(ptHead.x - rcPlate.Width());
            }
        }

        if (!FX_EDIT_IsFloatEqual(rcPlate.top,rcPlate.bottom))
        {
            if (FX_EDIT_IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
                FX_EDIT_IsFloatEqual(ptFootEdit.y, rcPlate.bottom))
            {
                if (FX_EDIT_IsFloatSmaller(ptHeadEdit.y, rcPlate.top))
                {
                    SetScrollPosY(ptFoot.y + rcPlate.Height());
                }
            }
            else if (FX_EDIT_IsFloatBigger(ptHeadEdit.y, rcPlate.top))
            {
                if (FX_EDIT_IsFloatBigger(ptFootEdit.y, rcPlate.bottom))
                {
                    SetScrollPosY(ptHead.y);
                }
            }
        }
    }
}

void CFX_Edit::Refresh(REFRESH_PLAN_E ePlan,const CPVT_WordRange * pRange1,const CPVT_WordRange * pRange2)
{
    if (m_bEnableRefresh && m_pVT->IsValid())
    {
        m_Refresh.BeginRefresh();
        RefreshPushLineRects(GetVisibleWordRange());

//      if (!FX_EDIT_IsFloatEqual(m_ptRefreshScrollPos.x,m_ptScrollPos.x) ||
//          !FX_EDIT_IsFloatEqual(m_ptRefreshScrollPos.y,m_ptScrollPos.y))
//      {
            m_Refresh.NoAnalyse();
            m_ptRefreshScrollPos = m_ptScrollPos;
//      }
//      else
//      {
//          switch (ePlan)
//          {
//          case RP_ANALYSE:
//              m_Refresh.Analyse(m_pVT->GetAlignment());
//
//              if (pRange1) RefreshPushRandomRects(*pRange1);
//              if (pRange2) RefreshPushRandomRects(*pRange2);
//              break;
//          case RP_NOANALYSE:
//              m_Refresh.NoAnalyse();
//              break;
//          case RP_OPTIONAL:
//              if (pRange1) RefreshPushRandomRects(*pRange1);
//              if (pRange2) RefreshPushRandomRects(*pRange2);
//              break;
//          }
//      }

        if (m_bNotify && m_pNotify)
        {
            if (!m_bNotifyFlag)
            {
                m_bNotifyFlag = true;
                if (const CFX_Edit_RectArray * pRects = m_Refresh.GetRefreshRects())
                {
                    for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++)
                        m_pNotify->IOnInvalidateRect(pRects->GetAt(i));
                }
                m_bNotifyFlag = false;
            }
        }

        m_Refresh.EndRefresh();
    }
}

void CFX_Edit::RefreshPushLineRects(const CPVT_WordRange & wr)
{
    if (m_pVT->IsValid())
    {
        if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
        {
            CPVT_WordPlace wpBegin = wr.BeginPos;
            m_pVT->UpdateWordPlace(wpBegin);
            CPVT_WordPlace wpEnd = wr.EndPos;
            m_pVT->UpdateWordPlace(wpEnd);
            pIterator->SetAt(wpBegin);

            CPVT_Line lineinfo;
            do
            {
                if (!pIterator->GetLine(lineinfo))break;
                if (lineinfo.lineplace.LineCmp(wpEnd) > 0)break;

                CPDF_Rect rcLine(lineinfo.ptLine.x,
                                    lineinfo.ptLine.y + lineinfo.fLineDescent,
                                    lineinfo.ptLine.x + lineinfo.fLineWidth,
                                    lineinfo.ptLine.y + lineinfo.fLineAscent);

                m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace,lineinfo.lineEnd),VTToEdit(rcLine));

            }while (pIterator->NextLine());
        }
    }
}

void CFX_Edit::RefreshPushRandomRects(const CPVT_WordRange & wr)
{
    if (m_pVT->IsValid())
    {
        if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
        {
            CPVT_WordRange wrTemp = wr;

            m_pVT->UpdateWordPlace(wrTemp.BeginPos);
            m_pVT->UpdateWordPlace(wrTemp.EndPos);
            pIterator->SetAt(wrTemp.BeginPos);

            CPVT_Word wordinfo;
            CPVT_Line lineinfo;
            CPVT_WordPlace place;

            while (pIterator->NextWord())
            {
                place = pIterator->GetAt();
                if (place.WordCmp(wrTemp.EndPos) > 0) break;

                pIterator->GetWord(wordinfo);
                pIterator->GetLine(lineinfo);

                if (place.LineCmp(wrTemp.BeginPos) == 0 || place.LineCmp(wrTemp.EndPos) == 0)
                {
                    CPDF_Rect rcWord(wordinfo.ptWord.x,
                                        lineinfo.ptLine.y + lineinfo.fLineDescent,
                                        wordinfo.ptWord.x + wordinfo.fWidth,
                                        lineinfo.ptLine.y + lineinfo.fLineAscent);

                    m_Refresh.AddRefresh(VTToEdit(rcWord));
                }
                else
                {
                    CPDF_Rect rcLine(lineinfo.ptLine.x,
                                        lineinfo.ptLine.y + lineinfo.fLineDescent,
                                        lineinfo.ptLine.x + lineinfo.fLineWidth,
                                        lineinfo.ptLine.y + lineinfo.fLineAscent);

                    m_Refresh.AddRefresh(VTToEdit(rcLine));

                    pIterator->NextLine();
                }
            }
        }
    }
}

void CFX_Edit::RefreshWordRange(const CPVT_WordRange& wr)
{
    if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
    {
        CPVT_WordRange wrTemp = wr;

        m_pVT->UpdateWordPlace(wrTemp.BeginPos);
        m_pVT->UpdateWordPlace(wrTemp.EndPos);
        pIterator->SetAt(wrTemp.BeginPos);

        CPVT_Word wordinfo;
        CPVT_Line lineinfo;
        CPVT_WordPlace place;

        while (pIterator->NextWord())
        {
            place = pIterator->GetAt();
            if (place.WordCmp(wrTemp.EndPos) > 0) break;

            pIterator->GetWord(wordinfo);
            pIterator->GetLine(lineinfo);

            if (place.LineCmp(wrTemp.BeginPos) == 0 || place.LineCmp(wrTemp.EndPos) == 0)
            {
                CPDF_Rect rcWord(wordinfo.ptWord.x,
                                    lineinfo.ptLine.y + lineinfo.fLineDescent,
                                    wordinfo.ptWord.x + wordinfo.fWidth,
                                    lineinfo.ptLine.y + lineinfo.fLineAscent);

                if (m_bNotify && m_pNotify)
                {
                    if (!m_bNotifyFlag)
                    {
                        m_bNotifyFlag = true;
                        CPDF_Rect rcRefresh = VTToEdit(rcWord);
                        m_pNotify->IOnInvalidateRect(&rcRefresh);
                        m_bNotifyFlag = false;
                    }
                }
            }
            else
            {
                CPDF_Rect rcLine(lineinfo.ptLine.x,
                                    lineinfo.ptLine.y + lineinfo.fLineDescent,
                                    lineinfo.ptLine.x + lineinfo.fLineWidth,
                                    lineinfo.ptLine.y + lineinfo.fLineAscent);

                if (m_bNotify && m_pNotify)
                {
                    if (!m_bNotifyFlag)
                    {
                        m_bNotifyFlag = true;
                        CPDF_Rect rcRefresh = VTToEdit(rcLine);
                        m_pNotify->IOnInvalidateRect(&rcRefresh);
                        m_bNotifyFlag = false;
                    }
                }

                pIterator->NextLine();
            }
        }
    }
}

void CFX_Edit::SetCaret(const CPVT_WordPlace & place)
{
    m_wpOldCaret = m_wpCaret;
    m_wpCaret = place;
}

void CFX_Edit::SetCaretInfo()
{
    if (m_bNotify && m_pNotify)
    {
        if (!m_bNotifyFlag)
        {
            CPDF_Point ptHead(0.0f,0.0f),ptFoot(0.0f,0.0f);

            if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
            {
                pIterator->SetAt(m_wpCaret);
                CPVT_Word word;
                CPVT_Line line;
                if (pIterator->GetWord(word))
                {
                    ptHead.x = word.ptWord.x + word.fWidth;
                    ptHead.y = word.ptWord.y + word.fAscent;
                    ptFoot.x = word.ptWord.x + word.fWidth;
                    ptFoot.y = word.ptWord.y + word.fDescent;
                }
                else if (pIterator->GetLine(line))
                {
                    ptHead.x = line.ptLine.x;
                    ptHead.y = line.ptLine.y + line.fLineAscent;
                    ptFoot.x = line.ptLine.x;
                    ptFoot.y = line.ptLine.y + line.fLineDescent;
                }
            }

            m_bNotifyFlag = true;
            m_pNotify->IOnSetCaret(!m_SelState.IsExist(),VTToEdit(ptHead),VTToEdit(ptFoot), m_wpCaret);
            m_bNotifyFlag = false;
        }
    }

    SetCaretChange();
}

void CFX_Edit::SetCaretChange()
{
    if (m_wpCaret == m_wpOldCaret) return;

    if (m_bNotify && m_pVT->IsRichText() && m_pNotify)
    {
        CPVT_SecProps SecProps;
        CPVT_WordProps WordProps;

        if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
        {
            pIterator->SetAt(m_wpCaret);
            CPVT_Word word;
            CPVT_Section section;

            if (pIterator->GetSection(section))
            {
                SecProps = section.SecProps;
                WordProps = section.WordProps;
            }

            if (pIterator->GetWord(word))
            {
                WordProps = word.WordProps;
            }
        }

        if (!m_bNotifyFlag)
        {
            m_bNotifyFlag = true;
            m_pNotify->IOnCaretChange(SecProps,WordProps);
            m_bNotifyFlag = false;
        }
    }
}

void CFX_Edit::SetCaret(int32_t nPos)
{
    if (m_pVT->IsValid())
    {
        SelectNone();
        SetCaret(m_pVT->WordIndexToWordPlace(nPos));
        m_SelState.Set(m_wpCaret,m_wpCaret);

        ScrollToCaret();
        SetCaretOrigin();
        SetCaretInfo();
    }
}

void CFX_Edit::OnMouseDown(const CPDF_Point & point,bool bShift,bool bCtrl)
{
    if (m_pVT->IsValid())
    {
        SelectNone();
        SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
        m_SelState.Set(m_wpCaret,m_wpCaret);

        ScrollToCaret();
        SetCaretOrigin();
        SetCaretInfo();
    }
}

void CFX_Edit::OnMouseMove(const CPDF_Point & point,bool bShift,bool bCtrl)
{
    if (m_pVT->IsValid())
    {
        SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));

        if (m_wpCaret != m_wpOldCaret)
        {
            m_SelState.SetEndPos(m_wpCaret);

            ScrollToCaret();
            CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
            Refresh(RP_OPTIONAL,&wr);
            SetCaretOrigin();
            SetCaretInfo();
        }
    }
}

void CFX_Edit::OnVK_UP(bool bShift,bool bCtrl)
{
    if (m_pVT->IsValid())
    {
        SetCaret(m_pVT->GetUpWordPlace(m_wpCaret,m_ptCaret));

        if (bShift)
        {
            if (m_SelState.IsExist())
                m_SelState.SetEndPos(m_wpCaret);
            else
                m_SelState.Set(m_wpOldCaret,m_wpCaret);

            if (m_wpOldCaret != m_wpCaret)
            {
                ScrollToCaret();
                CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
                Refresh(RP_OPTIONAL, &wr);
                SetCaretInfo();
            }
        }
        else
        {
            SelectNone();

            ScrollToCaret();
            SetCaretInfo();
        }
    }
}

void CFX_Edit::OnVK_DOWN(bool bShift,bool bCtrl)
{
    if (m_pVT->IsValid())
    {
        SetCaret(m_pVT->GetDownWordPlace(m_wpCaret,m_ptCaret));

        if (bShift)
        {
            if (m_SelState.IsExist())
                m_SelState.SetEndPos(m_wpCaret);
            else
                m_SelState.Set(m_wpOldCaret,m_wpCaret);

            if (m_wpOldCaret != m_wpCaret)
            {
                ScrollToCaret();
                CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
                Refresh(RP_OPTIONAL, &wr);
                SetCaretInfo();
            }
        }
        else
        {
            SelectNone();

            ScrollToCaret();
            SetCaretInfo();
        }
    }
}

void CFX_Edit::OnVK_LEFT(bool bShift,bool bCtrl)
{
    if (m_pVT->IsValid())
    {
        if (bShift)
        {
            if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
                m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
                SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));

            SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));

            if (m_SelState.IsExist())
                m_SelState.SetEndPos(m_wpCaret);
            else
                m_SelState.Set(m_wpOldCaret, m_wpCaret);

            if (m_wpOldCaret != m_wpCaret)
            {
                ScrollToCaret();
                CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
                Refresh(RP_OPTIONAL,&wr);
                SetCaretInfo();
            }
        }
        else
        {
            if (m_SelState.IsExist())
            {
                if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
                    SetCaret(m_SelState.BeginPos);
                else
                    SetCaret(m_SelState.EndPos);

                SelectNone();
                ScrollToCaret();
                SetCaretInfo();
            }
            else
            {
                if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
                    m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
                    SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));

                SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));

                ScrollToCaret();
                SetCaretOrigin();
                SetCaretInfo();
            }
        }
    }
}

void CFX_Edit::OnVK_RIGHT(bool bShift,bool bCtrl)
{
    if (m_pVT->IsValid())
    {
        if (bShift)
        {
            SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));

            if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
                m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
                SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));

            if (m_SelState.IsExist())
                m_SelState.SetEndPos(m_wpCaret);
            else
                m_SelState.Set(m_wpOldCaret,m_wpCaret);

            if (m_wpOldCaret != m_wpCaret)
            {
                ScrollToCaret();
                CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
                Refresh(RP_OPTIONAL,&wr);
                SetCaretInfo();
            }
        }
        else
        {
            if (m_SelState.IsExist())
            {
                if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)>0)
                    SetCaret(m_SelState.BeginPos);
                else
                    SetCaret(m_SelState.EndPos);

                SelectNone();
                ScrollToCaret();
                SetCaretInfo();
            }
            else
            {
                SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));

                if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
                    m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
                    SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));

                ScrollToCaret();
                SetCaretOrigin();
                SetCaretInfo();
            }
        }
    }
}

void CFX_Edit::OnVK_HOME(bool bShift,bool bCtrl)
{
    if (m_pVT->IsValid())
    {
        if (bShift)
        {
            if (bCtrl)
                SetCaret(m_pVT->GetBeginWordPlace());
            else
                SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));

            if (m_SelState.IsExist())
                m_SelState.SetEndPos(m_wpCaret);
            else
                m_SelState.Set(m_wpOldCaret,m_wpCaret);

            ScrollToCaret();
            CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
            Refresh(RP_OPTIONAL, &wr);
            SetCaretInfo();
        }
        else
        {
            if (m_SelState.IsExist())
            {
                if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
                    SetCaret(m_SelState.BeginPos);
                else
                    SetCaret(m_SelState.EndPos);

                SelectNone();
                ScrollToCaret();
                SetCaretInfo();
            }
            else
            {
                if (bCtrl)
                    SetCaret(m_pVT->GetBeginWordPlace());
                else
                    SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));

                ScrollToCaret();
                SetCaretOrigin();
                SetCaretInfo();
            }
        }
    }
}

void CFX_Edit::OnVK_END(bool bShift,bool bCtrl)
{
    if (m_pVT->IsValid())
    {
        if (bShift)
        {
            if (bCtrl)
                SetCaret(m_pVT->GetEndWordPlace());
            else
                SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));

            if (m_SelState.IsExist())
                m_SelState.SetEndPos(m_wpCaret);
            else
                m_SelState.Set(m_wpOldCaret, m_wpCaret);

            ScrollToCaret();
            CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
            Refresh(RP_OPTIONAL, &wr);
            SetCaretInfo();
        }
        else
        {
            if (m_SelState.IsExist())
            {
                if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)>0)
                    SetCaret(m_SelState.BeginPos);
                else
                    SetCaret(m_SelState.EndPos);

                SelectNone();
                ScrollToCaret();
                SetCaretInfo();
            }
            else
            {
                if (bCtrl)
                    SetCaret(m_pVT->GetEndWordPlace());
                else
                    SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));

                ScrollToCaret();
                SetCaretOrigin();
                SetCaretInfo();
            }
        }
    }
}

void CFX_Edit::SetText(const FX_WCHAR* text,int32_t charset,
                        const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps, bool bAddUndo, bool bPaint)
{
    Empty();
    DoInsertText(CPVT_WordPlace(0,0,-1), text, charset, pSecProps, pWordProps);
    if (bPaint) Paint();
    if (m_bOprNotify && m_pOprNotify)
        m_pOprNotify->OnSetText(m_wpCaret, m_wpOldCaret);
    //if (bAddUndo)
}

bool CFX_Edit::InsertWord(FX_WORD word, int32_t charset, const CPVT_WordProps * pWordProps, bool bAddUndo, bool bPaint)
{
    if (IsTextOverflow()) return false;

    if (m_pVT->IsValid())
    {
        m_pVT->UpdateWordPlace(m_wpCaret);

        SetCaret(m_pVT->InsertWord(m_wpCaret,word,GetCharSetFromUnicode(word, charset),pWordProps));
        m_SelState.Set(m_wpCaret,m_wpCaret);

        if (m_wpCaret != m_wpOldCaret)
        {
            if (bAddUndo && m_bEnableUndo)
            {
                AddEditUndoItem(new CFXEU_InsertWord(this,m_wpOldCaret,m_wpCaret,word,charset,pWordProps));
            }

            if (bPaint)
                PaintInsertText(m_wpOldCaret, m_wpCaret);

            if (m_bOprNotify && m_pOprNotify)
                m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);

            return true;
        }
    }

    return false;
}

bool CFX_Edit::InsertReturn(const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,
                               bool bAddUndo, bool bPaint)
{
    if (IsTextOverflow()) return false;

    if (m_pVT->IsValid())
    {
        m_pVT->UpdateWordPlace(m_wpCaret);
        SetCaret(m_pVT->InsertSection(m_wpCaret,pSecProps,pWordProps));
        m_SelState.Set(m_wpCaret,m_wpCaret);

        if (m_wpCaret != m_wpOldCaret)
        {
            if (bAddUndo && m_bEnableUndo)
            {
                AddEditUndoItem(new CFXEU_InsertReturn(this,m_wpOldCaret,m_wpCaret,pSecProps,pWordProps));
            }

            if (bPaint)
            {
                RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
                ScrollToCaret();
                CPVT_WordRange wr(m_wpOldCaret, GetVisibleWordRange().EndPos);
                Refresh(RP_ANALYSE, &wr);
                SetCaretOrigin();
                SetCaretInfo();
            }

            if (m_bOprNotify && m_pOprNotify)
                m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);

            return true;
        }
    }

    return false;
}

bool CFX_Edit::Backspace(bool bAddUndo, bool bPaint)
{
    if (m_pVT->IsValid())
    {
        if (m_wpCaret == m_pVT->GetBeginWordPlace()) return false;

        CPVT_Section section;
        CPVT_Word word;

        if (bAddUndo)
        {
            if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
            {
                pIterator->SetAt(m_wpCaret);
                pIterator->GetSection(section);
                pIterator->GetWord(word);
            }
        }

        m_pVT->UpdateWordPlace(m_wpCaret);
        SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
        m_SelState.Set(m_wpCaret,m_wpCaret);

        if (m_wpCaret != m_wpOldCaret)
        {
            if (bAddUndo && m_bEnableUndo)
            {
                if (m_wpCaret.SecCmp(m_wpOldCaret) != 0)
                    AddEditUndoItem(new CFXEU_Backspace(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
                        section.SecProps,section.WordProps));
                else
                    AddEditUndoItem(new CFXEU_Backspace(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
                        section.SecProps,word.WordProps));
            }

            if (bPaint)
            {
                RearrangePart(CPVT_WordRange(m_wpCaret,m_wpOldCaret));
                ScrollToCaret();

                CPVT_WordRange wr;
                if (m_wpCaret.SecCmp(m_wpOldCaret) !=0)
                    wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpCaret),GetVisibleWordRange().EndPos);
                else if (m_wpCaret.LineCmp(m_wpOldCaret) !=0)
                    wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(m_wpCaret),m_pVT->GetSectionEndPlace(m_wpCaret));
                else
                    wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpCaret),m_pVT->GetSectionEndPlace(m_wpCaret));

                Refresh(RP_ANALYSE, &wr);

                SetCaretOrigin();
                SetCaretInfo();
            }

            if (m_bOprNotify && m_pOprNotify)
                m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);

            return true;
        }
    }

    return false;
}

bool CFX_Edit::Delete(bool bAddUndo, bool bPaint)
{
    if (m_pVT->IsValid())
    {
        if (m_wpCaret == m_pVT->GetEndWordPlace()) return false;

        CPVT_Section section;
        CPVT_Word word;

        if (bAddUndo)
        {
            if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
            {
                pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
                pIterator->GetSection(section);
                pIterator->GetWord(word);
            }
        }

        m_pVT->UpdateWordPlace(m_wpCaret);
        bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));

        SetCaret(m_pVT->DeleteWord(m_wpCaret));
        m_SelState.Set(m_wpCaret,m_wpCaret);

        if (bAddUndo && m_bEnableUndo)
        {
            if (bSecEnd)
                AddEditUndoItem(new CFXEU_Delete(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
                    section.SecProps,section.WordProps,bSecEnd));
            else
                AddEditUndoItem(new CFXEU_Delete(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
                    section.SecProps,word.WordProps,bSecEnd));
        }

        if (bPaint)
        {
            RearrangePart(CPVT_WordRange(m_wpOldCaret,m_wpCaret));
            ScrollToCaret();

            CPVT_WordRange wr;
            if (bSecEnd)
                wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpOldCaret),GetVisibleWordRange().EndPos);
            else if (m_wpCaret.LineCmp(m_wpOldCaret) !=0)
                wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(m_wpCaret),m_pVT->GetSectionEndPlace(m_wpCaret));
            else
                wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpOldCaret),m_pVT->GetSectionEndPlace(m_wpCaret));

            Refresh(RP_ANALYSE, &wr);

            SetCaretOrigin();
            SetCaretInfo();
        }

        if (m_bOprNotify && m_pOprNotify)
            m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret);

        return true;
    }

    return false;
}

bool CFX_Edit::Empty()
{
    if (m_pVT->IsValid())
    {
        m_pVT->DeleteWords(GetWholeWordRange());
        SetCaret(m_pVT->GetBeginWordPlace());

        return true;
    }

    return false;
}

bool CFX_Edit::Clear(bool bAddUndo, bool bPaint)
{
    if (m_pVT->IsValid())
    {
        if (m_SelState.IsExist())
        {
            CPVT_WordRange range = m_SelState.ConvertToWordRange();

            if (bAddUndo && m_bEnableUndo)
            {
                if (m_pVT->IsRichText())
                {
                    BeginGroupUndo(L"");

                    if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
                    {
                        pIterator->SetAt(range.EndPos);

                        CPVT_Word wordinfo;
                        CPVT_Section secinfo;
                        do
                        {
                            CPVT_WordPlace place = pIterator->GetAt();
                            if (place.WordCmp(range.BeginPos) <= 0)break;

                            CPVT_WordPlace oldplace = m_pVT->GetPrevWordPlace(place);

                            if (oldplace.SecCmp(place) != 0)
                            {
                                if (pIterator->GetSection(secinfo))
                                {
                                    AddEditUndoItem(new CFXEU_ClearRich(this,oldplace,place,range,wordinfo.Word,
                                        wordinfo.nCharset,secinfo.SecProps,secinfo.WordProps));
                                }
                            }
                            else
                            {
                                if (pIterator->GetWord(wordinfo))
                                {
                                    oldplace = m_pVT->AjustLineHeader(oldplace,true);
                                    place = m_pVT->AjustLineHeader(place,true);

                                    AddEditUndoItem(new CFXEU_ClearRich(this,oldplace,place,range,wordinfo.Word,
                                        wordinfo.nCharset,secinfo.SecProps,wordinfo.WordProps));
                                }
                            }
                        }while (pIterator->PrevWord());
                    }
                    EndGroupUndo();
                }
                else
                {
                    AddEditUndoItem(new CFXEU_Clear(this,range,GetSelText()));
                }
            }

            SelectNone();
            SetCaret(m_pVT->DeleteWords(range));
            m_SelState.Set(m_wpCaret,m_wpCaret);

            if (bPaint)
            {
                RearrangePart(range);
                ScrollToCaret();

                CPVT_WordRange wr(m_wpOldCaret, GetVisibleWordRange().EndPos);
                Refresh(RP_ANALYSE, &wr);

                SetCaretOrigin();
                SetCaretInfo();
            }

            if (m_bOprNotify && m_pOprNotify)
                m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret);

            return true;
        }
    }

    return false;
}

bool CFX_Edit::InsertText(const FX_WCHAR* text, int32_t charset,
                    const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps, bool bAddUndo, bool bPaint)
{
    if (IsTextOverflow()) return false;

    m_pVT->UpdateWordPlace(m_wpCaret);
    SetCaret(DoInsertText(m_wpCaret, text, charset, pSecProps, pWordProps));
    m_SelState.Set(m_wpCaret,m_wpCaret);

    if (m_wpCaret != m_wpOldCaret)
    {
        if (bAddUndo && m_bEnableUndo)
        {
            AddEditUndoItem(new CFXEU_InsertText(this,m_wpOldCaret,m_wpCaret,text,charset,pSecProps,pWordProps));
        }

        if (bPaint)
            PaintInsertText(m_wpOldCaret, m_wpCaret);

        if (m_bOprNotify && m_pOprNotify)
            m_pOprNotify->OnInsertText(m_wpCaret, m_wpOldCaret);

        return true;
    }
    return false;
}

void CFX_Edit::PaintInsertText(const CPVT_WordPlace & wpOld, const CPVT_WordPlace & wpNew)
{
    if (m_pVT->IsValid())
    {
        RearrangePart(CPVT_WordRange(wpOld,wpNew));
        ScrollToCaret();

        CPVT_WordRange wr;
        if (m_wpCaret.LineCmp(wpOld) !=0)
            wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(wpOld),m_pVT->GetSectionEndPlace(wpNew));
        else
            wr = CPVT_WordRange(wpOld,m_pVT->GetSectionEndPlace(wpNew));
        Refresh(RP_ANALYSE, &wr);
        SetCaretOrigin();
        SetCaretInfo();
    }
}

bool CFX_Edit::Redo()
{
    if (m_bEnableUndo)
    {
        if (m_Undo.CanRedo())
        {
            m_Undo.Redo();
            return true;
        }
    }

    return false;
}

bool CFX_Edit::Undo()
{
    if (m_bEnableUndo)
    {
        if (m_Undo.CanUndo())
        {
            m_Undo.Undo();
            return true;
        }
    }

    return false;
}

void CFX_Edit::SetCaretOrigin()
{
    if (m_pVT->IsValid())
    {
        if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
        {
            pIterator->SetAt(m_wpCaret);
            CPVT_Word word;
            CPVT_Line line;
            if (pIterator->GetWord(word))
            {
                m_ptCaret.x = word.ptWord.x + word.fWidth;
                m_ptCaret.y = word.ptWord.y;
            }
            else if (pIterator->GetLine(line))
            {
                m_ptCaret.x = line.ptLine.x;
                m_ptCaret.y = line.ptLine.y;
            }
        }
    }
}

int32_t CFX_Edit::WordPlaceToWordIndex(const CPVT_WordPlace & place) const
{
    if (m_pVT->IsValid())
        return m_pVT->WordPlaceToWordIndex(place);

    return -1;
}

CPVT_WordPlace CFX_Edit::WordIndexToWordPlace(int32_t index) const
{
    if (m_pVT->IsValid())
        return m_pVT->WordIndexToWordPlace(index);

    return CPVT_WordPlace();
}

bool CFX_Edit::IsTextFull() const
{
    int32_t nTotalWords = m_pVT->GetTotalWords();
    int32_t nLimitChar = m_pVT->GetLimitChar();
    int32_t nCharArray = m_pVT->GetCharArray();

    return IsTextOverflow() || (nLimitChar>0 && nTotalWords >= nLimitChar)
        || (nCharArray>0 && nTotalWords >= nCharArray);
}

bool CFX_Edit::IsTextOverflow() const
{
    if (!m_bEnableScroll && !m_bEnableOverflow)
    {
        CPDF_Rect rcPlate = m_pVT->GetPlateRect();
        CPDF_Rect rcContent = m_pVT->GetContentRect();

        if (m_pVT->IsMultiLine() && GetTotalLines() > 1)
        {
            if (FX_EDIT_IsFloatBigger(rcContent.Height(),rcPlate.Height())) return true;
        }

        if (FX_EDIT_IsFloatBigger(rcContent.Width(),rcPlate.Width())) return true;
    }

    return false;
}

CPVT_WordPlace CFX_Edit::GetLineBeginPlace(const CPVT_WordPlace & place) const
{
    return m_pVT->GetLineBeginPlace(place);
}

CPVT_WordPlace CFX_Edit::GetLineEndPlace(const CPVT_WordPlace & place) const
{
    return m_pVT->GetLineEndPlace(place);
}

CPVT_WordPlace CFX_Edit::GetSectionBeginPlace(const CPVT_WordPlace & place) const
{
    return m_pVT->GetSectionBeginPlace(place);
}

CPVT_WordPlace CFX_Edit::GetSectionEndPlace(const CPVT_WordPlace & place) const
{
    return m_pVT->GetSectionEndPlace(place);
}

bool CFX_Edit::CanUndo() const
{
    if (m_bEnableUndo)
    {
        return m_Undo.CanUndo();
    }

    return false;
}

bool CFX_Edit::CanRedo() const
{
    if (m_bEnableUndo)
    {
        return m_Undo.CanRedo();
    }

    return false;
}

bool CFX_Edit::IsModified() const
{
    if (m_bEnableUndo)
    {
        return m_Undo.IsModified();
    }

    return false;
}

void CFX_Edit::EnableRefresh(bool bRefresh)
{
    m_bEnableRefresh = bRefresh;
}

void CFX_Edit::EnableUndo(bool bUndo)
{
    m_bEnableUndo = bUndo;
}

void CFX_Edit::EnableNotify(bool bNotify)
{
    m_bNotify = bNotify;
}

void CFX_Edit::EnableOprNotify(bool bNotify)
{
    m_bOprNotify = bNotify;
}

FX_FLOAT CFX_Edit::GetLineTop(const CPVT_WordPlace& place) const
{
    if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator())
    {
        CPVT_WordPlace wpOld = pIterator->GetAt();

        pIterator->SetAt(place);
        CPVT_Line line;
        pIterator->GetLine(line);

        pIterator->SetAt(wpOld);

        return line.ptLine.y + line.fLineAscent;
    }

    return 0.0f;
}

FX_FLOAT CFX_Edit::GetLineBottom(const CPVT_WordPlace& place) const
{
    if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator())
    {
        CPVT_WordPlace wpOld = pIterator->GetAt();

        pIterator->SetAt(place);
        CPVT_Line line;
        pIterator->GetLine(line);

        pIterator->SetAt(wpOld);

        return line.ptLine.y + line.fLineDescent;
    }

    return 0.0f;
}

CPVT_WordPlace CFX_Edit::DoInsertText(const CPVT_WordPlace& place, const FX_WCHAR* text, int32_t charset,
                                      const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps)
{
    CPVT_WordPlace wp = place;

    if (m_pVT->IsValid())
    {
        CFX_WideString sText = text;

        for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++)
        {
            FX_WORD word = sText[i];
            switch (word)
            {
            case 0x0D:
                wp = m_pVT->InsertSection(wp,pSecProps,pWordProps);
                if (sText[i+1] == 0x0A)
                    i++;
                break;
            case 0x0A:
                wp = m_pVT->InsertSection(wp,pSecProps,pWordProps);
                if (sText[i+1] == 0x0D)
                    i++;
                break;
            case 0x09:
                word = 0x20;
            default:
                wp = m_pVT->InsertWord(wp,word,GetCharSetFromUnicode(word, charset),pWordProps);
                break;
            }
        }
    }

    return wp;
}

int32_t CFX_Edit::GetCharSetFromUnicode(FX_WORD word, int32_t nOldCharset)
{
    if (IFX_Edit_FontMap* pFontMap = GetFontMap())
        return pFontMap->CharSetFromUnicode(word, nOldCharset);
    return nOldCharset;
}

void CFX_Edit::BeginGroupUndo(const CFX_WideString& sTitle)
{
    ASSERT(m_pGroupUndoItem == NULL);

    m_pGroupUndoItem = new CFX_Edit_GroupUndoItem(sTitle);
}

void CFX_Edit::EndGroupUndo()
{
    ASSERT(m_pGroupUndoItem != NULL);

    m_pGroupUndoItem->UpdateItems();
    m_Undo.AddItem(m_pGroupUndoItem);
    if (m_bOprNotify && m_pOprNotify)
        m_pOprNotify->OnAddUndo(m_pGroupUndoItem);
    m_pGroupUndoItem = NULL;
}

void CFX_Edit::AddEditUndoItem(CFX_Edit_UndoItem* pEditUndoItem)
{
    if (m_pGroupUndoItem)
        m_pGroupUndoItem->AddUndoItem(pEditUndoItem);
    else
    {
        m_Undo.AddItem(pEditUndoItem);
        if (m_bOprNotify && m_pOprNotify)
            m_pOprNotify->OnAddUndo(pEditUndoItem);
    }
}

void CFX_Edit::AddUndoItem(IFX_Edit_UndoItem* pUndoItem)
{
    m_Undo.AddItem(pUndoItem);
    if (m_bOprNotify && m_pOprNotify)
        m_pOprNotify->OnAddUndo(pUndoItem);
}

