// Copyright 2016 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 "core/fpdfdoc/cpdf_variabletext.h"

#include <algorithm>
#include <utility>

#include "core/fpdfapi/font/cpdf_font.h"
#include "core/fpdfdoc/cline.h"
#include "core/fpdfdoc/cpvt_word.h"
#include "core/fpdfdoc/cpvt_wordinfo.h"
#include "core/fpdfdoc/csection.h"
#include "core/fpdfdoc/ipvt_fontmap.h"
#include "core/fxcrt/fx_codepage.h"
#include "third_party/base/compiler_specific.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"

namespace {

const float kFontScale = 0.001f;
const uint8_t kReturnLength = 1;
const float kScalePercent = 0.01f;

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

}  // namespace

CPDF_VariableText::Provider::Provider(IPVT_FontMap* pFontMap)
    : m_pFontMap(pFontMap) {
  ASSERT(m_pFontMap);
}

CPDF_VariableText::Provider::~Provider() {}

uint32_t CPDF_VariableText::Provider::GetCharWidth(int32_t nFontIndex,
                                                   uint16_t word) {
  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
    uint32_t charcode = pPDFFont->CharCodeFromUnicode(word);
    if (charcode != CPDF_Font::kInvalidCharCode)
      return pPDFFont->GetCharWidthF(charcode);
  }
  return 0;
}

int32_t CPDF_VariableText::Provider::GetTypeAscent(int32_t nFontIndex) {
  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
    return pPDFFont->GetTypeAscent();
  return 0;
}

int32_t CPDF_VariableText::Provider::GetTypeDescent(int32_t nFontIndex) {
  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
    return pPDFFont->GetTypeDescent();
  return 0;
}

int32_t CPDF_VariableText::Provider::GetWordFontIndex(uint16_t word,
                                                      int32_t charset,
                                                      int32_t nFontIndex) {
  if (CPDF_Font* pDefFont = m_pFontMap->GetPDFFont(0)) {
    if (pDefFont->CharCodeFromUnicode(word) != CPDF_Font::kInvalidCharCode)
      return 0;
  }
  if (CPDF_Font* pSysFont = m_pFontMap->GetPDFFont(1)) {
    if (pSysFont->CharCodeFromUnicode(word) != CPDF_Font::kInvalidCharCode)
      return 1;
  }
  return -1;
}

bool CPDF_VariableText::Provider::IsLatinWord(uint16_t word) {
  return (word >= 0x61 && word <= 0x7A) || (word >= 0x41 && word <= 0x5A) ||
         word == 0x2D || word == 0x27;
}

int32_t CPDF_VariableText::Provider::GetDefaultFontIndex() {
  return 0;
}

CPDF_VariableText::Iterator::Iterator(CPDF_VariableText* pVT)
    : m_CurPos(-1, -1, -1), m_pVT(pVT) {}

CPDF_VariableText::Iterator::~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;
}

bool CPDF_VariableText::Iterator::NextWord() {
  if (m_CurPos == m_pVT->GetEndWordPlace())
    return false;

  m_CurPos = m_pVT->GetNextWordPlace(m_CurPos);
  return true;
}

bool CPDF_VariableText::Iterator::PrevWord() {
  if (m_CurPos == m_pVT->GetBeginWordPlace())
    return false;

  m_CurPos = m_pVT->GetPrevWordPlace(m_CurPos);
  return true;
}

bool CPDF_VariableText::Iterator::NextLine() {
  if (!pdfium::IndexInBounds(m_pVT->m_SectionArray, m_CurPos.nSecIndex))
    return false;

  CSection* pSection = m_pVT->m_SectionArray[m_CurPos.nSecIndex].get();
  if (m_CurPos.nLineIndex <
      pdfium::CollectionSize<int32_t>(pSection->m_LineArray) - 1) {
    m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex + 1, -1);
    return true;
  }
  if (m_CurPos.nSecIndex <
      pdfium::CollectionSize<int32_t>(m_pVT->m_SectionArray) - 1) {
    m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex + 1, 0, -1);
    return true;
  }
  return false;
}

