// 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/include/fpdfdoc/fpdf_doc.h"
#include "core/include/fpdfdoc/fpdf_vt.h"
#include "pdf_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 CPDF_Point& 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 int special_chars[128] = {
    0x0000, 0x000C, 0x0008, 0x000C, 0x0008, 0x0000, 0x0020, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0000,
    0x0010, 0x0000, 0x0000, 0x0028, 0x000C, 0x0008, 0x0000, 0x0000, 0x0028,
    0x0028, 0x0028, 0x0028, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
    0x0002, 0x0002, 0x0002, 0x0002, 0x0008, 0x0008, 0x0000, 0x0000, 0x0000,
    0x0008, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
    0x0001, 0x000C, 0x0000, 0x0008, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001,
    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x000C, 0x0000, 0x0008,
    0x0000, 0x0000,
};
static FX_BOOL IsLatin(FX_WORD word) {
  if (word <= 0x007F) {
    if (special_chars[word] & 0x0001) {
      return TRUE;
    }
  }
  if ((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)) {
    return TRUE;
  }
  return FALSE;
}
static FX_BOOL IsDigit(FX_DWORD word) {
  return word >= 0x0030 && word <= 0x0039;
}
static FX_BOOL IsCJK(FX_DWORD 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) {
    if (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 TRUE;
    }
    return FALSE;
  }
  if (word >= 0xFF66 && word <= 0xFF9D) {
    return TRUE;
  }
  return FALSE;
}
static FX_BOOL IsPunctuation(FX_DWORD word) {
  if (word <= 0x007F) {
    if ((special_chars[word] >> 3) & 1) {
      return TRUE;
    }
  } else if (word >= 0x0080 && word <= 0x00FF) {
    if (word == 0x0082 || word == 0x0084 || word == 0x0085 || word == 0x0091 ||
        word == 0x0092 || word == 0x0093 || word <= 0x0094 || word == 0x0096 ||
        word == 0x00B4 || word == 0x00B8) {
      return TRUE;
    }
  } else if (word >= 0x2000 && word <= 0x206F) {
    if (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) {
      return TRUE;
    }
  } else if (word >= 0x3000 && word <= 0x303F) {
    if (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) {
      return TRUE;
    }
  } else if (word >= 0xFE50 && word <= 0xFE6F) {
    if ((word >= 0xFE50 && word <= 0xFE5E) || word == 0xFE63) {
      return TRUE;
    }
  } else if (word >= 0xFF00 && word <= 0xFFEF) {
    if (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 TRUE;
    }
  }
  return FALSE;
}
static FX_BOOL IsConnectiveSymbol(FX_DWORD word) {
  if (word <= 0x007F) {
    if ((special_chars[word] >> 5) & 1) {
      return TRUE;
    }
  }
  return FALSE;
}
static FX_BOOL IsOpenStylePunctuation(FX_DWORD word) {
  if (word <= 0x007F) {
    if ((special_chars[word] >> 2) & 1) {
      return TRUE;
    }
  } else if (word == 0x300A || word == 0x300C || word == 0x300E ||
             word == 0x3010 || word == 0x3014 || word == 0x3016 ||
             word == 0x3018 || word == 0x301A || word == 0xFF08 ||
             word == 0xFF3B || word == 0xFF5B || word == 0xFF62) {
    return TRUE;
  }
  return FALSE;
}
static FX_BOOL IsCurrencySymbol(FX_WORD word) {
  if (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) {
    return TRUE;
  }
  return FALSE;
}
static FX_BOOL IsPrefixSymbol(FX_WORD word) {
  if (IsCurrencySymbol(word)) {
    return TRUE;
  }
  if (word == 0x2116) {
    return TRUE;
  }
  return FALSE;
}
static FX_BOOL IsSpace(FX_WORD word) {
  return word == 0x0020 || word == 0x3000;
}
static FX_BOOL NeedDivision(FX_WORD prevWord, FX_WORD 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,
                                             FX_WORD 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;
    FX_WORD 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;
    }
    FX_WORD 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 CPDF_Point& point) const {
  CPDF_Point 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(
            CPDF_Point(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 CPDF_Point& point) const {
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    CPVT_WordPlace temp = place;
    CPDF_Point 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 CPDF_Point& point) const {
  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
    CPVT_WordPlace temp = place;
    CPDF_Point 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;
}
CPDF_Rect 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,
                                         FX_WORD Word,
                                         FX_WORD 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,
                                        FX_WORD Word,
                                        FX_WORD 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(FX_WORD 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(FX_WORD 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(
            CPDF_Point(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(CPDF_Point(
          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;
}
