// 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 "xfa/fde/cfde_txtedtpage.h"

#include <algorithm>

#include "xfa/fde/cfde_txtedtbuf.h"
#include "xfa/fde/cfde_txtedtbufiter.h"
#include "xfa/fde/cfde_txtedtengine.h"
#include "xfa/fde/cfde_txtedtparag.h"
#include "xfa/fde/ifde_txtedtengine.h"
#include "xfa/fde/ifde_txtedtpage.h"
#include "xfa/fde/cfde_txtedttextset.h"
#include "xfa/fde/cfx_wordbreak.h"

namespace {

const double kTolerance = 0.1f;

}  // namespace

IFDE_TxtEdtPage* IFDE_TxtEdtPage::Create(CFDE_TxtEdtEngine* pEngine,
                                         int32_t nIndex) {
  return (IFDE_TxtEdtPage*)new CFDE_TxtEdtPage(pEngine, nIndex);
}

CFDE_TxtEdtPage::CFDE_TxtEdtPage(CFDE_TxtEdtEngine* pEngine, int32_t nPageIndex)
    : m_pIter(nullptr),
      m_pTextSet(nullptr),
      m_pBgnParag(nullptr),
      m_pEndParag(nullptr),
      m_nRefCount(0),
      m_nPageStart(-1),
      m_nCharCount(0),
      m_nPageIndex(nPageIndex),
      m_bLoaded(FALSE),
      m_pCharWidth(nullptr) {
  FXSYS_memset(&m_rtPage, 0, sizeof(CFX_RectF));
  FXSYS_memset(&m_rtPageMargin, 0, sizeof(CFX_RectF));
  FXSYS_memset(&m_rtPageContents, 0, sizeof(CFX_RectF));
  FXSYS_memset(&m_rtPageCanvas, 0, sizeof(CFX_RectF));
  m_pEditEngine = (CFDE_TxtEdtEngine*)pEngine;
}

CFDE_TxtEdtPage::~CFDE_TxtEdtPage() {
  m_PieceMassArr.RemoveAll(TRUE);
  delete m_pTextSet;
  delete[] m_pCharWidth;
}

CFDE_TxtEdtEngine* CFDE_TxtEdtPage::GetEngine() const {
  return m_pEditEngine;
}

FDE_VISUALOBJTYPE CFDE_TxtEdtPage::GetType() {
  return FDE_VISUALOBJ_Text;
}

FX_BOOL CFDE_TxtEdtPage::GetBBox(FDE_HVISUALOBJ hVisualObj, CFX_RectF& bbox) {
  return FALSE;
}

FX_BOOL CFDE_TxtEdtPage::GetMatrix(FDE_HVISUALOBJ hVisualObj,
                                   CFX_Matrix& matrix) {
  return FALSE;
}

FX_BOOL CFDE_TxtEdtPage::GetRect(FDE_HVISUALOBJ hVisualObj, CFX_RectF& rt) {
  return FALSE;
}

FX_BOOL CFDE_TxtEdtPage::GetClip(FDE_HVISUALOBJ hVisualObj, CFX_RectF& rt) {
  return FALSE;
}

int32_t CFDE_TxtEdtPage::GetCharRect(int32_t nIndex,
                                     CFX_RectF& rect,
                                     FX_BOOL bBBox) const {
  ASSERT(m_nRefCount > 0);
  ASSERT(nIndex >= 0 && nIndex < m_nCharCount);
  if (m_nRefCount < 1) {
    return 0;
  }
  int32_t nCount = m_PieceMassArr.GetSize();
  for (int32_t i = 0; i < nCount; i++) {
    const FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(i);
    if (nIndex >= pPiece->nStart &&
        nIndex < (pPiece->nStart + pPiece->nCount)) {
      CFX_RectFArray rectArr;
      if (bBBox) {
        m_pTextSet->GetCharRects_Impl((FDE_HVISUALOBJ)pPiece, rectArr, bBBox);
      } else {
        m_pTextSet->GetCharRects((FDE_HVISUALOBJ)pPiece, rectArr);
      }
      rect = rectArr[nIndex - pPiece->nStart];
      return pPiece->nBidiLevel;
    }
  }
  ASSERT(0);
  return 0;
}

