// Copyright 2017 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 "xfa/fxfa/cxfa_textlayout.h"

#include <math.h>

#include <algorithm>
#include <utility>

#include "core/fxcrt/check.h"
#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/css/cfx_csscomputedstyle.h"
#include "core/fxcrt/css/cfx_cssstyleselector.h"
#include "core/fxcrt/notreached.h"
#include "core/fxcrt/stl_util.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
#include "core/fxcrt/xml/cfx_xmltext.h"
#include "core/fxge/cfx_fillrenderoptions.h"
#include "core/fxge/cfx_graphstatedata.h"
#include "core/fxge/cfx_path.h"
#include "core/fxge/cfx_renderdevice.h"
#include "core/fxge/text_char_pos.h"
#include "fxjs/xfa/cjx_object.h"
#include "xfa/fde/cfde_textout.h"
#include "xfa/fgas/font/cfgas_gefont.h"
#include "xfa/fgas/layout/cfgas_linkuserdata.h"
#include "xfa/fgas/layout/cfgas_rtfbreak.h"
#include "xfa/fgas/layout/cfgas_textuserdata.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_textparser.h"
#include "xfa/fxfa/cxfa_textprovider.h"
#include "xfa/fxfa/cxfa_texttabstopscontext.h"
#include "xfa/fxfa/parser/cxfa_font.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_para.h"

namespace {

constexpr float kHeightTolerance = 0.001f;

void ProcessText(WideString* pText) {
  size_t iLen = pText->GetLength();
  if (iLen == 0) {
    return;
  }

  size_t iTrimFront = 0;
  {
    // Span's lifetime must end before ReleaseBuffer() below.
    pdfium::span<wchar_t> psz = pText->GetBuffer(iLen);
    wchar_t wPrev = 0;
    for (size_t i = 0; i < iLen; i++) {
      wchar_t wch = psz[i];
      if (wch < 0x20) {
        wch = 0x20;
      }
      if (wch == 0x20 && wPrev == 0x20) {
        continue;
      }

      wPrev = wch;
      psz[iTrimFront++] = wch;
    }
  }
  pText->ReleaseBuffer(iTrimFront);
}

}  // namespace

CXFA_TextLayout::TextPiece::TextPiece() = default;

CXFA_TextLayout::TextPiece::~TextPiece() = default;

CXFA_TextLayout::PieceLine::PieceLine() = default;

CXFA_TextLayout::PieceLine::~PieceLine() = default;

CXFA_TextLayout::LoaderContext::LoaderContext() = default;

CXFA_TextLayout::LoaderContext::~LoaderContext() = default;

void CXFA_TextLayout::LoaderContext::Trace(cppgc::Visitor* visitor) const {
  visitor->Trace(pNode);
}

CXFA_TextLayout::CXFA_TextLayout(CXFA_FFDoc* doc,
                                 CXFA_TextProvider* pTextProvider)
    : doc_(doc),
      text_provider_(pTextProvider),
      text_parser_(cppgc::MakeGarbageCollected<CXFA_TextParser>(
          doc->GetHeap()->GetAllocationHandle())) {
  DCHECK(text_provider_);
}

CXFA_TextLayout::~CXFA_TextLayout() = default;

void CXFA_TextLayout::Trace(cppgc::Visitor* visitor) const {
  visitor->Trace(doc_);
  visitor->Trace(text_provider_);
  visitor->Trace(text_data_node_);
  visitor->Trace(text_parser_);
  visitor->Trace(loader_);
}

void CXFA_TextLayout::Unload() {
  piece_lines_.clear();
  break_.reset();
}

WideString CXFA_TextLayout::GetLinkURLAtPoint(const CFX_PointF& point) {
  for (const auto& pPieceLine : piece_lines_) {
    for (const auto& pPiece : pPieceLine->text_pieces_) {
      if (pPiece->pLinkData && pPiece->rtPiece.Contains(point)) {
        return pPiece->pLinkData->GetLinkURL();
      }
    }
  }
  return WideString();
}

void CXFA_TextLayout::GetTextDataNode() {
  CXFA_Node* pNode = text_provider_->GetTextNode(&rich_text_);
  if (pNode && rich_text_) {
    text_parser_->Reset();
  }

  text_data_node_ = pNode;
}

CFX_XMLNode* CXFA_TextLayout::GetXMLContainerNode() {
  if (!rich_text_) {
    return nullptr;
  }

  CFX_XMLNode* pXMLRoot = text_data_node_->GetXMLMappingNode();
  if (!pXMLRoot) {
    return nullptr;
  }

  for (CFX_XMLNode* pXMLChild = pXMLRoot->GetFirstChild(); pXMLChild;
       pXMLChild = pXMLChild->GetNextSibling()) {
    CFX_XMLElement* pXMLElement = ToXMLElement(pXMLChild);
    if (!pXMLElement) {
      continue;
    }
    WideString wsTag = pXMLElement->GetLocalTagName();
    if (wsTag.EqualsASCII("body") || wsTag.EqualsASCII("html")) {
      return pXMLChild;
    }
  }
  return nullptr;
}

std::unique_ptr<CFGAS_RTFBreak> CXFA_TextLayout::CreateBreak(bool bDefault) {
  Mask<CFGAS_Break::LayoutStyle> dwStyle = CFGAS_Break::LayoutStyle::kExpandTab;
  if (!bDefault) {
    dwStyle |= CFGAS_Break::LayoutStyle::kPagination;
  }

  auto pBreak = std::make_unique<CFGAS_RTFBreak>(dwStyle);
  pBreak->SetLineBreakTolerance(1);
  pBreak->SetFont(text_parser_->GetFont(doc_.Get(), text_provider_, nullptr));
  pBreak->SetFontSize(text_parser_->GetFontSize(text_provider_, nullptr));
  return pBreak;
}

