// Copyright 2016 The PDFium Authors
// 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/cpvt_variabletext.h"

#include <algorithm>
#include <array>
#include <utility>

#include "core/fpdfapi/font/cpdf_font.h"
#include "core/fpdfdoc/cpvt_section.h"
#include "core/fpdfdoc/cpvt_word.h"
#include "core/fpdfdoc/cpvt_wordinfo.h"
#include "core/fpdfdoc/ipvt_fontmap.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/span.h"
#include "core/fxcrt/stl_util.h"

namespace {

constexpr float kFontScale = 0.001f;
constexpr uint8_t kReturnLength = 1;

constexpr auto kFontSizeSteps = std::to_array<const uint8_t>(
    {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

CPVT_VariableText::Provider::Provider(IPVT_FontMap* font_map)
    : font_map_(font_map) {
  DCHECK(font_map_);
}

CPVT_VariableText::Provider::~Provider() = default;

int CPVT_VariableText::Provider::GetCharWidth(int32_t nFontIndex,
                                              uint16_t word) {
  RetainPtr<CPDF_Font> pPDFFont = font_map_->GetPDFFont(nFontIndex);
  if (!pPDFFont) {
    return 0;
  }

  uint32_t charcode = pPDFFont->CharCodeFromUnicode(word);
  if (charcode == CPDF_Font::kInvalidCharCode) {
    return 0;
  }

  return pPDFFont->GetCharWidth(charcode);
}

int32_t CPVT_VariableText::Provider::GetTypeAscent(int32_t nFontIndex) {
  RetainPtr<CPDF_Font> pPDFFont = font_map_->GetPDFFont(nFontIndex);
  return pPDFFont ? pPDFFont->GetTypeAscent() : 0;
}

int32_t CPVT_VariableText::Provider::GetTypeDescent(int32_t nFontIndex) {
  RetainPtr<CPDF_Font> pPDFFont = font_map_->GetPDFFont(nFontIndex);
  return pPDFFont ? pPDFFont->GetTypeDescent() : 0;
}

int32_t CPVT_VariableText::Provider::GetWordFontIndex(uint16_t word,
                                                      FX_Charset charset,
                                                      int32_t nFontIndex) {
  if (RetainPtr<CPDF_Font> pDefFont = font_map_->GetPDFFont(0)) {
    if (pDefFont->CharCodeFromUnicode(word) != CPDF_Font::kInvalidCharCode) {
      return 0;
    }
  }
  if (RetainPtr<CPDF_Font> pSysFont = font_map_->GetPDFFont(1)) {
    if (pSysFont->CharCodeFromUnicode(word) != CPDF_Font::kInvalidCharCode) {
      return 1;
    }
  }
  return -1;
}

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

CPVT_VariableText::Iterator::Iterator(CPVT_VariableText* pVT) : vt_(pVT) {
  DCHECK(vt_);
}

CPVT_VariableText::Iterator::~Iterator() = default;

void CPVT_VariableText::Iterator::SetAt(int32_t nWordIndex) {
  cur_pos_ = vt_->WordIndexToWordPlace(nWordIndex);
}

void CPVT_VariableText::Iterator::SetAt(const CPVT_WordPlace& place) {
  cur_pos_ = place;
}

bool CPVT_VariableText::Iterator::NextWord() {
  if (cur_pos_ == vt_->GetEndWordPlace()) {
    return false;
  }

  cur_pos_ = vt_->GetNextWordPlace(cur_pos_);
  return true;
}

bool CPVT_VariableText::Iterator::NextLine() {
  if (!fxcrt::IndexInBounds(vt_->section_array_, cur_pos_.nSecIndex)) {
    return false;
  }

  CPVT_Section* pSection = vt_->section_array_[cur_pos_.nSecIndex].get();
  if (cur_pos_.nLineIndex < pSection->GetLineArraySize() - 1) {
    cur_pos_ = CPVT_WordPlace(cur_pos_.nSecIndex, cur_pos_.nLineIndex + 1, -1);
    return true;
  }
  if (cur_pos_.nSecIndex <
      fxcrt::CollectionSize<int32_t>(vt_->section_array_) - 1) {
    cur_pos_ = CPVT_WordPlace(cur_pos_.nSecIndex + 1, 0, -1);
    return true;
  }
  return false;
}

bool CPVT_VariableText::Iterator::GetWord(CPVT_Word& word) const {
  word.WordPlace = cur_pos_;
  if (!fxcrt::IndexInBounds(vt_->section_array_, cur_pos_.nSecIndex)) {
    return false;
  }

  CPVT_Section* pSection = vt_->section_array_[cur_pos_.nSecIndex].get();
  if (!pSection->GetLineFromArray(cur_pos_.nLineIndex)) {
    return false;
  }

  const CPVT_WordInfo* pInfo = pSection->GetWordFromArray(cur_pos_.nWordIndex);
  if (!pInfo) {
    return false;
  }

  word.Word = pInfo->Word;
  word.nCharset = pInfo->nCharset;
  word.fWidth = vt_->GetWordWidth(*pInfo);
  word.ptWord =
      vt_->InToOut(CFX_PointF(pInfo->fWordX + pSection->GetRect().left,
                              pInfo->fWordY + pSection->GetRect().top));
  word.fAscent = vt_->GetWordAscent(*pInfo);
  word.fDescent = vt_->GetWordDescent(*pInfo);
  word.nFontIndex = pInfo->nFontIndex;
  word.fFontSize = vt_->GetWordFontSize();
  return true;
}

bool CPVT_VariableText::Iterator::GetLine(CPVT_Line& line) const {
  DCHECK(vt_);
  line.lineplace = CPVT_WordPlace(cur_pos_.nSecIndex, cur_pos_.nLineIndex, -1);
  if (!fxcrt::IndexInBounds(vt_->section_array_, cur_pos_.nSecIndex)) {
    return false;
  }

  CPVT_Section* pSection = vt_->section_array_[cur_pos_.nSecIndex].get();
  const CPVT_Section::Line* pLine =
      pSection->GetLineFromArray(cur_pos_.nLineIndex);
  if (!pLine) {
    return false;
  }

  line.ptLine = vt_->InToOut(
      CFX_PointF(pLine->line_info_.fLineX + pSection->GetRect().left,
                 pLine->line_info_.fLineY + pSection->GetRect().top));
  line.fLineWidth = pLine->line_info_.fLineWidth;
  line.fLineAscent = pLine->line_info_.fLineAscent;
  line.fLineDescent = pLine->line_info_.fLineDescent;
  line.lineEnd = pLine->GetEndWordPlace();
  return true;
}

CPVT_VariableText::CPVT_VariableText(Provider* pProvider)
    : vt_provider_(pProvider) {}

CPVT_VariableText::~CPVT_VariableText() = default;

void CPVT_VariableText::Initialize() {
  if (initialized_) {
    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 (!section_array_.empty()) {
    section_array_.front()->ResetLinePlace();
  }

  initialized_ = true;
}

CPVT_WordPlace CPVT_VariableText::InsertWord(const CPVT_WordPlace& place,
                                             uint16_t word,
                                             FX_Charset charset) {
  int32_t nTotalWords = GetTotalWords();
  if (limit_char_ > 0 && nTotalWords >= limit_char_) {
    return place;
  }
  if (char_array_ > 0 && nTotalWords >= char_array_) {
    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 CPVT_VariableText::InsertSection(const CPVT_WordPlace& place) {
  int32_t nTotalWords = GetTotalWords();
  if (limit_char_ > 0 && nTotalWords >= limit_char_) {
    return place;
  }
  if (char_array_ > 0 && nTotalWords >= char_array_) {
    return place;
  }
  if (!multi_line_) {
    return place;
  }

  CPVT_WordPlace wordplace = place;
  UpdateWordPlace(wordplace);
  if (!fxcrt::IndexInBounds(section_array_, wordplace.nSecIndex)) {
    return place;
  }

  CPVT_Section* pSection = section_array_[wordplace.nSecIndex].get();
  CPVT_WordPlace NewPlace(wordplace.nSecIndex + 1, 0, -1);
  AddSection(NewPlace);
  CPVT_WordPlace result = NewPlace;
  if (fxcrt::IndexInBounds(section_array_, NewPlace.nSecIndex)) {
    CPVT_Section* pNewSection = section_array_[NewPlace.nSecIndex].get();
    for (int32_t w = wordplace.nWordIndex + 1; w < pSection->GetWordArraySize();
         ++w) {
      NewPlace.nWordIndex++;
      pNewSection->AddWord(NewPlace, *pSection->GetWordFromArray(w));
    }
  }
  ClearSectionRightWords(wordplace);
  return result;
}

CPVT_WordPlace CPVT_VariableText::DeleteWords(
    const CPVT_WordRange& PlaceRange) {
  bool bLastSecPos =
      fxcrt::IndexInBounds(section_array_, PlaceRange.EndPos.nSecIndex) &&
      PlaceRange.EndPos ==
          section_array_[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 CPVT_VariableText::DeleteWord(const CPVT_WordPlace& place) {
  return ClearRightWord(PrevLineHeaderPlace(place));
}

CPVT_WordPlace CPVT_VariableText::BackSpaceWord(const CPVT_WordPlace& place) {
  return ClearLeftWord(PrevLineHeaderPlace(place));
}

void CPVT_VariableText::SetText(const WideString& swText) {
  DeleteWords(CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
  CPVT_WordPlace wp(0, 0, -1);
  if (!section_array_.empty()) {
    section_array_.front()->SetRect(CPVT_FloatRect());
  }

  FX_SAFE_INT32 nCharCount = 0;
  for (size_t i = 0, sz = swText.GetLength(); i < sz; i++) {
    if (limit_char_ > 0 && nCharCount.ValueOrDie() >= limit_char_) {
      break;
    }
    if (char_array_ > 0 && nCharCount.ValueOrDie() >= char_array_) {
      break;
    }

    uint16_t word = swText[i];
    switch (word) {
      case 0x0D:
        if (multi_line_) {
          if (i + 1 < sz && swText[i + 1] == 0x0A) {
            i++;
          }
          wp.AdvanceSection();
          AddSection(wp);
        }
        break;
      case 0x0A:
        if (multi_line_) {
          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::kDefault);
        break;
    }
    nCharCount++;
  }
}

void CPVT_VariableText::UpdateWordPlace(CPVT_WordPlace& place) const {
  if (place.nSecIndex < 0) {
    place = GetBeginWordPlace();
  }
  if (static_cast<size_t>(place.nSecIndex) >= section_array_.size()) {
    place = GetEndWordPlace();
  }

  place = PrevLineHeaderPlace(place);
  if (fxcrt::IndexInBounds(section_array_, place.nSecIndex)) {
    section_array_[place.nSecIndex]->UpdateWordPlace(place);
  }
}

int32_t CPVT_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 = fxcrt::CollectionSize<int32_t>(section_array_);
       i < sz && i < newplace.nSecIndex; i++) {
    CPVT_Section* pSection = section_array_[i].get();
    nIndex += pSection->GetWordArraySize();
    if (i != sz - 1) {
      nIndex += kReturnLength;
    }
  }
  if (fxcrt::IndexInBounds(section_array_, i)) {
    nIndex += newplace.nWordIndex + kReturnLength;
  }
  return nIndex;
}

CPVT_WordPlace CPVT_VariableText::WordIndexToWordPlace(int32_t index) const {
  CPVT_WordPlace place = GetBeginWordPlace();
  int32_t nOldIndex = 0;
  int32_t nIndex = 0;
  bool bFound = false;
  for (size_t i = 0; i < section_array_.size(); ++i) {
    CPVT_Section* pSection = section_array_[i].get();
    nIndex += pSection->GetWordArraySize();
    if (nIndex == index) {
      place = pSection->GetEndWordPlace();
      bFound = true;
      break;
    }
    if (nIndex > index) {
      place.nSecIndex = pdfium::checked_cast<int32_t>(i);
      place.nWordIndex = index - nOldIndex - 1;
      pSection->UpdateWordPlace(place);
      bFound = true;
      break;
    }
    if (i != section_array_.size() - 1) {
      nIndex += kReturnLength;
    }
    nOldIndex = nIndex;
  }
  if (!bFound) {
    place = GetEndWordPlace();
  }
  return place;
}

CPVT_WordPlace CPVT_VariableText::GetBeginWordPlace() const {
  return initialized_ ? CPVT_WordPlace(0, 0, -1) : CPVT_WordPlace();
}

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

CPVT_WordPlace CPVT_VariableText::GetPrevWordPlace(
    const CPVT_WordPlace& place) const {
  if (place.nSecIndex < 0) {
    return GetBeginWordPlace();
  }
  if (static_cast<size_t>(place.nSecIndex) >= section_array_.size()) {
    return GetEndWordPlace();
  }

  CPVT_Section* pSection = section_array_[place.nSecIndex].get();
  if (place > pSection->GetBeginWordPlace()) {
    return pSection->GetPrevWordPlace(place);
  }
  if (!fxcrt::IndexInBounds(section_array_, place.nSecIndex - 1)) {
    return GetBeginWordPlace();
  }
  return section_array_[place.nSecIndex - 1]->GetEndWordPlace();
}

CPVT_WordPlace CPVT_VariableText::GetNextWordPlace(
    const CPVT_WordPlace& place) const {
  if (place.nSecIndex < 0) {
    return GetBeginWordPlace();
  }
  if (static_cast<size_t>(place.nSecIndex) >= section_array_.size()) {
    return GetEndWordPlace();
  }

  CPVT_Section* pSection = section_array_[place.nSecIndex].get();
  if (place < pSection->GetEndWordPlace()) {
    return pSection->GetNextWordPlace(place);
  }
  if (!fxcrt::IndexInBounds(section_array_, place.nSecIndex + 1)) {
    return GetEndWordPlace();
  }
  return section_array_[place.nSecIndex + 1]->GetBeginWordPlace();
}

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

CPVT_WordPlace CPVT_VariableText::GetUpWordPlace(
    const CPVT_WordPlace& place,
    const CFX_PointF& point) const {
  if (!fxcrt::IndexInBounds(section_array_, place.nSecIndex)) {
    return place;
  }

  CPVT_Section* pSection = section_array_[place.nSecIndex].get();
  CPVT_WordPlace temp = place;
  CFX_PointF pt = OutToIn(point);
  if (temp.nLineIndex-- > 0) {
    return pSection->SearchWordPlace(pt.x - pSection->GetRect().left, temp);
  }
  if (temp.nSecIndex-- > 0) {
    if (fxcrt::IndexInBounds(section_array_, temp.nSecIndex)) {
      CPVT_Section* pLastSection = section_array_[temp.nSecIndex].get();
      temp.nLineIndex = pLastSection->GetLineArraySize() - 1;
      return pLastSection->SearchWordPlace(pt.x - pLastSection->GetRect().left,
                                           temp);
    }
  }
  return place;
}

CPVT_WordPlace CPVT_VariableText::GetDownWordPlace(
    const CPVT_WordPlace& place,
    const CFX_PointF& point) const {
  if (!fxcrt::IndexInBounds(section_array_, place.nSecIndex)) {
    return place;
  }

  CPVT_Section* pSection = section_array_[place.nSecIndex].get();
  CPVT_WordPlace temp = place;
  CFX_PointF pt = OutToIn(point);
  if (temp.nLineIndex++ < pSection->GetLineArraySize() - 1) {
    return pSection->SearchWordPlace(pt.x - pSection->GetRect().left, temp);
  }
  temp.AdvanceSection();
  if (!fxcrt::IndexInBounds(section_array_, temp.nSecIndex)) {
    return place;
  }

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

CPVT_WordPlace CPVT_VariableText::GetLineBeginPlace(
    const CPVT_WordPlace& place) const {
  return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, -1);
}

CPVT_WordPlace CPVT_VariableText::GetLineEndPlace(
    const CPVT_WordPlace& place) const {
  if (!fxcrt::IndexInBounds(section_array_, place.nSecIndex)) {
    return place;
  }

  CPVT_Section* pSection = section_array_[place.nSecIndex].get();
  const CPVT_Section::Line* pLine =
      pSection->GetLineFromArray(place.nLineIndex);
  if (!pLine) {
    return place;
  }

  return pLine->GetEndWordPlace();
}

CPVT_WordPlace CPVT_VariableText::GetSectionBeginPlace(
    const CPVT_WordPlace& place) const {
  return CPVT_WordPlace(place.nSecIndex, 0, -1);
}

CPVT_WordPlace CPVT_VariableText::GetSectionEndPlace(
    const CPVT_WordPlace& place) const {
  if (!fxcrt::IndexInBounds(section_array_, place.nSecIndex)) {
    return place;
  }

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

int32_t CPVT_VariableText::GetTotalWords() const {
  int32_t nTotal = 0;
  for (const auto& pSection : section_array_) {
    nTotal += pSection->GetWordArraySize() + kReturnLength;
  }
  return nTotal - kReturnLength;
}

CPVT_WordPlace CPVT_VariableText::AddSection(const CPVT_WordPlace& place) {
  if (IsValid() && !multi_line_) {
    return place;
  }

  int32_t nSecIndex = std::clamp(
      place.nSecIndex, 0, fxcrt::CollectionSize<int32_t>(section_array_));

  auto pSection = std::make_unique<CPVT_Section>(this);
  pSection->SetRect(CPVT_FloatRect());
  pSection->SetPlaceIndex(nSecIndex);
  section_array_.insert(section_array_.begin() + nSecIndex,
                        std::move(pSection));
  return place;
}

CPVT_WordPlace CPVT_VariableText::AddLine(const CPVT_WordPlace& place,
                                          const CPVT_LineInfo& lineinfo) {
  if (!fxcrt::IndexInBounds(section_array_, place.nSecIndex)) {
    return place;
  }

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

CPVT_WordPlace CPVT_VariableText::AddWord(const CPVT_WordPlace& place,
                                          const CPVT_WordInfo& wordinfo) {
  if (section_array_.empty()) {
    return place;
  }

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

void CPVT_VariableText::SetPlateRect(const CFX_FloatRect& rect) {
  plate_rect_ = rect;
}

CFX_FloatRect CPVT_VariableText::GetContentRect() const {
  return InToOut(content_rect_);
}

const CFX_FloatRect& CPVT_VariableText::GetPlateRect() const {
  return plate_rect_;
}

float CPVT_VariableText::GetWordFontSize() const {
  return GetFontSize();
}

float CPVT_VariableText::GetWordWidth(int32_t nFontIndex,
                                      uint16_t Word,
                                      uint16_t SubWord,
                                      float fFontSize,
                                      float fWordTail) const {
  return GetCharWidth(nFontIndex, Word, SubWord) * fFontSize * kFontScale +
         fWordTail;
}

float CPVT_VariableText::GetWordWidth(const CPVT_WordInfo& WordInfo) const {
  return GetWordWidth(WordInfo.nFontIndex, WordInfo.Word, GetSubWord(),
                      GetWordFontSize(), WordInfo.fWordTail);
}

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

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

float CPVT_VariableText::GetFontAscent(int32_t nFontIndex,
                                       float fFontSize) const {
  float ascent = vt_provider_ ? vt_provider_->GetTypeAscent(nFontIndex) : 0;
  return ascent * fFontSize * kFontScale;
}

float CPVT_VariableText::GetFontDescent(int32_t nFontIndex,
                                        float fFontSize) const {
  float descent = vt_provider_ ? vt_provider_->GetTypeDescent(nFontIndex) : 0;
  return descent * fFontSize * kFontScale;
}

float CPVT_VariableText::GetWordAscent(const CPVT_WordInfo& WordInfo,
                                       float fFontSize) const {
  return GetFontAscent(WordInfo.nFontIndex, fFontSize);
}

float CPVT_VariableText::GetWordDescent(const CPVT_WordInfo& WordInfo,
                                        float fFontSize) const {
  return GetFontDescent(WordInfo.nFontIndex, fFontSize);
}

float CPVT_VariableText::GetWordAscent(const CPVT_WordInfo& WordInfo) const {
  return GetFontAscent(WordInfo.nFontIndex, GetWordFontSize());
}

float CPVT_VariableText::GetWordDescent(const CPVT_WordInfo& WordInfo) const {
  return GetFontDescent(WordInfo.nFontIndex, GetWordFontSize());
}

float CPVT_VariableText::GetLineLeading() {
  return line_leading_;
}

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

void CPVT_VariableText::ClearSectionRightWords(const CPVT_WordPlace& place) {
  CPVT_WordPlace wordplace = PrevLineHeaderPlace(place);
  if (!fxcrt::IndexInBounds(section_array_, place.nSecIndex)) {
    return;
  }

  CPVT_Section* pSection = section_array_[place.nSecIndex].get();
  pSection->EraseWordsFrom(wordplace.nWordIndex + 1);
}

CPVT_WordPlace CPVT_VariableText::PrevLineHeaderPlace(
    const CPVT_WordPlace& place) const {
  if (place.nWordIndex < 0 && place.nLineIndex > 0) {
    return GetPrevWordPlace(place);
  }
  return place;
}

CPVT_WordPlace CPVT_VariableText::NextLineHeaderPlace(
    const CPVT_WordPlace& place) const {
  if (place.nWordIndex < 0 && place.nLineIndex > 0) {
    return GetNextWordPlace(place);
  }
  return place;
}

void CPVT_VariableText::ClearEmptySection(const CPVT_WordPlace& place) {
  if (place.nSecIndex == 0 && section_array_.size() == 1) {
    return;
  }

  if (!fxcrt::IndexInBounds(section_array_, place.nSecIndex)) {
    return;
  }

  if (section_array_[place.nSecIndex]->GetWordArraySize() != 0) {
    return;
  }

  section_array_.erase(section_array_.begin() + place.nSecIndex);
}

void CPVT_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 CPVT_VariableText::LinkLatterSection(const CPVT_WordPlace& place) {
  CPVT_WordPlace oldplace = PrevLineHeaderPlace(place);
  if (!fxcrt::IndexInBounds(section_array_, place.nSecIndex + 1)) {
    return;
  }

  CPVT_Section* pNextSection = section_array_[place.nSecIndex + 1].get();
  if (fxcrt::IndexInBounds(section_array_, oldplace.nSecIndex)) {
    CPVT_Section* pSection = section_array_[oldplace.nSecIndex].get();
    for (int32_t i = 0; i < pNextSection->GetWordArraySize(); ++i) {
      oldplace.nWordIndex++;
      pSection->AddWord(oldplace, *pNextSection->GetWordFromArray(i));
    }
  }
  section_array_.erase(section_array_.begin() + place.nSecIndex + 1);
}

void CPVT_VariableText::ClearWords(const CPVT_WordRange& PlaceRange) {
  CPVT_WordRange NewRange;
  NewRange.BeginPos = PrevLineHeaderPlace(PlaceRange.BeginPos);
  NewRange.EndPos = PrevLineHeaderPlace(PlaceRange.EndPos);
  for (int32_t s = NewRange.EndPos.nSecIndex; s >= NewRange.BeginPos.nSecIndex;
       s--) {
    if (fxcrt::IndexInBounds(section_array_, s)) {
      section_array_[s]->ClearWords(NewRange);
    }
  }
}

CPVT_WordPlace CPVT_VariableText::ClearLeftWord(const CPVT_WordPlace& place) {
  if (!fxcrt::IndexInBounds(section_array_, place.nSecIndex)) {
    return place;
  }

  CPVT_Section* pSection = section_array_[place.nSecIndex].get();
  CPVT_WordPlace leftplace = GetPrevWordPlace(place);
  if (leftplace == place) {
    return place;
  }

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

CPVT_WordPlace CPVT_VariableText::ClearRightWord(const CPVT_WordPlace& place) {
  if (!fxcrt::IndexInBounds(section_array_, place.nSecIndex)) {
    return place;
  }

  CPVT_Section* pSection = section_array_[place.nSecIndex].get();
  CPVT_WordPlace rightplace = NextLineHeaderPlace(GetNextWordPlace(place));
  if (rightplace == place) {
    return place;
  }

  if (rightplace.nSecIndex != place.nSecIndex) {
    LinkLatterSection(place);
  } else {
    pSection->ClearWord(rightplace);
  }
  return place;
}

void CPVT_VariableText::RearrangeAll() {
  Rearrange(CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
}

void CPVT_VariableText::RearrangePart(const CPVT_WordRange& PlaceRange) {
  Rearrange(PlaceRange);
}

void CPVT_VariableText::Rearrange(const CPVT_WordRange& PlaceRange) {
  CPVT_FloatRect rcRet;
  if (IsValid()) {
    if (auto_font_size_) {
      SetFontSize(GetAutoFontSize());
      rcRet = RearrangeSections(
          CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
    } else {
      rcRet = RearrangeSections(PlaceRange);
    }
  }
  content_rect_ = rcRet;
}

float CPVT_VariableText::GetAutoFontSize() {
  constexpr size_t kFullSize = kFontSizeSteps.size();
  constexpr size_t kQuarterSize = kFullSize / 4;

  static_assert(kFullSize >= 4,
                "kFontSizeSteps.size() must be at least 4 to ensure "
                "kQuarterSize is not zero.");

  if (GetPlateWidth() <= 0) {
    return 0;
  }

  size_t span_size = IsMultiLine() ? kQuarterSize : kFullSize;
  auto font_span = pdfium::span(kFontSizeSteps).first(span_size);

  constexpr bool kUnusedValue = true;
  auto it = std::lower_bound(
      font_span.begin(), font_span.end(), kUnusedValue,
      [this](uint8_t font_size, bool) { return !IsBigger(font_size); });

  if (it == font_span.end()) {
    return static_cast<float>(font_span.back());
  }

  if (it == font_span.begin()) {
    return static_cast<float>(*it);
  }
  return static_cast<float>(font_span[it - font_span.begin() - 1]);
}

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

CPVT_FloatRect CPVT_VariableText::RearrangeSections(
    const CPVT_WordRange& PlaceRange) {
  float fPosY = 0;
  CPVT_FloatRect rcRet;
  for (int32_t s = 0, sz = fxcrt::CollectionSize<int32_t>(section_array_);
       s < sz; s++) {
    CPVT_WordPlace place;
    place.nSecIndex = s;
    CPVT_Section* pSection = section_array_[s].get();
    pSection->SetPlace(place);
    CPVT_FloatRect rcSec = pSection->GetRect();
    if (s >= PlaceRange.BeginPos.nSecIndex) {
      if (s <= PlaceRange.EndPos.nSecIndex) {
        rcSec = pSection->Rearrange();
        rcSec.top += fPosY;
        rcSec.bottom += fPosY;
      } else {
        float fOldHeight = pSection->GetRect().bottom - pSection->GetRect().top;
        rcSec.top = fPosY;
        rcSec.bottom = fPosY + fOldHeight;
      }
      pSection->SetRect(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;
}

int CPVT_VariableText::GetCharWidth(int32_t nFontIndex,
                                    uint16_t Word,
                                    uint16_t SubWord) const {
  if (!vt_provider_) {
    return 0;
  }
  uint16_t word = SubWord ? SubWord : Word;
  return vt_provider_->GetCharWidth(nFontIndex, word);
}

int32_t CPVT_VariableText::GetWordFontIndex(uint16_t word,
                                            FX_Charset charset,
                                            int32_t nFontIndex) {
  return vt_provider_
             ? vt_provider_->GetWordFontIndex(word, charset, nFontIndex)
             : -1;
}

int32_t CPVT_VariableText::GetDefaultFontIndex() {
  return vt_provider_ ? vt_provider_->GetDefaultFontIndex() : -1;
}

CPVT_VariableText::Iterator* CPVT_VariableText::GetIterator() {
  if (!vt_iterator_) {
    vt_iterator_ = std::make_unique<CPVT_VariableText::Iterator>(this);
  }
  return vt_iterator_.get();
}

void CPVT_VariableText::SetProvider(Provider* pProvider) {
  vt_provider_ = pProvider;
}

CPVT_VariableText::Provider* CPVT_VariableText::GetProvider() {
  return vt_provider_;
}

CFX_PointF CPVT_VariableText::GetBTPoint() const {
  return CFX_PointF(plate_rect_.left, plate_rect_.top);
}

CFX_PointF CPVT_VariableText::GetETPoint() const {
  return CFX_PointF(plate_rect_.right, plate_rect_.bottom);
}

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

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

CFX_FloatRect CPVT_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);
}