int32_t CFDE_TxtEdtPage::GetCharIndex(const CFX_PointF& fPoint,
                                      FX_BOOL& bBefore) {
  FX_BOOL bVertical = m_pEditEngine->GetEditParams()->dwLayoutStyles &
                      FDE_TEXTEDITLAYOUT_DocVertical;
  CFX_PointF ptF = fPoint;
  NormalizePt2Rect(ptF, m_rtPageContents, kTolerance);
  int32_t nCount = m_PieceMassArr.GetSize();
  CFX_RectF rtLine;
  int32_t nBgn = 0;
  int32_t nEnd = 0;
  FX_BOOL bInLine = FALSE;
  int32_t i = 0;
  for (i = 0; i < nCount; i++) {
    const FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(i);
    if (!bInLine && (bVertical ? (pPiece->rtPiece.left <= ptF.x &&
                                  pPiece->rtPiece.right() > ptF.x)
                               : (pPiece->rtPiece.top <= ptF.y &&
                                  pPiece->rtPiece.bottom() > ptF.y))) {
      nBgn = nEnd = i;
      rtLine = pPiece->rtPiece;
      bInLine = TRUE;
    } else if (bInLine) {
      if (bVertical ? (!(pPiece->rtPiece.left <= ptF.x &&
                         pPiece->rtPiece.right() > ptF.x))
                    : (pPiece->rtPiece.bottom() <= ptF.y ||
                       pPiece->rtPiece.top > ptF.y)) {
        nEnd = i - 1;
        break;
      } else {
        rtLine.Union(pPiece->rtPiece);
      }
    }
  }
  NormalizePt2Rect(ptF, rtLine, kTolerance);
  int32_t nCaret = 0;
  FDE_TEXTEDITPIECE* pPiece = NULL;
  for (i = nBgn; i <= nEnd; i++) {
    pPiece = m_PieceMassArr.GetPtrAt(i);
    nCaret = m_nPageStart + pPiece->nStart;
    if (pPiece->rtPiece.Contains(ptF)) {
      CFX_RectFArray rectArr;
      m_pTextSet->GetCharRects((FDE_HVISUALOBJ)pPiece, rectArr);
      int32_t nRtCount = rectArr.GetSize();
      for (int32_t j = 0; j < nRtCount; j++) {
        if (rectArr[j].Contains(ptF)) {
          nCaret = m_nPageStart + pPiece->nStart + j;
          if (nCaret >= m_pEditEngine->GetTextBufLength()) {
            bBefore = TRUE;
            return m_pEditEngine->GetTextBufLength();
          }
          FX_WCHAR wChar = m_pEditEngine->GetTextBuf()->GetCharByIndex(nCaret);
          if (wChar == L'\n' || wChar == L'\r') {
            if (wChar == L'\n') {
              if (m_pEditEngine->GetTextBuf()->GetCharByIndex(nCaret - 1) ==
                  L'\r') {
                nCaret--;
              }
            }
            bBefore = TRUE;
            return nCaret;
          }
          if (bVertical
                  ? (ptF.y > ((rectArr[j].top + rectArr[j].bottom()) / 2))
                  : (ptF.x > ((rectArr[j].left + rectArr[j].right()) / 2))) {
            bBefore = FX_IsOdd(pPiece->nBidiLevel);
          } else {
            bBefore = !FX_IsOdd(pPiece->nBidiLevel);
          }
          return nCaret;
        }
      }
    }
  }
  bBefore = TRUE;
  return nCaret;
}

int32_t CFDE_TxtEdtPage::GetCharStart() const {
  return m_nPageStart;
}

int32_t CFDE_TxtEdtPage::GetCharCount() const {
  return m_nCharCount;
}