bool CPDF_VariableText::Iterator::GetWord(CPVT_Word& word) const {
  word.WordPlace = m_CurPos;
  if (!pdfium::IndexInBounds(m_pVT->m_SectionArray, m_CurPos.nSecIndex))
    return false;

  CSection* pSection = m_pVT->m_SectionArray[m_CurPos.nSecIndex].get();
  if (!pdfium::IndexInBounds(pSection->m_LineArray, m_CurPos.nLineIndex) ||
      !pdfium::IndexInBounds(pSection->m_WordArray, m_CurPos.nWordIndex)) {
    return false;
  }

  CPVT_WordInfo* pWord = pSection->m_WordArray[m_CurPos.nWordIndex].get();
  word.Word = pWord->Word;
  word.nCharset = pWord->nCharset;
  word.fWidth = m_pVT->GetWordWidth(*pWord);
  word.ptWord =
      m_pVT->InToOut(CFX_PointF(pWord->fWordX + pSection->m_Rect.left,
                                pWord->fWordY + pSection->m_Rect.top));
  word.fAscent = m_pVT->GetWordAscent(*pWord);
  word.fDescent = m_pVT->GetWordDescent(*pWord);
  word.nFontIndex = m_pVT->GetWordFontIndex(*pWord);
  word.fFontSize = m_pVT->GetWordFontSize();
  return true;
}

