// Copyright 2017 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "xfa/fxfa/cxfa_textlayout.h"

#include <algorithm>
#include <utility>

#include "core/fxcrt/css/cfx_csscomputedstyle.h"
#include "core/fxcrt/css/cfx_cssstyleselector.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_pathdata.h"
#include "core/fxge/cfx_renderdevice.h"
#include "core/fxge/text_char_pos.h"
#include "fxjs/xfa/cjx_object.h"
#include "third_party/base/check.h"
#include "third_party/base/notreached.h"
#include "third_party/base/stl_util.h"
#include "xfa/fde/cfde_textout.h"
#include "xfa/fgas/font/cfgas_gefont.h"
#include "xfa/fgas/layout/cfx_linkuserdata.h"
#include "xfa/fgas/layout/cfx_rtfbreak.h"
#include "xfa/fgas/layout/cfx_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) {
  int32_t iLen = pText->GetLength();
  if (iLen == 0)
    return;

  int32_t iTrimLeft = 0;
  {
    // Span's lifetime must end before ReleaseBuffer() below.
    pdfium::span<wchar_t> psz = pText->GetBuffer(iLen);
    wchar_t wPrev = 0;
    for (int32_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[iTrimLeft++] = wch;
    }
  }
  pText->ReleaseBuffer(iTrimLeft);
}

}  // 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)
    : m_pDoc(doc),
      m_pTextProvider(pTextProvider),
      m_pTextParser(cppgc::MakeGarbageCollected<CXFA_TextParser>(
          doc->GetHeap()->GetAllocationHandle())) {
  DCHECK(m_pTextProvider);
}

CXFA_TextLayout::~CXFA_TextLayout() = default;

void CXFA_TextLayout::Trace(cppgc::Visitor* visitor) const {
  visitor->Trace(m_pDoc);
  visitor->Trace(m_pTextProvider);
  visitor->Trace(m_pTextDataNode);
  visitor->Trace(m_pTextParser);
  if (m_pLoader)
    m_pLoader->Trace(visitor);
}

void CXFA_TextLayout::Unload() {
  m_pieceLines.clear();
  m_pBreak.reset();
}

const wchar_t* CXFA_TextLayout::GetLinkURLAtPoint(const CFX_PointF& point) {
  for (const auto& pPieceLine : m_pieceLines) {
    for (const auto& pPiece : pPieceLine->m_textPieces) {
      if (pPiece->pLinkData && pPiece->rtPiece.Contains(point))
        return pPiece->pLinkData->GetLinkURL();
    }
  }
  return nullptr;
}