void CXFA_TextLayout::InitBreak(float fLineWidth) {
  CXFA_Para* para = text_provider_->GetParaIfExists();
  float fStart = 0;
  float fStartPos = 0;
  if (para) {
    CFGAS_RTFBreak::LineAlignment iAlign = CFGAS_RTFBreak::LineAlignment::Left;
    switch (para->GetHorizontalAlign()) {
      case XFA_AttributeValue::Center:
        iAlign = CFGAS_RTFBreak::LineAlignment::Center;
        break;
      case XFA_AttributeValue::Right:
        iAlign = CFGAS_RTFBreak::LineAlignment::Right;
        break;
      case XFA_AttributeValue::Justify:
        iAlign = CFGAS_RTFBreak::LineAlignment::Justified;
        break;
      case XFA_AttributeValue::JustifyAll:
        iAlign = CFGAS_RTFBreak::LineAlignment::Distributed;
        break;
      case XFA_AttributeValue::Left:
      case XFA_AttributeValue::Radix:
        break;
      default:
        NOTREACHED();
    }
    break_->SetAlignment(iAlign);

    fStart = para->GetMarginLeft();
    if (text_provider_->IsCheckButtonAndAutoWidth()) {
      if (iAlign != CFGAS_RTFBreak::LineAlignment::Left) {
        fLineWidth -= para->GetMarginRight();
      }
    } else {
      fLineWidth -= para->GetMarginRight();
    }
    if (fLineWidth < 0) {
      fLineWidth = fStart;
    }

    fStartPos = fStart;
    float fIndent = para->GetTextIndent();
    if (fIndent > 0) {
      fStartPos += fIndent;
    }
  }

  break_->SetLineBoundary(fStart, fLineWidth);
  break_->SetLineStartPos(fStartPos);

  CXFA_Font* font = text_provider_->GetFontIfExists();
  if (font) {
    break_->SetHorizontalScale(
        static_cast<int32_t>(font->GetHorizontalScale()));
    break_->SetVerticalScale(static_cast<int32_t>(font->GetVerticalScale()));
    break_->SetCharSpace(font->GetLetterSpacing());
  }

  float fFontSize = text_parser_->GetFontSize(text_provider_, nullptr);
  break_->SetFontSize(fFontSize);
  break_->SetFont(text_parser_->GetFont(doc_.Get(), text_provider_, nullptr));
  break_->SetLineBreakTolerance(fFontSize * 0.2f);
}

void CXFA_TextLayout::InitBreak(CFX_CSSComputedStyle* pStyle,
                                CFX_CSSDisplay eDisplay,
                                float fLineWidth,
                                const CFX_XMLNode* pXMLNode,
                                CFX_CSSComputedStyle* pParentStyle) {
  if (!pStyle) {
    InitBreak(fLineWidth);
    return;
  }

  if (eDisplay == CFX_CSSDisplay::Block ||
      eDisplay == CFX_CSSDisplay::ListItem) {
    CFGAS_RTFBreak::LineAlignment iAlign = CFGAS_RTFBreak::LineAlignment::Left;
    switch (pStyle->GetTextAlign()) {
      case CFX_CSSTextAlign::Right:
        iAlign = CFGAS_RTFBreak::LineAlignment::Right;
        break;
      case CFX_CSSTextAlign::Center:
        iAlign = CFGAS_RTFBreak::LineAlignment::Center;
        break;
      case CFX_CSSTextAlign::Justify:
        iAlign = CFGAS_RTFBreak::LineAlignment::Justified;
        break;
      case CFX_CSSTextAlign::JustifyAll:
        iAlign = CFGAS_RTFBreak::LineAlignment::Distributed;
        break;
      default:
        break;
    }
    break_->SetAlignment(iAlign);

    float fStart = 0;
    const CFX_CSSRect* pRect = pStyle->GetMarginWidth();
    const CFX_CSSRect* pPaddingRect = pStyle->GetPaddingWidth();
    if (pRect) {
      fStart = pRect->left.GetValue();
      fLineWidth -= pRect->right.GetValue();
      if (pPaddingRect) {
        fStart += pPaddingRect->left.GetValue();
        fLineWidth -= pPaddingRect->right.GetValue();
      }
      if (eDisplay == CFX_CSSDisplay::ListItem) {
        const CFX_CSSRect* pParRect = pParentStyle->GetMarginWidth();
        const CFX_CSSRect* pParPaddingRect = pParentStyle->GetPaddingWidth();
        if (pParRect) {
          fStart += pParRect->left.GetValue();
          fLineWidth -= pParRect->right.GetValue();
          if (pParPaddingRect) {
            fStart += pParPaddingRect->left.GetValue();
            fLineWidth -= pParPaddingRect->right.GetValue();
          }
        }
        CFX_CSSRect pNewRect;
        pNewRect.left.Set(CFX_CSSLengthUnit::Point, fStart);
        pNewRect.right.Set(CFX_CSSLengthUnit::Point, pRect->right.GetValue());
        pNewRect.top.Set(CFX_CSSLengthUnit::Point, pRect->top.GetValue());
        pNewRect.bottom.Set(CFX_CSSLengthUnit::Point, pRect->bottom.GetValue());
        pStyle->SetMarginWidth(pNewRect);
      }
    }
    break_->SetLineBoundary(fStart, fLineWidth);
    float fIndent = pStyle->GetTextIndent().GetValue();
    if (fIndent > 0) {
      fStart += fIndent;
    }

    break_->SetLineStartPos(fStart);
    break_->SetTabWidth(text_parser_->GetTabInterval(pStyle));
    if (!tabstop_context_) {
      tabstop_context_ = std::make_unique<CXFA_TextTabstopsContext>();
    }
    text_parser_->GetTabstops(pStyle, tabstop_context_.get());
    for (const auto& stop : tabstop_context_->tabstops_) {
      break_->AddPositionedTab(stop.fTabstops);
    }
  }
  float fFontSize = text_parser_->GetFontSize(text_provider_, pStyle);
  break_->SetFontSize(fFontSize);
  break_->SetLineBreakTolerance(fFontSize * 0.2f);
  break_->SetFont(text_parser_->GetFont(doc_.Get(), text_provider_, pStyle));
  break_->SetHorizontalScale(
      text_parser_->GetHorScale(text_provider_, pStyle, pXMLNode));
  break_->SetVerticalScale(text_parser_->GetVerScale(text_provider_, pStyle));
  break_->SetCharSpace(pStyle->GetLetterSpacing().GetValue());
}

float CXFA_TextLayout::GetLayoutHeight() {
  if (!loader_) {
    return 0;
  }

  if (loader_->lineHeights.empty() && loader_->fWidth > 0) {
    CFX_SizeF szMax(loader_->fWidth, loader_->fHeight);
    loader_->bSaveLineHeight = true;
    loader_->fLastPos = 0;
    CFX_SizeF szDef = CalcSize(szMax, szMax);
    loader_->bSaveLineHeight = false;
    return szDef.height;
  }

  float fHeight = loader_->fHeight;
  if (fHeight < 0.1f) {
    fHeight = 0;
    for (float value : loader_->lineHeights) {
      fHeight += value;
    }
  }
  return fHeight;
}