bool CPDF_VariableText::Iterator::GetLine(CPVT_Line& line) const {
  ASSERT(m_pVT);
  line.lineplace = CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex, -1);
  if (!pdfium::IndexInBounds(m_pVT->m_SectionArray, m_CurPos.nSecIndex))
    return false;

  CSection* pSection = m_pVT->m_SectionArray[m_CurPos.nSecIndex].get();
  if (!pdfium::IndexInBounds(pSection->m_LineArray, m_CurPos.nLineIndex))
    return false;

  CLine* pLine = pSection->m_LineArray[m_CurPos.nLineIndex].get();
  line.ptLine = m_pVT->InToOut(
      CFX_PointF(pLine->m_LineInfo.fLineX + pSection->m_Rect.left,
                 pLine->m_LineInfo.fLineY + pSection->m_Rect.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;
}

CPDF_VariableText::CPDF_VariableText() = default;

CPDF_VariableText::~CPDF_VariableText() = default;

void CPDF_VariableText::Initialize() {
  if (m_bInitialized)
    return;

  CPVT_WordPlace place;
  place.nSecIndex = 0;
  AddSection(place);

  CPVT_LineInfo lineinfo;
  lineinfo.fLineAscent = GetFontAscent(GetDefaultFontIndex(), GetFontSize());
  lineinfo.fLineDescent = GetFontDescent(GetDefaultFontIndex(), GetFontSize());
  AddLine(place, lineinfo);

  if (!m_SectionArray.empty())
    m_SectionArray.front()->ResetLinePlace();

  m_bInitialized = true;
}

CPVT_WordPlace CPDF_VariableText::InsertWord(const CPVT_WordPlace& place,
                                             uint16_t word,
                                             int32_t charset) {
  int32_t nTotalWords = GetTotalWords();
  if (m_nLimitChar > 0 && nTotalWords >= m_nLimitChar)
    return place;
  if (m_nCharArray > 0 && nTotalWords >= m_nCharArray)
    return place;

  CPVT_WordPlace newplace = place;
  newplace.nWordIndex++;
  int32_t nFontIndex =
      GetSubWord() > 0 ? GetDefaultFontIndex()
                       : GetWordFontIndex(word, charset, GetDefaultFontIndex());
  return AddWord(newplace, CPVT_WordInfo(word, charset, nFontIndex));
}

CPVT_WordPlace CPDF_VariableText::InsertSection(const CPVT_WordPlace& place) {
  int32_t nTotalWords = GetTotalWords();
  if (m_nLimitChar > 0 && nTotalWords >= m_nLimitChar)
    return place;
  if (m_nCharArray > 0 && nTotalWords >= m_nCharArray)
    return place;
  if (!m_bMultiLine)
    return place;

  CPVT_WordPlace wordplace = place;
  UpdateWordPlace(wordplace);
  if (!pdfium::IndexInBounds(m_SectionArray, wordplace.nSecIndex))
    return place;

  CSection* pSection = m_SectionArray[wordplace.nSecIndex].get();
  CPVT_WordPlace NewPlace(wordplace.nSecIndex + 1, 0, -1);
  AddSection(NewPlace);
  CPVT_WordPlace result = NewPlace;
  if (pdfium::IndexInBounds(m_SectionArray, NewPlace.nSecIndex)) {
    CSection* pNewSection = m_SectionArray[NewPlace.nSecIndex].get();
    for (int32_t w = wordplace.nWordIndex + 1;
         w < pdfium::CollectionSize<int32_t>(pSection->m_WordArray); ++w) {
      NewPlace.nWordIndex++;
      pNewSection->AddWord(NewPlace, *pSection->m_WordArray[w]);
    }
  }
  ClearSectionRightWords(wordplace);
  return result;
}

CPVT_WordPlace CPDF_VariableText::DeleteWords(
    const CPVT_WordRange& PlaceRange) {
  bool bLastSecPos =
      pdfium::IndexInBounds(m_SectionArray, PlaceRange.EndPos.nSecIndex) &&
      PlaceRange.EndPos ==
          m_SectionArray[PlaceRange.EndPos.nSecIndex]->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 WideString& swText) {
  DeleteWords(CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
  CPVT_WordPlace wp(0, 0, -1);
  if (!m_SectionArray.empty())
    m_SectionArray.front()->m_Rect = CPVT_FloatRect();

  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[i];
    switch (word) {
      case 0x0D:
        if (m_bMultiLine) {
          if (i + 1 < sz && swText[i + 1] == 0x0A)
            i++;
          wp.AdvanceSection();
          AddSection(wp);
        }
        break;
      case 0x0A:
        if (m_bMultiLine) {
          if (i + 1 < sz && swText[i + 1] == 0x0D)
            i++;
          wp.AdvanceSection();
          AddSection(wp);
        }
        break;
      case 0x09:
        word = 0x20;
        FALLTHROUGH;
      default:
        wp = InsertWord(wp, word, FX_CHARSET_Default);
        break;
    }
    nCharCount++;
  }
}

void CPDF_VariableText::UpdateWordPlace(CPVT_WordPlace& place) const {
  if (place.nSecIndex < 0)
    place = GetBeginWordPlace();
  if (place.nSecIndex >= pdfium::CollectionSize<int32_t>(m_SectionArray))
    place = GetEndWordPlace();

  place = AdjustLineHeader(place, true);
  if (pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
    m_SectionArray[place.nSecIndex]->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 = pdfium::CollectionSize<int32_t>(m_SectionArray);
       i < sz && i < newplace.nSecIndex; i++) {
    CSection* pSection = m_SectionArray[i].get();
    nIndex += pdfium::CollectionSize<int32_t>(pSection->m_WordArray);
    if (i != sz - 1)
      nIndex += kReturnLength;
  }
  if (pdfium::IndexInBounds(m_SectionArray, i))
    nIndex += newplace.nWordIndex + kReturnLength;
  return nIndex;
}

CPVT_WordPlace CPDF_VariableText::WordIndexToWordPlace(int32_t index) const {
  CPVT_WordPlace place = GetBeginWordPlace();
  int32_t nOldIndex = 0;
  int32_t nIndex = 0;
  bool bFound = false;
  for (int32_t i = 0, sz = pdfium::CollectionSize<int32_t>(m_SectionArray);
       i < sz; i++) {
    CSection* pSection = m_SectionArray[i].get();
    nIndex += pdfium::CollectionSize<int32_t>(pSection->m_WordArray);
    if (nIndex == index) {
      place = pSection->GetEndWordPlace();
      bFound = true;
      break;
    }
    if (nIndex > index) {
      place.nSecIndex = i;
      place.nWordIndex = index - nOldIndex - 1;
      pSection->UpdateWordPlace(place);
      bFound = true;
      break;
    }
    if (i != sz - 1)
      nIndex += kReturnLength;
    nOldIndex = nIndex;
  }
  if (!bFound)
    place = GetEndWordPlace();
  return place;
}

CPVT_WordPlace CPDF_VariableText::GetBeginWordPlace() const {
  return m_bInitialized ? CPVT_WordPlace(0, 0, -1) : CPVT_WordPlace();
}

CPVT_WordPlace CPDF_VariableText::GetEndWordPlace() const {
  if (m_SectionArray.empty())
    return CPVT_WordPlace();
  return m_SectionArray.back()->GetEndWordPlace();
}

CPVT_WordPlace CPDF_VariableText::GetPrevWordPlace(
    const CPVT_WordPlace& place) const {
  if (place.nSecIndex < 0)
    return GetBeginWordPlace();
  if (place.nSecIndex >= pdfium::CollectionSize<int32_t>(m_SectionArray))
    return GetEndWordPlace();

  CSection* pSection = m_SectionArray[place.nSecIndex].get();
  if (place > pSection->GetBeginWordPlace())
    return pSection->GetPrevWordPlace(place);
  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex - 1))
    return GetBeginWordPlace();
  return m_SectionArray[place.nSecIndex - 1]->GetEndWordPlace();
}