void CXFA_TextLayout::GetTextDataNode() {
  CXFA_Node* pNode = m_pTextProvider->GetTextNode(&m_bRichText);
  if (pNode && m_bRichText)
    m_pTextParser->Reset();

  m_pTextDataNode = pNode;
}

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

  CFX_XMLNode* pXMLRoot = m_pTextDataNode->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<CFX_RTFBreak> CXFA_TextLayout::CreateBreak(bool bDefault) {
  uint32_t dwStyle = FX_LAYOUTSTYLE_ExpandTab;
  if (!bDefault)
    dwStyle |= FX_LAYOUTSTYLE_Pagination;

  auto pBreak = std::make_unique<CFX_RTFBreak>(dwStyle);
  pBreak->SetLineBreakTolerance(1);
  pBreak->SetFont(
      m_pTextParser->GetFont(m_pDoc.Get(), m_pTextProvider, nullptr));
  pBreak->SetFontSize(m_pTextParser->GetFontSize(m_pTextProvider, nullptr));
  return pBreak;
}

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

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

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

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

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

  float fFontSize = m_pTextParser->GetFontSize(m_pTextProvider, nullptr);
  m_pBreak->SetFontSize(fFontSize);
  m_pBreak->SetFont(
      m_pTextParser->GetFont(m_pDoc.Get(), m_pTextProvider, nullptr));
  m_pBreak->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) {
    CFX_RTFLineAlignment iAlign = CFX_RTFLineAlignment::Left;
    switch (pStyle->GetTextAlign()) {
      case CFX_CSSTextAlign::Right:
        iAlign = CFX_RTFLineAlignment::Right;
        break;
      case CFX_CSSTextAlign::Center:
        iAlign = CFX_RTFLineAlignment::Center;
        break;
      case CFX_CSSTextAlign::Justify:
        iAlign = CFX_RTFLineAlignment::Justified;
        break;
      case CFX_CSSTextAlign::JustifyAll:
        iAlign = CFX_RTFLineAlignment::Distributed;
        break;
      default:
        break;
    }
    m_pBreak->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);
      }
    }
    m_pBreak->SetLineBoundary(fStart, fLineWidth);
    float fIndent = pStyle->GetTextIndent().GetValue();
    if (fIndent > 0)
      fStart += fIndent;

    m_pBreak->SetLineStartPos(fStart);
    m_pBreak->SetTabWidth(m_pTextParser->GetTabInterval(pStyle));
    if (!m_pTabstopContext)
      m_pTabstopContext = std::make_unique<CXFA_TextTabstopsContext>();
    m_pTextParser->GetTabstops(pStyle, m_pTabstopContext.get());
    for (const auto& stop : m_pTabstopContext->m_tabstops)
      m_pBreak->AddPositionedTab(stop.fTabstops);
  }
  float fFontSize = m_pTextParser->GetFontSize(m_pTextProvider, pStyle);
  m_pBreak->SetFontSize(fFontSize);
  m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f);
  m_pBreak->SetFont(
      m_pTextParser->GetFont(m_pDoc.Get(), m_pTextProvider, pStyle));
  m_pBreak->SetHorizontalScale(
      m_pTextParser->GetHorScale(m_pTextProvider, pStyle, pXMLNode));
  m_pBreak->SetVerticalScale(
      m_pTextParser->GetVerScale(m_pTextProvider, pStyle));
  m_pBreak->SetCharSpace(pStyle->GetLetterSpacing().GetValue());
}

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

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

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