float CXFA_TextLayout::StartLayout(float fWidth) {
  if (!loader_) {
    loader_ = cppgc::MakeGarbageCollected<LoaderContext>(
        doc_->GetHeap()->GetAllocationHandle());
  }

  if (fWidth < 0 ||
      (loader_->fWidth > -1 && fabs(fWidth - loader_->fWidth) > 0)) {
    loader_->lineHeights.clear();
    blocks_.clear();
    Unload();
    loader_->fStartLineOffset = 0;
  }
  loader_->fWidth = fWidth;

  if (fWidth >= 0) {
    return fWidth;
  }

  CFX_SizeF szMax;

  loader_->bSaveLineHeight = true;
  loader_->fLastPos = 0;
  CFX_SizeF szDef = CalcSize(szMax, szMax);
  loader_->bSaveLineHeight = false;
  return szDef.width;
}

float CXFA_TextLayout::DoLayout(float fTextHeight) {
  if (!loader_) {
    return fTextHeight;
  }

  UpdateLoaderHeight(fTextHeight);
  return fTextHeight;
}

float CXFA_TextLayout::DoSplitLayout(size_t szBlockIndex,
                                     float fCalcHeight,
                                     float fTextHeight) {
  if (!loader_) {
    return fCalcHeight;
  }

  UpdateLoaderHeight(fTextHeight);

  if (fCalcHeight < 0) {
    return fCalcHeight;
  }

  has_block_ = true;
  if (blocks_.empty() && loader_->fHeight > 0) {
    float fHeight = fTextHeight - GetLayoutHeight();
    if (fHeight > 0) {
      XFA_AttributeValue iAlign = text_parser_->GetVAlign(text_provider_);
      if (iAlign == XFA_AttributeValue::Middle) {
        fHeight /= 2.0f;
      } else if (iAlign != XFA_AttributeValue::Bottom) {
        fHeight = 0;
      }
      loader_->fStartLineOffset = fHeight;
    }
  }

  float fLinePos = loader_->fStartLineOffset;
  size_t szLineIndex = 0;
  if (!blocks_.empty()) {
    if (szBlockIndex < blocks_.size()) {
      szLineIndex = blocks_[szBlockIndex].szIndex;
    } else {
      szLineIndex = GetNextIndexFromLastBlockData();
    }
    for (size_t i = 0; i < std::min(szBlockIndex, loader_->blockHeights.size());
         ++i) {
      fLinePos -= loader_->blockHeights[i].fHeight;
    }
  }

  if (szLineIndex >= loader_->lineHeights.size()) {
    return fCalcHeight;
  }

  if (loader_->lineHeights[szLineIndex] - fCalcHeight > kHeightTolerance) {
    return 0;
  }

  for (size_t i = szLineIndex; i < loader_->lineHeights.size(); ++i) {
    float fLineHeight = loader_->lineHeights[i];
    if (fLinePos + fLineHeight - fCalcHeight <= kHeightTolerance) {
      fLinePos += fLineHeight;
      continue;
    }

    if (szBlockIndex < blocks_.size()) {
      blocks_[szBlockIndex] = {szLineIndex, i - szLineIndex};
    } else {
      blocks_.push_back({szLineIndex, i - szLineIndex});
    }

    if (i != szLineIndex) {
      return fLinePos;
    }

    if (fCalcHeight > fLinePos) {
      return fCalcHeight;
    }

    if (szBlockIndex < loader_->blockHeights.size() &&
        loader_->blockHeights[szBlockIndex].szBlockIndex == szBlockIndex) {
      loader_->blockHeights[szBlockIndex].fHeight = fCalcHeight;
    } else {
      loader_->blockHeights.push_back({szBlockIndex, fCalcHeight});
    }
    return fCalcHeight;
  }
  return fCalcHeight;
}

size_t CXFA_TextLayout::CountBlocks() const {
  size_t szCount = blocks_.size();
  return szCount > 0 ? szCount : 1;
}

size_t CXFA_TextLayout::GetNextIndexFromLastBlockData() const {
  return blocks_.back().szIndex + blocks_.back().szLength;
}

void CXFA_TextLayout::UpdateLoaderHeight(float fTextHeight) {
  loader_->fHeight = fTextHeight;
  if (loader_->fHeight < 0) {
    loader_->fHeight = GetLayoutHeight();
  }
}

CFX_SizeF CXFA_TextLayout::CalcSize(const CFX_SizeF& minSize,
                                    const CFX_SizeF& maxSize) {
  float width = maxSize.width;
  if (width < 1) {
    width = 0xFFFF;
  }

  break_ = CreateBreak(false);
  float fLinePos = 0;
  lines_ = 0;
  max_width_ = 0;
  Loader(width, &fLinePos, false);
  if (fLinePos < 0.1f) {
    fLinePos = text_parser_->GetFontSize(text_provider_, nullptr);
  }

  tabstop_context_.reset();
  return CFX_SizeF(max_width_, fLinePos);
}

float CXFA_TextLayout::Layout(const CFX_SizeF& size) {
  if (size.width < 1) {
    return 0.f;
  }

  Unload();
  break_ = CreateBreak(true);
  if (loader_) {
    loader_->iTotalLines = -1;
    loader_->nCharIdx = 0;
  }

  lines_ = 0;
  float fLinePos = 0;
  Loader(size.width, &fLinePos, true);
  UpdateAlign(size.height, fLinePos);
  tabstop_context_.reset();
  return fLinePos;
}