CPVT_WordPlace CPDF_VariableText::GetNextWordPlace(
    const CPVT_WordPlace& place) const {
  if (place.nSecIndex < 0)
    return GetBeginWordPlace();
  if (place.nSecIndex >= pdfium::CollectionSize<int32_t>(m_SectionArray))
    return GetEndWordPlace();

  CSection* pSection = m_SectionArray[place.nSecIndex].get();
  if (place < pSection->GetEndWordPlace())
    return pSection->GetNextWordPlace(place);
  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex + 1))
    return GetEndWordPlace();
  return m_SectionArray[place.nSecIndex + 1]->GetBeginWordPlace();
}

CPVT_WordPlace CPDF_VariableText::SearchWordPlace(
    const CFX_PointF& point) const {
  CFX_PointF pt = OutToIn(point);
  CPVT_WordPlace place = GetBeginWordPlace();
  int32_t nLeft = 0;
  int32_t nRight = pdfium::CollectionSize<int32_t>(m_SectionArray) - 1;
  int32_t nMid = pdfium::CollectionSize<int32_t>(m_SectionArray) / 2;
  bool bUp = true;
  bool bDown = true;
  while (nLeft <= nRight) {
    if (!pdfium::IndexInBounds(m_SectionArray, nMid))
      break;
    CSection* pSection = m_SectionArray[nMid].get();
    if (IsFloatBigger(pt.y, pSection->m_Rect.top))
      bUp = false;
    if (IsFloatBigger(pSection->m_Rect.bottom, pt.y))
      bDown = false;
    if (IsFloatSmaller(pt.y, pSection->m_Rect.top)) {
      nRight = nMid - 1;
      nMid = (nLeft + nRight) / 2;
      continue;
    }
    if (IsFloatBigger(pt.y, pSection->m_Rect.bottom)) {
      nLeft = nMid + 1;
      nMid = (nLeft + nRight) / 2;
      continue;
    }
    place = pSection->SearchWordPlace(
        CFX_PointF(pt.x - pSection->m_Rect.left, pt.y - pSection->m_Rect.top));
    place.nSecIndex = nMid;
    return place;
  }
  if (bUp)
    place = GetBeginWordPlace();
  if (bDown)
    place = GetEndWordPlace();
  return place;
}

CPVT_WordPlace CPDF_VariableText::GetUpWordPlace(
    const CPVT_WordPlace& place,
    const CFX_PointF& point) const {
  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
    return place;

  CSection* pSection = m_SectionArray[place.nSecIndex].get();
  CPVT_WordPlace temp = place;
  CFX_PointF pt = OutToIn(point);
  if (temp.nLineIndex-- > 0) {
    return pSection->SearchWordPlace(pt.x - pSection->m_Rect.left, temp);
  }
  if (temp.nSecIndex-- > 0) {
    if (pdfium::IndexInBounds(m_SectionArray, temp.nSecIndex)) {
      CSection* pLastSection = m_SectionArray[temp.nSecIndex].get();
      temp.nLineIndex =
          pdfium::CollectionSize<int32_t>(pLastSection->m_LineArray) - 1;
      return pLastSection->SearchWordPlace(pt.x - pLastSection->m_Rect.left,
                                           temp);
    }
  }
  return place;
}