float CXFA_TextLayout::StartLayout(float fWidth) {
  if (!m_pLoader)
    m_pLoader = std::make_unique<LoaderContext>();

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

  if (fWidth >= 0)
    return fWidth;

  CFX_SizeF szMax;

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

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

  UpdateLoaderHeight(fTextHeight);
  return fTextHeight;
}

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

  UpdateLoaderHeight(fTextHeight);

  if (fCalcHeight < 0)
    return fCalcHeight;

  m_bHasBlock = true;
  if (m_Blocks.empty() && m_pLoader->fHeight > 0) {
    float fHeight = fTextHeight - GetLayoutHeight();
    if (fHeight > 0) {
      XFA_AttributeValue iAlign = m_pTextParser->GetVAlign(m_pTextProvider);
      if (iAlign == XFA_AttributeValue::Middle)
        fHeight /= 2.0f;
      else if (iAlign != XFA_AttributeValue::Bottom)
        fHeight = 0;
      m_pLoader->fStartLineOffset = fHeight;
    }
  }

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

  if (szLineIndex >= m_pLoader->lineHeights.size())
    return fCalcHeight;

  if (m_pLoader->lineHeights[szLineIndex] - fCalcHeight > kHeightTolerance)
    return 0;

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

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

    if (i != szLineIndex)
      return fLinePos;

    if (fCalcHeight > fLinePos)
      return fCalcHeight;

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

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

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

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

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

  m_pBreak = CreateBreak(false);
  float fLinePos = 0;
  m_iLines = 0;
  m_fMaxWidth = 0;
  Loader(width, &fLinePos, false);
  if (fLinePos < 0.1f)
    fLinePos = m_pTextParser->GetFontSize(m_pTextProvider, nullptr);

  m_pTabstopContext.reset();
  return CFX_SizeF(m_fMaxWidth, fLinePos);
}

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

  Unload();
  m_pBreak = CreateBreak(true);
  if (m_pLoader) {
    m_pLoader->iTotalLines = -1;
    m_pLoader->iChar = 0;
  }

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

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

  if (!m_pLoader || m_pLoader->fWidth < 1)
    return false;

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

    m_pLoader->iChar = 0;
    if (!m_Blocks.empty())
      m_pLoader->iTotalLines = m_Blocks[szBlockIndex].szLength;

    Loader(szText.width, &fLinePos, true);
    if (m_Blocks.empty() && m_pLoader->fStartLineOffset < 0.1f)
      UpdateAlign(szText.height, fLinePos);
  } else if (m_pTextDataNode) {
    if (!m_Blocks.empty() && szBlockIndex < m_Blocks.size() - 1)
      m_pLoader->iTotalLines = m_Blocks[szBlockIndex].szLength;

    m_pBreak->Reset();
    if (m_bRichText) {
      CFX_XMLNode* pContainerNode = GetXMLContainerNode();
      if (!pContainerNode)
        return true;

      const CFX_XMLNode* pXMLNode = m_pLoader->pXMLNode.Get();
      if (!pXMLNode)
        return true;

      const CFX_XMLNode* pSaveXMLNode = pXMLNode;
      for (; pXMLNode; pXMLNode = pXMLNode->GetNextSibling()) {
        if (!LoadRichText(pXMLNode, szText.width, &fLinePos,
                          m_pLoader->pParentStyle, true, nullptr, true, false,
                          0)) {
          break;
        }
      }
      while (!pXMLNode) {
        pXMLNode = pSaveXMLNode->GetParent();
        if (pXMLNode == pContainerNode)
          break;
        if (!LoadRichText(pXMLNode, szText.width, &fLinePos,
                          m_pLoader->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,
                            m_pLoader->pParentStyle, true, nullptr, true, false,
                            0)) {
            break;
          }
        }
      }
    } else {
      pNode = m_pLoader->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 (!m_pLoader)
    return;

  if (m_pLoader->lineHeights.empty())
    return;

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

  size_t i;
  for (i = szLineIndex; i < m_pLoader->lineHeights.size(); ++i) {
    float fLineHeight = m_pLoader->lineHeights[i];
    if (fLinePos + fLineHeight - rtText.height > kHeightTolerance) {
      m_Blocks.push_back({szLineIndex, i - szLineIndex});
      return;
    }
    fLinePos += fLineHeight;
  }
  if (i > szLineIndex)
    m_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 (m_pieceLines.empty()) {
    size_t szBlockCount = CountBlocks();
    for (size_t i = 0; i < szBlockCount; ++i)
      LayoutInternal(i);
    m_pTabstopContext.reset();
    m_pLoader.reset();
  }

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

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

    PieceLine* pPieceLine = m_pieceLines[i + szLineStart].get();
    for (size_t j = 0; j < pPieceLine->m_textPieces.size(); ++j) {
      const TextPiece* pPiece = pPieceLine->m_textPieces[j].get();
      int32_t iChars = pPiece->iChars;
      if (pdfium::CollectionSize<int32_t>(char_pos) < iChars)
        char_pos.resize(iChars);
      RenderString(pFxDevice, pPieceLine, j, &char_pos, mtDoc2Device);
    }
    for (size_t j = 0; j < pPieceLine->m_textPieces.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 (m_pTextParser->GetVAlign(m_pTextProvider)) {
    case XFA_AttributeValue::Middle:
      fHeight /= 2.0f;
      break;
    case XFA_AttributeValue::Bottom:
      break;
    default:
      return;
  }

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

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

  if (!m_bRichText) {
    LoadText(m_pTextDataNode, textWidth, pLinePos, bSavePieces);
    return;
  }

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

  if (!m_pTextParser->IsParsed())
    m_pTextParser->DoParse(pXMLContainer, m_pTextProvider);

  auto pRootStyle = m_pTextParser->CreateRootStyle(m_pTextProvider);
  LoadRichText(pXMLContainer, textWidth, pLinePos, pRootStyle, bSavePieces,
               nullptr, true, false, 0);
}

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

  CXFA_Para* para = m_pTextProvider->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();
        break;
    }
  }

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

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

  CXFA_TextParser::Context* pContext =
      m_pTextParser->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 (pContext) {
      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 = pContext->GetDisplay();
      if (eDisplay != CFX_CSSDisplay::Block &&
          eDisplay != CFX_CSSDisplay::Inline &&
          eDisplay != CFX_CSSDisplay::ListItem) {
        return true;
      }

      pStyle = m_pTextParser->ComputeStyle(pXMLNode, pParentStyle.Get());
      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<CFX_LinkUserData>(wsLinkContent);
      }

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

      int32_t iLength = wsText.GetLength();
      if (iLength > 0 && bContentNode && !bSpaceRun)
        ProcessText(&wsText);

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

      if (wsText.GetLength() > 0) {
        if (!m_pLoader || m_pLoader->iChar == 0) {
          auto pUserData = pdfium::MakeRetain<CFX_TextUserData>(
              bContentNode ? pParentStyle : pStyle, pLinkData);
          m_pBreak->SetUserData(pUserData);
        }

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

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

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

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

  if (!pContext || bContentNode)
    return true;

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

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

bool CXFA_TextLayout::AppendChar(const WideString& wsText,
                                 float* pLinePos,
                                 float fSpaceAbove,
                                 bool bSavePieces) {
  CFX_Char::BreakType dwStatus = CFX_Char::BreakType::kNone;
  int32_t iChar = 0;
  if (m_pLoader)
    iChar = m_pLoader->iChar;

  int32_t iLength = wsText.GetLength();
  for (int32_t i = iChar; i < iLength; i++) {
    wchar_t wch = wsText[i];
    if (wch == 0xA0)
      wch = 0x20;

    dwStatus = m_pBreak->AppendChar(wch);
    if (dwStatus != CFX_Char::BreakType::kNone &&
        dwStatus != CFX_Char::BreakType::kPiece) {
      AppendTextLine(dwStatus, pLinePos, bSavePieces, false);
      if (IsEnd(bSavePieces)) {
        if (m_pLoader)
          m_pLoader->iChar = i;
        return true;
      }
      if (dwStatus == CFX_Char::BreakType::kParagraph && m_bRichText)
        *pLinePos += fSpaceAbove;
    }
  }
  if (m_pLoader)
    m_pLoader->iChar = 0;

  return false;
}

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

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

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

  if (!m_pTabstopContext || m_pTabstopContext->m_tabstops.empty())
    return;

  int32_t iPieces = pdfium::CollectionSize<int32_t>(pPieceLine->m_textPieces);
  if (iPieces == 0)
    return;

  TextPiece* pPiece = pPieceLine->m_textPieces[iPieces - 1].get();
  int32_t& iTabstopsIndex = m_pTabstopContext->m_iTabIndex;
  int32_t iCount = m_pTextParser->CountTabs(pStyle);
  if (!pdfium::IndexInBounds(m_pTabstopContext->m_tabstops, iTabstopsIndex))
    return;

  if (iCount > 0) {
    iTabstopsIndex++;
    m_pTabstopContext->m_bHasTabstops = true;
    float fRight = 0;
    if (iPieces > 1) {
      const TextPiece* p = pPieceLine->m_textPieces[iPieces - 2].get();
      fRight = p->rtPiece.right();
    }
    m_pTabstopContext->m_fTabWidth =
        pPiece->rtPiece.width + pPiece->rtPiece.left - fRight;
  } else if (iTabstopsIndex > -1) {
    float fLeft = 0;
    if (m_pTabstopContext->m_bHasTabstops) {
      uint32_t dwAlign = m_pTabstopContext->m_tabstops[iTabstopsIndex].dwAlign;
      if (dwAlign == FX_HashCode_GetW(L"center", false)) {
        fLeft = pPiece->rtPiece.width / 2.0f;
      } else if (dwAlign == FX_HashCode_GetW(L"right", false) ||
                 dwAlign == FX_HashCode_GetW(L"before", false)) {
        fLeft = pPiece->rtPiece.width;
      } else if (dwAlign == FX_HashCode_GetW(L"decimal", false)) {
        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;
        }
      }
      m_pTabstopContext->m_fLeft =
          std::min(fLeft, m_pTabstopContext->m_fTabWidth);
      m_pTabstopContext->m_bHasTabstops = false;
      m_pTabstopContext->m_fTabWidth = 0;
    }
    pPiece->rtPiece.left -= m_pTabstopContext->m_fLeft;
  }
}

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

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

    float fLineStep = 0, fBaseLine = 0;
    int32_t i = 0;
    for (i = 0; i < iPieces; i++) {
      const CFX_BreakPiece* pPiece = m_pBreak->GetBreakPieceUnstable(i);
      CFX_TextUserData* pUserData = pPiece->m_pUserData.Get();
      if (pUserData)
        pStyle = pUserData->m_pStyle;
      float fVerScale = pPiece->m_iVerticalScale / 100.0f;

      auto pTP = std::make_unique<TextPiece>();
      pTP->iChars = pPiece->m_iCharCount;
      pTP->szText = pPiece->GetString();
      pTP->Widths = pPiece->GetWidths();
      pTP->iBidiLevel = pPiece->m_iBidiLevel;
      pTP->iHorScale = pPiece->m_iHorizontalScale;
      pTP->iVerScale = pPiece->m_iVerticalScale;
      pTP->iUnderline =
          m_pTextParser->GetUnderline(m_pTextProvider, pStyle.Get());
      pTP->iPeriod =
          m_pTextParser->GetUnderlinePeriod(m_pTextProvider, pStyle.Get());
      pTP->iLineThrough =
          m_pTextParser->GetLinethrough(m_pTextProvider, pStyle.Get());
      pTP->dwColor = m_pTextParser->GetColor(m_pTextProvider, pStyle.Get());
      pTP->pFont =
          m_pTextParser->GetFont(m_pDoc.Get(), m_pTextProvider, pStyle.Get());
      pTP->fFontSize =
          m_pTextParser->GetFontSize(m_pTextProvider, pStyle.Get());
      pTP->rtPiece.left = pPiece->m_iStartPos / 20000.0f;
      pTP->rtPiece.width = pPiece->m_iWidth / 20000.0f;
      pTP->rtPiece.height =
          static_cast<float>(pPiece->m_iFontSize) * fVerScale / 20.0f;
      float fBaseLineTemp =
          m_pTextParser->GetBaseline(m_pTextProvider, pStyle.Get());
      pTP->rtPiece.top = fBaseLineTemp;

      float fLineHeight = m_pTextParser->GetLineHeight(
          m_pTextProvider, pStyle.Get(), m_iLines == 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->m_pLinkData : nullptr;
      pPieceLine->m_textPieces.push_back(std::move(pTP));
      DoTabstops(pStyle.Get(), pPieceLine);
    }
    for (const auto& pTP : pPieceLine->m_textPieces) {
      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 CFX_BreakPiece* pPiece = m_pBreak->GetBreakPieceUnstable(i);
      CFX_TextUserData* pUserData = pPiece->m_pUserData.Get();
      if (pUserData)
        pStyle = pUserData->m_pStyle;
      float fVerScale = pPiece->m_iVerticalScale / 100.0f;
      float fBaseLine =
          m_pTextParser->GetBaseline(m_pTextProvider, pStyle.Get());
      float fLineHeight = m_pTextParser->GetLineHeight(
          m_pTextProvider, pStyle.Get(), m_iLines == 0, fVerScale);
      if (fBaseLine > 0) {
        float fLineHeightTmp =
            fBaseLine +
            static_cast<float>(pPiece->m_iFontSize) * fVerScale / 20.0f;
        if (fLineHeight < fLineHeightTmp) {
          fLineHeight = fLineHeightTmp;
        }
      }
      fLineStep = std::max(fLineStep, fLineHeight);
      fLineWidth += pPiece->m_iWidth / 20000.0f;
    }
    *pLinePos += fLineStep;
    m_fMaxWidth = std::max(m_fMaxWidth, fLineWidth);
    if (m_pLoader && m_pLoader->bSaveLineHeight) {
      float fHeight = *pLinePos - m_pLoader->fLastPos;
      m_pLoader->fLastPos = *pLinePos;
      m_pLoader->lineHeights.push_back(fHeight);
    }
  }

  m_pBreak->ClearBreakPieces();
  if (dwStatus == CFX_Char::BreakType::kParagraph) {
    m_pBreak->Reset();
    if (!pStyle && bEndBreak) {
      CXFA_Para* para = m_pTextProvider->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;

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

    m_pBreak->SetLineStartPos(fStart);
  }
  m_iLines++;
}