int32_t CFDE_TxtEdtPage::GetDisplayPos(const CFX_RectF& rtClip,
                                       FXTEXT_CHARPOS*& pCharPos,
                                       CFX_RectF* pBBox) const {
  pCharPos = FX_Alloc(FXTEXT_CHARPOS, m_nCharCount);
  int32_t nCharPosCount = 0;
  FDE_HVISUALOBJ hVisualObj = NULL;
  int32_t nVisualObjCount = m_PieceMassArr.GetSize();
  FXTEXT_CHARPOS* pos = pCharPos;
  CFX_RectF rtObj;
  for (int32_t i = 0; i < nVisualObjCount; i++) {
    hVisualObj = (FDE_HVISUALOBJ)m_PieceMassArr.GetPtrAt(i);
    m_pTextSet->GetRect(hVisualObj, rtObj);
    if (!rtClip.IntersectWith(rtObj)) {
      continue;
    }
    int32_t nCount = m_pTextSet->GetDisplayPos(hVisualObj, pos, FALSE);
    nCharPosCount += nCount;
    pos += nCount;
  }
  if ((nCharPosCount * 5) < (m_nCharCount << 2)) {
    FXTEXT_CHARPOS* pTemp = FX_Alloc(FXTEXT_CHARPOS, nCharPosCount);
    FXSYS_memcpy(pTemp, pCharPos, sizeof(FXTEXT_CHARPOS) * nCharPosCount);
    FX_Free(pCharPos);
    pCharPos = pTemp;
  }
  return nCharPosCount;
}

void CFDE_TxtEdtPage::CalcRangeRectArray(int32_t nStart,
                                         int32_t nCount,
                                         CFX_RectFArray& RectFArr) const {
  int32_t nPieceCount = m_PieceMassArr.GetSize();
  int32_t nEnd = nStart + nCount - 1;
  FX_BOOL bInRange = FALSE;
  for (int32_t i = 0; i < nPieceCount; i++) {
    FDE_TEXTEDITPIECE* piece = m_PieceMassArr.GetPtrAt(i);
    if (!bInRange) {
      if (nStart >= piece->nStart && nStart < (piece->nStart + piece->nCount)) {
        int32_t nRangeEnd = piece->nCount - 1;
        FX_BOOL bEnd = FALSE;
        if (nEnd >= piece->nStart && nEnd < (piece->nStart + piece->nCount)) {
          nRangeEnd = nEnd - piece->nStart;
          bEnd = TRUE;
        }
        CFX_RectFArray rcArr;
        m_pTextSet->GetCharRects((FDE_HVISUALOBJ)piece, rcArr);
        CFX_RectF rectPiece = rcArr[nStart - piece->nStart];
        rectPiece.Union(rcArr[nRangeEnd]);
        RectFArr.Add(rectPiece);
        if (bEnd) {
          return;
        }
        bInRange = TRUE;
      }
    } else {
      if (nEnd >= piece->nStart && nEnd < (piece->nStart + piece->nCount)) {
        CFX_RectFArray rcArr;
        m_pTextSet->GetCharRects((FDE_HVISUALOBJ)piece, rcArr);
        CFX_RectF rectPiece = rcArr[0];
        rectPiece.Union(rcArr[nEnd - piece->nStart]);
        RectFArr.Add(rectPiece);
        return;
      }
      RectFArr.Add(piece->rtPiece);
    }
  }
}

int32_t CFDE_TxtEdtPage::SelectWord(const CFX_PointF& fPoint, int32_t& nCount) {
  if (m_nRefCount < 0) {
    return -1;
  }
  CFDE_TxtEdtBuf* pBuf = m_pEditEngine->GetTextBuf();
  FX_BOOL bBefore;
  int32_t nIndex = GetCharIndex(fPoint, bBefore);
  if (nIndex == m_pEditEngine->GetTextBufLength()) {
    nIndex = m_pEditEngine->GetTextBufLength() - 1;
  }
  if (nIndex < 0) {
    return -1;
  }
  std::unique_ptr<CFX_WordBreak> pIter(new CFX_WordBreak);
  pIter->Attach(new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pBuf));
  pIter->SetAt(nIndex);
  nCount = pIter->GetWordLength();
  return pIter->GetWordPos();
}

FX_BOOL CFDE_TxtEdtPage::IsLoaded(const CFX_RectF* pClipBox) {
  return m_bLoaded;
}