CPVT_WordPlace CPDF_VariableText::GetDownWordPlace(
    const CPVT_WordPlace& place,
    const CFX_PointF& point) const {
  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
    return place;

  CSection* pSection = m_SectionArray[place.nSecIndex].get();
  CPVT_WordPlace temp = place;
  CFX_PointF pt = OutToIn(point);
  if (temp.nLineIndex++ <
      pdfium::CollectionSize<int32_t>(pSection->m_LineArray) - 1) {
    return pSection->SearchWordPlace(pt.x - pSection->m_Rect.left, temp);
  }
  temp.AdvanceSection();
  if (!pdfium::IndexInBounds(m_SectionArray, temp.nSecIndex))
    return place;

  return m_SectionArray[temp.nSecIndex]->SearchWordPlace(
      pt.x - pSection->m_Rect.left, temp);
}

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 (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
    return place;

  CSection* pSection = m_SectionArray[place.nSecIndex].get();
  if (!pdfium::IndexInBounds(pSection->m_LineArray, place.nLineIndex))
    return place;

  return pSection->m_LineArray[place.nLineIndex]->GetEndWordPlace();
}

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 (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
    return place;

  return m_SectionArray[place.nSecIndex]->GetEndWordPlace();
}

int32_t CPDF_VariableText::GetTotalWords() const {
  int32_t nTotal = 0;
  for (const auto& pSection : m_SectionArray) {
    nTotal +=
        pdfium::CollectionSize<int32_t>(pSection->m_WordArray) + kReturnLength;
  }
  return nTotal - kReturnLength;
}

CPVT_WordPlace CPDF_VariableText::AddSection(const CPVT_WordPlace& place) {
  if (IsValid() && !m_bMultiLine)
    return place;

  int32_t nSecIndex = pdfium::clamp(
      place.nSecIndex, 0, pdfium::CollectionSize<int32_t>(m_SectionArray));

  auto pSection = pdfium::MakeUnique<CSection>(this);
  pSection->m_Rect = CPVT_FloatRect();
  pSection->SecPlace.nSecIndex = nSecIndex;
  m_SectionArray.insert(m_SectionArray.begin() + nSecIndex,
                        std::move(pSection));
  return place;
}

CPVT_WordPlace CPDF_VariableText::AddLine(const CPVT_WordPlace& place,
                                          const CPVT_LineInfo& lineinfo) {
  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
    return place;

  return m_SectionArray[place.nSecIndex]->AddLine(lineinfo);
}

CPVT_WordPlace CPDF_VariableText::AddWord(const CPVT_WordPlace& place,
                                          const CPVT_WordInfo& wordinfo) {
  if (m_SectionArray.empty())
    return place;

  CPVT_WordPlace newplace = place;
  newplace.nSecIndex =
      pdfium::clamp(newplace.nSecIndex, 0,
                    pdfium::CollectionSize<int32_t>(m_SectionArray) - 1);
  return m_SectionArray[newplace.nSecIndex]->AddWord(newplace, wordinfo);
}

void CPDF_VariableText::SetPlateRect(const CFX_FloatRect& rect) {
  m_rcPlate = rect;
}

void CPDF_VariableText::SetContentRect(const CPVT_FloatRect& rect) {
  m_rcContent = rect;
}

CFX_FloatRect CPDF_VariableText::GetContentRect() const {
  return InToOut(CPVT_FloatRect(m_rcContent));
}

const CFX_FloatRect& CPDF_VariableText::GetPlateRect() const {
  return m_rcPlate;
}

float CPDF_VariableText::GetWordFontSize() {
  return GetFontSize();
}

int32_t CPDF_VariableText::GetWordFontIndex(const CPVT_WordInfo& WordInfo) {
  return WordInfo.nFontIndex;
}

float CPDF_VariableText::GetWordWidth(int32_t nFontIndex,
                                      uint16_t Word,
                                      uint16_t SubWord,
                                      float fCharSpace,
                                      int32_t nHorzScale,
                                      float fFontSize,
                                      float fWordTail) {
  return (GetCharWidth(nFontIndex, Word, SubWord) * fFontSize * kFontScale +
          fCharSpace) *
             nHorzScale * kScalePercent +
         fWordTail;
}

float CPDF_VariableText::GetWordWidth(const CPVT_WordInfo& WordInfo) {
  return GetWordWidth(GetWordFontIndex(WordInfo), WordInfo.Word, GetSubWord(),
                      GetCharSpace(), GetHorzScale(), GetWordFontSize(),
                      WordInfo.fWordTail);
}

float CPDF_VariableText::GetLineAscent() {
  return GetFontAscent(GetDefaultFontIndex(), GetFontSize());
}

float CPDF_VariableText::GetLineDescent() {
  return GetFontDescent(GetDefaultFontIndex(), GetFontSize());
}

float CPDF_VariableText::GetFontAscent(int32_t nFontIndex, float fFontSize) {
  return (float)GetTypeAscent(nFontIndex) * fFontSize * kFontScale;
}