void CXFA_TextLayout::RenderString(CFX_RenderDevice* pDevice,
                                   PieceLine* pPieceLine,
                                   size_t szPiece,
                                   std::vector<TextCharPos>* pCharPos,
                                   const CFX_Matrix& mtDoc2Device) {
  const TextPiece* pPiece = pPieceLine->m_textPieces[szPiece].get();
  size_t szCount = GetDisplayPos(pPiece, pCharPos);
  if (szCount > 0) {
    auto span = pdfium::make_span(pCharPos->data(), szCount);
    CFDE_TextOut::DrawString(pDevice, pPiece->dwColor, pPiece->pFont, span,
                             pPiece->fFontSize, mtDoc2Device);
  }
  pPieceLine->m_charCounts.push_back(szCount);
}

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

  CFX_PathData path;
  size_t szChars = GetDisplayPos(pPiece, pCharPos);
  if (szChars > 0) {
    CFX_PointF pt1;
    CFX_PointF pt2;
    float fEndY = (*pCharPos)[0].m_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].m_Origin.x;
          pt2.x = pt1.x +
                  (*pCharPos)[j].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
          pt1.y = pt2.y = fEndY;
          path.AppendLine(pt1, pt2);
        }
        fEndY += 2.0f;
      }
    } else {
      pt1.x = (*pCharPos)[0].m_Origin.x;
      pt2.x = (*pCharPos)[szChars - 1].m_Origin.x +
              (*pCharPos)[szChars - 1].m_FontCharWidth * 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].m_Origin.y - pPiece->rtPiece.height * 0.25f;
    pt1.x = (*pCharPos)[0].m_Origin.x;
    pt2.x =
        (*pCharPos)[szChars - 1].m_Origin.x +
        (*pCharPos)[szChars - 1].m_FontCharWidth * 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->m_charCounts[szPiecePrev] > 0) {
        bHasCount = true;
        break;
      }
    }
    if (!bHasCount)
      return;

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

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

    fOrgX =
        (*pCharPos)[szChars - 1].m_Origin.x +
        (*pCharPos)[szChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
    pPiece = pPieceLine->m_textPieces[szPieceNext].get();
    szChars = GetDisplayPos(pPiece, pCharPos);
    if (szChars < 1)
      return;

    fEndX = (*pCharPos)[0].m_Origin.x;
    CFX_PointF pt1;
    CFX_PointF pt2;
    pt1.x = fOrgX;
    pt2.x = fEndX;
    float fEndY = (*pCharPos)[0].m_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].m_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;
    }
  }

  CFX_GraphStateData graphState;
  graphState.m_LineCap = CFX_GraphStateData::LineCapButt;
  graphState.m_LineJoin = CFX_GraphStateData::LineJoinMiter;
  graphState.m_LineWidth = 1;
  graphState.m_MiterLimit = 10;
  graphState.m_DashPhase = 0;
  pDevice->DrawPath(&path, &mtDoc2Device, &graphState, 0, pPiece->dwColor,
                    CFX_FillRenderOptions());
}

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