// 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) {
      *pLinePos += fSpaceAbove;
    } else {
      fSpaceAbove = 0;
    }
  }

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