float CPDF_VariableText::GetFontDescent(int32_t nFontIndex, float fFontSize) {
  return (float)GetTypeDescent(nFontIndex) * fFontSize * kFontScale;
}

float CPDF_VariableText::GetWordAscent(const CPVT_WordInfo& WordInfo,
                                       float fFontSize) {
  return GetFontAscent(GetWordFontIndex(WordInfo), fFontSize);
}

float CPDF_VariableText::GetWordDescent(const CPVT_WordInfo& WordInfo,
                                        float fFontSize) {
  return GetFontDescent(GetWordFontIndex(WordInfo), fFontSize);
}

float CPDF_VariableText::GetWordAscent(const CPVT_WordInfo& WordInfo) {
  return GetFontAscent(GetWordFontIndex(WordInfo), GetWordFontSize());
}

float CPDF_VariableText::GetWordDescent(const CPVT_WordInfo& WordInfo) {
  return GetFontDescent(GetWordFontIndex(WordInfo), GetWordFontSize());
}

float CPDF_VariableText::GetLineLeading() {
  return m_fLineLeading;
}

float CPDF_VariableText::GetLineIndent() {
  return 0.0f;
}

int32_t CPDF_VariableText::GetAlignment() {
  return m_nAlignment;
}

void CPDF_VariableText::ClearSectionRightWords(const CPVT_WordPlace& place) {
  CPVT_WordPlace wordplace = AdjustLineHeader(place, true);
  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
    return;

  CSection* pSection = m_SectionArray[place.nSecIndex].get();
  if (!pdfium::IndexInBounds(pSection->m_WordArray, wordplace.nWordIndex + 1))
    return;

  pSection->m_WordArray.erase(
      pSection->m_WordArray.begin() + wordplace.nWordIndex + 1,
      pSection->m_WordArray.end());
}

CPVT_WordPlace CPDF_VariableText::AdjustLineHeader(const CPVT_WordPlace& place,
                                                   bool bPrevOrNext) const {
  if (place.nWordIndex < 0 && place.nLineIndex > 0)
    return bPrevOrNext ? GetPrevWordPlace(place) : GetNextWordPlace(place);
  return place;
}

bool CPDF_VariableText::ClearEmptySection(const CPVT_WordPlace& place) {
  if (place.nSecIndex == 0 && m_SectionArray.size() == 1)
    return false;

  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
    return false;

  if (!m_SectionArray[place.nSecIndex]->m_WordArray.empty())
    return false;

  m_SectionArray.erase(m_SectionArray.begin() + place.nSecIndex);
  return true;
}

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 (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex + 1))
    return;

  CSection* pNextSection = m_SectionArray[place.nSecIndex + 1].get();
  if (pdfium::IndexInBounds(m_SectionArray, oldplace.nSecIndex)) {
    CSection* pSection = m_SectionArray[oldplace.nSecIndex].get();
    for (auto& pWord : pNextSection->m_WordArray) {
      oldplace.nWordIndex++;
      pSection->AddWord(oldplace, *pWord);
    }
  }
  m_SectionArray.erase(m_SectionArray.begin() + 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 (pdfium::IndexInBounds(m_SectionArray, s))
      m_SectionArray[s]->ClearWords(NewRange);
  }
}

CPVT_WordPlace CPDF_VariableText::ClearLeftWord(const CPVT_WordPlace& place) {
  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
    return place;

  CSection* pSection = m_SectionArray[place.nSecIndex].get();
  CPVT_WordPlace leftplace = GetPrevWordPlace(place);
  if (leftplace == place)
    return place;

  if (leftplace.nSecIndex != place.nSecIndex) {
    if (pSection->m_WordArray.empty())
      ClearEmptySection(place);
    else
      LinkLatterSection(leftplace);
  } else {
    pSection->ClearWord(place);
  }
  return leftplace;
}

CPVT_WordPlace CPDF_VariableText::ClearRightWord(const CPVT_WordPlace& place) {
  if (!pdfium::IndexInBounds(m_SectionArray, place.nSecIndex))
    return place;

  CSection* pSection = m_SectionArray[place.nSecIndex].get();
  CPVT_WordPlace rightplace = AdjustLineHeader(GetNextWordPlace(place), false);
  if (rightplace == place)
    return 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;
}

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;
    else
      nLeft = nMid + 1;
    nMid = (nLeft + nRight) / 2;
  }
  return (float)gFontSizeSteps[nMid];
}

