// 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/src/fee/fde_txtedtpage.h"

#include <algorithm>

#include "xfa/src/fee/fx_wordbreak/fx_wordbreak.h"
#include "xfa/src/fee/fde_txtedtbuf.h"
#include "xfa/src/fee/fde_txtedtengine.h"
#include "xfa/src/fee/fde_txtedtparag.h"
#include "xfa/src/fee/ifde_txtedtbuf.h"
#include "xfa/src/fee/ifde_txtedtengine.h"
#include "xfa/src/fee/ifde_txtedtpage.h"

#define FDE_TXTEDT_TOLERANCE 0.1f

IFDE_TxtEdtPage* IFDE_TxtEdtPage::Create(IFDE_TxtEdtEngine* pEngine,
                                         int32_t nIndex) {
  return (IFDE_TxtEdtPage*)new CFDE_TxtEdtPage(pEngine, nIndex);
}
CFDE_TxtEdtTextSet::CFDE_TxtEdtTextSet(CFDE_TxtEdtPage* pPage)
    : m_pPage(pPage) {}
CFDE_TxtEdtTextSet::~CFDE_TxtEdtTextSet() {}
FDE_VISUALOBJTYPE CFDE_TxtEdtTextSet::GetType() {
  return FDE_VISUALOBJ_Text;
}
FX_BOOL CFDE_TxtEdtTextSet::GetBBox(FDE_HVISUALOBJ hVisualObj,
                                    CFX_RectF& bbox) {
  return FALSE;
}
FX_BOOL CFDE_TxtEdtTextSet::GetMatrix(FDE_HVISUALOBJ hVisualObj,
                                      CFX_Matrix& matrix) {
  return FALSE;
}
FX_BOOL CFDE_TxtEdtTextSet::GetRect(FDE_HVISUALOBJ hVisualObj, CFX_RectF& rt) {
  rt = ((FDE_TEXTEDITPIECE*)(hVisualObj))->rtPiece;
  return TRUE;
}
FX_BOOL CFDE_TxtEdtTextSet::GetClip(FDE_HVISUALOBJ hVisualObj, CFX_RectF& rt) {
  return FALSE;
}
int32_t CFDE_TxtEdtTextSet::GetString(FDE_HVISUALOBJ hText,
                                      CFX_WideString& wsText) {
  FDE_TEXTEDITPIECE* pPiece = (FDE_TEXTEDITPIECE*)hText;
  FX_WCHAR* pBuffer = wsText.GetBuffer(pPiece->nCount);
  for (int32_t i = 0; i < pPiece->nCount; i++) {
    pBuffer[i] = m_pPage->GetChar((void*)hText, i);
  }
  wsText.ReleaseBuffer(pPiece->nCount);
  return pPiece->nCount;
}
IFX_Font* CFDE_TxtEdtTextSet::GetFont(FDE_HVISUALOBJ hText) {
  return m_pPage->GetEngine()->GetEditParams()->pFont;
}
FX_FLOAT CFDE_TxtEdtTextSet::GetFontSize(FDE_HVISUALOBJ hText) {
  return m_pPage->GetEngine()->GetEditParams()->fFontSize;
}
FX_ARGB CFDE_TxtEdtTextSet::GetFontColor(FDE_HVISUALOBJ hText) {
  return m_pPage->GetEngine()->GetEditParams()->dwFontColor;
}
int32_t CFDE_TxtEdtTextSet::GetDisplayPos(FDE_HVISUALOBJ hText,
                                          FXTEXT_CHARPOS* pCharPos,
                                          FX_BOOL bCharCode,
                                          CFX_WideString* pWSForms) {
  if (hText == NULL) {
    return 0;
  }
  FDE_TEXTEDITPIECE* pPiece = (FDE_TEXTEDITPIECE*)hText;
  int32_t nLength = pPiece->nCount;
  if (nLength < 1) {
    return 0;
  }
  CFDE_TxtEdtEngine* pEngine = (CFDE_TxtEdtEngine*)(m_pPage->GetEngine());
  const FDE_TXTEDTPARAMS* pTextParams = pEngine->GetEditParams();
  IFX_TxtBreak* pBreak = pEngine->GetTextBreak();
  FX_DWORD dwLayoutStyle = pBreak->GetLayoutStyles();
  FX_TXTRUN tr;
  tr.pAccess = m_pPage;
  tr.pIdentity = (void*)hText;
  tr.pStr = NULL;
  tr.pWidths = NULL;
  tr.iLength = nLength;
  tr.pFont = pTextParams->pFont;
  tr.fFontSize = pTextParams->fFontSize;
  tr.dwStyles = dwLayoutStyle;
  tr.iCharRotation = pTextParams->nCharRotation;
  tr.dwCharStyles = pPiece->dwCharStyles;
  tr.pRect = &(pPiece->rtPiece);
  tr.wLineBreakChar = pTextParams->wLineBreakChar;
  return pBreak->GetDisplayPos(&tr, pCharPos, bCharCode, pWSForms);
}
int32_t CFDE_TxtEdtTextSet::GetCharRects(FDE_HVISUALOBJ hText,
                                         CFX_RectFArray& rtArray) {
  return GetCharRects_Impl(hText, rtArray);
}
int32_t CFDE_TxtEdtTextSet::GetCharRects_Impl(FDE_HVISUALOBJ hText,
                                              CFX_RectFArray& rtArray,
                                              FX_BOOL bBBox) {
  if (hText == NULL) {
    return 0;
  }
  FDE_TEXTEDITPIECE* pPiece = (FDE_TEXTEDITPIECE*)hText;
  CFDE_TxtEdtEngine* pEngine = (CFDE_TxtEdtEngine*)(m_pPage->GetEngine());
  int32_t nLength = pPiece->nCount;
  if (nLength < 1) {
    return 0;
  }
  const FDE_TXTEDTPARAMS* pTextParams = pEngine->GetEditParams();
  FX_DWORD dwLayoutStyle = pEngine->GetTextBreak()->GetLayoutStyles();
  FX_TXTRUN tr;
  tr.pAccess = m_pPage;
  tr.pIdentity = (void*)hText;
  tr.pStr = NULL;
  tr.pWidths = NULL;
  tr.iLength = nLength;
  tr.pFont = pTextParams->pFont;
  tr.fFontSize = pTextParams->fFontSize;
  tr.dwStyles = dwLayoutStyle;
  tr.iCharRotation = pTextParams->nCharRotation;
  tr.dwCharStyles = pPiece->dwCharStyles;
  tr.pRect = &(pPiece->rtPiece);
  tr.wLineBreakChar = pTextParams->wLineBreakChar;
  return pEngine->GetTextBreak()->GetCharRects(&tr, rtArray, bBBox);
}
CFDE_TxtEdtPage::CFDE_TxtEdtPage(IFDE_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);
  if (m_pTextSet) {
    delete m_pTextSet;
    m_pTextSet = NULL;
  }
  if (m_pCharWidth) {
    delete[] m_pCharWidth;
    m_pCharWidth = NULL;
  }
  if (m_pIter != NULL) {
    m_pIter->Release();
    m_pIter = NULL;
  }
}
void CFDE_TxtEdtPage::Release() {
  delete this;
}
IFDE_TxtEdtEngine* CFDE_TxtEdtPage::GetEngine() const {
  return (IFDE_TxtEdtEngine*)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 {
  FXSYS_assert(m_nRefCount > 0);
  FXSYS_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;
    }
  }
  FXSYS_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, FDE_TXTEDT_TOLERANCE);
  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, FDE_TXTEDT_TOLERANCE);
  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;
  }
  IFDE_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;
  }
  IFX_WordBreak* pIter = FX_WordBreak_Create();
  pIter->Attach(new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pBuf));
  pIter->SetAt(nIndex);
  nCount = pIter->GetWordLength();
  int32_t nRet = pIter->GetWordPos();
  pIter->Release();
  return nRet;
}
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;
  }
  IFDE_TxtEdtBuf* pBuf = m_pEditEngine->GetTextBuf();
  const FDE_TXTEDTPARAMS* pParams = m_pEditEngine->GetEditParams();
  if (m_pIter != NULL) {
    m_pIter->Release();
  }
  FX_WCHAR wcAlias = 0;
  if (pParams->dwMode & FDE_TEXTEDITMODE_Password) {
    wcAlias = m_pEditEngine->GetAliasChar();
  }
  m_pIter = new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pBuf, wcAlias);
  IFX_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);
  FX_DWORD 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;
  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;
  }
  pIter->Release();
  m_nRefCount = 1;
  m_bLoaded = TRUE;
  return 0;
}
void CFDE_TxtEdtPage::UnloadPage(const CFX_RectF* pClipBox) {
  FXSYS_assert(m_nRefCount > 0);
  m_nRefCount--;
  if (m_nRefCount == 0) {
    m_PieceMassArr.RemoveAll();
    if (m_pTextSet) {
      delete m_pTextSet;
      m_pTextSet = NULL;
    }
    if (m_pCharWidth) {
      delete[] m_pCharWidth;
      m_pCharWidth = NULL;
    }
    if (m_pBgnParag) {
      m_pBgnParag->UnloadParag();
    }
    if (m_pEndParag) {
      m_pEndParag->UnloadParag();
    }
    if (m_pIter) {
      m_pIter->Release();
      m_pIter = NULL;
    }
    m_pBgnParag = NULL;
    m_pEndParag = NULL;
  }
}

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