int32_t CFDE_TxtEdtPage::LoadPage(const CFX_RectF* pClipBox,
                                  IFX_Pause* pPause) {
  if (m_nRefCount > 0) {
    m_nRefCount++;
    return m_nRefCount;
  }
  CFDE_TxtEdtBuf* pBuf = m_pEditEngine->GetTextBuf();
  const FDE_TXTEDTPARAMS* pParams = m_pEditEngine->GetEditParams();
  FX_WCHAR wcAlias = 0;
  if (pParams->dwMode & FDE_TEXTEDITMODE_Password) {
    wcAlias = m_pEditEngine->GetAliasChar();
  }
  m_pIter.reset(
      new CFDE_TxtEdtBufIter(static_cast<CFDE_TxtEdtBuf*>(pBuf), wcAlias));
  CFX_TxtBreak* pBreak = m_pEditEngine->GetTextBreak();
  pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
  pBreak->ClearBreakPieces();
  int32_t nPageLineCount = m_pEditEngine->GetPageLineCount();
  int32_t nStartLine = nPageLineCount * m_nPageIndex;
  int32_t nEndLine = std::min((nStartLine + nPageLineCount - 1),
                              (m_pEditEngine->GetLineCount() - 1));
  int32_t nPageStart, nPageEnd, nTemp, nBgnParag, nStartLineInParag, nEndParag,
      nEndLineInParag;
  nBgnParag = m_pEditEngine->Line2Parag(0, 0, nStartLine, nStartLineInParag);
  m_pBgnParag = (CFDE_TxtEdtParag*)m_pEditEngine->GetParag(nBgnParag);
  m_pBgnParag->LoadParag();
  m_pBgnParag->GetLineRange(nStartLine - nStartLineInParag, nPageStart, nTemp);
  nEndParag = m_pEditEngine->Line2Parag(nBgnParag, nStartLineInParag, nEndLine,
                                        nEndLineInParag);
  m_pEndParag = (CFDE_TxtEdtParag*)m_pEditEngine->GetParag(nEndParag);
  m_pEndParag->LoadParag();
  m_pEndParag->GetLineRange(nEndLine - nEndLineInParag, nPageEnd, nTemp);
  nPageEnd += (nTemp - 1);
  FX_BOOL bVertial = pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical;
  FX_BOOL bLineReserve =
      pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve;
  FX_FLOAT fLineStart =
      bVertial
          ? (bLineReserve ? (pParams->fPlateWidth - pParams->fLineSpace) : 0.0f)
          : 0.0f;
  FX_FLOAT fLineStep =
      (bVertial && bLineReserve) ? (-pParams->fLineSpace) : pParams->fLineSpace;
  FX_FLOAT fLinePos = fLineStart;
  if (m_pTextSet == NULL) {
    m_pTextSet = new CFDE_TxtEdtTextSet(this);
  }
  m_PieceMassArr.RemoveAll(TRUE);
  uint32_t dwBreakStatus = FX_TXTBREAK_None;
  int32_t nPieceStart = 0;
  if (m_pCharWidth != NULL) {
    delete[] m_pCharWidth;
  }
  m_pCharWidth = new int32_t[nPageEnd - nPageStart + 1];
  pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
  pBreak->ClearBreakPieces();
  m_nPageStart = nPageStart;
  m_nCharCount = nPageEnd - nPageStart + 1;
  FX_BOOL bReload = FALSE;
  FX_FLOAT fDefCharWidth = 0;
  std::unique_ptr<IFX_CharIter> pIter(m_pIter->Clone());
  pIter->SetAt(nPageStart);
  m_pIter->SetAt(nPageStart);
  FX_BOOL bFirstPiece = TRUE;
  do {
    if (bReload) {
      dwBreakStatus = pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
    } else {
      FX_WCHAR wAppend = pIter->GetChar();
      dwBreakStatus = pBreak->AppendChar(wAppend);
    }
    if (pIter->GetAt() == nPageEnd && dwBreakStatus < FX_TXTBREAK_LineBreak) {
      dwBreakStatus = pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
    }
    if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
      int32_t nPieceCount = pBreak->CountBreakPieces();
      for (int32_t j = 0; j < nPieceCount; j++) {
        const CFX_TxtPiece* pPiece = pBreak->GetBreakPiece(j);
        FDE_TEXTEDITPIECE TxtEdtPiece;
        FXSYS_memset(&TxtEdtPiece, 0, sizeof(FDE_TEXTEDITPIECE));
        TxtEdtPiece.nBidiLevel = pPiece->m_iBidiLevel;
        TxtEdtPiece.nCount = pPiece->GetLength();
        TxtEdtPiece.nStart = nPieceStart;
        TxtEdtPiece.dwCharStyles = pPiece->m_dwCharStyles;
        if (FX_IsOdd(pPiece->m_iBidiLevel)) {
          TxtEdtPiece.dwCharStyles |= FX_TXTCHARSTYLE_OddBidiLevel;
        }
        FX_FLOAT fParaBreakWidth = 0.0f;
        if (pPiece->m_dwStatus > FX_TXTBREAK_PieceBreak) {
          FX_WCHAR wRtChar = pParams->wLineBreakChar;
          if (TxtEdtPiece.nCount >= 2) {
            FX_WCHAR wChar = pBuf->GetCharByIndex(
                m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 1);
            FX_WCHAR wCharPre = pBuf->GetCharByIndex(
                m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 2);
            if (wChar == wRtChar) {
              fParaBreakWidth += fDefCharWidth;
            }
            if (wCharPre == wRtChar) {
              fParaBreakWidth += fDefCharWidth;
            }
          } else if (TxtEdtPiece.nCount >= 1) {
            FX_WCHAR wChar = pBuf->GetCharByIndex(
                m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 1);
            if (wChar == wRtChar) {
              fParaBreakWidth += fDefCharWidth;
            }
          }
        }
        if (pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
          TxtEdtPiece.rtPiece.left = fLinePos;
          TxtEdtPiece.rtPiece.top = (FX_FLOAT)pPiece->m_iStartPos / 20000.0f;
          TxtEdtPiece.rtPiece.width = pParams->fLineSpace;
          TxtEdtPiece.rtPiece.height =
              (FX_FLOAT)pPiece->m_iWidth / 20000.0f + fParaBreakWidth;
        } else {
          TxtEdtPiece.rtPiece.left = (FX_FLOAT)pPiece->m_iStartPos / 20000.0f;
          TxtEdtPiece.rtPiece.top = fLinePos;
          TxtEdtPiece.rtPiece.width =
              (FX_FLOAT)pPiece->m_iWidth / 20000.0f + fParaBreakWidth;
          TxtEdtPiece.rtPiece.height = pParams->fLineSpace;
        }
        if (bFirstPiece) {
          m_rtPageContents = TxtEdtPiece.rtPiece;
          bFirstPiece = FALSE;
        } else {
          m_rtPageContents.Union(TxtEdtPiece.rtPiece);
        }
        nPieceStart += TxtEdtPiece.nCount;
        m_PieceMassArr.Add(TxtEdtPiece);
        for (int32_t k = 0; k < TxtEdtPiece.nCount; k++) {
          CFX_Char* ptc = pPiece->GetCharPtr(k);
          m_pCharWidth[TxtEdtPiece.nStart + k] = ptc->m_iCharWidth;
        }
      }
      fLinePos += fLineStep;
      pBreak->ClearBreakPieces();
    }
    if (pIter->GetAt() == nPageEnd && dwBreakStatus == FX_TXTBREAK_LineBreak) {
      bReload = TRUE;
      pIter->Next(TRUE);
    }
  } while (pIter->Next(FALSE) && (pIter->GetAt() <= nPageEnd));
  if (m_rtPageContents.left != 0) {
    FX_FLOAT fDelta = 0.0f;
    if (m_rtPageContents.width < pParams->fPlateWidth) {
      if (pParams->dwAlignment & FDE_TEXTEDITALIGN_Right) {
        fDelta = pParams->fPlateWidth - m_rtPageContents.width;
      } else if (pParams->dwAlignment & FDE_TEXTEDITALIGN_Center) {
        if ((pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) &&
            m_nCharCount > 1) {
          int32_t nCount = m_nCharCount - 1;
          int32_t n = (m_pEditEngine->m_nLimit - nCount) / 2;
          fDelta = (m_rtPageContents.width / nCount) * n;
        } else {
          fDelta = (pParams->fPlateWidth - m_rtPageContents.width) / 2;
        }
      }
    }
    FX_FLOAT fOffset = m_rtPageContents.left - fDelta;
    int32_t nCount = m_PieceMassArr.GetSize();
    for (int32_t i = 0; i < nCount; i++) {
      FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(i);
      pPiece->rtPiece.Offset(-fOffset, 0.0f);
    }
    m_rtPageContents.Offset(-fOffset, 0.0f);
  }
  if (m_pEditEngine->GetEditParams()->dwLayoutStyles &
      FDE_TEXTEDITLAYOUT_LastLineHeight) {
    m_rtPageContents.height -= pParams->fLineSpace - pParams->fFontSize;
    int32_t nCount = m_PieceMassArr.GetSize();
    FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(nCount - 1);
    pPiece->rtPiece.height = pParams->fFontSize;
  }
  m_nRefCount = 1;
  m_bLoaded = TRUE;
  return 0;
}