bool CXFA_TextLayout::LayoutInternal(size_t szBlockIndex) {
  DCHECK(szBlockIndex < CountBlocks());

  if (!loader_ || loader_->fWidth < 1) {
    return false;
  }

  loader_->iTotalLines = -1;
  lines_ = 0;
  float fLinePos = 0;
  CXFA_Node* pNode = nullptr;
  CFX_SizeF szText(loader_->fWidth, loader_->fHeight);
  if (szBlockIndex < loader_->blockHeights.size()) {
    return true;
  }
  if (szBlockIndex == loader_->blockHeights.size()) {
    Unload();
    break_ = CreateBreak(true);
    fLinePos = loader_->fStartLineOffset;
    for (size_t i = 0; i < loader_->blockHeights.size(); ++i) {
      fLinePos -= loader_->blockHeights[i].fHeight;
    }

    loader_->nCharIdx = 0;
    if (!blocks_.empty()) {
      loader_->iTotalLines =
          pdfium::checked_cast<int32_t>(blocks_[szBlockIndex].szLength);
    }
    Loader(szText.width, &fLinePos, true);
    if (blocks_.empty() && loader_->fStartLineOffset < 0.1f) {
      UpdateAlign(szText.height, fLinePos);
    }
  } else if (text_data_node_) {
    if (!blocks_.empty() && szBlockIndex < blocks_.size() - 1) {
      loader_->iTotalLines =
          pdfium::checked_cast<int32_t>(blocks_[szBlockIndex].szLength);
    }
    break_->Reset();
    if (rich_text_) {
      CFX_XMLNode* pContainerNode = GetXMLContainerNode();
      if (!pContainerNode) {
        return true;
      }

      const CFX_XMLNode* pXMLNode = loader_->pXMLNode;
      if (!pXMLNode) {
        return true;
      }

      const CFX_XMLNode* pSaveXMLNode = pXMLNode;
      for (; pXMLNode; pXMLNode = pXMLNode->GetNextSibling()) {
        if (!LoadRichText(pXMLNode, szText.width, &fLinePos,
                          loader_->pParentStyle, true, nullptr, true, false,
                          0)) {
          break;
        }
      }
      while (!pXMLNode) {
        pXMLNode = pSaveXMLNode->GetParent();
        if (pXMLNode == pContainerNode) {
          break;
        }
        if (!LoadRichText(pXMLNode, szText.width, &fLinePos,
                          loader_->pParentStyle, true, nullptr, false, false,
                          0)) {
          break;
        }
        pSaveXMLNode = pXMLNode;
        pXMLNode = pXMLNode->GetNextSibling();
        if (!pXMLNode) {
          continue;
        }
        for (; pXMLNode; pXMLNode = pXMLNode->GetNextSibling()) {
          if (!LoadRichText(pXMLNode, szText.width, &fLinePos,
                            loader_->pParentStyle, true, nullptr, true, false,
                            0)) {
            break;
          }
        }
      }
    } else {
      pNode = loader_->pNode.Get();
      if (!pNode) {
        return true;
      }
      LoadText(pNode, szText.width, &fLinePos, true);
    }
  }
  return true;
}

void CXFA_TextLayout::ItemBlocks(const CFX_RectF& rtText, size_t szBlockIndex) {
  if (!loader_) {
    return;
  }

  if (loader_->lineHeights.empty()) {
    return;
  }

  float fLinePos = loader_->fStartLineOffset;
  size_t szLineIndex = 0;
  if (szBlockIndex > 0) {
    if (szBlockIndex <= loader_->blockHeights.size()) {
      for (size_t i = 0; i < szBlockIndex; ++i) {
        fLinePos -= loader_->blockHeights[i].fHeight;
      }
    } else {
      fLinePos = 0;
    }
    szLineIndex = GetNextIndexFromLastBlockData();
  }

  size_t i;
  for (i = szLineIndex; i < loader_->lineHeights.size(); ++i) {
    float fLineHeight = loader_->lineHeights[i];
    if (fLinePos + fLineHeight - rtText.height > kHeightTolerance) {
      blocks_.push_back({szLineIndex, i - szLineIndex});
      return;
    }
    fLinePos += fLineHeight;
  }
  if (i > szLineIndex) {
    blocks_.push_back({szLineIndex, i - szLineIndex});
  }
}

bool CXFA_TextLayout::DrawString(CFX_RenderDevice* pFxDevice,
                                 const CFX_Matrix& mtDoc2Device,
                                 const CFX_RectF& rtClip,
                                 size_t szBlockIndex) {
  if (!pFxDevice) {
    return false;
  }

  pFxDevice->SaveState();
  pFxDevice->SetClip_Rect(rtClip.GetOuterRect());

  if (piece_lines_.empty()) {
    size_t szBlockCount = CountBlocks();
    for (size_t i = 0; i < szBlockCount; ++i) {
      LayoutInternal(i);
    }
    tabstop_context_.reset();
    loader_.Clear();
  }

  std::vector<TextCharPos> char_pos(1);
  size_t szLineStart = 0;
  size_t szPieceLines = piece_lines_.size();
  if (!blocks_.empty()) {
    if (szBlockIndex < blocks_.size()) {
      szLineStart = blocks_[szBlockIndex].szIndex;
      szPieceLines = blocks_[szBlockIndex].szLength;
    } else {
      szPieceLines = 0;
    }
  }

  for (size_t i = 0; i < szPieceLines; ++i) {
    if (i + szLineStart >= piece_lines_.size()) {
      break;
    }

    PieceLine* pPieceLine = piece_lines_[i + szLineStart].get();
    for (size_t j = 0; j < pPieceLine->text_pieces_.size(); ++j) {
      const TextPiece* pPiece = pPieceLine->text_pieces_[j].get();
      int32_t iChars = pPiece->iChars;
      if (fxcrt::CollectionSize<int32_t>(char_pos) < iChars) {
        char_pos.resize(iChars);
      }
      RenderString(pFxDevice, pPieceLine, j, char_pos, mtDoc2Device);
    }
    for (size_t j = 0; j < pPieceLine->text_pieces_.size(); ++j) {
      RenderPath(pFxDevice, pPieceLine, j, char_pos, mtDoc2Device);
    }
  }
  pFxDevice->RestoreState(false);
  return szPieceLines > 0;
}

void CXFA_TextLayout::UpdateAlign(float fHeight, float fBottom) {
  fHeight -= fBottom;
  if (fHeight < 0.1f) {
    return;
  }

  switch (text_parser_->GetVAlign(text_provider_)) {
    case XFA_AttributeValue::Middle:
      fHeight /= 2.0f;
      break;
    case XFA_AttributeValue::Bottom:
      break;
    default:
      return;
  }

  for (const auto& pPieceLine : piece_lines_) {
    for (const auto& pPiece : pPieceLine->text_pieces_) {
      pPiece->rtPiece.top += fHeight;
    }
  }
}

