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

#include "core/fpdfdoc/pdf_vt.h"
#include "core/include/fpdfdoc/fpdf_doc.h"
#include "core/include/fpdfdoc/fpdf_vt.h"

const uint8_t gFontSizeSteps[] = {4,  6,  8,   9,   10,  12,  14, 18, 20,
                                  25, 30, 35,  40,  45,  50,  55, 60, 70,
                                  80, 90, 100, 110, 120, 130, 144};
#define PVT_RETURN_LENGTH 1
#define PVT_DEFAULT_FONTSIZE 18.0f
#define PVTWORD_SCRIPT_NORMAL 0
#define PVTWORD_SCRIPT_SUPER 1
#define PVTWORD_SCRIPT_SUB 2
#define PVT_FONTSCALE 0.001f
#define PVT_PERCENT 0.01f
#define PVT_HALF 0.5f
CLine::CLine() {}
CLine::~CLine() {}
CPVT_WordPlace CLine::GetBeginWordPlace() const {
  return CPVT_WordPlace(LinePlace.nSecIndex, LinePlace.nLineIndex, -1);
}
CPVT_WordPlace CLine::GetEndWordPlace() const {
  return CPVT_WordPlace(LinePlace.nSecIndex, LinePlace.nLineIndex,
                        m_LineInfo.nEndWordIndex);
}
CPVT_WordPlace CLine::GetPrevWordPlace(const CPVT_WordPlace& place) const {
  if (place.nWordIndex > m_LineInfo.nEndWordIndex) {
    return CPVT_WordPlace(place.nSecIndex, place.nLineIndex,
                          m_LineInfo.nEndWordIndex);
  }
  return CPVT_WordPlace(place.nSecIndex, place.nLineIndex,
                        place.nWordIndex - 1);
}
CPVT_WordPlace CLine::GetNextWordPlace(const CPVT_WordPlace& place) const {
  if (place.nWordIndex < m_LineInfo.nBeginWordIndex) {
    return CPVT_WordPlace(place.nSecIndex, place.nLineIndex,
                          m_LineInfo.nBeginWordIndex);
  }
  return CPVT_WordPlace(place.nSecIndex, place.nLineIndex,
                        place.nWordIndex + 1);
}
CSection::CSection(CPDF_VariableText* pVT) : m_pVT(pVT) {}
CSection::~CSection() {
  ResetAll();
}
void CSection::ResetAll() {
  ResetWordArray();
  ResetLineArray();
}
void CSection::ResetLineArray() {
  m_LineArray.RemoveAll();
}
void CSection::ResetWordArray() {
  for (int32_t i = 0, sz = m_WordArray.GetSize(); i < sz; i++) {
    delete m_WordArray.GetAt(i);
  }
  m_WordArray.RemoveAll();
}
void CSection::ResetLinePlace() {
  for (int32_t i = 0, sz = m_LineArray.GetSize(); i < sz; i++) {
    if (CLine* pLine = m_LineArray.GetAt(i)) {
      pLine->LinePlace = CPVT_WordPlace(SecPlace.nSecIndex, i, -1);
    }
  }
}
CPVT_WordPlace CSection::AddWord(const CPVT_WordPlace& place,
                                 const CPVT_WordInfo& wordinfo) {
  CPVT_WordInfo* pWord = new CPVT_WordInfo(wordinfo);
  int32_t nWordIndex =
      std::max(std::min(place.nWordIndex, m_WordArray.GetSize()), 0);
  if (nWordIndex == m_WordArray.GetSize()) {
    m_WordArray.Add(pWord);
  } else {
    m_WordArray.InsertAt(nWordIndex, pWord);
  }
  return place;
}
CPVT_WordPlace CSection::AddLine(const CPVT_LineInfo& lineinfo) {
  return CPVT_WordPlace(SecPlace.nSecIndex, m_LineArray.Add(lineinfo), -1);
}
CPVT_FloatRect CSection::Rearrange() {
  if (m_pVT->m_nCharArray > 0) {
    return CTypeset(this).CharArray();
  }
  return CTypeset(this).Typeset();
}
CPVT_Size CSection::GetSectionSize(FX_FLOAT fFontSize) {
  return CTypeset(this).GetEditSize(fFontSize);
}
CPVT_WordPlace CSection::GetBeginWordPlace() const {
  if (CLine* pLine = m_LineArray.GetAt(0)) {
    return pLine->GetBeginWordPlace();
  }
  return SecPlace;
}
CPVT_WordPlace CSection::GetEndWordPlace() const {
  if (CLine* pLine = m_LineArray.GetAt(m_LineArray.GetSize() - 1)) {
    return pLine->GetEndWordPlace();
  }
  return SecPlace;
}
CPVT_WordPlace CSection::GetPrevWordPlace(const CPVT_WordPlace& place) const {
  if (place.nLineIndex < 0) {
    return GetBeginWordPlace();
  }
  if (place.nLineIndex >= m_LineArray.GetSize()) {
    return GetEndWordPlace();
  }
  if (CLine* pLine = m_LineArray.GetAt(place.nLineIndex)) {
    if (place.nWordIndex == pLine->m_LineInfo.nBeginWordIndex) {
      return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, -1);
    }
    if (place.nWordIndex < pLine->m_LineInfo.nBeginWordIndex) {
      if (CLine* pPrevLine = m_LineArray.GetAt(place.nLineIndex - 1)) {
        return pPrevLine->GetEndWordPlace();
      }
    } else {
      return pLine->GetPrevWordPlace(place);
    }
  }
  return place;
}
CPVT_WordPlace CSection::GetNextWordPlace(const CPVT_WordPlace& place) const {
  if (place.nLineIndex < 0) {
    return GetBeginWordPlace();
  }
  if (place.nLineIndex >= m_LineArray.GetSize()) {
    return GetEndWordPlace();
  }
  if (CLine* pLine = m_LineArray.GetAt(place.nLineIndex)) {
    if (place.nWordIndex >= pLine->m_LineInfo.nEndWordIndex) {
      if (CLine* pNextLine = m_LineArray.GetAt(place.nLineIndex + 1)) {
        return pNextLine->GetBeginWordPlace();
      }
    } else {
      return pLine->GetNextWordPlace(place);
    }
  }
  return place;
}
void CSection::UpdateWordPlace(CPVT_WordPlace& place) const {
  int32_t nLeft = 0;
  int32_t nRight = m_LineArray.GetSize() - 1;
  int32_t nMid = (nLeft + nRight) / 2;
  while (nLeft <= nRight) {
    if (CLine* pLine = m_LineArray.GetAt(nMid)) {
      if (place.nWordIndex < pLine->m_LineInfo.nBeginWordIndex) {
        nRight = nMid - 1;
        nMid = (nLeft + nRight) / 2;
      } else if (place.nWordIndex > pLine->m_LineInfo.nEndWordIndex) {
        nLeft = nMid + 1;
        nMid = (nLeft + nRight) / 2;
      } else {
        place.nLineIndex = nMid;
        return;
      }
    } else {
      break;
    }
  }
}
CPVT_WordPlace CSection::SearchWordPlace(const CFX_FloatPoint& point) const {
  ASSERT(m_pVT);
  CPVT_WordPlace place = GetBeginWordPlace();
  FX_BOOL bUp = TRUE;
  FX_BOOL bDown = TRUE;
  int32_t nLeft = 0;
  int32_t nRight = m_LineArray.GetSize() - 1;
  int32_t nMid = m_LineArray.GetSize() / 2;
  FX_FLOAT fTop = 0;
  FX_FLOAT fBottom = 0;
  while (nLeft <= nRight) {
    if (CLine* pLine = m_LineArray.GetAt(nMid)) {
      fTop = pLine->m_LineInfo.fLineY - pLine->m_LineInfo.fLineAscent -
             m_pVT->GetLineLeading(m_SecInfo);
      fBottom = pLine->m_LineInfo.fLineY - pLine->m_LineInfo.fLineDescent;
      if (IsFloatBigger(point.y, fTop)) {
        bUp = FALSE;
      }
      if (IsFloatSmaller(point.y, fBottom)) {
        bDown = FALSE;
      }
      if (IsFloatSmaller(point.y, fTop)) {
        nRight = nMid - 1;
        nMid = (nLeft + nRight) / 2;
        continue;
      } else if (IsFloatBigger(point.y, fBottom)) {
        nLeft = nMid + 1;
        nMid = (nLeft + nRight) / 2;
        continue;
      } else {
        place = SearchWordPlace(
            point.x,
            CPVT_WordRange(pLine->GetNextWordPlace(pLine->GetBeginWordPlace()),
                           pLine->GetEndWordPlace()));
        place.nLineIndex = nMid;
        return place;
      }
    }
  }
  if (bUp) {
    place = GetBeginWordPlace();
  }
  if (bDown) {
    place = GetEndWordPlace();
  }
  return place;
}
CPVT_WordPlace CSection::SearchWordPlace(
    FX_FLOAT fx,
    const CPVT_WordPlace& lineplace) const {
  if (CLine* pLine = m_LineArray.GetAt(lineplace.nLineIndex)) {
    return SearchWordPlace(
        fx - m_SecInfo.rcSection.left,
        CPVT_WordRange(pLine->GetNextWordPlace(pLine->GetBeginWordPlace()),
                       pLine->GetEndWordPlace()));
  }
  return GetBeginWordPlace();
}
CPVT_WordPlace CSection::SearchWordPlace(FX_FLOAT fx,
                                         const CPVT_WordRange& range) const {
  CPVT_WordPlace wordplace = range.BeginPos;
  wordplace.nWordIndex = -1;
  if (!m_pVT) {
    return wordplace;
  }
  int32_t nLeft = range.BeginPos.nWordIndex;
  int32_t nRight = range.EndPos.nWordIndex + 1;
  int32_t nMid = (nLeft + nRight) / 2;
  while (nLeft < nRight) {
    if (nMid == nLeft) {
      break;
    }
    if (nMid == nRight) {
      nMid--;
      break;
    }
    if (CPVT_WordInfo* pWord = m_WordArray.GetAt(nMid)) {
      if (fx > pWord->fWordX + m_pVT->GetWordWidth(*pWord) * PVT_HALF) {
        nLeft = nMid;
        nMid = (nLeft + nRight) / 2;
        continue;
      } else {
        nRight = nMid;
        nMid = (nLeft + nRight) / 2;
        continue;
      }
    } else {
      break;
    }
  }
  if (CPVT_WordInfo* pWord = m_WordArray.GetAt(nMid)) {
    if (fx > pWord->fWordX + m_pVT->GetWordWidth(*pWord) * PVT_HALF) {
      wordplace.nWordIndex = nMid;
    }
  }
  return wordplace;
}
void CSection::ClearLeftWords(int32_t nWordIndex) {
  for (int32_t i = nWordIndex; i >= 0; i--) {
    delete m_WordArray.GetAt(i);
    m_WordArray.RemoveAt(i);
  }
}
void CSection::ClearRightWords(int32_t nWordIndex) {
  for (int32_t i = m_WordArray.GetSize() - 1; i > nWordIndex; i--) {
    delete m_WordArray.GetAt(i);
    m_WordArray.RemoveAt(i);
  }
}
void CSection::ClearMidWords(int32_t nBeginIndex, int32_t nEndIndex) {
  for (int32_t i = nEndIndex; i > nBeginIndex; i--) {
    delete m_WordArray.GetAt(i);
    m_WordArray.RemoveAt(i);
  }
}
void CSection::ClearWords(const CPVT_WordRange& PlaceRange) {
  CPVT_WordPlace SecBeginPos = GetBeginWordPlace();
  CPVT_WordPlace SecEndPos = GetEndWordPlace();
  if (PlaceRange.BeginPos.WordCmp(SecBeginPos) >= 0) {
    if (PlaceRange.EndPos.WordCmp(SecEndPos) <= 0) {
      ClearMidWords(PlaceRange.BeginPos.nWordIndex,
                    PlaceRange.EndPos.nWordIndex);
    } else {
      ClearRightWords(PlaceRange.BeginPos.nWordIndex);
    }
  } else if (PlaceRange.EndPos.WordCmp(SecEndPos) <= 0) {
    ClearLeftWords(PlaceRange.EndPos.nWordIndex);
  } else {
    ResetWordArray();
  }
}
void CSection::ClearWord(const CPVT_WordPlace& place) {
  delete m_WordArray.GetAt(place.nWordIndex);
  m_WordArray.RemoveAt(place.nWordIndex);
}
CTypeset::CTypeset(CSection* pSection)
    : m_rcRet(0.0f, 0.0f, 0.0f, 0.0f),
      m_pVT(pSection->m_pVT),
      m_pSection(pSection) {}
