// 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_section.h"

#include <algorithm>
#include <array>
#include <memory>

#include "core/fpdfdoc/cpvt_variabletext.h"
#include "core/fpdfdoc/cpvt_wordinfo.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/containers/adapters.h"
#include "core/fxcrt/fx_bidi.h"
#include "core/fxcrt/notreached.h"
#include "core/fxcrt/stl_util.h"

namespace {

constexpr std::array<const uint8_t, 128> kSpecialChars = {{
    0x00, 0x0C, 0x08, 0x0C, 0x08, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00,
    0x10, 0x00, 0x00, 0x28, 0x0C, 0x08, 0x00, 0x00, 0x28, 0x28, 0x28, 0x28,
    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x08, 0x08,
    0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0C, 0x00, 0x08, 0x00, 0x00,
    0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x0C, 0x00, 0x08, 0x00, 0x00,
}};

bool IsLatin(uint16_t word) {
  if (word <= 0x007F) {
    return !!(kSpecialChars[word] & 0x01);
  }
  return ((word >= 0x00C0 && word <= 0x00FF) ||
          (word >= 0x0100 && word <= 0x024F) ||
          (word >= 0x1E00 && word <= 0x1EFF) ||
          (word >= 0x2C60 && word <= 0x2C7F) ||
          (word >= 0xA720 && word <= 0xA7FF) ||
          (word >= 0xFF21 && word <= 0xFF3A) ||
          (word >= 0xFF41 && word <= 0xFF5A));
}

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

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

bool IsPunctuation(uint32_t word) {
  if (word <= 0x007F) {
    return !!(kSpecialChars[word] & 0x08);
  }
  if (word >= 0x0080 && word <= 0x00FF) {
    return (word == 0x0082 || word == 0x0084 || word == 0x0085 ||
            word == 0x0091 || word == 0x0092 || word == 0x0093 ||
            word <= 0x0094 || word == 0x0096 || word == 0x00B4 ||
            word == 0x00B8);
  }
  if (word >= 0x2000 && word <= 0x206F) {
    return (
        word == 0x2010 || word == 0x2011 || word == 0x2012 || word == 0x2013 ||
        word == 0x2018 || word == 0x2019 || word == 0x201A || word == 0x201B ||
        word == 0x201C || word == 0x201D || word == 0x201E || word == 0x201F ||
        word == 0x2032 || word == 0x2033 || word == 0x2034 || word == 0x2035 ||
        word == 0x2036 || word == 0x2037 || word == 0x203C || word == 0x203D ||
        word == 0x203E || word == 0x2044);
  }
  if (word >= 0x3000 && word <= 0x303F) {
    return (
        word == 0x3001 || word == 0x3002 || word == 0x3003 || word == 0x3005 ||
        word == 0x3009 || word == 0x300A || word == 0x300B || word == 0x300C ||
        word == 0x300D || word == 0x300F || word == 0x300E || word == 0x3010 ||
        word == 0x3011 || word == 0x3014 || word == 0x3015 || word == 0x3016 ||
        word == 0x3017 || word == 0x3018 || word == 0x3019 || word == 0x301A ||
        word == 0x301B || word == 0x301D || word == 0x301E || word == 0x301F);
  }
  if (word >= 0xFE50 && word <= 0xFE6F) {
    return (word >= 0xFE50 && word <= 0xFE5E) || word == 0xFE63;
  }
  if (word >= 0xFF00 && word <= 0xFFEF) {
    return (
        word == 0xFF01 || word == 0xFF02 || word == 0xFF07 || word == 0xFF08 ||
        word == 0xFF09 || word == 0xFF0C || word == 0xFF0E || word == 0xFF0F ||
        word == 0xFF1A || word == 0xFF1B || word == 0xFF1F || word == 0xFF3B ||
        word == 0xFF3D || word == 0xFF40 || word == 0xFF5B || word == 0xFF5C ||
        word == 0xFF5D || word == 0xFF61 || word == 0xFF62 || word == 0xFF63 ||
        word == 0xFF64 || word == 0xFF65 || word == 0xFF9E || word == 0xFF9F);
  }
  return false;
}

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

bool IsOpenStylePunctuation(uint32_t word) {
  if (word <= 0x007F) {
    return !!(kSpecialChars[word] & 0x04);
  }
  return (word == 0x300A || word == 0x300C || word == 0x300E ||
          word == 0x3010 || word == 0x3014 || word == 0x3016 ||
          word == 0x3018 || word == 0x301A || word == 0xFF08 ||
          word == 0xFF3B || word == 0xFF5B || word == 0xFF62);
}

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

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

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

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

}  // namespace