void CXFA_TextLayout::Loader(float textWidth,
                             float* pLinePos,
                             bool bSavePieces) {
  GetTextDataNode();
  if (!text_data_node_) {
    return;
  }

  if (!rich_text_) {
    LoadText(text_data_node_, textWidth, pLinePos, bSavePieces);
    return;
  }

  const CFX_XMLNode* pXMLContainer = GetXMLContainerNode();
  if (!pXMLContainer) {
    return;
  }

  if (!text_parser_->IsParsed()) {
    text_parser_->DoParse(pXMLContainer, text_provider_);
  }

  auto pRootStyle = text_parser_->CreateRootStyle(text_provider_);
  LoadRichText(pXMLContainer, textWidth, pLinePos, std::move(pRootStyle),
               bSavePieces, nullptr, true, false, 0);
}

void CXFA_TextLayout::LoadText(CXFA_Node* pNode,
                               float textWidth,
                               float* pLinePos,
                               bool bSavePieces) {
  InitBreak(textWidth);

  CXFA_Para* para = text_provider_->GetParaIfExists();
  float fSpaceAbove = 0;
  if (para) {
    fSpaceAbove = para->GetSpaceAbove();
    if (fSpaceAbove < 0.1f) {
      fSpaceAbove = 0;
    }

    switch (para->GetVerticalAlign()) {
      case XFA_AttributeValue::Top:
      case XFA_AttributeValue::Middle:
      case XFA_AttributeValue::Bottom: {
        *pLinePos += fSpaceAbove;
        break;
      }
      default:
        NOTREACHED();
    }
  }

  WideString wsText = pNode->JSObject()->GetContent(false);
  wsText.TrimBack(L" ");
  bool bRet = AppendChar(wsText, pLinePos, fSpaceAbove, bSavePieces);
  if (bRet && loader_) {
    loader_->pNode = pNode;
  } else {
    EndBreak(CFGAS_Char::BreakType::kParagraph, pLinePos, bSavePieces);
  }
}

bool CXFA_TextLayout::LoadRichText(const CFX_XMLNode* pXMLNode,
                                   float textWidth,
                                   float* pLinePos,
                                   RetainPtr<CFX_CSSComputedStyle> pParentStyle,
                                   bool bSavePieces,
                                   RetainPtr<CFGAS_LinkUserData> pLinkData,
                                   bool bEndBreak,
                                   bool bIsOl,
                                   int32_t iLiCount) {
  if (!pXMLNode) {
    return false;
  }

  CXFA_TextParser::Context* context =
      text_parser_->GetParseContextFromMap(pXMLNode);
  CFX_CSSDisplay eDisplay = CFX_CSSDisplay::None;
  bool bContentNode = false;
  float fSpaceBelow = 0;
  RetainPtr<CFX_CSSComputedStyle> pStyle;
  WideString wsName;
  if (bEndBreak) {
    bool bCurOl = false;
    bool bCurLi = false;
    const CFX_XMLElement* pElement = nullptr;
    if (context) {
      if (pXMLNode->GetType() == CFX_XMLNode::Type::kText) {
        bContentNode = true;
      } else if (pXMLNode->GetType() == CFX_XMLNode::Type::kElement) {
        pElement = static_cast<const CFX_XMLElement*>(pXMLNode);
        wsName = pElement->GetLocalTagName();
      }
      if (wsName.EqualsASCII("ol")) {
        bIsOl = true;
        bCurOl = true;
      }

      eDisplay = context->GetDisplay();
      if (eDisplay != CFX_CSSDisplay::Block &&
          eDisplay != CFX_CSSDisplay::Inline &&
          eDisplay != CFX_CSSDisplay::ListItem) {
        return true;
      }

      pStyle = text_parser_->ComputeStyle(pXMLNode, pParentStyle);
      InitBreak(bContentNode ? pParentStyle.Get() : pStyle.Get(), eDisplay,
                textWidth, pXMLNode, pParentStyle.Get());
      if ((eDisplay == CFX_CSSDisplay::Block ||
           eDisplay == CFX_CSSDisplay::ListItem) &&
          pStyle &&
          (wsName.IsEmpty() ||
           !(wsName.EqualsASCII("body") || wsName.EqualsASCII("html") ||
             wsName.EqualsASCII("ol") || wsName.EqualsASCII("ul")))) {
        const CFX_CSSRect* pRect = pStyle->GetMarginWidth();
        if (pRect) {
          *pLinePos += pRect->top.GetValue();
          fSpaceBelow = pRect->bottom.GetValue();
        }
      }

      if (wsName.EqualsASCII("a")) {
        WideString wsLinkContent = pElement->GetAttribute(L"href");
        if (!wsLinkContent.IsEmpty()) {
          pLinkData = pdfium::MakeRetain<CFGAS_LinkUserData>(wsLinkContent);
        }
      }

      int32_t iTabCount = text_parser_->CountTabs(
          bContentNode ? pParentStyle.Get() : pStyle.Get());
      bool bSpaceRun = text_parser_->IsSpaceRun(
          bContentNode ? pParentStyle.Get() : pStyle.Get());
      WideString wsText;
      if (bContentNode && iTabCount == 0) {
        wsText = ToXMLText(pXMLNode)->GetText();
      } else if (wsName.EqualsASCII("br")) {
        wsText = WideString(L'\n');
      } else if (wsName.EqualsASCII("li")) {
        bCurLi = true;
        if (bIsOl) {
          wsText = WideString::Format(L"%d.  ", iLiCount);
        } else {
          wsText = 0x00B7 + WideStringView(L" ");
        }
      } else if (!bContentNode) {
        if (iTabCount > 0) {
          while (iTabCount-- > 0) {
            wsText += L'\t';
          }
        } else {
          std::optional<WideString> obj =
              text_parser_->GetEmbeddedObj(text_provider_, pXMLNode);
          if (obj.has_value()) {
            wsText = obj.value();
          }
        }
      }

      if (!wsText.IsEmpty() && bContentNode && !bSpaceRun) {
        ProcessText(&wsText);
      }

      if (loader_) {
        if (wsText.GetLength() > 0 && loader_->bFilterSpace) {
          wsText.TrimFront(L" ");
        }
        if (CFX_CSSDisplay::Block == eDisplay) {
          loader_->bFilterSpace = true;
        } else if (CFX_CSSDisplay::Inline == eDisplay &&
                   loader_->bFilterSpace) {
          loader_->bFilterSpace = false;
        } else if (wsText.GetLength() > 0 && wsText.Back() == 0x20) {
          loader_->bFilterSpace = true;
        } else if (wsText.GetLength() != 0) {
          loader_->bFilterSpace = false;
        }
      }

      if (wsText.GetLength() > 0) {
        if (!loader_ || loader_->nCharIdx == 0) {
          auto pUserData = pdfium::MakeRetain<CFGAS_TextUserData>(
              bContentNode ? pParentStyle : pStyle, pLinkData);
          break_->SetUserData(pUserData);
        }

        if (AppendChar(wsText, pLinePos, 0, bSavePieces)) {
          if (loader_) {
            loader_->bFilterSpace = false;
          }
          if (!IsEnd(bSavePieces)) {
            return true;
          }
          if (loader_ && loader_->iTotalLines > -1) {
            loader_->pXMLNode = pXMLNode;
            loader_->pParentStyle = pParentStyle;
          }
          return false;
        }
      }
    }

    for (CFX_XMLNode* pChildNode = pXMLNode->GetFirstChild(); pChildNode;
         pChildNode = pChildNode->GetNextSibling()) {
      if (bCurOl) {
        iLiCount++;
      }

      if (!LoadRichText(pChildNode, textWidth, pLinePos,
                        context ? pStyle : pParentStyle, bSavePieces, pLinkData,
                        true, bIsOl, iLiCount)) {
        return false;
      }
    }

    if (loader_) {
      if (CFX_CSSDisplay::Block == eDisplay) {
        loader_->bFilterSpace = true;
      }
    }
    if (bCurLi) {
      EndBreak(CFGAS_Char::BreakType::kLine, pLinePos, bSavePieces);
    }
  } else {
    if (context) {
      eDisplay = context->GetDisplay();
    }
  }

  if (!context || bContentNode) {
    return true;
  }

  CFGAS_Char::BreakType dwStatus = (eDisplay == CFX_CSSDisplay::Block)
                                       ? CFGAS_Char::BreakType::kParagraph
                                       : CFGAS_Char::BreakType::kPiece;
  EndBreak(dwStatus, pLinePos, bSavePieces);
  if (eDisplay == CFX_CSSDisplay::Block) {
    *pLinePos += fSpaceBelow;
    if (tabstop_context_) {
      tabstop_context_->RemoveAll();
    }
  }
  if (!IsEnd(bSavePieces)) {
    return true;
  }

  if (loader_ && loader_->iTotalLines > -1) {
    loader_->pXMLNode = pXMLNode->GetNextSibling();
    loader_->pParentStyle = pParentStyle;
  }
  return false;
}