CTypeset::~CTypeset() {}
CPVT_FloatRect CTypeset::CharArray() {
  ASSERT(m_pSection);
  FX_FLOAT fLineAscent =
      m_pVT->GetFontAscent(m_pVT->GetDefaultFontIndex(), m_pVT->GetFontSize());
  FX_FLOAT fLineDescent =
      m_pVT->GetFontDescent(m_pVT->GetDefaultFontIndex(), m_pVT->GetFontSize());
  m_rcRet.Default();
  FX_FLOAT x = 0.0f, y = 0.0f;
  FX_FLOAT fNextWidth;
  int32_t nStart = 0;
  FX_FLOAT fNodeWidth = m_pVT->GetPlateWidth() /
                        (m_pVT->m_nCharArray <= 0 ? 1 : m_pVT->m_nCharArray);
  if (CLine* pLine = m_pSection->m_LineArray.GetAt(0)) {
    x = 0.0f;
    y += m_pVT->GetLineLeading(m_pSection->m_SecInfo);
    y += fLineAscent;
    nStart = 0;
    switch (m_pVT->GetAlignment(m_pSection->m_SecInfo)) {
      case 0:
        pLine->m_LineInfo.fLineX = fNodeWidth * PVT_HALF;
        break;
      case 1:
        nStart = (m_pVT->m_nCharArray - m_pSection->m_WordArray.GetSize()) / 2;
        pLine->m_LineInfo.fLineX = fNodeWidth * nStart - fNodeWidth * PVT_HALF;
        break;
      case 2:
        nStart = m_pVT->m_nCharArray - m_pSection->m_WordArray.GetSize();
        pLine->m_LineInfo.fLineX = fNodeWidth * nStart - fNodeWidth * PVT_HALF;
        break;
    }
    for (int32_t w = 0, sz = m_pSection->m_WordArray.GetSize(); w < sz; w++) {
      if (w >= m_pVT->m_nCharArray) {
        break;
      }
      fNextWidth = 0;
      if (CPVT_WordInfo* pNextWord =
              (CPVT_WordInfo*)m_pSection->m_WordArray.GetAt(w + 1)) {
        pNextWord->fWordTail = 0;
        fNextWidth = m_pVT->GetWordWidth(*pNextWord);
      }
      if (CPVT_WordInfo* pWord =
              (CPVT_WordInfo*)m_pSection->m_WordArray.GetAt(w)) {
        pWord->fWordTail = 0;
        FX_FLOAT fWordWidth = m_pVT->GetWordWidth(*pWord);
        FX_FLOAT fWordAscent = m_pVT->GetWordAscent(*pWord);
        FX_FLOAT fWordDescent = m_pVT->GetWordDescent(*pWord);
        x = (FX_FLOAT)(fNodeWidth * (w + nStart + 0.5) - fWordWidth * PVT_HALF);
        pWord->fWordX = x;
        pWord->fWordY = y;
        if (w == 0) {
          pLine->m_LineInfo.fLineX = x;
        }
        if (w != m_pSection->m_WordArray.GetSize() - 1) {
          pWord->fWordTail =
              (fNodeWidth - (fWordWidth + fNextWidth) * PVT_HALF > 0
                   ? fNodeWidth - (fWordWidth + fNextWidth) * PVT_HALF
                   : 0);
        } else {
          pWord->fWordTail = 0;
        }
        x += fWordWidth;
        fLineAscent = std::max(fLineAscent, fWordAscent);
        fLineDescent = std::min(fLineDescent, fWordDescent);
      }
    }
    pLine->m_LineInfo.nBeginWordIndex = 0;
    pLine->m_LineInfo.nEndWordIndex = m_pSection->m_WordArray.GetSize() - 1;
    pLine->m_LineInfo.fLineY = y;
    pLine->m_LineInfo.fLineWidth = x - pLine->m_LineInfo.fLineX;
    pLine->m_LineInfo.fLineAscent = fLineAscent;
    pLine->m_LineInfo.fLineDescent = fLineDescent;
    y += (-fLineDescent);
  }
  return m_rcRet = CPVT_FloatRect(0, 0, x, y);
}
CPVT_Size CTypeset::GetEditSize(FX_FLOAT fFontSize) {
  ASSERT(m_pSection);
  ASSERT(m_pVT);
  SplitLines(FALSE, fFontSize);
  return CPVT_Size(m_rcRet.Width(), m_rcRet.Height());
}
CPVT_FloatRect CTypeset::Typeset() {
  ASSERT(m_pVT);
  m_pSection->m_LineArray.Empty();
  SplitLines(TRUE, 0.0f);
  m_pSection->m_LineArray.Clear();
  OutputLines();
  return m_rcRet;
}

static const uint8_t special_chars[128] = {
    0x00, 0x0C, 0x08, 0x0C, 0x08, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00,
    0x10, 0x00, 0x00, 0x28, 0x0C, 0x08, 0x00, 0x00, 0x28, 0x28, 0x28, 0x28,
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x08, 0x08,
    0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0C, 0x00, 0x08, 0x00, 0x00,
    0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x0C, 0x00, 0x08, 0x00, 0x00,
};

static bool IsLatin(uint16_t word) {
  if (word <= 0x007F)
    return !!(special_chars[word] & 0x01);

  return ((word >= 0x00C0 && word <= 0x00FF) ||
          (word >= 0x0100 && word <= 0x024F) ||
          (word >= 0x1E00 && word <= 0x1EFF) ||
          (word >= 0x2C60 && word <= 0x2C7F) ||
          (word >= 0xA720 && word <= 0xA7FF) ||
          (word >= 0xFF21 && word <= 0xFF3A) ||
          (word >= 0xFF41 && word <= 0xFF5A));
}

static bool IsDigit(uint32_t word) {
  return word >= 0x0030 && word <= 0x0039;
}