bool CPDF_VariableText::IsBigger(float fFontSize) const {
  CFX_SizeF szTotal;
  for (const auto& pSection : m_SectionArray) {
    CFX_SizeF size = pSection->GetSectionSize(fFontSize);
    szTotal.width = std::max(size.width, szTotal.width);
    szTotal.height += size.height;
    if (IsFloatBigger(szTotal.width, GetPlateWidth()) ||
        IsFloatBigger(szTotal.height, GetPlateHeight())) {
      return true;
    }
  }
  return false;
}

CPVT_FloatRect CPDF_VariableText::RearrangeSections(
    const CPVT_WordRange& PlaceRange) {
  CPVT_WordPlace place;
  float fPosY = 0;
  float fOldHeight;
  int32_t nSSecIndex = PlaceRange.BeginPos.nSecIndex;
  int32_t nESecIndex = PlaceRange.EndPos.nSecIndex;
  CPVT_FloatRect rcRet;
  for (int32_t s = 0, sz = pdfium::CollectionSize<int32_t>(m_SectionArray);
       s < sz; s++) {
    place.nSecIndex = s;
    CSection* pSection = m_SectionArray[s].get();
    pSection->SecPlace = place;
    CPVT_FloatRect rcSec = pSection->m_Rect;
    if (s >= nSSecIndex) {
      if (s <= nESecIndex) {
        rcSec = pSection->Rearrange();
        rcSec.top += fPosY;
        rcSec.bottom += fPosY;
      } else {
        fOldHeight = pSection->m_Rect.bottom - pSection->m_Rect.top;
        rcSec.top = fPosY;
        rcSec.bottom = fPosY + fOldHeight;
      }
      pSection->m_Rect = 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;
}

uint32_t CPDF_VariableText::GetCharWidth(int32_t nFontIndex,
                                         uint16_t Word,
                                         uint16_t SubWord) {
  if (!m_pVTProvider)
    return 0;
  uint16_t word = SubWord ? SubWord : Word;
  return m_pVTProvider->GetCharWidth(nFontIndex, word);
}

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

bool CPDF_VariableText::IsLatinWord(uint16_t word) {
  return m_pVTProvider ? m_pVTProvider->IsLatinWord(word) : false;
}

CPDF_VariableText::Iterator* CPDF_VariableText::GetIterator() {
  if (!m_pVTIterator)
    m_pVTIterator = pdfium::MakeUnique<CPDF_VariableText::Iterator>(this);
  return m_pVTIterator.get();
}

void CPDF_VariableText::SetProvider(CPDF_VariableText::Provider* pProvider) {
  m_pVTProvider = pProvider;
}

CFX_PointF CPDF_VariableText::GetBTPoint() const {
  return CFX_PointF(m_rcPlate.left, m_rcPlate.top);
}

CFX_PointF CPDF_VariableText::GetETPoint() const {
  return CFX_PointF(m_rcPlate.right, m_rcPlate.bottom);
}

CFX_PointF CPDF_VariableText::InToOut(const CFX_PointF& point) const {
  return CFX_PointF(point.x + GetBTPoint().x, GetBTPoint().y - point.y);
}

CFX_PointF CPDF_VariableText::OutToIn(const CFX_PointF& point) const {
  return CFX_PointF(point.x - GetBTPoint().x, GetBTPoint().y - point.y);
}

CFX_FloatRect CPDF_VariableText::InToOut(const CPVT_FloatRect& rect) const {
  CFX_PointF ptLeftTop = InToOut(CFX_PointF(rect.left, rect.top));
  CFX_PointF ptRightBottom = InToOut(CFX_PointF(rect.right, rect.bottom));
  return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x,
                       ptLeftTop.y);
}

CPVT_FloatRect CPDF_VariableText::OutToIn(const CFX_FloatRect& rect) const {
  CFX_PointF ptLeftTop = OutToIn(CFX_PointF(rect.left, rect.top));
  CFX_PointF ptRightBottom = OutToIn(CFX_PointF(rect.right, rect.bottom));
  return CPVT_FloatRect(ptLeftTop.x, ptLeftTop.y, ptRightBottom.x,
                        ptRightBottom.y);
}