bool CXFA_TextLayout::AppendChar(const WideString& wsText,
                                 float* pLinePos,
                                 float fSpaceAbove,
                                 bool bSavePieces) {
  CFGAS_Char::BreakType dwStatus = CFGAS_Char::BreakType::kNone;
  size_t iChar = loader_ ? loader_->nCharIdx : 0;
  size_t iLength = wsText.GetLength();
  for (size_t i = iChar; i < iLength; i++) {
    wchar_t wch = wsText[i];
    if (wch == 0xA0) {
      wch = 0x20;
    }

    dwStatus = break_->AppendChar(wch);
    if (dwStatus != CFGAS_Char::BreakType::kNone &&
        dwStatus != CFGAS_Char::BreakType::kPiece) {
      AppendTextLine(dwStatus, pLinePos, bSavePieces, false);
      if (IsEnd(bSavePieces)) {
        if (loader_) {
          loader_->nCharIdx = i;
        }
        return true;
      }
      if (dwStatus == CFGAS_Char::BreakType::kParagraph && rich_text_) {
        *pLinePos += fSpaceAbove;
      }
    }
  }
  if (loader_) {
    loader_->nCharIdx = 0;
  }

  return false;
}

bool CXFA_TextLayout::IsEnd(bool bSavePieces) {
  if (!bSavePieces) {
    return false;
  }
  if (loader_ && loader_->iTotalLines > 0) {
    return lines_ >= loader_->iTotalLines;
  }
  return false;
}

void CXFA_TextLayout::EndBreak(CFGAS_Char::BreakType dwStatus,
                               float* pLinePos,
                               bool bSavePieces) {
  dwStatus = break_->EndBreak(dwStatus);
  if (dwStatus != CFGAS_Char::BreakType::kNone &&
      dwStatus != CFGAS_Char::BreakType::kPiece) {
    AppendTextLine(dwStatus, pLinePos, bSavePieces, true);
  }
}

void CXFA_TextLayout::DoTabstops(CFX_CSSComputedStyle* pStyle,
                                 PieceLine* pPieceLine) {
  if (!pStyle || !pPieceLine) {
    return;
  }

  if (!tabstop_context_ || tabstop_context_->tabstops_.empty()) {
    return;
  }

  int32_t iPieces = fxcrt::CollectionSize<int32_t>(pPieceLine->text_pieces_);
  if (iPieces == 0) {
    return;
  }

  TextPiece* pPiece = pPieceLine->text_pieces_[iPieces - 1].get();
  int32_t& iTabstopsIndex = tabstop_context_->tab_index_;
  int32_t iCount = text_parser_->CountTabs(pStyle);
  if (!fxcrt::IndexInBounds(tabstop_context_->tabstops_, iTabstopsIndex)) {
    return;
  }

  if (iCount > 0) {
    iTabstopsIndex++;
    tabstop_context_->has_tabstops_ = true;
    float fRight = 0;
    if (iPieces > 1) {
      const TextPiece* p = pPieceLine->text_pieces_[iPieces - 2].get();
      fRight = p->rtPiece.right();
    }
    tabstop_context_->tab_width_ =
        pPiece->rtPiece.width + pPiece->rtPiece.left - fRight;
  } else if (iTabstopsIndex > -1) {
    float fLeft = 0;
    if (tabstop_context_->has_tabstops_) {
      uint32_t dwAlign = tabstop_context_->tabstops_[iTabstopsIndex].dwAlign;
      if (dwAlign == FX_HashCode_GetW(L"center")) {
        fLeft = pPiece->rtPiece.width / 2.0f;
      } else if (dwAlign == FX_HashCode_GetW(L"right") ||
                 dwAlign == FX_HashCode_GetW(L"before")) {
        fLeft = pPiece->rtPiece.width;
      } else if (dwAlign == FX_HashCode_GetW(L"decimal")) {
        int32_t iChars = pPiece->iChars;
        for (int32_t i = 0; i < iChars; i++) {
          if (pPiece->szText[i] == L'.') {
            break;
          }

          fLeft += pPiece->Widths[i] / 20000.0f;
        }
      }
      tabstop_context_->left_ = std::min(fLeft, tabstop_context_->tab_width_);
      tabstop_context_->has_tabstops_ = false;
      tabstop_context_->tab_width_ = 0;
    }
    pPiece->rtPiece.left -= tabstop_context_->left_;
  }
}