CPVT_Section::Line::Line(const CPVT_LineInfo& lineinfo)
    : line_info_(lineinfo) {}

CPVT_Section::Line::~Line() = default;

CPVT_WordPlace CPVT_Section::Line::GetBeginWordPlace() const {
  return CPVT_WordPlace(line_place_.nSecIndex, line_place_.nLineIndex, -1);
}

CPVT_WordPlace CPVT_Section::Line::GetEndWordPlace() const {
  return CPVT_WordPlace(line_place_.nSecIndex, line_place_.nLineIndex,
                        line_info_.nEndWordIndex);
}

CPVT_WordPlace CPVT_Section::Line::GetPrevWordPlace(
    const CPVT_WordPlace& place) const {
  if (place.nWordIndex > line_info_.nEndWordIndex) {
    return CPVT_WordPlace(place.nSecIndex, place.nLineIndex,
                          line_info_.nEndWordIndex);
  }
  return CPVT_WordPlace(place.nSecIndex, place.nLineIndex,
                        place.nWordIndex - 1);
}

CPVT_WordPlace CPVT_Section::Line::GetNextWordPlace(
    const CPVT_WordPlace& place) const {
  if (place.nWordIndex < line_info_.nBeginWordIndex) {
    return CPVT_WordPlace(place.nSecIndex, place.nLineIndex,
                          line_info_.nBeginWordIndex);
  }
  return CPVT_WordPlace(place.nSecIndex, place.nLineIndex,
                        place.nWordIndex + 1);
}

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

CPVT_Section::~CPVT_Section() = default;

void CPVT_Section::ResetLinePlace() {
  int32_t i = 0;
  for (auto& pLine : line_array_) {
    pLine->line_place_ = CPVT_WordPlace(sec_place_.nSecIndex, i, -1);
    ++i;
  }
}

CPVT_WordPlace CPVT_Section::AddWord(const CPVT_WordPlace& place,
                                     const CPVT_WordInfo& wordinfo) {
  int32_t nWordIndex = std::clamp(place.nWordIndex, 0,
                                  fxcrt::CollectionSize<int32_t>(word_array_));
  word_array_.insert(word_array_.begin() + nWordIndex,
                     std::make_unique<CPVT_WordInfo>(wordinfo));
  return place;
}

CPVT_WordPlace CPVT_Section::AddLine(const CPVT_LineInfo& lineinfo) {
  line_array_.push_back(std::make_unique<Line>(lineinfo));
  return CPVT_WordPlace(sec_place_.nSecIndex,
                        fxcrt::CollectionSize<int32_t>(line_array_) - 1, -1);
}

CPVT_FloatRect CPVT_Section::Rearrange() {
  if (vt_->GetCharArray() > 0) {
    return RearrangeCharArray();
  }
  return RearrangeTypeset();
}

CFX_SizeF CPVT_Section::GetSectionSize(float fFontSize) {
  CPVT_FloatRect result = SplitLines(/*bTypeset=*/false, fFontSize);
  return CFX_SizeF(result.Width(), result.Height());
}

CPVT_WordPlace CPVT_Section::GetBeginWordPlace() const {
  if (line_array_.empty()) {
    return sec_place_;
  }
  return line_array_.front()->GetBeginWordPlace();
}