void CFDE_TxtEdtPage::UnloadPage(const CFX_RectF* pClipBox) {
  ASSERT(m_nRefCount > 0);
  m_nRefCount--;
  if (m_nRefCount != 0)
    return;

  m_PieceMassArr.RemoveAll();
  delete m_pTextSet;
  m_pTextSet = nullptr;
  delete[] m_pCharWidth;
  m_pCharWidth = nullptr;
  if (m_pBgnParag) {
    m_pBgnParag->UnloadParag();
    m_pBgnParag = nullptr;
  }
  if (m_pEndParag) {
    m_pEndParag->UnloadParag();
    m_pEndParag = nullptr;
  }
  m_pIter.reset();
}

const CFX_RectF& CFDE_TxtEdtPage::GetContentsBox() {
  return m_rtPageContents;
}

FX_POSITION CFDE_TxtEdtPage::GetFirstPosition(FDE_HVISUALOBJ hCanvas) {
  if (m_PieceMassArr.GetSize() < 1) {
    return NULL;
  }
  return (FX_POSITION)1;
}

FDE_HVISUALOBJ CFDE_TxtEdtPage::GetNext(FDE_HVISUALOBJ hCanvas,
                                        FX_POSITION& pos,
                                        IFDE_VisualSet*& pVisualSet) {
  if (m_pTextSet == NULL) {
    pos = NULL;
    return NULL;
  }
  int32_t nPos = (int32_t)(uintptr_t)pos;
  pVisualSet = m_pTextSet;
  if (nPos + 1 > m_PieceMassArr.GetSize()) {
    pos = NULL;
  } else {
    pos = (FX_POSITION)(uintptr_t)(nPos + 1);
  }
  return (FDE_HVISUALOBJ)(m_PieceMassArr.GetPtrAt(nPos - 1));
}