void CXFA_TextLayout::AppendTextLine(CFGAS_Char::BreakType dwStatus,
                                     float* pLinePos,
                                     bool bSavePieces,
                                     bool bEndBreak) {
  int32_t iPieces = break_->CountBreakPieces();
  if (iPieces < 1) {
    return;
  }

  RetainPtr<CFX_CSSComputedStyle> pStyle;
  if (bSavePieces) {
    auto pNew = std::make_unique<PieceLine>();
    PieceLine* pPieceLine = pNew.get();
    piece_lines_.push_back(std::move(pNew));
    if (tabstop_context_) {
      tabstop_context_->Reset();
    }

    float fLineStep = 0;
    float fBaseLine = 0;
    int32_t i = 0;
    for (i = 0; i < iPieces; i++) {
      const CFGAS_BreakPiece* pPiece = break_->GetBreakPieceUnstable(i);
      const CFGAS_TextUserData* pUserData = pPiece->GetUserData();
      if (pUserData) {
        pStyle = pUserData->style_;
      }
      float fVerScale = pPiece->GetVerticalScale() / 100.0f;

      auto pTP = std::make_unique<TextPiece>();
      pTP->iChars = pPiece->GetCharCount();
      pTP->szText = pPiece->GetString();
      pTP->Widths = pPiece->GetWidths();
      pTP->iBidiLevel = pPiece->GetBidiLevel();
      pTP->iHorScale = pPiece->GetHorizontalScale();
      pTP->iVerScale = pPiece->GetVerticalScale();
      pTP->iUnderline =
          text_parser_->GetUnderline(text_provider_, pStyle.Get());
      pTP->iPeriod =
          text_parser_->GetUnderlinePeriod(text_provider_, pStyle.Get());
      pTP->iLineThrough =
          text_parser_->GetLinethrough(text_provider_, pStyle.Get());
      pTP->dwColor = text_parser_->GetColor(text_provider_, pStyle.Get());
      pTP->font =
          text_parser_->GetFont(doc_.Get(), text_provider_, pStyle.Get());
      pTP->fFontSize = text_parser_->GetFontSize(text_provider_, pStyle.Get());
      pTP->rtPiece.left = pPiece->GetStartPos() / 20000.0f;
      pTP->rtPiece.width = pPiece->GetWidth() / 20000.0f;
      pTP->rtPiece.height =
          static_cast<float>(pPiece->GetFontSize()) * fVerScale / 20.0f;
      float fBaseLineTemp =
          text_parser_->GetBaseline(text_provider_, pStyle.Get());
      pTP->rtPiece.top = fBaseLineTemp;

      float fLineHeight = text_parser_->GetLineHeight(
          text_provider_, pStyle.Get(), lines_ == 0, fVerScale);
      if (fBaseLineTemp > 0) {
        float fLineHeightTmp = fBaseLineTemp + pTP->rtPiece.height;
        if (fLineHeight < fLineHeightTmp) {
          fLineHeight = fLineHeightTmp;
        }
      }
      fLineStep = std::max(fLineStep, fLineHeight);
      pTP->pLinkData = pUserData ? pUserData->link_data_ : nullptr;
      pPieceLine->text_pieces_.push_back(std::move(pTP));
      DoTabstops(pStyle.Get(), pPieceLine);
    }
    for (const auto& pTP : pPieceLine->text_pieces_) {
      float& fTop = pTP->rtPiece.top;
      float fBaseLineTemp = fTop;
      fTop = *pLinePos + fLineStep - pTP->rtPiece.height - fBaseLineTemp;
      fTop = std::max(0.0f, fTop);
    }
    *pLinePos += fLineStep + fBaseLine;
  } else {
    float fLineStep = 0;
    float fLineWidth = 0;
    for (int32_t i = 0; i < iPieces; i++) {
      const CFGAS_BreakPiece* pPiece = break_->GetBreakPieceUnstable(i);
      const CFGAS_TextUserData* pUserData = pPiece->GetUserData();
      if (pUserData) {
        pStyle = pUserData->style_;
      }
      float fVerScale = pPiece->GetVerticalScale() / 100.0f;
      float fBaseLine = text_parser_->GetBaseline(text_provider_, pStyle.Get());
      float fLineHeight = text_parser_->GetLineHeight(
          text_provider_, pStyle.Get(), lines_ == 0, fVerScale);
      if (fBaseLine > 0) {
        float fLineHeightTmp =
            fBaseLine +
            static_cast<float>(pPiece->GetFontSize()) * fVerScale / 20.0f;
        if (fLineHeight < fLineHeightTmp) {
          fLineHeight = fLineHeightTmp;
        }
      }
      fLineStep = std::max(fLineStep, fLineHeight);
      fLineWidth += pPiece->GetWidth() / 20000.0f;
    }
    *pLinePos += fLineStep;
    max_width_ = std::max(max_width_, fLineWidth);
    if (loader_ && loader_->bSaveLineHeight) {
      float fHeight = *pLinePos - loader_->fLastPos;
      loader_->fLastPos = *pLinePos;
      loader_->lineHeights.push_back(fHeight);
    }
  }

  break_->ClearBreakPieces();
  if (dwStatus == CFGAS_Char::BreakType::kParagraph) {
    break_->Reset();
    if (!pStyle && bEndBreak) {
      CXFA_Para* para = text_provider_->GetParaIfExists();
      if (para) {
        float fStartPos = para->GetMarginLeft();
        float fIndent = para->GetTextIndent();
        if (fIndent > 0) {
          fStartPos += fIndent;
        }

        float fSpaceBelow = para->GetSpaceBelow();
        if (fSpaceBelow < 0.1f) {
          fSpaceBelow = 0;
        }

        break_->SetLineStartPos(fStartPos);
        *pLinePos += fSpaceBelow;
      }
    }
  }

  if (pStyle) {
    float fStart = 0;
    const CFX_CSSRect* pRect = pStyle->GetMarginWidth();
    if (pRect) {
      fStart = pRect->left.GetValue();
    }

    float fTextIndent = pStyle->GetTextIndent().GetValue();
    if (fTextIndent < 0) {
      fStart -= fTextIndent;
    }

    break_->SetLineStartPos(fStart);
  }
  lines_++;
}