CPVT_WordPlace CPVT_Section::GetEndWordPlace() const {
  if (line_array_.empty()) {
    return sec_place_;
  }
  return line_array_.back()->GetEndWordPlace();
}

CPVT_WordPlace CPVT_Section::GetPrevWordPlace(
    const CPVT_WordPlace& place) const {
  if (place.nLineIndex < 0) {
    return GetBeginWordPlace();
  }

  if (place.nLineIndex >= fxcrt::CollectionSize<int32_t>(line_array_)) {
    return GetEndWordPlace();
  }

  Line* pLine = line_array_[place.nLineIndex].get();
  if (place.nWordIndex == pLine->line_info_.nBeginWordIndex) {
    return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, -1);
  }

  if (place.nWordIndex >= pLine->line_info_.nBeginWordIndex) {
    return pLine->GetPrevWordPlace(place);
  }

  if (!fxcrt::IndexInBounds(line_array_, place.nLineIndex - 1)) {
    return place;
  }

  return line_array_[place.nLineIndex - 1]->GetEndWordPlace();
}

CPVT_WordPlace CPVT_Section::GetNextWordPlace(
    const CPVT_WordPlace& place) const {
  if (place.nLineIndex < 0) {
    return GetBeginWordPlace();
  }

  if (place.nLineIndex >= fxcrt::CollectionSize<int32_t>(line_array_)) {
    return GetEndWordPlace();
  }

  Line* pLine = line_array_[place.nLineIndex].get();
  if (place.nWordIndex < pLine->line_info_.nEndWordIndex) {
    return pLine->GetNextWordPlace(place);
  }

  if (!fxcrt::IndexInBounds(line_array_, place.nLineIndex + 1)) {
    return place;
  }

  return line_array_[place.nLineIndex + 1]->GetBeginWordPlace();
}

void CPVT_Section::UpdateWordPlace(CPVT_WordPlace& place) const {
  int32_t nLeft = 0;
  int32_t nRight = fxcrt::CollectionSize<int32_t>(line_array_) - 1;
  int32_t nMid = (nLeft + nRight) / 2;
  while (nLeft <= nRight) {
    Line* pLine = line_array_[nMid].get();
    if (place.nWordIndex < pLine->line_info_.nBeginWordIndex) {
      nRight = nMid - 1;
      nMid = (nLeft + nRight) / 2;
    } else if (place.nWordIndex > pLine->line_info_.nEndWordIndex) {
      nLeft = nMid + 1;
      nMid = (nLeft + nRight) / 2;
    } else {
      place.nLineIndex = nMid;
      return;
    }
  }
}