static bool IsCJK(uint32_t word) {
  if ((word >= 0x1100 && word <= 0x11FF) ||
      (word >= 0x2E80 && word <= 0x2FFF) ||
      (word >= 0x3040 && word <= 0x9FBF) ||
      (word >= 0xAC00 && word <= 0xD7AF) ||
      (word >= 0xF900 && word <= 0xFAFF) ||
      (word >= 0xFE30 && word <= 0xFE4F) ||
      (word >= 0x20000 && word <= 0x2A6DF) ||
      (word >= 0x2F800 && word <= 0x2FA1F)) {
    return true;
  }
  if (word >= 0x3000 && word <= 0x303F) {
    return (
        word == 0x3005 || word == 0x3006 || word == 0x3021 || word == 0x3022 ||
        word == 0x3023 || word == 0x3024 || word == 0x3025 || word == 0x3026 ||
        word == 0x3027 || word == 0x3028 || word == 0x3029 || word == 0x3031 ||
        word == 0x3032 || word == 0x3033 || word == 0x3034 || word == 0x3035);
  }
  return word >= 0xFF66 && word <= 0xFF9D;
}

static bool IsPunctuation(uint32_t word) {
  if (word <= 0x007F)
    return !!(special_chars[word] & 0x08);

  if (word >= 0x0080 && word <= 0x00FF) {
    return (word == 0x0082 || word == 0x0084 || word == 0x0085 ||
            word == 0x0091 || word == 0x0092 || word == 0x0093 ||
            word <= 0x0094 || word == 0x0096 || word == 0x00B4 ||
            word == 0x00B8);
  }

  if (word >= 0x2000 && word <= 0x206F) {
    return (
        word == 0x2010 || word == 0x2011 || word == 0x2012 || word == 0x2013 ||
        word == 0x2018 || word == 0x2019 || word == 0x201A || word == 0x201B ||
        word == 0x201C || word == 0x201D || word == 0x201E || word == 0x201F ||
        word == 0x2032 || word == 0x2033 || word == 0x2034 || word == 0x2035 ||
        word == 0x2036 || word == 0x2037 || word == 0x203C || word == 0x203D ||
        word == 0x203E || word == 0x2044);
  }

  if (word >= 0x3000 && word <= 0x303F) {
    return (
        word == 0x3001 || word == 0x3002 || word == 0x3003 || word == 0x3005 ||
        word == 0x3009 || word == 0x300A || word == 0x300B || word == 0x300C ||
        word == 0x300D || word == 0x300F || word == 0x300E || word == 0x3010 ||
        word == 0x3011 || word == 0x3014 || word == 0x3015 || word == 0x3016 ||
        word == 0x3017 || word == 0x3018 || word == 0x3019 || word == 0x301A ||
        word == 0x301B || word == 0x301D || word == 0x301E || word == 0x301F);
  }

  if (word >= 0xFE50 && word <= 0xFE6F)
    return (word >= 0xFE50 && word <= 0xFE5E) || word == 0xFE63;

  if (word >= 0xFF00 && word <= 0xFFEF) {
    return (
        word == 0xFF01 || word == 0xFF02 || word == 0xFF07 || word == 0xFF08 ||
        word == 0xFF09 || word == 0xFF0C || word == 0xFF0E || word == 0xFF0F ||
        word == 0xFF1A || word == 0xFF1B || word == 0xFF1F || word == 0xFF3B ||
        word == 0xFF3D || word == 0xFF40 || word == 0xFF5B || word == 0xFF5C ||
        word == 0xFF5D || word == 0xFF61 || word == 0xFF62 || word == 0xFF63 ||
        word == 0xFF64 || word == 0xFF65 || word == 0xFF9E || word == 0xFF9F);
  }

  return false;
}

static bool IsConnectiveSymbol(uint32_t word) {
  return word <= 0x007F && (special_chars[word] & 0x20);
}

static bool IsOpenStylePunctuation(uint32_t word) {
  if (word <= 0x007F)
    return !!(special_chars[word] & 0x04);

  return (word == 0x300A || word == 0x300C || word == 0x300E ||
          word == 0x3010 || word == 0x3014 || word == 0x3016 ||
          word == 0x3018 || word == 0x301A || word == 0xFF08 ||
          word == 0xFF3B || word == 0xFF5B || word == 0xFF62);
}

static bool IsCurrencySymbol(uint16_t word) {
  return (word == 0x0024 || word == 0x0080 || word == 0x00A2 ||
          word == 0x00A3 || word == 0x00A4 || word == 0x00A5 ||
          (word >= 0x20A0 && word <= 0x20CF) || word == 0xFE69 ||
          word == 0xFF04 || word == 0xFFE0 || word == 0xFFE1 ||
          word == 0xFFE5 || word == 0xFFE6);
}

static bool IsPrefixSymbol(uint16_t word) {
  return IsCurrencySymbol(word) || word == 0x2116;
}

static bool IsSpace(uint16_t word) {
  return word == 0x0020 || word == 0x3000;
}

static bool NeedDivision(uint16_t prevWord, uint16_t curWord) {
  if ((IsLatin(prevWord) || IsDigit(prevWord)) &&
      (IsLatin(curWord) || IsDigit(curWord))) {
    return false;
  }
  if (IsSpace(curWord) || IsPunctuation(curWord)) {
    return false;
  }
  if (IsConnectiveSymbol(prevWord) || IsConnectiveSymbol(curWord)) {
    return false;
  }
  if (IsSpace(prevWord) || IsPunctuation(prevWord)) {
    return true;
  }
  if (IsPrefixSymbol(prevWord)) {
    return false;
  }
  if (IsPrefixSymbol(curWord) || IsCJK(curWord)) {
    return true;
  }
  if (IsCJK(prevWord)) {
    return true;
  }
  return false;
}