void CXFA_TextLayout::RenderString(CFX_RenderDevice* pDevice,
                                   PieceLine* pPieceLine,
                                   size_t szPiece,
                                   pdfium::span<TextCharPos> pCharPos,
                                   const CFX_Matrix& mtDoc2Device) {
  const TextPiece* pPiece = pPieceLine->text_pieces_[szPiece].get();
  size_t szCount = GetDisplayPos(pPiece, pCharPos);
  if (szCount > 0) {
    CFDE_TextOut::DrawString(pDevice, pPiece->dwColor, pPiece->font,
                             pCharPos.first(szCount), pPiece->fFontSize,
                             mtDoc2Device);
  }
  pPieceLine->char_counts_.push_back(szCount);
}

void CXFA_TextLayout::RenderPath(CFX_RenderDevice* pDevice,
                                 const PieceLine* pPieceLine,
                                 size_t szPiece,
                                 pdfium::span<TextCharPos> pCharPos,
                                 const CFX_Matrix& mtDoc2Device) {
  const TextPiece* pPiece = pPieceLine->text_pieces_[szPiece].get();
  bool bNoUnderline = pPiece->iUnderline < 1 || pPiece->iUnderline > 2;
  bool bNoLineThrough = pPiece->iLineThrough < 1 || pPiece->iLineThrough > 2;
  if (bNoUnderline && bNoLineThrough) {
    return;
  }

  CFX_Path path;
  size_t szChars = GetDisplayPos(pPiece, pCharPos);
  if (szChars > 0) {
    CFX_PointF pt1;
    CFX_PointF pt2;
    float fEndY = pCharPos[0].origin_.y + 1.05f;
    if (pPiece->iPeriod == XFA_AttributeValue::Word) {
      for (int32_t i = 0; i < pPiece->iUnderline; i++) {
        for (size_t j = 0; j < szChars; j++) {
          pt1.x = pCharPos[j].origin_.x;
          pt2.x = pt1.x +
                  pCharPos[j].font_char_width_ * pPiece->fFontSize / 1000.0f;
          pt1.y = pt2.y = fEndY;
          path.AppendLine(pt1, pt2);
        }
        fEndY += 2.0f;
      }
    } else {
      pt1.x = pCharPos[0].origin_.x;
      pt2.x =
          pCharPos[szChars - 1].origin_.x +
          pCharPos[szChars - 1].font_char_width_ * pPiece->fFontSize / 1000.0f;
      for (int32_t i = 0; i < pPiece->iUnderline; i++) {
        pt1.y = pt2.y = fEndY;
        path.AppendLine(pt1, pt2);
        fEndY += 2.0f;
      }
    }
    fEndY = pCharPos[0].origin_.y - pPiece->rtPiece.height * 0.25f;
    pt1.x = pCharPos[0].origin_.x;
    pt2.x =
        pCharPos[szChars - 1].origin_.x +
        pCharPos[szChars - 1].font_char_width_ * pPiece->fFontSize / 1000.0f;
    for (int32_t i = 0; i < pPiece->iLineThrough; i++) {
      pt1.y = pt2.y = fEndY;
      path.AppendLine(pt1, pt2);
      fEndY += 2.0f;
    }
  } else {
    if (bNoLineThrough &&
        (bNoUnderline || pPiece->iPeriod != XFA_AttributeValue::All)) {
      return;
    }
    bool bHasCount = false;
    size_t szPiecePrev = szPiece;
    size_t szPieceNext = szPiece;
    while (szPiecePrev > 0) {
      szPiecePrev--;
      if (pPieceLine->char_counts_[szPiecePrev] > 0) {
        bHasCount = true;
        break;
      }
    }
    if (!bHasCount) {
      return;
    }

    bHasCount = false;
    while (szPieceNext + 1 < pPieceLine->text_pieces_.size()) {
      ++szPieceNext;
      if (pPieceLine->char_counts_[szPieceNext] > 0) {
        bHasCount = true;
        break;
      }
    }
    if (!bHasCount) {
      return;
    }

    float fOrgX = 0.0f;
    float fEndX = 0.0f;
    pPiece = pPieceLine->text_pieces_[szPiecePrev].get();
    szChars = GetDisplayPos(pPiece, pCharPos);
    if (szChars < 1) {
      return;
    }

    fOrgX =
        pCharPos[szChars - 1].origin_.x +
        pCharPos[szChars - 1].font_char_width_ * pPiece->fFontSize / 1000.0f;
    pPiece = pPieceLine->text_pieces_[szPieceNext].get();
    szChars = GetDisplayPos(pPiece, pCharPos);
    if (szChars < 1) {
      return;
    }

    fEndX = pCharPos[0].origin_.x;
    CFX_PointF pt1;
    CFX_PointF pt2;
    pt1.x = fOrgX;
    pt2.x = fEndX;
    float fEndY = pCharPos[0].origin_.y + 1.05f;
    for (int32_t i = 0; i < pPiece->iUnderline; i++) {
      pt1.y = fEndY;
      pt2.y = fEndY;
      path.AppendLine(pt1, pt2);
      fEndY += 2.0f;
    }
    fEndY = pCharPos[0].origin_.y - pPiece->rtPiece.height * 0.25f;
    for (int32_t i = 0; i < pPiece->iLineThrough; i++) {
      pt1.y = fEndY;
      pt2.y = fEndY;
      path.AppendLine(pt1, pt2);
      fEndY += 2.0f;
    }
  }

  const CFX_GraphStateData graph_state;
  pDevice->DrawPath(path, &mtDoc2Device, &graph_state, 0, pPiece->dwColor,
                    CFX_FillRenderOptions());
}

size_t CXFA_TextLayout::GetDisplayPos(const TextPiece* pPiece,
                                      pdfium::span<TextCharPos> pCharPos) {
  if (!pPiece || pPiece->iChars < 1) {
    return 0;
  }
  return break_->GetDisplayPos(pPiece, pCharPos);
}