FDE_HVISUALOBJ CFDE_TxtEdtPage::GetParentCanvas(FDE_HVISUALOBJ hCanvas,
                                                IFDE_VisualSet*& pVisualSet) {
  return NULL;
}

FX_WCHAR CFDE_TxtEdtPage::GetChar(void* pIdentity, int32_t index) const {
  int32_t nIndex =
      m_nPageStart + ((FDE_TEXTEDITPIECE*)pIdentity)->nStart + index;
  if (nIndex != m_pIter->GetAt()) {
    m_pIter->SetAt(nIndex);
  }
  FX_WCHAR wChar = m_pIter->GetChar();
  m_pIter->Next();
  return wChar;
}

int32_t CFDE_TxtEdtPage::GetWidth(void* pIdentity, int32_t index) const {
  int32_t nWidth =
      m_pCharWidth[((FDE_TEXTEDITPIECE*)pIdentity)->nStart + index];
  return nWidth;
}

void CFDE_TxtEdtPage::NormalizePt2Rect(CFX_PointF& ptF,
                                       const CFX_RectF& rtF,
                                       FX_FLOAT fTolerance) const {
  if (rtF.Contains(ptF.x, ptF.y)) {
    return;
  }
  if (ptF.x < rtF.left) {
    ptF.x = rtF.left;
  } else if (ptF.x >= rtF.right()) {
    ptF.x = rtF.right() - fTolerance;
  }
  if (ptF.y < rtF.top) {
    ptF.y = rtF.top;
  } else if (ptF.y >= rtF.bottom()) {
    ptF.y = rtF.bottom() - fTolerance;
  }
}