CPVT_WordPlace CPVT_Section::SearchWordPlace(const CFX_PointF& point) const {
  CPVT_WordPlace place = GetBeginWordPlace();
  bool bUp = true;
  bool bDown = true;
  int32_t nLeft = 0;
  int32_t nRight = fxcrt::CollectionSize<int32_t>(line_array_) - 1;
  int32_t nMid = fxcrt::CollectionSize<int32_t>(line_array_) / 2;
  while (nLeft <= nRight) {
    Line* pLine = line_array_[nMid].get();
    float fTop = pLine->line_info_.fLineY - pLine->line_info_.fLineAscent -
                 vt_->GetLineLeading();
    float fBottom = pLine->line_info_.fLineY - pLine->line_info_.fLineDescent;
    if (FXSYS_IsFloatBigger(point.y, fTop)) {
      bUp = false;
    }
    if (FXSYS_IsFloatSmaller(point.y, fBottom)) {
      bDown = false;
    }
    if (FXSYS_IsFloatSmaller(point.y, fTop)) {
      nRight = nMid - 1;
      nMid = (nLeft + nRight) / 2;
      continue;
    }
    if (FXSYS_IsFloatBigger(point.y, fBottom)) {
      nLeft = nMid + 1;
      nMid = (nLeft + nRight) / 2;
      continue;
    }
    place = SearchWordPlaceImpl(
        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 CPVT_Section::SearchWordPlace(
    float fx,
    const CPVT_WordPlace& lineplace) const {
  if (!fxcrt::IndexInBounds(line_array_, lineplace.nLineIndex)) {
    return GetBeginWordPlace();
  }

  Line* pLine = line_array_[lineplace.nLineIndex].get();
  return SearchWordPlaceImpl(
      fx - rect_.left,
      CPVT_WordRange(pLine->GetNextWordPlace(pLine->GetBeginWordPlace()),
                     pLine->GetEndWordPlace()));
}

CPVT_WordPlace CPVT_Section::SearchWordPlaceImpl(
    float fx,
    const CPVT_WordRange& range) const {
  CPVT_WordPlace wordplace = range.BeginPos;
  wordplace.nWordIndex = -1;

  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 (!fxcrt::IndexInBounds(word_array_, nMid)) {
      break;
    }
    CPVT_WordInfo* pWord = word_array_[nMid].get();
    if (fx > pWord->fWordX + vt_->GetWordWidth(*pWord) * 0.5f) {
      nLeft = nMid;
      nMid = (nLeft + nRight) / 2;
      continue;
    }
    nRight = nMid;
    nMid = (nLeft + nRight) / 2;
  }
  if (fxcrt::IndexInBounds(word_array_, nMid)) {
    CPVT_WordInfo* pWord = word_array_[nMid].get();
    if (fx > pWord->fWordX + vt_->GetWordWidth(*pWord) * 0.5f) {
      wordplace.nWordIndex = nMid;
    }
  }
  return wordplace;
}

int32_t CPVT_Section::GetLineArraySize() const {
  return fxcrt::CollectionSize<int32_t>(line_array_);
}

const CPVT_Section::Line* CPVT_Section::GetLineFromArray(int32_t index) const {
  if (!fxcrt::IndexInBounds(line_array_, index)) {
    return nullptr;
  }

  return line_array_[index].get();
}

int32_t CPVT_Section::GetWordArraySize() const {
  return fxcrt::CollectionSize<int32_t>(word_array_);
}

const CPVT_WordInfo* CPVT_Section::GetWordFromArray(int32_t index) const {
  if (!fxcrt::IndexInBounds(word_array_, index)) {
    return nullptr;
  }

  return word_array_[index].get();
}

void CPVT_Section::EraseWordsFrom(int32_t index) {
  if (!fxcrt::IndexInBounds(word_array_, index)) {
    return;
  }

  word_array_.erase(word_array_.begin() + index, word_array_.end());
}

CPVT_FloatRect CPVT_Section::RearrangeCharArray() const {
  if (line_array_.empty()) {
    return CPVT_FloatRect();
  }

  float fNodeWidth = vt_->GetPlateWidth() /
                     (vt_->GetCharArray() <= 0 ? 1 : vt_->GetCharArray());
  float fLineAscent =
      vt_->GetFontAscent(vt_->GetDefaultFontIndex(), vt_->GetFontSize());
  float fLineDescent =
      vt_->GetFontDescent(vt_->GetDefaultFontIndex(), vt_->GetFontSize());
  float x = 0.0f;
  float y = vt_->GetLineLeading() + fLineAscent;
  int32_t nStart = 0;
  CPVT_Section::Line* pLine = line_array_.front().get();
  switch (vt_->GetAlignment()) {
    case CPVT_VariableText::Alignment::kLeft:
      pLine->line_info_.fLineX = fNodeWidth * 0.5f;
      break;
    case CPVT_VariableText::Alignment::kCenter:
      nStart =
          (vt_->GetCharArray() - fxcrt::CollectionSize<int32_t>(word_array_)) /
          2;
      pLine->line_info_.fLineX = fNodeWidth * nStart - fNodeWidth * 0.5f;
      break;
    case CPVT_VariableText::Alignment::kRight:
      nStart =
          vt_->GetCharArray() - fxcrt::CollectionSize<int32_t>(word_array_);
      pLine->line_info_.fLineX = fNodeWidth * nStart - fNodeWidth * 0.5f;
      break;
  }
  for (int32_t w = 0, sz = fxcrt::CollectionSize<int32_t>(word_array_); w < sz;
       w++) {
    if (w >= vt_->GetCharArray()) {
      break;
    }

    float fNextWidth = 0;
    if (fxcrt::IndexInBounds(word_array_, w + 1)) {
      CPVT_WordInfo* pNextWord = word_array_[w + 1].get();
      pNextWord->fWordTail = 0;
      fNextWidth = vt_->GetWordWidth(*pNextWord);
    }
    CPVT_WordInfo* pWord = word_array_[w].get();
    pWord->fWordTail = 0;
    float fWordWidth = vt_->GetWordWidth(*pWord);
    float fWordAscent = vt_->GetWordAscent(*pWord);
    float fWordDescent = vt_->GetWordDescent(*pWord);
    x = (float)(fNodeWidth * (w + nStart + 0.5) - fWordWidth * 0.5f);
    pWord->fWordX = x;
    pWord->fWordY = y;
    if (w == 0) {
      pLine->line_info_.fLineX = x;
    }
    if (w != fxcrt::CollectionSize<int32_t>(word_array_) - 1) {
      pWord->fWordTail = (fNodeWidth - (fWordWidth + fNextWidth) * 0.5f > 0
                              ? fNodeWidth - (fWordWidth + fNextWidth) * 0.5f
                              : 0);
    } else {
      pWord->fWordTail = 0;
    }
    x += fWordWidth;
    fLineAscent = std::max(fLineAscent, fWordAscent);
    fLineDescent = std::min(fLineDescent, fWordDescent);
  }
  pLine->line_info_.nBeginWordIndex = 0;
  pLine->line_info_.nEndWordIndex =
      fxcrt::CollectionSize<int32_t>(word_array_) - 1;
  pLine->line_info_.fLineY = y;
  pLine->line_info_.fLineWidth = x - pLine->line_info_.fLineX;
  pLine->line_info_.fLineAscent = fLineAscent;
  pLine->line_info_.fLineDescent = fLineDescent;
  return CPVT_FloatRect(0, 0, x, y - fLineDescent);
}

CPVT_FloatRect CPVT_Section::RearrangeTypeset() {
  line_array_.clear();
  return OutputLines(SplitLines(/*bTypeset=*/true, /*fFontSize=*/0.0f));
}

CPVT_FloatRect CPVT_Section::SplitLines(bool bTypeset, float fFontSize) {
  CPVT_LineInfo line;
  if (word_array_.empty()) {
    float fLineAscent;
    float fLineDescent;
    if (bTypeset) {
      fLineAscent = vt_->GetLineAscent();
      fLineDescent = vt_->GetLineDescent();
      line.nBeginWordIndex = -1;
      line.nEndWordIndex = -1;
      line.fLineWidth = 0;
      line.fLineAscent = fLineAscent;
      line.fLineDescent = fLineDescent;
      AddLine(line);
    } else {
      fLineAscent = vt_->GetFontAscent(vt_->GetDefaultFontIndex(), fFontSize);
      fLineDescent = vt_->GetFontDescent(vt_->GetDefaultFontIndex(), fFontSize);
    }
    float fMaxY = vt_->GetLineLeading() + fLineAscent - fLineDescent;
    return CPVT_FloatRect(0, 0, 0, fMaxY);
  }

  int32_t nLineHead = 0;
  int32_t nLineTail = 0;
  float fMaxX = 0.0f;
  float fMaxY = 0.0f;
  float fLineWidth = 0.0f;
  float fBackupLineWidth = 0.0f;
  float fLineAscent = 0.0f;
  float fBackupLineAscent = 0.0f;
  float fLineDescent = 0.0f;
  float fBackupLineDescent = 0.0f;
  int32_t nWordStartPos = 0;
  bool bFullWord = false;
  int32_t nLineFullWordIndex = 0;
  int32_t nCharIndex = 0;
  float fWordWidth = 0;
  float fTypesetWidth =
      std::max(vt_->GetPlateWidth() - vt_->GetLineIndent(), 0.0f);
  int32_t nTotalWords = fxcrt::CollectionSize<int32_t>(word_array_);
  bool bOpened = false;
  int32_t i = 0;
  while (i < nTotalWords) {
    CPVT_WordInfo* pWord = word_array_[i].get();
    CPVT_WordInfo* pOldWord = pWord;
    if (i > 0) {
      pOldWord = word_array_[i - 1].get();
    }
    if (pWord) {
      if (bTypeset) {
        fLineAscent = std::max(fLineAscent, vt_->GetWordAscent(*pWord));
        fLineDescent = std::min(fLineDescent, vt_->GetWordDescent(*pWord));
        fWordWidth = vt_->GetWordWidth(*pWord);
      } else {
        fLineAscent =
            std::max(fLineAscent, vt_->GetWordAscent(*pWord, fFontSize));
        fLineDescent =
            std::min(fLineDescent, vt_->GetWordDescent(*pWord, fFontSize));
        fWordWidth =
            vt_->GetWordWidth(pWord->nFontIndex, pWord->Word, vt_->GetSubWord(),
                              fFontSize, pWord->fWordTail);
      }
      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 (vt_->IsAutoReturn() && 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.fLineWidth = fLineWidth;
        line.fLineAscent = fLineAscent;
        line.fLineDescent = fLineDescent;
        AddLine(line);
      }
      fMaxY += (fLineAscent + vt_->GetLineLeading());
      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.fLineWidth = fLineWidth;
      line.fLineAscent = fLineAscent;
      line.fLineDescent = fLineDescent;
      AddLine(line);
    }
    fMaxY += (fLineAscent + vt_->GetLineLeading());
    fMaxY -= fLineDescent;
    fMaxX = std::max(fLineWidth, fMaxX);
  }
  return CPVT_FloatRect(0, 0, fMaxX, fMaxY);
}

CPVT_FloatRect CPVT_Section::OutputLines(const CPVT_FloatRect& rect) const {
  float fLineIndent = vt_->GetLineIndent();
  float fTypesetWidth = std::max(vt_->GetPlateWidth() - fLineIndent, 0.0f);
  CPVT_VariableText::Alignment alignment = vt_->GetAlignment();
  auto get_alignment_offset = [alignment, fTypesetWidth](float line_width) {
    switch (alignment) {
      case CPVT_VariableText::Alignment::kLeft:
        return 0.0f;
      case CPVT_VariableText::Alignment::kCenter:
        return (fTypesetWidth - line_width) * 0.5f;
      case CPVT_VariableText::Alignment::kRight:
        return fTypesetWidth - line_width;
    }
    NOTREACHED();
  };

  float fMinX = get_alignment_offset(rect.Width());
  float fMaxX = fMinX + rect.Width();
  float fMinY = 0.0f;
  float fMaxY = rect.Height();

  float fPosY = 0.0f;
  for (const auto& line : line_array_) {
    float fPosX =
        get_alignment_offset(line->line_info_.fLineWidth) + fLineIndent;
    fPosY += vt_->GetLineLeading();
    fPosY += line->line_info_.fLineAscent;

    line->line_info_.fLineX = fPosX - fMinX;
    line->line_info_.fLineY = fPosY - fMinY;
    int32_t line_start = line->line_info_.nBeginWordIndex;
    // `nEndWordIndex` is inclusive. Thus, `line_start == nEndWordIndex` implies
    // a single-word line (length 1), except for the special case where both are
    // -1 (representing an empty line), which also computes to length 1 but
    // safely yields an empty span due to internal clamping in
    // GetWordRangeIteratorPair().
    int32_t line_length = line->line_info_.nEndWordIndex - line_start + 1;
    pdfium::span<const std::unique_ptr<CPVT_WordInfo>> words =
        GetWordRangeSpan(line_start, line_length);

    WideString line_str;
    line_str.Reserve(words.size());
    for (const auto& word : words) {
      line_str += word->Word;
    }

    CFX_BidiString bidi(line_str);
    const bool is_overall_direction_right =
        bidi.OverallDirection() == CFX_BidiChar::Direction::kRight;

    auto position_word = [&](CPVT_WordInfo& word) {
      word.fWordX = fPosX - fMinX;
      word.fWordY = fPosY - fMinY;
      fPosX += vt_->GetWordWidth(word);
    };

    for (const auto& segment : bidi) {
      auto segment_words = words.subspan(segment.start, segment.count);
      const bool is_rtl =
          (segment.direction == CFX_BidiChar::Direction::kRight ||
           (segment.direction == CFX_BidiChar::Direction::kNeutral &&
            is_overall_direction_right));

      if (is_rtl) {
        for (const auto& word : pdfium::Reversed(segment_words)) {
          word->is_rtl = true;
          position_word(*word);
        }
      } else {
        for (const auto& word : segment_words) {
          word->is_rtl = false;
          position_word(*word);
        }
      }
    }
    fPosY -= line->line_info_.fLineDescent;
  }
  return CPVT_FloatRect(fMinX, fMinY, fMaxX, fMaxY);
}

void CPVT_Section::ClearLeftWords(int32_t word_index) {
  WordRangeIteratorPair range = GetWordRangeIteratorPair(0, word_index + 1);
  word_array_.erase(range.begin, range.end);
}

void CPVT_Section::ClearRightWords(int32_t word_index) {
  WordRangeIteratorPair range =
      GetWordRangeIteratorPair(word_index + 1, GetWordArraySize());
  word_array_.erase(range.begin, range.end);
}

void CPVT_Section::ClearMidWords(int32_t begin_index, int32_t end_index) {
  WordRangeIteratorPair range =
      GetWordRangeIteratorPair(begin_index + 1, end_index + 1);
  word_array_.erase(range.begin, range.end);
}

CPVT_Section::WordRangeIteratorPair CPVT_Section::GetWordRangeIteratorPair(
    int32_t begin_index,
    int32_t end_index) const {
  int32_t size = fxcrt::CollectionSize<int32_t>(word_array_);
  end_index = std::clamp(end_index, 0, size);
  begin_index = std::clamp(begin_index, 0, end_index);
  // SAFETY: indices clamped to `word_array_` size.
  return UNSAFE_BUFFERS(
      {word_array_.begin() + begin_index, word_array_.begin() + end_index});
}

pdfium::span<const std::unique_ptr<CPVT_WordInfo>>
CPVT_Section::GetWordRangeSpan(int32_t start, int32_t length) const {
  WordRangeIteratorPair range = GetWordRangeIteratorPair(start, start + length);
  // SAFETY: GetWordRangeIteratorPair() above returns valid iterators or
  // `word_array_.end()`.
  return UNSAFE_BUFFERS(pdfium::span<const std::unique_ptr<CPVT_WordInfo>>(
      std::to_address(range.begin), std::to_address(range.end)));
}

void CPVT_Section::ClearWords(const CPVT_WordRange& PlaceRange) {
  CPVT_WordPlace SecBeginPos = GetBeginWordPlace();
  CPVT_WordPlace SecEndPos = GetEndWordPlace();
  if (PlaceRange.BeginPos >= SecBeginPos) {
    if (PlaceRange.EndPos <= SecEndPos) {
      ClearMidWords(PlaceRange.BeginPos.nWordIndex,
                    PlaceRange.EndPos.nWordIndex);
    } else {
      ClearRightWords(PlaceRange.BeginPos.nWordIndex);
    }
  } else if (PlaceRange.EndPos <= SecEndPos) {
    ClearLeftWords(PlaceRange.EndPos.nWordIndex);
  } else {
    word_array_.clear();
  }
}

void CPVT_Section::ClearWord(const CPVT_WordPlace& place) {
  if (fxcrt::IndexInBounds(word_array_, place.nWordIndex)) {
    word_array_.erase(word_array_.begin() + place.nWordIndex);
  }
}