void CTypeset::SplitLines(FX_BOOL bTypeset, FX_FLOAT fFontSize) {
  ASSERT(m_pVT);
  ASSERT(m_pSection);
  int32_t nLineHead = 0;
  int32_t nLineTail = 0;
  FX_FLOAT fMaxX = 0.0f, fMaxY = 0.0f;
  FX_FLOAT fLineWidth = 0.0f, fBackupLineWidth = 0.0f;
  FX_FLOAT fLineAscent = 0.0f, fBackupLineAscent = 0.0f;
  FX_FLOAT fLineDescent = 0.0f, fBackupLineDescent = 0.0f;
  int32_t nWordStartPos = 0;
  FX_BOOL bFullWord = FALSE;
  int32_t nLineFullWordIndex = 0;
  int32_t nCharIndex = 0;
  CPVT_LineInfo line;
  FX_FLOAT fWordWidth = 0;
  FX_FLOAT fTypesetWidth = std::max(
      m_pVT->GetPlateWidth() - m_pVT->GetLineIndent(m_pSection->m_SecInfo),
      0.0f);
  int32_t nTotalWords = m_pSection->m_WordArray.GetSize();
  FX_BOOL bOpened = FALSE;
  if (nTotalWords > 0) {
    int32_t i = 0;
    while (i < nTotalWords) {
      CPVT_WordInfo* pWord = m_pSection->m_WordArray.GetAt(i);
      CPVT_WordInfo* pOldWord = pWord;
      if (i > 0) {
        pOldWord = m_pSection->m_WordArray.GetAt(i - 1);
      }
      if (pWord) {
        if (bTypeset) {
          fLineAscent =
              std::max(fLineAscent, m_pVT->GetWordAscent(*pWord, TRUE));
          fLineDescent =
              std::min(fLineDescent, m_pVT->GetWordDescent(*pWord, TRUE));
          fWordWidth = m_pVT->GetWordWidth(*pWord);
        } else {
          fLineAscent =
              std::max(fLineAscent, m_pVT->GetWordAscent(*pWord, fFontSize));
          fLineDescent =
              std::min(fLineDescent, m_pVT->GetWordDescent(*pWord, fFontSize));
          fWordWidth = m_pVT->GetWordWidth(
              pWord->nFontIndex, pWord->Word, m_pVT->m_wSubWord,
              m_pVT->m_fCharSpace, m_pVT->m_nHorzScale, fFontSize,
              pWord->fWordTail, 0);
        }
        if (!bOpened) {
          if (IsOpenStylePunctuation(pWord->Word)) {
            bOpened = TRUE;
            bFullWord = TRUE;
          } else if (pOldWord) {
            if (NeedDivision(pOldWord->Word, pWord->Word)) {
              bFullWord = TRUE;
            }
          }
        } else {
          if (!IsSpace(pWord->Word) && !IsOpenStylePunctuation(pWord->Word)) {
            bOpened = FALSE;
          }
        }
        if (bFullWord) {
          bFullWord = FALSE;
          if (nCharIndex > 0) {
            nLineFullWordIndex++;
          }
          nWordStartPos = i;
          fBackupLineWidth = fLineWidth;
          fBackupLineAscent = fLineAscent;
          fBackupLineDescent = fLineDescent;
        }
        nCharIndex++;
      }
      if (m_pVT->m_bLimitWidth && fTypesetWidth > 0 &&
          fLineWidth + fWordWidth > fTypesetWidth) {
        if (nLineFullWordIndex > 0) {
          i = nWordStartPos;
          fLineWidth = fBackupLineWidth;
          fLineAscent = fBackupLineAscent;
          fLineDescent = fBackupLineDescent;
        }
        if (nCharIndex == 1) {
          fLineWidth = fWordWidth;
          i++;
        }
        nLineTail = i - 1;
        if (bTypeset) {
          line.nBeginWordIndex = nLineHead;
          line.nEndWordIndex = nLineTail;
          line.nTotalWord = nLineTail - nLineHead + 1;
          line.fLineWidth = fLineWidth;
          line.fLineAscent = fLineAscent;
          line.fLineDescent = fLineDescent;
          m_pSection->AddLine(line);
        }
        fMaxY += (fLineAscent + m_pVT->GetLineLeading(m_pSection->m_SecInfo));
        fMaxY += (-fLineDescent);
        fMaxX = std::max(fLineWidth, fMaxX);
        nLineHead = i;
        fLineWidth = 0.0f;
        fLineAscent = 0.0f;
        fLineDescent = 0.0f;
        nCharIndex = 0;
        nLineFullWordIndex = 0;
        bFullWord = FALSE;
      } else {
        fLineWidth += fWordWidth;
        i++;
      }
    }
    if (nLineHead <= nTotalWords - 1) {
      nLineTail = nTotalWords - 1;
      if (bTypeset) {
        line.nBeginWordIndex = nLineHead;
        line.nEndWordIndex = nLineTail;
        line.nTotalWord = nLineTail - nLineHead + 1;
        line.fLineWidth = fLineWidth;
        line.fLineAscent = fLineAscent;
        line.fLineDescent = fLineDescent;
        m_pSection->AddLine(line);
      }
      fMaxY += (fLineAscent + m_pVT->GetLineLeading(m_pSection->m_SecInfo));
      fMaxY += (-fLineDescent);
      fMaxX = std::max(fLineWidth, fMaxX);
    }
  } else {
    if (bTypeset) {
      fLineAscent = m_pVT->GetLineAscent(m_pSection->m_SecInfo);
      fLineDescent = m_pVT->GetLineDescent(m_pSection->m_SecInfo);
    } else {
      fLineAscent =
          m_pVT->GetFontAscent(m_pVT->GetDefaultFontIndex(), fFontSize);
      fLineDescent =
          m_pVT->GetFontDescent(m_pVT->GetDefaultFontIndex(), fFontSize);
    }
    if (bTypeset) {
      line.nBeginWordIndex = -1;
      line.nEndWordIndex = -1;
      line.nTotalWord = 0;
      line.fLineWidth = 0;
      line.fLineAscent = fLineAscent;
      line.fLineDescent = fLineDescent;
      m_pSection->AddLine(line);
    }
    fMaxY += (m_pVT->GetLineLeading(m_pSection->m_SecInfo) + fLineAscent +
              (-fLineDescent));
  }
  m_rcRet = CPVT_FloatRect(0, 0, fMaxX, fMaxY);
}
void CTypeset::OutputLines() {
  ASSERT(m_pVT);
  ASSERT(m_pSection);
  FX_FLOAT fMinX = 0.0f, fMinY = 0.0f, fMaxX = 0.0f, fMaxY = 0.0f;
  FX_FLOAT fPosX = 0.0f, fPosY = 0.0f;
  FX_FLOAT fLineIndent = m_pVT->GetLineIndent(m_pSection->m_SecInfo);
  FX_FLOAT fTypesetWidth = std::max(m_pVT->GetPlateWidth() - fLineIndent, 0.0f);
  switch (m_pVT->GetAlignment(m_pSection->m_SecInfo)) {
    default:
    case 0:
      fMinX = 0.0f;
      break;
    case 1:
      fMinX = (fTypesetWidth - m_rcRet.Width()) * PVT_HALF;
      break;
    case 2:
      fMinX = fTypesetWidth - m_rcRet.Width();
      break;
  }
  fMaxX = fMinX + m_rcRet.Width();
  fMinY = 0.0f;
  fMaxY = m_rcRet.Height();
  int32_t nTotalLines = m_pSection->m_LineArray.GetSize();
  if (nTotalLines > 0) {
    m_pSection->m_SecInfo.nTotalLine = nTotalLines;
    for (int32_t l = 0; l < nTotalLines; l++) {
      if (CLine* pLine = m_pSection->m_LineArray.GetAt(l)) {
        switch (m_pVT->GetAlignment(m_pSection->m_SecInfo)) {
          default:
          case 0:
            fPosX = 0;
            break;
          case 1:
            fPosX = (fTypesetWidth - pLine->m_LineInfo.fLineWidth) * PVT_HALF;
            break;
          case 2:
            fPosX = fTypesetWidth - pLine->m_LineInfo.fLineWidth;
            break;
        }
        fPosX += fLineIndent;
        fPosY += m_pVT->GetLineLeading(m_pSection->m_SecInfo);
        fPosY += pLine->m_LineInfo.fLineAscent;
        pLine->m_LineInfo.fLineX = fPosX - fMinX;
        pLine->m_LineInfo.fLineY = fPosY - fMinY;
        for (int32_t w = pLine->m_LineInfo.nBeginWordIndex;
             w <= pLine->m_LineInfo.nEndWordIndex; w++) {
          if (CPVT_WordInfo* pWord = m_pSection->m_WordArray.GetAt(w)) {
            pWord->fWordX = fPosX - fMinX;
            if (pWord->pWordProps) {
              switch (pWord->pWordProps->nScriptType) {
                default:
                case PVTWORD_SCRIPT_NORMAL:
                  pWord->fWordY = fPosY - fMinY;
                  break;
                case PVTWORD_SCRIPT_SUPER:
                  pWord->fWordY = fPosY - m_pVT->GetWordAscent(*pWord) - fMinY;
                  break;
                case PVTWORD_SCRIPT_SUB:
                  pWord->fWordY = fPosY - m_pVT->GetWordDescent(*pWord) - fMinY;
                  break;
              }
            } else {
              pWord->fWordY = fPosY - fMinY;
            }
            fPosX += m_pVT->GetWordWidth(*pWord);
          }
        }
        fPosY += (-pLine->m_LineInfo.fLineDescent);
      }
    }
  }
  m_rcRet = CPVT_FloatRect(fMinX, fMinY, fMaxX, fMaxY);
}
CPDF_VariableText::CPDF_VariableText()
    : m_nLimitChar(0),
      m_nCharArray(0),
      m_bMultiLine(FALSE),
      m_bLimitWidth(FALSE),
      m_bAutoFontSize(FALSE),
      m_nAlignment(0),
      m_fLineLeading(0.0f),
      m_fCharSpace(0.0f),
      m_nHorzScale(100),
      m_wSubWord(0),
      m_fFontSize(0.0f),
      m_bInitial(FALSE),
      m_bRichText(FALSE),
      m_pVTProvider(NULL),
      m_pVTIterator(NULL) {}
CPDF_VariableText::~CPDF_VariableText() {
  delete m_pVTIterator;
  m_pVTIterator = NULL;
  ResetAll();
}
void CPDF_VariableText::Initialize() {
  if (!m_bInitial) {
    CPVT_SectionInfo secinfo;
    if (m_bRichText) {
      secinfo.pSecProps = new CPVT_SecProps(0.0f, 0.0f, 0);
      secinfo.pWordProps = new CPVT_WordProps(GetDefaultFontIndex(),
                                              PVT_DEFAULT_FONTSIZE, 0, 0, 0);
    }
    CPVT_WordPlace place;
    place.nSecIndex = 0;
    AddSection(place, secinfo);
    CPVT_LineInfo lineinfo;
    lineinfo.fLineAscent = GetFontAscent(GetDefaultFontIndex(), GetFontSize());
    lineinfo.fLineDescent =
        GetFontDescent(GetDefaultFontIndex(), GetFontSize());
    AddLine(place, lineinfo);
    if (CSection* pSection = m_SectionArray.GetAt(0)) {
      pSection->ResetLinePlace();
    }
    m_bInitial = TRUE;
  }
}
void CPDF_VariableText::ResetAll() {
  m_bInitial = FALSE;
  ResetSectionArray();
}
CPVT_WordPlace CPDF_VariableText::InsertWord(const CPVT_WordPlace& place,
                                             uint16_t word,
                                             int32_t charset,
                                             const CPVT_WordProps* pWordProps) {
  int32_t nTotlaWords = GetTotalWords();
  if (m_nLimitChar > 0 && nTotlaWords >= m_nLimitChar) {
    return place;
  }
  if (m_nCharArray > 0 && nTotlaWords >= m_nCharArray) {
    return place;
  }
  CPVT_WordPlace newplace = place;
  newplace.nWordIndex++;
  if (m_bRichText) {
    CPVT_WordProps* pNewProps =
        pWordProps ? new CPVT_WordProps(*pWordProps) : new CPVT_WordProps();
    pNewProps->nFontIndex =
        GetWordFontIndex(word, charset, pWordProps->nFontIndex);
    return AddWord(newplace, CPVT_WordInfo(word, charset, -1, pNewProps));
  }
  int32_t nFontIndex =
      GetSubWord() > 0 ? GetDefaultFontIndex()
                       : GetWordFontIndex(word, charset, GetDefaultFontIndex());
  return AddWord(newplace, CPVT_WordInfo(word, charset, nFontIndex, NULL));
}
CPVT_WordPlace CPDF_VariableText::InsertSection(
    const CPVT_WordPlace& place,
    const CPVT_SecProps* pSecProps,
    const CPVT_WordProps* pWordProps) {
  int32_t nTotlaWords = GetTotalWords();
  if (m_nLimitChar > 0 && nTotlaWords >= m_nLimitChar) {
    return place;
  }
  if (m_nCharArray > 0 && nTotlaWords >= m_nCharArray) {
    return place;
  }
  if (!m_bMultiLine) {
    return place;
  }
  CPVT_WordPlace wordplace = place;
  UpdateWordPlace(wordplace);
  CPVT_WordPlace newplace = place;
  if (CSection* pSection = m_SectionArray.GetAt(wordplace.nSecIndex)) {
    CPVT_WordPlace NewPlace(wordplace.nSecIndex + 1, 0, -1);
    CPVT_SectionInfo secinfo;
    if (m_bRichText) {
      if (pSecProps) {
        secinfo.pSecProps = new CPVT_SecProps(*pSecProps);
      }
      if (pWordProps) {
        secinfo.pWordProps = new CPVT_WordProps(*pWordProps);
      }
    }
    AddSection(NewPlace, secinfo);
    newplace = NewPlace;
    if (CSection* pNewSection = m_SectionArray.GetAt(NewPlace.nSecIndex)) {
      for (int32_t w = wordplace.nWordIndex + 1,
                   sz = pSection->m_WordArray.GetSize();
           w < sz; w++) {
        if (CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(w)) {
          NewPlace.nWordIndex++;
          pNewSection->AddWord(NewPlace, *pWord);
        }
      }
    }
    ClearSectionRightWords(wordplace);
  }
  return newplace;
}
CPVT_WordPlace CPDF_VariableText::InsertText(const CPVT_WordPlace& place,
                                             const FX_WCHAR* text,
                                             int32_t charset,
                                             const CPVT_SecProps* pSecProps,
                                             const CPVT_WordProps* pProps) {
  CFX_WideString swText = text;
  CPVT_WordPlace wp = place;
  for (int32_t i = 0, sz = swText.GetLength(); i < sz; i++) {
    CPVT_WordPlace oldwp = wp;
    uint16_t word = swText.GetAt(i);
    switch (word) {
      case 0x0D:
        if (m_bMultiLine) {
          if (swText.GetAt(i + 1) == 0x0A) {
            i += 1;
          }
          wp = InsertSection(wp, pSecProps, pProps);
        }
        break;
      case 0x0A:
        if (m_bMultiLine) {
          if (swText.GetAt(i + 1) == 0x0D) {
            i += 1;
          }
          wp = InsertSection(wp, pSecProps, pProps);
        }
        break;
      case 0x09:
        word = 0x20;
      default:
        wp = InsertWord(wp, word, charset, pProps);
        break;
    }
    if (wp == oldwp) {
      break;
    }
  }
  return wp;
}
CPVT_WordPlace CPDF_VariableText::DeleteWords(
    const CPVT_WordRange& PlaceRange) {
  FX_BOOL bLastSecPos = FALSE;
  if (CSection* pSection = m_SectionArray.GetAt(PlaceRange.EndPos.nSecIndex)) {
    bLastSecPos = (PlaceRange.EndPos == pSection->GetEndWordPlace());
  }
  ClearWords(PlaceRange);
  if (PlaceRange.BeginPos.nSecIndex != PlaceRange.EndPos.nSecIndex) {
    ClearEmptySections(PlaceRange);
    if (!bLastSecPos) {
      LinkLatterSection(PlaceRange.BeginPos);
    }
  }
  return PlaceRange.BeginPos;
}
CPVT_WordPlace CPDF_VariableText::DeleteWord(const CPVT_WordPlace& place) {
  return ClearRightWord(AdjustLineHeader(place, TRUE));
}
CPVT_WordPlace CPDF_VariableText::BackSpaceWord(const CPVT_WordPlace& place) {
  return ClearLeftWord(AdjustLineHeader(place, TRUE));
}
void CPDF_VariableText::SetText(const FX_WCHAR* text,
                                int32_t charset,
                                const CPVT_SecProps* pSecProps,
                                const CPVT_WordProps* pWordProps) {
  DeleteWords(CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
  CFX_WideString swText = text;
  CPVT_WordPlace wp(0, 0, -1);
  CPVT_SectionInfo secinfo;
  if (m_bRichText) {
    if (pSecProps) {
      secinfo.pSecProps = new CPVT_SecProps(*pSecProps);
    }
    if (pWordProps) {
      secinfo.pWordProps = new CPVT_WordProps(*pWordProps);
    }
  }
  if (CSection* pSection = m_SectionArray.GetAt(0)) {
    pSection->m_SecInfo = secinfo;
  }
  int32_t nCharCount = 0;
  for (int32_t i = 0, sz = swText.GetLength(); i < sz; i++) {
    if (m_nLimitChar > 0 && nCharCount >= m_nLimitChar) {
      break;
    }
    if (m_nCharArray > 0 && nCharCount >= m_nCharArray) {
      break;
    }
    uint16_t word = swText.GetAt(i);
    switch (word) {
      case 0x0D:
        if (m_bMultiLine) {
          if (swText.GetAt(i + 1) == 0x0A) {
            i += 1;
          }
          wp.nSecIndex++;
          wp.nLineIndex = 0;
          wp.nWordIndex = -1;
          AddSection(wp, secinfo);
        }
        break;
      case 0x0A:
        if (m_bMultiLine) {
          if (swText.GetAt(i + 1) == 0x0D) {
            i += 1;
          }
          wp.nSecIndex++;
          wp.nLineIndex = 0;
          wp.nWordIndex = -1;
          AddSection(wp, secinfo);
        }
        break;
      case 0x09:
        word = 0x20;
      default:
        wp = InsertWord(wp, word, charset, pWordProps);
        break;
    }
    nCharCount++;
  }
}
void CPDF_VariableText::UpdateWordPlace(CPVT_WordPlace& place) const {
  if (place.nSecIndex < 0) {
    place = GetBeginWordPlace();
  }
  if (place.nSecIndex >= m_SectionArray.GetSize()) {
    place = GetEndWordPlace();
  }
  place = AdjustLineHeader(place, TRUE);
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    pSection->UpdateWordPlace(place);
  }
}
int32_t CPDF_VariableText::WordPlaceToWordIndex(
    const CPVT_WordPlace& place) const {
  CPVT_WordPlace newplace = place;
  UpdateWordPlace(newplace);
  int32_t nIndex = 0;
  int32_t i = 0;
  int32_t sz = 0;
  for (i = 0, sz = m_SectionArray.GetSize(); i < sz && i < newplace.nSecIndex;
       i++) {
    if (CSection* pSection = m_SectionArray.GetAt(i)) {
      nIndex += pSection->m_WordArray.GetSize();
      if (i != m_SectionArray.GetSize() - 1) {
        nIndex += PVT_RETURN_LENGTH;
      }
    }
  }
  if (i >= 0 && i < m_SectionArray.GetSize()) {
    nIndex += newplace.nWordIndex + PVT_RETURN_LENGTH;
  }
  return nIndex;
}
CPVT_WordPlace CPDF_VariableText::WordIndexToWordPlace(int32_t index) const {
  CPVT_WordPlace place = GetBeginWordPlace();
  int32_t nOldIndex = 0, nIndex = 0;
  FX_BOOL bFind = FALSE;
  for (int32_t i = 0, sz = m_SectionArray.GetSize(); i < sz; i++) {
    if (CSection* pSection = m_SectionArray.GetAt(i)) {
      nIndex += pSection->m_WordArray.GetSize();
      if (nIndex == index) {
        place = pSection->GetEndWordPlace();
        bFind = TRUE;
        break;
      } else if (nIndex > index) {
        place.nSecIndex = i;
        place.nWordIndex = index - nOldIndex - 1;
        pSection->UpdateWordPlace(place);
        bFind = TRUE;
        break;
      }
      if (i != m_SectionArray.GetSize() - 1) {
        nIndex += PVT_RETURN_LENGTH;
      }
      nOldIndex = nIndex;
    }
  }
  if (!bFind) {
    place = GetEndWordPlace();
  }
  return place;
}
CPVT_WordPlace CPDF_VariableText::GetBeginWordPlace() const {
  return m_bInitial ? CPVT_WordPlace(0, 0, -1) : CPVT_WordPlace();
}
CPVT_WordPlace CPDF_VariableText::GetEndWordPlace() const {
  if (CSection* pSection = m_SectionArray.GetAt(m_SectionArray.GetSize() - 1)) {
    return pSection->GetEndWordPlace();
  }
  return CPVT_WordPlace();
}
CPVT_WordPlace CPDF_VariableText::GetPrevWordPlace(
    const CPVT_WordPlace& place) const {
  if (place.nSecIndex < 0) {
    return GetBeginWordPlace();
  }
  if (place.nSecIndex >= m_SectionArray.GetSize()) {
    return GetEndWordPlace();
  }
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    if (place.WordCmp(pSection->GetBeginWordPlace()) <= 0) {
      if (CSection* pPrevSection = m_SectionArray.GetAt(place.nSecIndex - 1)) {
        return pPrevSection->GetEndWordPlace();
      }
      return GetBeginWordPlace();
    }
    return pSection->GetPrevWordPlace(place);
  }
  return place;
}
CPVT_WordPlace CPDF_VariableText::GetNextWordPlace(
    const CPVT_WordPlace& place) const {
  if (place.nSecIndex < 0) {
    return GetBeginWordPlace();
  }
  if (place.nSecIndex >= m_SectionArray.GetSize()) {
    return GetEndWordPlace();
  }
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    if (place.WordCmp(pSection->GetEndWordPlace()) >= 0) {
      if (CSection* pNextSection = m_SectionArray.GetAt(place.nSecIndex + 1)) {
        return pNextSection->GetBeginWordPlace();
      }
      return GetEndWordPlace();
    }
    return pSection->GetNextWordPlace(place);
  }
  return place;
}
CPVT_WordPlace CPDF_VariableText::SearchWordPlace(
    const CFX_FloatPoint& point) const {
  CFX_FloatPoint pt = OutToIn(point);
  CPVT_WordPlace place = GetBeginWordPlace();
  int32_t nLeft = 0;
  int32_t nRight = m_SectionArray.GetSize() - 1;
  int32_t nMid = m_SectionArray.GetSize() / 2;
  FX_BOOL bUp = TRUE;
  FX_BOOL bDown = TRUE;
  while (nLeft <= nRight) {
    if (CSection* pSection = m_SectionArray.GetAt(nMid)) {
      if (IsFloatBigger(pt.y, pSection->m_SecInfo.rcSection.top)) {
        bUp = FALSE;
      }
      if (IsFloatBigger(pSection->m_SecInfo.rcSection.bottom, pt.y)) {
        bDown = FALSE;
      }
      if (IsFloatSmaller(pt.y, pSection->m_SecInfo.rcSection.top)) {
        nRight = nMid - 1;
        nMid = (nLeft + nRight) / 2;
        continue;
      } else if (IsFloatBigger(pt.y, pSection->m_SecInfo.rcSection.bottom)) {
        nLeft = nMid + 1;
        nMid = (nLeft + nRight) / 2;
        continue;
      } else {
        place = pSection->SearchWordPlace(
            CFX_FloatPoint(pt.x - pSection->m_SecInfo.rcSection.left,
                           pt.y - pSection->m_SecInfo.rcSection.top));
        place.nSecIndex = nMid;
        return place;
      }
    } else {
      break;
    }
  }
  if (bUp) {
    place = GetBeginWordPlace();
  }
  if (bDown) {
    place = GetEndWordPlace();
  }
  return place;
}
CPVT_WordPlace CPDF_VariableText::GetUpWordPlace(
    const CPVT_WordPlace& place,
    const CFX_FloatPoint& point) const {
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    CPVT_WordPlace temp = place;
    CFX_FloatPoint pt = OutToIn(point);
    if (temp.nLineIndex-- > 0) {
      return pSection->SearchWordPlace(
          pt.x - pSection->m_SecInfo.rcSection.left, temp);
    }
    if (temp.nSecIndex-- > 0) {
      if (CSection* pLastSection = m_SectionArray.GetAt(temp.nSecIndex)) {
        temp.nLineIndex = pLastSection->m_LineArray.GetSize() - 1;
        return pLastSection->SearchWordPlace(
            pt.x - pLastSection->m_SecInfo.rcSection.left, temp);
      }
    }
  }
  return place;
}
CPVT_WordPlace CPDF_VariableText::GetDownWordPlace(
    const CPVT_WordPlace& place,
    const CFX_FloatPoint& point) const {
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    CPVT_WordPlace temp = place;
    CFX_FloatPoint pt = OutToIn(point);
    if (temp.nLineIndex++ < pSection->m_LineArray.GetSize() - 1) {
      return pSection->SearchWordPlace(
          pt.x - pSection->m_SecInfo.rcSection.left, temp);
    }
    if (temp.nSecIndex++ < m_SectionArray.GetSize() - 1) {
      if (CSection* pNextSection = m_SectionArray.GetAt(temp.nSecIndex)) {
        temp.nLineIndex = 0;
        return pNextSection->SearchWordPlace(
            pt.x - pSection->m_SecInfo.rcSection.left, temp);
      }
    }
  }
  return place;
}
CPVT_WordPlace CPDF_VariableText::GetLineBeginPlace(
    const CPVT_WordPlace& place) const {
  return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, -1);
}
CPVT_WordPlace CPDF_VariableText::GetLineEndPlace(
    const CPVT_WordPlace& place) const {
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    if (CLine* pLine = pSection->m_LineArray.GetAt(place.nLineIndex))
      return pLine->GetEndWordPlace();
  }
  return place;
}
CPVT_WordPlace CPDF_VariableText::GetSectionBeginPlace(
    const CPVT_WordPlace& place) const {
  return CPVT_WordPlace(place.nSecIndex, 0, -1);
}
CPVT_WordPlace CPDF_VariableText::GetSectionEndPlace(
    const CPVT_WordPlace& place) const {
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    return pSection->GetEndWordPlace();
  }
  return place;
}
int32_t CPDF_VariableText::GetTotalWords() const {
  int32_t nTotal = 0;
  for (int32_t i = 0, sz = m_SectionArray.GetSize(); i < sz; i++)
    if (CSection* pSection = m_SectionArray.GetAt(i)) {
      nTotal += (pSection->m_WordArray.GetSize() + PVT_RETURN_LENGTH);
    }
  return nTotal - PVT_RETURN_LENGTH;
}
void CPDF_VariableText::ResetSectionArray() {
  for (int32_t s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) {
    delete m_SectionArray.GetAt(s);
  }
  m_SectionArray.RemoveAll();
}
CPVT_WordPlace CPDF_VariableText::AddSection(const CPVT_WordPlace& place,
                                             const CPVT_SectionInfo& secinfo) {
  if (IsValid() && !m_bMultiLine) {
    return place;
  }
  int32_t nSecIndex =
      std::max(std::min(place.nSecIndex, m_SectionArray.GetSize()), 0);
  CSection* pSection = new CSection(this);
  pSection->m_SecInfo = secinfo;
  pSection->SecPlace.nSecIndex = nSecIndex;
  if (nSecIndex == m_SectionArray.GetSize()) {
    m_SectionArray.Add(pSection);
  } else {
    m_SectionArray.InsertAt(nSecIndex, pSection);
  }
  return place;
}
CPVT_WordPlace CPDF_VariableText::AddLine(const CPVT_WordPlace& place,
                                          const CPVT_LineInfo& lineinfo) {
  if (m_SectionArray.IsEmpty()) {
    return place;
  }
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    return pSection->AddLine(lineinfo);
  }
  return place;
}
CPVT_WordPlace CPDF_VariableText::AddWord(const CPVT_WordPlace& place,
                                          const CPVT_WordInfo& wordinfo) {
  if (m_SectionArray.GetSize() <= 0) {
    return place;
  }
  CPVT_WordPlace newplace = place;
  newplace.nSecIndex =
      std::max(std::min(newplace.nSecIndex, m_SectionArray.GetSize() - 1), 0);
  if (CSection* pSection = m_SectionArray.GetAt(newplace.nSecIndex)) {
    return pSection->AddWord(newplace, wordinfo);
  }
  return place;
}
FX_BOOL CPDF_VariableText::GetWordInfo(const CPVT_WordPlace& place,
                                       CPVT_WordInfo& wordinfo) {
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    if (CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(place.nWordIndex)) {
      wordinfo = *pWord;
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CPDF_VariableText::SetWordInfo(const CPVT_WordPlace& place,
                                       const CPVT_WordInfo& wordinfo) {
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    if (CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(place.nWordIndex)) {
      *pWord = wordinfo;
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CPDF_VariableText::GetLineInfo(const CPVT_WordPlace& place,
                                       CPVT_LineInfo& lineinfo) {
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    if (CLine* pLine = pSection->m_LineArray.GetAt(place.nLineIndex)) {
      lineinfo = pLine->m_LineInfo;
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CPDF_VariableText::GetSectionInfo(const CPVT_WordPlace& place,
                                          CPVT_SectionInfo& secinfo) {
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    secinfo = pSection->m_SecInfo;
    return TRUE;
  }
  return FALSE;
}
CFX_FloatRect CPDF_VariableText::GetContentRect() const {
  return InToOut(CPVT_FloatRect(CPDF_EditContainer::GetContentRect()));
}
FX_FLOAT CPDF_VariableText::GetWordFontSize(const CPVT_WordInfo& WordInfo,
                                            FX_BOOL bFactFontSize) {
  return m_bRichText && WordInfo.pWordProps
             ? (WordInfo.pWordProps->nScriptType == PVTWORD_SCRIPT_NORMAL ||
                        bFactFontSize
                    ? WordInfo.pWordProps->fFontSize
                    : WordInfo.pWordProps->fFontSize * PVT_HALF)
             : GetFontSize();
}
int32_t CPDF_VariableText::GetWordFontIndex(const CPVT_WordInfo& WordInfo) {
  return m_bRichText && WordInfo.pWordProps ? WordInfo.pWordProps->nFontIndex
                                            : WordInfo.nFontIndex;
}
FX_FLOAT CPDF_VariableText::GetWordWidth(int32_t nFontIndex,
                                         uint16_t Word,
                                         uint16_t SubWord,
                                         FX_FLOAT fCharSpace,
                                         int32_t nHorzScale,
                                         FX_FLOAT fFontSize,
                                         FX_FLOAT fWordTail,
                                         int32_t nWordStyle) {
  return (GetCharWidth(nFontIndex, Word, SubWord, nWordStyle) * fFontSize *
              PVT_FONTSCALE +
          fCharSpace) *
             nHorzScale * PVT_PERCENT +
         fWordTail;
}
FX_FLOAT CPDF_VariableText::GetWordWidth(const CPVT_WordInfo& WordInfo) {
  return GetWordWidth(
      GetWordFontIndex(WordInfo), WordInfo.Word, GetSubWord(),
      GetCharSpace(WordInfo), GetHorzScale(WordInfo), GetWordFontSize(WordInfo),
      WordInfo.fWordTail,
      WordInfo.pWordProps ? WordInfo.pWordProps->nWordStyle : 0);
}
FX_FLOAT CPDF_VariableText::GetLineAscent(const CPVT_SectionInfo& SecInfo) {
  return m_bRichText && SecInfo.pWordProps
             ? GetFontAscent(SecInfo.pWordProps->nFontIndex,
                             SecInfo.pWordProps->fFontSize)
             : GetFontAscent(GetDefaultFontIndex(), GetFontSize());
}
FX_FLOAT CPDF_VariableText::GetLineDescent(const CPVT_SectionInfo& SecInfo) {
  return m_bRichText && SecInfo.pWordProps
             ? GetFontDescent(SecInfo.pWordProps->nFontIndex,
                              SecInfo.pWordProps->fFontSize)
             : GetFontDescent(GetDefaultFontIndex(), GetFontSize());
}
FX_FLOAT CPDF_VariableText::GetFontAscent(int32_t nFontIndex,
                                          FX_FLOAT fFontSize) {
  return (FX_FLOAT)GetTypeAscent(nFontIndex) * fFontSize * PVT_FONTSCALE;
}
FX_FLOAT CPDF_VariableText::GetFontDescent(int32_t nFontIndex,
                                           FX_FLOAT fFontSize) {
  return (FX_FLOAT)GetTypeDescent(nFontIndex) * fFontSize * PVT_FONTSCALE;
}
FX_FLOAT CPDF_VariableText::GetWordAscent(const CPVT_WordInfo& WordInfo,
                                          FX_FLOAT fFontSize) {
  return GetFontAscent(GetWordFontIndex(WordInfo), fFontSize);
}
FX_FLOAT CPDF_VariableText::GetWordDescent(const CPVT_WordInfo& WordInfo,
                                           FX_FLOAT fFontSize) {
  return GetFontDescent(GetWordFontIndex(WordInfo), fFontSize);
}
FX_FLOAT CPDF_VariableText::GetWordAscent(const CPVT_WordInfo& WordInfo,
                                          FX_BOOL bFactFontSize) {
  return GetFontAscent(GetWordFontIndex(WordInfo),
                       GetWordFontSize(WordInfo, bFactFontSize));
}
FX_FLOAT CPDF_VariableText::GetWordDescent(const CPVT_WordInfo& WordInfo,
                                           FX_BOOL bFactFontSize) {
  return GetFontDescent(GetWordFontIndex(WordInfo),
                        GetWordFontSize(WordInfo, bFactFontSize));
}
FX_FLOAT CPDF_VariableText::GetLineLeading(const CPVT_SectionInfo& SecInfo) {
  return m_bRichText && SecInfo.pSecProps ? SecInfo.pSecProps->fLineLeading
                                          : m_fLineLeading;
}
FX_FLOAT CPDF_VariableText::GetLineIndent(const CPVT_SectionInfo& SecInfo) {
  return m_bRichText && SecInfo.pSecProps ? SecInfo.pSecProps->fLineIndent
                                          : 0.0f;
}
int32_t CPDF_VariableText::GetAlignment(const CPVT_SectionInfo& SecInfo) {
  return m_bRichText && SecInfo.pSecProps ? SecInfo.pSecProps->nAlignment
                                          : m_nAlignment;
}
FX_FLOAT CPDF_VariableText::GetCharSpace(const CPVT_WordInfo& WordInfo) {
  return m_bRichText && WordInfo.pWordProps ? WordInfo.pWordProps->fCharSpace
                                            : m_fCharSpace;
}
int32_t CPDF_VariableText::GetHorzScale(const CPVT_WordInfo& WordInfo) {
  return m_bRichText && WordInfo.pWordProps ? WordInfo.pWordProps->nHorzScale
                                            : m_nHorzScale;
}
void CPDF_VariableText::ClearSectionRightWords(const CPVT_WordPlace& place) {
  CPVT_WordPlace wordplace = AdjustLineHeader(place, TRUE);
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    for (int32_t w = pSection->m_WordArray.GetSize() - 1;
         w > wordplace.nWordIndex; w--) {
      delete pSection->m_WordArray.GetAt(w);
      pSection->m_WordArray.RemoveAt(w);
    }
  }
}
CPVT_WordPlace CPDF_VariableText::AdjustLineHeader(const CPVT_WordPlace& place,
                                                   FX_BOOL bPrevOrNext) const {
  if (place.nWordIndex < 0 && place.nLineIndex > 0) {
    return bPrevOrNext ? GetPrevWordPlace(place) : GetNextWordPlace(place);
  }
  return place;
}
FX_BOOL CPDF_VariableText::ClearEmptySection(const CPVT_WordPlace& place) {
  if (place.nSecIndex == 0 && m_SectionArray.GetSize() == 1) {
    return FALSE;
  }
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    if (pSection->m_WordArray.GetSize() == 0) {
      delete pSection;
      m_SectionArray.RemoveAt(place.nSecIndex);
      return TRUE;
    }
  }
  return FALSE;
}
void CPDF_VariableText::ClearEmptySections(const CPVT_WordRange& PlaceRange) {
  CPVT_WordPlace wordplace;
  for (int32_t s = PlaceRange.EndPos.nSecIndex;
       s > PlaceRange.BeginPos.nSecIndex; s--) {
    wordplace.nSecIndex = s;
    ClearEmptySection(wordplace);
  }
}
void CPDF_VariableText::LinkLatterSection(const CPVT_WordPlace& place) {
  CPVT_WordPlace oldplace = AdjustLineHeader(place, TRUE);
  if (CSection* pNextSection = m_SectionArray.GetAt(place.nSecIndex + 1)) {
    if (CSection* pSection = m_SectionArray.GetAt(oldplace.nSecIndex)) {
      for (int32_t w = 0, sz = pNextSection->m_WordArray.GetSize(); w < sz;
           w++) {
        if (CPVT_WordInfo* pWord = pNextSection->m_WordArray.GetAt(w)) {
          oldplace.nWordIndex++;
          pSection->AddWord(oldplace, *pWord);
        }
      }
    }
    delete pNextSection;
    m_SectionArray.RemoveAt(place.nSecIndex + 1);
  }
}
void CPDF_VariableText::ClearWords(const CPVT_WordRange& PlaceRange) {
  CPVT_WordRange NewRange;
  NewRange.BeginPos = AdjustLineHeader(PlaceRange.BeginPos, TRUE);
  NewRange.EndPos = AdjustLineHeader(PlaceRange.EndPos, TRUE);
  for (int32_t s = NewRange.EndPos.nSecIndex; s >= NewRange.BeginPos.nSecIndex;
       s--) {
    if (CSection* pSection = m_SectionArray.GetAt(s)) {
      pSection->ClearWords(NewRange);
    }
  }
}
CPVT_WordPlace CPDF_VariableText::ClearLeftWord(const CPVT_WordPlace& place) {
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    CPVT_WordPlace leftplace = GetPrevWordPlace(place);
    if (leftplace != place) {
      if (leftplace.nSecIndex != place.nSecIndex) {
        if (pSection->m_WordArray.GetSize() == 0) {
          ClearEmptySection(place);
        } else {
          LinkLatterSection(leftplace);
        }
      } else {
        pSection->ClearWord(place);
      }
    }
    return leftplace;
  }
  return place;
}
CPVT_WordPlace CPDF_VariableText::ClearRightWord(const CPVT_WordPlace& place) {
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    CPVT_WordPlace rightplace =
        AdjustLineHeader(GetNextWordPlace(place), FALSE);
    if (rightplace != place) {
      if (rightplace.nSecIndex != place.nSecIndex) {
        LinkLatterSection(place);
      } else {
        pSection->ClearWord(rightplace);
      }
    }
  }
  return place;
}
void CPDF_VariableText::RearrangeAll() {
  Rearrange(CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
}
void CPDF_VariableText::RearrangePart(const CPVT_WordRange& PlaceRange) {
  Rearrange(PlaceRange);
}
CPVT_FloatRect CPDF_VariableText::Rearrange(const CPVT_WordRange& PlaceRange) {
  CPVT_FloatRect rcRet;
  if (IsValid()) {
    if (m_bAutoFontSize) {
      SetFontSize(GetAutoFontSize());
      rcRet = RearrangeSections(
          CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
    } else {
      rcRet = RearrangeSections(PlaceRange);
    }
  }
  SetContentRect(rcRet);
  return rcRet;
}
FX_FLOAT CPDF_VariableText::GetAutoFontSize() {
  int32_t nTotal = sizeof(gFontSizeSteps) / sizeof(uint8_t);
  if (IsMultiLine()) {
    nTotal /= 4;
  }
  if (nTotal <= 0) {
    return 0;
  }
  if (GetPlateWidth() <= 0) {
    return 0;
  }
  int32_t nLeft = 0;
  int32_t nRight = nTotal - 1;
  int32_t nMid = nTotal / 2;
  while (nLeft <= nRight) {
    if (IsBigger(gFontSizeSteps[nMid])) {
      nRight = nMid - 1;
      nMid = (nLeft + nRight) / 2;
      continue;
    } else {
      nLeft = nMid + 1;
      nMid = (nLeft + nRight) / 2;
      continue;
    }
  }
  return (FX_FLOAT)gFontSizeSteps[nMid];
}
FX_BOOL CPDF_VariableText::IsBigger(FX_FLOAT fFontSize) {
  FX_BOOL bBigger = FALSE;
  CPVT_Size szTotal;
  for (int32_t s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) {
    if (CSection* pSection = m_SectionArray.GetAt(s)) {
      CPVT_Size size = pSection->GetSectionSize(fFontSize);
      szTotal.x = std::max(size.x, szTotal.x);
      szTotal.y += size.y;
      if (IsFloatBigger(szTotal.x, GetPlateWidth()) ||
          IsFloatBigger(szTotal.y, GetPlateHeight())) {
        bBigger = TRUE;
        break;
      }
    }
  }
  return bBigger;
}
CPVT_FloatRect CPDF_VariableText::RearrangeSections(
    const CPVT_WordRange& PlaceRange) {
  CPVT_WordPlace place;
  FX_FLOAT fPosY = 0;
  FX_FLOAT fOldHeight;
  int32_t nSSecIndex = PlaceRange.BeginPos.nSecIndex;
  int32_t nESecIndex = PlaceRange.EndPos.nSecIndex;
  CPVT_FloatRect rcRet;
  for (int32_t s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) {
    place.nSecIndex = s;
    if (CSection* pSection = m_SectionArray.GetAt(s)) {
      pSection->SecPlace = place;
      CPVT_FloatRect rcSec = pSection->m_SecInfo.rcSection;
      if (s >= nSSecIndex) {
        if (s <= nESecIndex) {
          rcSec = pSection->Rearrange();
          rcSec.top += fPosY;
          rcSec.bottom += fPosY;
        } else {
          fOldHeight = pSection->m_SecInfo.rcSection.bottom -
                       pSection->m_SecInfo.rcSection.top;
          rcSec.top = fPosY;
          rcSec.bottom = fPosY + fOldHeight;
        }
        pSection->m_SecInfo.rcSection = rcSec;
        pSection->ResetLinePlace();
      }
      if (s == 0) {
        rcRet = rcSec;
      } else {
        rcRet.left = std::min(rcSec.left, rcRet.left);
        rcRet.top = std::min(rcSec.top, rcRet.top);
        rcRet.right = std::max(rcSec.right, rcRet.right);
        rcRet.bottom = std::max(rcSec.bottom, rcRet.bottom);
      }
      fPosY += rcSec.Height();
    }
  }
  return rcRet;
}
int32_t CPDF_VariableText::GetCharWidth(int32_t nFontIndex,
                                        uint16_t Word,
                                        uint16_t SubWord,
                                        int32_t nWordStyle) {
  if (!m_pVTProvider) {
    return 0;
  }
  if (SubWord > 0) {
    return m_pVTProvider->GetCharWidth(nFontIndex, SubWord, nWordStyle);
  }
  return m_pVTProvider->GetCharWidth(nFontIndex, Word, nWordStyle);
}
int32_t CPDF_VariableText::GetTypeAscent(int32_t nFontIndex) {
  return m_pVTProvider ? m_pVTProvider->GetTypeAscent(nFontIndex) : 0;
}
int32_t CPDF_VariableText::GetTypeDescent(int32_t nFontIndex) {
  return m_pVTProvider ? m_pVTProvider->GetTypeDescent(nFontIndex) : 0;
}
int32_t CPDF_VariableText::GetWordFontIndex(uint16_t word,
                                            int32_t charset,
                                            int32_t nFontIndex) {
  return m_pVTProvider
             ? m_pVTProvider->GetWordFontIndex(word, charset, nFontIndex)
             : -1;
}
int32_t CPDF_VariableText::GetDefaultFontIndex() {
  return m_pVTProvider ? m_pVTProvider->GetDefaultFontIndex() : -1;
}
FX_BOOL CPDF_VariableText::IsLatinWord(uint16_t word) {
  return m_pVTProvider ? m_pVTProvider->IsLatinWord(word) : FALSE;
}
IPDF_VariableText_Iterator* CPDF_VariableText::GetIterator() {
  if (!m_pVTIterator) {
    m_pVTIterator = new CPDF_VariableText_Iterator(this);
  }
  return m_pVTIterator;
}
IPDF_VariableText_Provider* CPDF_VariableText::SetProvider(
    IPDF_VariableText_Provider* pProvider) {
  IPDF_VariableText_Provider* pOld = m_pVTProvider;
  m_pVTProvider = pProvider;
  return pOld;
}
CPDF_VariableText_Iterator::CPDF_VariableText_Iterator(CPDF_VariableText* pVT)
    : m_CurPos(-1, -1, -1), m_pVT(pVT) {}
CPDF_VariableText_Iterator::~CPDF_VariableText_Iterator() {}
void CPDF_VariableText_Iterator::SetAt(int32_t nWordIndex) {
  m_CurPos = m_pVT->WordIndexToWordPlace(nWordIndex);
}
void CPDF_VariableText_Iterator::SetAt(const CPVT_WordPlace& place) {
  ASSERT(m_pVT);
  m_CurPos = place;
}
FX_BOOL CPDF_VariableText_Iterator::NextWord() {
  if (m_CurPos == m_pVT->GetEndWordPlace()) {
    return FALSE;
  }
  m_CurPos = m_pVT->GetNextWordPlace(m_CurPos);
  return TRUE;
}
FX_BOOL CPDF_VariableText_Iterator::PrevWord() {
  if (m_CurPos == m_pVT->GetBeginWordPlace()) {
    return FALSE;
  }
  m_CurPos = m_pVT->GetPrevWordPlace(m_CurPos);
  return TRUE;
}
FX_BOOL CPDF_VariableText_Iterator::NextLine() {
  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
    if (m_CurPos.nLineIndex < pSection->m_LineArray.GetSize() - 1) {
      m_CurPos =
          CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex + 1, -1);
      return TRUE;
    }
    if (m_CurPos.nSecIndex < m_pVT->m_SectionArray.GetSize() - 1) {
      m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex + 1, 0, -1);
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CPDF_VariableText_Iterator::PrevLine() {
  if (m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
    if (m_CurPos.nLineIndex > 0) {
      m_CurPos =
          CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex - 1, -1);
      return TRUE;
    }
    if (m_CurPos.nSecIndex > 0) {
      if (CSection* pLastSection =
              m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex - 1)) {
        m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex - 1,
                                  pLastSection->m_LineArray.GetSize() - 1, -1);
        return TRUE;
      }
    }
  }
  return FALSE;
}
FX_BOOL CPDF_VariableText_Iterator::NextSection() {
  if (m_CurPos.nSecIndex < m_pVT->m_SectionArray.GetSize() - 1) {
    m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex + 1, 0, -1);
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CPDF_VariableText_Iterator::PrevSection() {
  ASSERT(m_pVT);
  if (m_CurPos.nSecIndex > 0) {
    m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex - 1, 0, -1);
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CPDF_VariableText_Iterator::GetWord(CPVT_Word& word) const {
  word.WordPlace = m_CurPos;
  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
    if (pSection->m_LineArray.GetAt(m_CurPos.nLineIndex)) {
      if (CPVT_WordInfo* pWord =
              pSection->m_WordArray.GetAt(m_CurPos.nWordIndex)) {
        word.Word = pWord->Word;
        word.nCharset = pWord->nCharset;
        word.fWidth = m_pVT->GetWordWidth(*pWord);
        word.ptWord = m_pVT->InToOut(
            CFX_FloatPoint(pWord->fWordX + pSection->m_SecInfo.rcSection.left,
                           pWord->fWordY + pSection->m_SecInfo.rcSection.top));
        word.fAscent = m_pVT->GetWordAscent(*pWord);
        word.fDescent = m_pVT->GetWordDescent(*pWord);
        if (pWord->pWordProps) {
          word.WordProps = *pWord->pWordProps;
        }
        word.nFontIndex = m_pVT->GetWordFontIndex(*pWord);
        word.fFontSize = m_pVT->GetWordFontSize(*pWord);
        return TRUE;
      }
    }
  }
  return FALSE;
}
FX_BOOL CPDF_VariableText_Iterator::SetWord(const CPVT_Word& word) {
  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
    if (CPVT_WordInfo* pWord =
            pSection->m_WordArray.GetAt(m_CurPos.nWordIndex)) {
      if (pWord->pWordProps) {
        *pWord->pWordProps = word.WordProps;
      }
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CPDF_VariableText_Iterator::GetLine(CPVT_Line& line) const {
  ASSERT(m_pVT);
  line.lineplace = CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex, -1);
  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
    if (CLine* pLine = pSection->m_LineArray.GetAt(m_CurPos.nLineIndex)) {
      line.ptLine = m_pVT->InToOut(CFX_FloatPoint(
          pLine->m_LineInfo.fLineX + pSection->m_SecInfo.rcSection.left,
          pLine->m_LineInfo.fLineY + pSection->m_SecInfo.rcSection.top));
      line.fLineWidth = pLine->m_LineInfo.fLineWidth;
      line.fLineAscent = pLine->m_LineInfo.fLineAscent;
      line.fLineDescent = pLine->m_LineInfo.fLineDescent;
      line.lineEnd = pLine->GetEndWordPlace();
      return TRUE;
    }
  }
  return FALSE;
}
FX_BOOL CPDF_VariableText_Iterator::GetSection(CPVT_Section& section) const {
  section.secplace = CPVT_WordPlace(m_CurPos.nSecIndex, 0, -1);
  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
    section.rcSection = m_pVT->InToOut(pSection->m_SecInfo.rcSection);
    if (pSection->m_SecInfo.pSecProps) {
      section.SecProps = *pSection->m_SecInfo.pSecProps;
    }
    if (pSection->m_SecInfo.pWordProps) {
      section.WordProps = *pSection->m_SecInfo.pWordProps;
    }
    return TRUE;
  }
  return FALSE;
}
FX_BOOL CPDF_VariableText_Iterator::SetSection(const CPVT_Section& section) {
  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
    if (pSection->m_SecInfo.pSecProps) {
      *pSection->m_SecInfo.pSecProps = section.SecProps;
    }
    if (pSection->m_SecInfo.pWordProps) {
      *pSection->m_SecInfo.pWordProps = section.WordProps;
    }
    return TRUE;
  }
  return FALSE;
}
