// Copyright 2014 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/app/xfa_textlayout.h"

#include <algorithm>

#include "core/fxcrt/fx_ext.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
#include "xfa/fde/cfde_path.h"
#include "xfa/fde/css/fde_csscache.h"
#include "xfa/fde/css/fde_cssstyleselector.h"
#include "xfa/fde/fde_gedevice.h"
#include "xfa/fde/fde_object.h"
#include "xfa/fde/xml/fde_xml_imp.h"
#include "xfa/fgas/crt/fgas_codepage.h"
#include "xfa/fxfa/app/xfa_ffwidgetacc.h"
#include "xfa/fxfa/parser/cxfa_measurement.h"
#include "xfa/fxfa/xfa_ffapp.h"
#include "xfa/fxfa/xfa_ffdoc.h"
#include "xfa/fxfa/xfa_fontmgr.h"

CXFA_CSSTagProvider::CXFA_CSSTagProvider()
    : m_bTagAvailable(false), m_bContent(false) {}

CXFA_CSSTagProvider::~CXFA_CSSTagProvider() {}

XFA_TextPiece::XFA_TextPiece()
    : pszText(nullptr), pFont(nullptr), pLinkData(nullptr) {}

XFA_TextPiece::~XFA_TextPiece() {
  if (pLinkData)
    pLinkData->Release();
}

CXFA_TextParseContext::CXFA_TextParseContext()
    : m_pParentStyle(nullptr),
      m_ppMatchedDecls(nullptr),
      m_dwMatchedDecls(0),
      m_eDisplay(FDE_CSSDISPLAY_None) {}

CXFA_TextParseContext::~CXFA_TextParseContext() {
  if (m_pParentStyle)
    m_pParentStyle->Release();
  FX_Free(m_ppMatchedDecls);
}

void CXFA_TextParseContext::SetDecls(const CFDE_CSSDeclaration** ppDeclArray,
                                     int32_t iDeclCount) {
  if (iDeclCount <= 0 || !ppDeclArray)
    return;

  m_dwMatchedDecls = iDeclCount;
  m_ppMatchedDecls = FX_Alloc(CFDE_CSSDeclaration*, iDeclCount);
  FXSYS_memcpy(m_ppMatchedDecls, ppDeclArray,
               iDeclCount * sizeof(CFDE_CSSDeclaration*));
}

CXFA_TextParser::CXFA_TextParser() : m_pUASheet(nullptr) {}

CXFA_TextParser::~CXFA_TextParser() {
  if (m_pUASheet)
    m_pUASheet->Release();

  FX_POSITION ps = m_mapXMLNodeToParseContext.GetStartPosition();
  while (ps) {
    CFDE_XMLNode* pXMLNode;
    CXFA_TextParseContext* pParseContext;
    m_mapXMLNodeToParseContext.GetNextAssoc(ps, pXMLNode, pParseContext);
    if (pParseContext)
      FXTARGET_DeleteWith(CXFA_TextParseContext, m_pAllocator.get(),
                          pParseContext);
  }
  m_mapXMLNodeToParseContext.RemoveAll();
}
void CXFA_TextParser::Reset() {
  FX_POSITION ps = m_mapXMLNodeToParseContext.GetStartPosition();
  while (ps) {
    CFDE_XMLNode* pXMLNode;
    CXFA_TextParseContext* pParseContext;
    m_mapXMLNodeToParseContext.GetNextAssoc(ps, pXMLNode, pParseContext);
    if (pParseContext)
      FXTARGET_DeleteWith(CXFA_TextParseContext, m_pAllocator.get(),
                          pParseContext);
  }
  m_mapXMLNodeToParseContext.RemoveAll();
  m_pAllocator.reset();
}
void CXFA_TextParser::InitCSSData(CXFA_TextProvider* pTextProvider) {
  if (!pTextProvider)
    return;

  if (!m_pSelector) {
    CXFA_FFDoc* pDoc = pTextProvider->GetDocNode();
    CFGAS_FontMgr* pFontMgr = pDoc->GetApp()->GetFDEFontMgr();
    ASSERT(pFontMgr);
    m_pSelector = pdfium::MakeUnique<CFDE_CSSStyleSelector>(pFontMgr);
    FX_FLOAT fFontSize = 10;
    CXFA_Font font = pTextProvider->GetFontNode();
    if (font) {
      fFontSize = font.GetFontSize();
    }
    m_pSelector->SetDefFontSize(fFontSize);
  }
  if (!m_pUASheet) {
    m_pUASheet = LoadDefaultSheetStyle();
    m_pSelector->SetStyleSheet(FDE_CSSSTYLESHEETGROUP_UserAgent, m_pUASheet);
    m_pSelector->UpdateStyleIndex(FDE_CSSMEDIATYPE_ALL);
  }
}

CXFA_LoaderContext::CXFA_LoaderContext()
    : m_bSaveLineHeight(false),
      m_fWidth(0),
      m_fHeight(0),
      m_fLastPos(0),
      m_fStartLineOffset(0),
      m_iChar(0),
      m_iTotalLines(-1),
      m_pXMLNode(nullptr),
      m_pNode(nullptr),
      m_pParentStyle(nullptr),
      m_dwFlags(0) {}

CXFA_LoaderContext::~CXFA_LoaderContext() {}

IFDE_CSSStyleSheet* CXFA_TextParser::LoadDefaultSheetStyle() {
  static const FX_WCHAR s_pStyle[] =
      L"html,body,ol,p,ul{display:block}"
      L"li{display:list-item}"
      L"ol,ul{padding-left:33px}ol{list-style-type:decimal}ol,ul{margin-top:0;"
      L"margin-bottom:0}ul,ol{margin:1.12em 0}"
      L"a{color:#0000ff;text-decoration:underline}b{font-weight:bolder}i{font-"
      L"style:italic}"
      L"sup{vertical-align:+15em;font-size:.66em}sub{vertical-align:-15em;font-"
      L"size:.66em}";
  return IFDE_CSSStyleSheet::LoadFromBuffer(
      CFX_WideString(), s_pStyle, FXSYS_wcslen(s_pStyle), FX_CODEPAGE_UTF8);
}
IFDE_CSSComputedStyle* CXFA_TextParser::CreateRootStyle(
    CXFA_TextProvider* pTextProvider) {
  CXFA_Font font = pTextProvider->GetFontNode();
  CXFA_Para para = pTextProvider->GetParaNode();
  IFDE_CSSComputedStyle* pStyle = m_pSelector->CreateComputedStyle(nullptr);
  IFDE_CSSFontStyle* pFontStyle = pStyle->GetFontStyles();
  IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles();
  FX_FLOAT fLineHeight = 0, fFontSize = 10;
  if (para) {
    fLineHeight = para.GetLineHeight();
    FDE_CSSLENGTH indent;
    indent.Set(FDE_CSSLENGTHUNIT_Point, para.GetTextIndent());
    pParaStyle->SetTextIndent(indent);
    FDE_CSSTEXTALIGN hAlign = FDE_CSSTEXTALIGN_Left;
    switch (para.GetHorizontalAlign()) {
      case XFA_ATTRIBUTEENUM_Center:
        hAlign = FDE_CSSTEXTALIGN_Center;
        break;
      case XFA_ATTRIBUTEENUM_Right:
        hAlign = FDE_CSSTEXTALIGN_Right;
        break;
      case XFA_ATTRIBUTEENUM_Justify:
        hAlign = FDE_CSSTEXTALIGN_Justify;
        break;
      case XFA_ATTRIBUTEENUM_JustifyAll:
        hAlign = FDE_CSSTEXTALIGN_JustifyAll;
        break;
    }
    pParaStyle->SetTextAlign(hAlign);
    FDE_CSSRECT rtMarginWidth;
    rtMarginWidth.left.Set(FDE_CSSLENGTHUNIT_Point, para.GetMarginLeft());
    rtMarginWidth.top.Set(FDE_CSSLENGTHUNIT_Point, para.GetSpaceAbove());
    rtMarginWidth.right.Set(FDE_CSSLENGTHUNIT_Point, para.GetMarginRight());
    rtMarginWidth.bottom.Set(FDE_CSSLENGTHUNIT_Point, para.GetSpaceBelow());
    pStyle->GetBoundaryStyles()->SetMarginWidth(rtMarginWidth);
  }
  if (font) {
    pFontStyle->SetColor(font.GetColor());
    pFontStyle->SetFontStyle(font.IsItalic() ? FDE_CSSFONTSTYLE_Italic
                                             : FDE_CSSFONTSTYLE_Normal);
    pFontStyle->SetFontWeight(font.IsBold() ? FXFONT_FW_BOLD
                                            : FXFONT_FW_NORMAL);
    pParaStyle->SetNumberVerticalAlign(-font.GetBaselineShift());
    fFontSize = font.GetFontSize();
    FDE_CSSLENGTH letterSpacing;
    letterSpacing.Set(FDE_CSSLENGTHUNIT_Point, font.GetLetterSpacing());
    pParaStyle->SetLetterSpacing(letterSpacing);
    uint32_t dwDecoration = 0;
    if (font.GetLineThrough() > 0) {
      dwDecoration |= FDE_CSSTEXTDECORATION_LineThrough;
    }
    if (font.GetUnderline() > 1) {
      dwDecoration |= FDE_CSSTEXTDECORATION_Double;
    } else if (font.GetUnderline() > 0) {
      dwDecoration |= FDE_CSSTEXTDECORATION_Underline;
    }
    pParaStyle->SetTextDecoration(dwDecoration);
  }
  pParaStyle->SetLineHeight(fLineHeight);
  pFontStyle->SetFontSize(fFontSize);
  return pStyle;
}
IFDE_CSSComputedStyle* CXFA_TextParser::CreateStyle(
    IFDE_CSSComputedStyle* pParentStyle) {
  IFDE_CSSComputedStyle* pNewStyle =
      m_pSelector->CreateComputedStyle(pParentStyle);
  ASSERT(pNewStyle);
  if (pParentStyle) {
    IFDE_CSSParagraphStyle* pParaStyle = pParentStyle->GetParagraphStyles();
    uint32_t dwDecoration = pParaStyle->GetTextDecoration();
    FX_FLOAT fBaseLine = 0;
    if (pParaStyle->GetVerticalAlign() == FDE_CSSVERTICALALIGN_Number) {
      fBaseLine = pParaStyle->GetNumberVerticalAlign();
    }
    pParaStyle = pNewStyle->GetParagraphStyles();
    pParaStyle->SetTextDecoration(dwDecoration);
    pParaStyle->SetNumberVerticalAlign(fBaseLine);
    IFDE_CSSBoundaryStyle* pBoundarytyle = pParentStyle->GetBoundaryStyles();
    const FDE_CSSRECT* pRect = pBoundarytyle->GetMarginWidth();
    if (pRect) {
      pBoundarytyle = pNewStyle->GetBoundaryStyles();
      pBoundarytyle->SetMarginWidth(*pRect);
    }
  }
  return pNewStyle;
}
IFDE_CSSComputedStyle* CXFA_TextParser::ComputeStyle(
    CFDE_XMLNode* pXMLNode,
    IFDE_CSSComputedStyle* pParentStyle) {
  CXFA_TextParseContext* pContext = static_cast<CXFA_TextParseContext*>(
      m_mapXMLNodeToParseContext.GetValueAt(pXMLNode));
  if (!pContext)
    return nullptr;
  pContext->m_pParentStyle = pParentStyle;
  pParentStyle->Retain();
  CXFA_CSSTagProvider tagProvider;
  ParseTagInfo(pXMLNode, tagProvider);
  if (tagProvider.m_bContent)
    return nullptr;
  IFDE_CSSComputedStyle* pStyle = CreateStyle(pParentStyle);
  CFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator();
  pCSSAccel->OnEnterTag(&tagProvider);
  m_pSelector->ComputeStyle(&tagProvider, pContext->GetDecls(),
                            pContext->CountDecls(), pStyle);
  pCSSAccel->OnLeaveTag(&tagProvider);
  return pStyle;
}
void CXFA_TextParser::DoParse(CFDE_XMLNode* pXMLContainer,
                              CXFA_TextProvider* pTextProvider) {
  if (!pXMLContainer || !pTextProvider || m_pAllocator) {
    return;
  }
  m_pAllocator = IFX_MemoryAllocator::Create(FX_ALLOCTYPE_Fixed, 32,
                                             sizeof(CXFA_CSSTagProvider));
  InitCSSData(pTextProvider);
  IFDE_CSSComputedStyle* pRootStyle = CreateRootStyle(pTextProvider);
  ParseRichText(pXMLContainer, pRootStyle);
  pRootStyle->Release();
}
void CXFA_TextParser::ParseRichText(CFDE_XMLNode* pXMLNode,
                                    IFDE_CSSComputedStyle* pParentStyle) {
  if (!pXMLNode)
    return;

  CXFA_CSSTagProvider tagProvider;
  ParseTagInfo(pXMLNode, tagProvider);
  if (!tagProvider.m_bTagAvailable)
    return;

  IFDE_CSSComputedStyle* pNewStyle = nullptr;
  if ((tagProvider.GetTagName() != FX_WSTRC(L"body")) ||
      (tagProvider.GetTagName() != FX_WSTRC(L"html"))) {
    CXFA_TextParseContext* pTextContext =
        FXTARGET_NewWith(m_pAllocator.get()) CXFA_TextParseContext;
    FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_Inline;
    if (!tagProvider.m_bContent) {
      pNewStyle = CreateStyle(pParentStyle);
      CFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator();
      pCSSAccel->OnEnterTag(&tagProvider);
      CFDE_CSSDeclarationArray DeclArray;
      int32_t iMatchedDecls =
          m_pSelector->MatchDeclarations(&tagProvider, DeclArray);
      const CFDE_CSSDeclaration** ppMatchDecls =
          const_cast<const CFDE_CSSDeclaration**>(DeclArray.GetData());
      m_pSelector->ComputeStyle(&tagProvider, ppMatchDecls, iMatchedDecls,
                                pNewStyle);
      pCSSAccel->OnLeaveTag(&tagProvider);
      if (iMatchedDecls > 0) {
        pTextContext->SetDecls(ppMatchDecls, iMatchedDecls);
      }
      eDisplay = pNewStyle->GetPositionStyles()->GetDisplay();
    }
    pTextContext->SetDisplay(eDisplay);
    m_mapXMLNodeToParseContext.SetAt(pXMLNode, pTextContext);
  }
  for (CFDE_XMLNode* pXMLChild =
           pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
       pXMLChild;
       pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) {
    ParseRichText(pXMLChild, pNewStyle);
  }
  if (pNewStyle)
    pNewStyle->Release();
}

bool CXFA_TextParser::TagValidate(const CFX_WideString& wsName) const {
  static const uint32_t s_XFATagName[] = {
      0x61,        // a
      0x62,        // b
      0x69,        // i
      0x70,        // p
      0x0001f714,  // br
      0x00022a55,  // li
      0x000239bb,  // ol
      0x00025881,  // ul
      0x0bd37faa,  // sub
      0x0bd37fb8,  // sup
      0xa73e3af2,  // span
      0xb182eaae,  // body
      0xdb8ac455,  // html
  };
  static const int32_t s_iCount = FX_ArraySize(s_XFATagName);

  return std::binary_search(s_XFATagName, s_XFATagName + s_iCount,
                            FX_HashCode_GetW(wsName.AsStringC(), true));
}

void CXFA_TextParser::ParseTagInfo(CFDE_XMLNode* pXMLNode,
                                   CXFA_CSSTagProvider& tagProvider) {
  CFX_WideString wsName;
  if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
    CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode);
    pXMLElement->GetLocalTagName(wsName);
    tagProvider.SetTagNameObj(wsName);
    tagProvider.m_bTagAvailable = TagValidate(wsName);

    CFX_WideString wsValue;
    pXMLElement->GetString(L"style", wsValue);
    if (!wsValue.IsEmpty()) {
      tagProvider.SetAttribute(L"style", wsValue);
    }
  } else if (pXMLNode->GetType() == FDE_XMLNODE_Text) {
    tagProvider.m_bTagAvailable = true;
    tagProvider.m_bContent = true;
  }
}

int32_t CXFA_TextParser::GetVAlign(CXFA_TextProvider* pTextProvider) const {
  CXFA_Para para = pTextProvider->GetParaNode();
  return para ? para.GetVerticalAlign() : XFA_ATTRIBUTEENUM_Top;
}

FX_FLOAT CXFA_TextParser::GetTabInterval(IFDE_CSSComputedStyle* pStyle) const {
  CFX_WideString wsValue;
  if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"tab-interval"), wsValue))
    return CXFA_Measurement(wsValue.AsStringC()).ToUnit(XFA_UNIT_Pt);
  return 36;
}

int32_t CXFA_TextParser::CountTabs(IFDE_CSSComputedStyle* pStyle) const {
  CFX_WideString wsValue;
  if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-count"), wsValue))
    return wsValue.GetInteger();
  return 0;
}

bool CXFA_TextParser::IsSpaceRun(IFDE_CSSComputedStyle* pStyle) const {
  CFX_WideString wsValue;
  if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-spacerun"), wsValue)) {
    wsValue.MakeLower();
    return wsValue == FX_WSTRC(L"yes");
  }
  return false;
}
CFGAS_GEFont* CXFA_TextParser::GetFont(CXFA_TextProvider* pTextProvider,
                                       IFDE_CSSComputedStyle* pStyle) const {
  CFX_WideStringC wsFamily = FX_WSTRC(L"Courier");
  uint32_t dwStyle = 0;
  CXFA_Font font = pTextProvider->GetFontNode();
  if (font) {
    font.GetTypeface(wsFamily);
    if (font.IsBold()) {
      dwStyle |= FX_FONTSTYLE_Bold;
    }
    if (font.IsItalic()) {
      dwStyle |= FX_FONTSTYLE_Italic;
    }
  }
  if (pStyle) {
    IFDE_CSSFontStyle* pFontStyle = pStyle->GetFontStyles();
    int32_t iCount = pFontStyle->CountFontFamilies();
    if (iCount > 0) {
      wsFamily = pFontStyle->GetFontFamily(iCount - 1);
    }
    dwStyle = 0;
    if (pFontStyle->GetFontWeight() > FXFONT_FW_NORMAL) {
      dwStyle |= FX_FONTSTYLE_Bold;
    }
    if (pFontStyle->GetFontStyle() == FDE_CSSFONTSTYLE_Italic) {
      dwStyle |= FX_FONTSTYLE_Italic;
    }
  }
  CXFA_FFDoc* pDoc = pTextProvider->GetDocNode();
  CXFA_FontMgr* pFontMgr = pDoc->GetApp()->GetXFAFontMgr();
  return pFontMgr->GetFont(pDoc, wsFamily, dwStyle);
}
FX_FLOAT CXFA_TextParser::GetFontSize(CXFA_TextProvider* pTextProvider,
                                      IFDE_CSSComputedStyle* pStyle) const {
  if (pStyle)
    return pStyle->GetFontStyles()->GetFontSize();

  CXFA_Font font = pTextProvider->GetFontNode();
  if (font) {
    return font.GetFontSize();
  }
  return 10;
}
int32_t CXFA_TextParser::GetHorScale(CXFA_TextProvider* pTextProvider,
                                     IFDE_CSSComputedStyle* pStyle,
                                     CFDE_XMLNode* pXMLNode) const {
  if (pStyle) {
    CFX_WideString wsValue;
    if (pStyle->GetCustomStyle(FX_WSTRC(L"xfa-font-horizontal-scale"),
                               wsValue)) {
      return wsValue.GetInteger();
    }
    while (pXMLNode) {
      CXFA_TextParseContext* pContext = static_cast<CXFA_TextParseContext*>(
          m_mapXMLNodeToParseContext.GetValueAt(pXMLNode));
      if (pContext && pContext->m_pParentStyle &&
          pContext->m_pParentStyle->GetCustomStyle(
              FX_WSTRC(L"xfa-font-horizontal-scale"), wsValue)) {
        return wsValue.GetInteger();
      }
      pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::Parent);
    }
  }
  if (CXFA_Font font = pTextProvider->GetFontNode()) {
    return static_cast<int32_t>(font.GetHorizontalScale());
  }
  return 100;
}
int32_t CXFA_TextParser::GetVerScale(CXFA_TextProvider* pTextProvider,
                                     IFDE_CSSComputedStyle* pStyle) const {
  if (pStyle) {
    CFX_WideString wsValue;
    if (pStyle->GetCustomStyle(FX_WSTRC(L"xfa-font-vertical-scale"), wsValue)) {
      return wsValue.GetInteger();
    }
  }
  if (CXFA_Font font = pTextProvider->GetFontNode()) {
    return (int32_t)font.GetVerticalScale();
  }
  return 100;
}
void CXFA_TextParser::GetUnderline(CXFA_TextProvider* pTextProvider,
                                   IFDE_CSSComputedStyle* pStyle,
                                   int32_t& iUnderline,
                                   int32_t& iPeriod) const {
  iUnderline = 0;
  iPeriod = XFA_ATTRIBUTEENUM_All;
  if (pStyle) {
    uint32_t dwDecoration = pStyle->GetParagraphStyles()->GetTextDecoration();
    if (dwDecoration & FDE_CSSTEXTDECORATION_Double) {
      iUnderline = 2;
    } else if (dwDecoration & FDE_CSSTEXTDECORATION_Underline) {
      iUnderline = 1;
    }
    CFX_WideString wsValue;
    if (pStyle->GetCustomStyle(FX_WSTRC(L"underlinePeriod"), wsValue)) {
      if (wsValue == FX_WSTRC(L"word")) {
        iPeriod = XFA_ATTRIBUTEENUM_Word;
      }
    } else if (CXFA_Font font = pTextProvider->GetFontNode()) {
      iPeriod = font.GetUnderlinePeriod();
    }
  } else {
    CXFA_Font font = pTextProvider->GetFontNode();
    if (font) {
      iUnderline = font.GetUnderline();
      iPeriod = font.GetUnderlinePeriod();
    }
  }
}
void CXFA_TextParser::GetLinethrough(CXFA_TextProvider* pTextProvider,
                                     IFDE_CSSComputedStyle* pStyle,
                                     int32_t& iLinethrough) const {
  if (pStyle) {
    uint32_t dwDecoration = pStyle->GetParagraphStyles()->GetTextDecoration();
    iLinethrough = (dwDecoration & FDE_CSSTEXTDECORATION_LineThrough) ? 1 : 0;
  } else {
    CXFA_Font font = pTextProvider->GetFontNode();
    if (font) {
      iLinethrough = font.GetLineThrough();
    }
  }
}
FX_ARGB CXFA_TextParser::GetColor(CXFA_TextProvider* pTextProvider,
                                  IFDE_CSSComputedStyle* pStyle) const {
  if (pStyle)
    return pStyle->GetFontStyles()->GetColor();

  if (CXFA_Font font = pTextProvider->GetFontNode())
    return font.GetColor();

  return 0xFF000000;
}
FX_FLOAT CXFA_TextParser::GetBaseline(CXFA_TextProvider* pTextProvider,
                                      IFDE_CSSComputedStyle* pStyle) const {
  if (pStyle) {
    IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles();
    if (pParaStyle->GetVerticalAlign() == FDE_CSSVERTICALALIGN_Number) {
      return pParaStyle->GetNumberVerticalAlign();
    }
  } else if (CXFA_Font font = pTextProvider->GetFontNode()) {
    return font.GetBaselineShift();
  }
  return 0;
}
FX_FLOAT CXFA_TextParser::GetLineHeight(CXFA_TextProvider* pTextProvider,
                                        IFDE_CSSComputedStyle* pStyle,
                                        bool bFirst,
                                        FX_FLOAT fVerScale) const {
  FX_FLOAT fLineHeight = 0;
  if (pStyle) {
    fLineHeight = pStyle->GetParagraphStyles()->GetLineHeight();
  } else if (CXFA_Para para = pTextProvider->GetParaNode()) {
    fLineHeight = para.GetLineHeight();
  }
  if (bFirst) {
    FX_FLOAT fFontSize = GetFontSize(pTextProvider, pStyle);
    if (fLineHeight < 0.1f) {
      fLineHeight = fFontSize;
    } else {
      fLineHeight = std::min(fLineHeight, fFontSize);
    }
  } else if (fLineHeight < 0.1f) {
    fLineHeight = GetFontSize(pTextProvider, pStyle) * 1.2f;
  }
  fLineHeight *= fVerScale;
  return fLineHeight;
}
bool CXFA_TextParser::GetEmbbedObj(CXFA_TextProvider* pTextProvider,
                                   CFDE_XMLNode* pXMLNode,
                                   CFX_WideString& wsValue) {
  wsValue.clear();
  if (!pXMLNode) {
    return false;
  }
  bool bRet = false;
  if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
    CFDE_XMLElement* pElement = static_cast<CFDE_XMLElement*>(pXMLNode);
    CFX_WideString wsAttr;
    pElement->GetString(L"xfa:embed", wsAttr);
    if (wsAttr.IsEmpty()) {
      return false;
    }
    if (wsAttr.GetAt(0) == L'#') {
      wsAttr.Delete(0);
    }
    CFX_WideString ws;
    pElement->GetString(L"xfa:embedType", ws);
    if (ws.IsEmpty()) {
      ws = L"som";
    } else {
      ws.MakeLower();
    }
    bool bURI = (ws == FX_WSTRC(L"uri"));
    if (!bURI && ws != FX_WSTRC(L"som")) {
      return false;
    }
    ws.clear();
    pElement->GetString(L"xfa:embedMode", ws);
    if (ws.IsEmpty()) {
      ws = L"formatted";
    } else {
      ws.MakeLower();
    }
    bool bRaw = (ws == FX_WSTRC(L"raw"));
    if (!bRaw && ws != FX_WSTRC(L"formatted")) {
      return false;
    }
    bRet = pTextProvider->GetEmbbedObj(bURI, bRaw, wsAttr, wsValue);
  }
  return bRet;
}
CXFA_TextParseContext* CXFA_TextParser::GetParseContextFromMap(
    CFDE_XMLNode* pXMLNode) {
  return (CXFA_TextParseContext*)m_mapXMLNodeToParseContext.GetValueAt(
      pXMLNode);
}
enum XFA_TABSTOPSSTATUS {
  XFA_TABSTOPSSTATUS_Error,
  XFA_TABSTOPSSTATUS_EOS,
  XFA_TABSTOPSSTATUS_None,
  XFA_TABSTOPSSTATUS_Alignment,
  XFA_TABSTOPSSTATUS_StartLeader,
  XFA_TABSTOPSSTATUS_Leader,
  XFA_TABSTOPSSTATUS_Location,
};
bool CXFA_TextParser::GetTabstops(IFDE_CSSComputedStyle* pStyle,
                                  CXFA_TextTabstopsContext* pTabstopContext) {
  if (!pStyle || !pTabstopContext) {
    return false;
  }
  CFX_WideString wsValue;
  if (!pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-stops"), wsValue) &&
      !pStyle->GetCustomStyle(FX_WSTRC(L"tab-stops"), wsValue)) {
    return false;
  }
  int32_t iLength = wsValue.GetLength();
  const FX_WCHAR* pTabStops = wsValue.c_str();
  int32_t iCur = 0;
  int32_t iLast = 0;
  CFX_WideString wsAlign;
  XFA_TABSTOPSSTATUS eStatus = XFA_TABSTOPSSTATUS_None;
  FX_WCHAR ch;
  while (iCur < iLength) {
    ch = pTabStops[iCur];
    switch (eStatus) {
      case XFA_TABSTOPSSTATUS_None:
        if (ch <= ' ') {
          iCur++;
        } else {
          eStatus = XFA_TABSTOPSSTATUS_Alignment;
          iLast = iCur;
        }
        break;
      case XFA_TABSTOPSSTATUS_Alignment:
        if (ch == ' ') {
          wsAlign = CFX_WideStringC(pTabStops + iLast, iCur - iLast);
          eStatus = XFA_TABSTOPSSTATUS_StartLeader;
          iCur++;
          while (iCur < iLength && pTabStops[iCur] <= ' ') {
            iCur++;
          }
          iLast = iCur;
        } else {
          iCur++;
        }
        break;
      case XFA_TABSTOPSSTATUS_StartLeader:
        if (ch != 'l') {
          eStatus = XFA_TABSTOPSSTATUS_Location;
        } else {
          int32_t iCount = 0;
          while (iCur < iLength) {
            ch = pTabStops[iCur];
            iCur++;
            if (ch == '(') {
              iCount++;
            } else if (ch == ')') {
              iCount--;
              if (iCount == 0) {
                break;
              }
            }
          }
          while (iCur < iLength && pTabStops[iCur] <= ' ') {
            iCur++;
          }
          iLast = iCur;
          eStatus = XFA_TABSTOPSSTATUS_Location;
        }
        break;
      case XFA_TABSTOPSSTATUS_Location:
        if (ch == ' ') {
          uint32_t dwHashCode = FX_HashCode_GetW(wsAlign.AsStringC(), true);
          CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast));
          FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt);
          pTabstopContext->Append(dwHashCode, fPos);
          wsAlign.clear();
          eStatus = XFA_TABSTOPSSTATUS_None;
        }
        iCur++;
        break;
      default:
        break;
    }
  }
  if (!wsAlign.IsEmpty()) {
    uint32_t dwHashCode = FX_HashCode_GetW(wsAlign.AsStringC(), true);
    CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast));
    FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt);
    pTabstopContext->Append(dwHashCode, fPos);
  }
  return true;
}

CXFA_TextLayout::CXFA_TextLayout(CXFA_TextProvider* pTextProvider)
    : m_bHasBlock(false),
      m_pTextProvider(pTextProvider),
      m_pTextDataNode(nullptr),
      m_bRichText(false),
      m_iLines(0),
      m_fMaxWidth(0),
      m_bBlockContinue(true) {
  ASSERT(m_pTextProvider);
}

CXFA_TextLayout::~CXFA_TextLayout() {
  m_textParser.Reset();
  Unload();
}

void CXFA_TextLayout::Unload() {
  for (int32_t i = 0; i < m_pieceLines.GetSize(); i++) {
    CXFA_PieceLine* pLine = m_pieceLines.GetAt(i);
    for (int32_t i = 0; i < pLine->m_textPieces.GetSize(); i++) {
      XFA_TextPiece* pPiece = pLine->m_textPieces.GetAt(i);
      // Release text and widths in a text piece.
      m_pAllocator->Free(pPiece->pszText);
      m_pAllocator->Free(pPiece->pWidths);
      // Release text piece.
      FXTARGET_DeleteWith(XFA_TextPiece, m_pAllocator.get(), pPiece);
    }
    pLine->m_textPieces.RemoveAll();
    // Release line.
    FXTARGET_DeleteWith(CXFA_PieceLine, m_pAllocator.get(), pLine);
  }
  m_pieceLines.RemoveAll();
  m_pBreak.reset();
  m_pAllocator.reset();
}

const CXFA_PieceLineArray* CXFA_TextLayout::GetPieceLines() {
  return &m_pieceLines;
}

void CXFA_TextLayout::GetTextDataNode() {
  if (!m_pTextProvider) {
    return;
  }
  CXFA_Node* pNode = m_pTextProvider->GetTextNode(m_bRichText);
  if (pNode && m_bRichText) {
    m_textParser.Reset();
  }
  m_pTextDataNode = pNode;
}
CFDE_XMLNode* CXFA_TextLayout::GetXMLContainerNode() {
  CFDE_XMLNode* pXMLContainer = nullptr;
  if (m_bRichText) {
    CFDE_XMLNode* pXMLRoot = m_pTextDataNode->GetXMLMappingNode();
    if (!pXMLRoot) {
      return pXMLContainer;
    }
    for (CFDE_XMLNode* pXMLChild =
             pXMLRoot->GetNodeItem(CFDE_XMLNode::FirstChild);
         pXMLChild;
         pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) {
      if (pXMLChild->GetType() == FDE_XMLNODE_Element) {
        CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLChild);
        CFX_WideString wsTag;
        pXMLElement->GetLocalTagName(wsTag);
        if (wsTag == FX_WSTRC(L"body") || wsTag == FX_WSTRC(L"html")) {
          pXMLContainer = pXMLChild;
          break;
        }
      }
    }
  }
  return pXMLContainer;
}
CFX_RTFBreak* CXFA_TextLayout::CreateBreak(bool bDefault) {
  uint32_t dwStyle = FX_RTFLAYOUTSTYLE_ExpandTab;
  if (!bDefault) {
    dwStyle |= FX_RTFLAYOUTSTYLE_Pagination;
  }
  CFX_RTFBreak* pBreak = new CFX_RTFBreak(0);
  pBreak->SetLayoutStyles(dwStyle);
  pBreak->SetLineBreakChar(L'\n');
  pBreak->SetLineBreakTolerance(1);
  pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, nullptr));
  pBreak->SetFontSize(m_textParser.GetFontSize(m_pTextProvider, nullptr));
  return pBreak;
}
void CXFA_TextLayout::InitBreak(FX_FLOAT fLineWidth) {
  CXFA_Font font = m_pTextProvider->GetFontNode();
  CXFA_Para para = m_pTextProvider->GetParaNode();
  FX_FLOAT fStart = 0;
  FX_FLOAT fStartPos = 0;
  if (para) {
    int32_t iAlign = FX_RTFLINEALIGNMENT_Left;
    switch (para.GetHorizontalAlign()) {
      case XFA_ATTRIBUTEENUM_Center:
        iAlign = FX_RTFLINEALIGNMENT_Center;
        break;
      case XFA_ATTRIBUTEENUM_Right:
        iAlign = FX_RTFLINEALIGNMENT_Right;
        break;
      case XFA_ATTRIBUTEENUM_Justify:
        iAlign = FX_RTFLINEALIGNMENT_Justified;
        break;
      case XFA_ATTRIBUTEENUM_JustifyAll:
        iAlign = FX_RTFLINEALIGNMENT_Distributed;
        break;
    }
    m_pBreak->SetAlignment(iAlign);
    fStart = para.GetMarginLeft();
    if (m_pTextProvider->IsCheckButtonAndAutoWidth()) {
      if (iAlign != FX_RTFLINEALIGNMENT_Left) {
        fLineWidth -= para.GetMarginRight();
      }
    } else {
      fLineWidth -= para.GetMarginRight();
    }
    if (fLineWidth < 0) {
      fLineWidth = fStart;
    }
    fStartPos = fStart;
    FX_FLOAT fIndent = para.GetTextIndent();
    if (fIndent > 0) {
      fStartPos += fIndent;
    }
  }
  m_pBreak->SetLineBoundary(fStart, fLineWidth);
  m_pBreak->SetLineStartPos(fStartPos);
  if (font) {
    m_pBreak->SetHorizontalScale((int32_t)font.GetHorizontalScale());
    m_pBreak->SetVerticalScale((int32_t)font.GetVerticalScale());
    m_pBreak->SetCharSpace(font.GetLetterSpacing());
  }
  FX_FLOAT fFontSize = m_textParser.GetFontSize(m_pTextProvider, nullptr);
  m_pBreak->SetFontSize(fFontSize);
  m_pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, nullptr));
  m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f);
}
void CXFA_TextLayout::InitBreak(IFDE_CSSComputedStyle* pStyle,
                                FDE_CSSDISPLAY eDisplay,
                                FX_FLOAT fLineWidth,
                                CFDE_XMLNode* pXMLNode,
                                IFDE_CSSComputedStyle* pParentStyle) {
  if (!pStyle) {
    InitBreak(fLineWidth);
    return;
  }
  IFDE_CSSParagraphStyle* pParaStyle = pStyle->GetParagraphStyles();
  if (eDisplay == FDE_CSSDISPLAY_Block || eDisplay == FDE_CSSDISPLAY_ListItem) {
    int32_t iAlign = FX_RTFLINEALIGNMENT_Left;
    switch (pParaStyle->GetTextAlign()) {
      case FDE_CSSTEXTALIGN_Right:
        iAlign = FX_RTFLINEALIGNMENT_Right;
        break;
      case FDE_CSSTEXTALIGN_Center:
        iAlign = FX_RTFLINEALIGNMENT_Center;
        break;
      case FDE_CSSTEXTALIGN_Justify:
        iAlign = FX_RTFLINEALIGNMENT_Justified;
        break;
      case FDE_CSSTEXTALIGN_JustifyAll:
        iAlign = FX_RTFLINEALIGNMENT_Distributed;
        break;
      default:
        break;
    }
    m_pBreak->SetAlignment(iAlign);
    FX_FLOAT fStart = 0;
    const FDE_CSSRECT* pRect = pStyle->GetBoundaryStyles()->GetMarginWidth();
    const FDE_CSSRECT* pPaddingRect =
        pStyle->GetBoundaryStyles()->GetPaddingWidth();
    if (pRect) {
      fStart = pRect->left.GetValue();
      fLineWidth -= pRect->right.GetValue();
      if (pPaddingRect) {
        fStart += pPaddingRect->left.GetValue();
        fLineWidth -= pPaddingRect->right.GetValue();
      }
      if (eDisplay == FDE_CSSDISPLAY_ListItem) {
        const FDE_CSSRECT* pParRect =
            pParentStyle->GetBoundaryStyles()->GetMarginWidth();
        const FDE_CSSRECT* pParPaddingRect =
            pParentStyle->GetBoundaryStyles()->GetPaddingWidth();
        if (pParRect) {
          fStart += pParRect->left.GetValue();
          fLineWidth -= pParRect->right.GetValue();
          if (pParPaddingRect) {
            fStart += pParPaddingRect->left.GetValue();
            fLineWidth -= pParPaddingRect->right.GetValue();
          }
        }
        FDE_CSSRECT pNewRect;
        pNewRect.left.Set(FDE_CSSLENGTHUNIT_Point, fStart);
        pNewRect.right.Set(FDE_CSSLENGTHUNIT_Point, pRect->right.GetValue());
        pNewRect.top.Set(FDE_CSSLENGTHUNIT_Point, pRect->top.GetValue());
        pNewRect.bottom.Set(FDE_CSSLENGTHUNIT_Point, pRect->bottom.GetValue());
        pStyle->GetBoundaryStyles()->SetMarginWidth(pNewRect);
      }
    }
    m_pBreak->SetLineBoundary(fStart, fLineWidth);
    FX_FLOAT fIndent = pParaStyle->GetTextIndent().GetValue();
    if (fIndent > 0) {
      fStart += fIndent;
    }
    m_pBreak->SetLineStartPos(fStart);
    m_pBreak->SetTabWidth(m_textParser.GetTabInterval(pStyle));
    if (!m_pTabstopContext)
      m_pTabstopContext = pdfium::MakeUnique<CXFA_TextTabstopsContext>();
    m_textParser.GetTabstops(pStyle, m_pTabstopContext.get());
    for (int32_t i = 0; i < m_pTabstopContext->m_iTabCount; i++) {
      XFA_TABSTOPS* pTab = m_pTabstopContext->m_tabstops.GetDataPtr(i);
      m_pBreak->AddPositionedTab(pTab->fTabstops);
    }
  }
  FX_FLOAT fFontSize = m_textParser.GetFontSize(m_pTextProvider, pStyle);
  m_pBreak->SetFontSize(fFontSize);
  m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f);
  m_pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, pStyle));
  m_pBreak->SetHorizontalScale(
      m_textParser.GetHorScale(m_pTextProvider, pStyle, pXMLNode));
  m_pBreak->SetVerticalScale(m_textParser.GetVerScale(m_pTextProvider, pStyle));
  m_pBreak->SetCharSpace(pParaStyle->GetLetterSpacing().GetValue());
}
int32_t CXFA_TextLayout::GetText(CFX_WideString& wsText) {
  GetTextDataNode();
  wsText.clear();
  if (m_bRichText) {
  } else {
    wsText = m_pTextDataNode->GetContent();
  }
  return wsText.GetLength();
}
FX_FLOAT CXFA_TextLayout::GetLayoutHeight() {
  if (!m_pLoader) {
    return 0;
  }
  int32_t iCount = m_pLoader->m_lineHeights.GetSize();
  if (iCount == 0 && m_pLoader->m_fWidth > 0) {
    CFX_SizeF szMax(m_pLoader->m_fWidth, m_pLoader->m_fHeight);
    CFX_SizeF szDef;
    m_pLoader->m_bSaveLineHeight = true;
    m_pLoader->m_fLastPos = 0;
    CalcSize(szMax, szMax, szDef);
    m_pLoader->m_bSaveLineHeight = false;
    return szDef.y;
  }
  FX_FLOAT fHeight = m_pLoader->m_fHeight;
  if (fHeight < 0.1f) {
    fHeight = 0;
    for (int32_t i = 0; i < iCount; i++) {
      fHeight += m_pLoader->m_lineHeights.ElementAt(i);
    }
  }
  return fHeight;
}
FX_FLOAT CXFA_TextLayout::StartLayout(FX_FLOAT fWidth) {
  if (!m_pLoader)
    m_pLoader = pdfium::MakeUnique<CXFA_LoaderContext>();

  if (fWidth < 0 || (m_pLoader->m_fWidth > -1 &&
                     FXSYS_fabs(fWidth - m_pLoader->m_fWidth) > 0)) {
    m_pLoader->m_lineHeights.RemoveAll();
    m_Blocks.RemoveAll();
    Unload();
    m_pLoader->m_fStartLineOffset = 0;
  }
  m_pLoader->m_fWidth = fWidth;
  if (fWidth < 0) {
    CFX_SizeF szMax;
    CFX_SizeF szDef;
    m_pLoader->m_bSaveLineHeight = true;
    m_pLoader->m_fLastPos = 0;
    CalcSize(szMax, szMax, szDef);
    m_pLoader->m_bSaveLineHeight = false;
    fWidth = szDef.x;
  }
  return fWidth;
}
bool CXFA_TextLayout::DoLayout(int32_t iBlockIndex,
                               FX_FLOAT& fCalcHeight,
                               FX_FLOAT fContentAreaHeight,
                               FX_FLOAT fTextHeight) {
  if (!m_pLoader) {
    return false;
  }
  int32_t iBlockCount = m_Blocks.GetSize();
  FX_FLOAT fHeight = fTextHeight;
  if (fHeight < 0) {
    fHeight = GetLayoutHeight();
  }
  m_pLoader->m_fHeight = fHeight;
  if (fContentAreaHeight < 0) {
    return false;
  }
  m_bHasBlock = true;
  if (iBlockCount == 0 && fHeight > 0) {
    fHeight = fTextHeight - GetLayoutHeight();
    if (fHeight > 0) {
      int32_t iAlign = m_textParser.GetVAlign(m_pTextProvider);
      if (iAlign == XFA_ATTRIBUTEENUM_Middle) {
        fHeight /= 2.0f;
      } else if (iAlign != XFA_ATTRIBUTEENUM_Bottom) {
        fHeight = 0;
      }
      m_pLoader->m_fStartLineOffset = fHeight;
    }
  }
  FX_FLOAT fLinePos = m_pLoader->m_fStartLineOffset;
  int32_t iLineIndex = 0;
  if (iBlockCount > 1) {
    if (iBlockCount >= (iBlockIndex + 1) * 2) {
      iLineIndex = m_Blocks.ElementAt(iBlockIndex * 2);
    } else {
      iLineIndex = m_Blocks.ElementAt(iBlockCount - 1) +
                   m_Blocks.ElementAt(iBlockCount - 2);
    }
    if (!m_pLoader->m_BlocksHeight.empty()) {
      for (int32_t i = 0; i < iBlockIndex; i++)
        fLinePos -= m_pLoader->m_BlocksHeight[i * 2 + 1];
    }
  }
  int32_t iCount = m_pLoader->m_lineHeights.GetSize();
  int32_t i = 0;
  for (i = iLineIndex; i < iCount; i++) {
    FX_FLOAT fLineHeight = m_pLoader->m_lineHeights.ElementAt(i);
    if ((i == iLineIndex) && (fLineHeight - fContentAreaHeight > 0.001)) {
      fCalcHeight = 0;
      return true;
    }
    if (fLinePos + fLineHeight - fContentAreaHeight > 0.001) {
      if (iBlockCount >= (iBlockIndex + 1) * 2) {
        m_Blocks.SetAt(iBlockIndex * 2, iLineIndex);
        m_Blocks.SetAt(iBlockIndex * 2 + 1, i - iLineIndex);
      } else {
        m_Blocks.Add(iLineIndex);
        m_Blocks.Add(i - iLineIndex);
      }
      if (i == iLineIndex) {
        if (fCalcHeight <= fLinePos) {
          if (pdfium::CollectionSize<int32_t>(m_pLoader->m_BlocksHeight) >
                  iBlockIndex * 2 &&
              (m_pLoader->m_BlocksHeight[iBlockIndex * 2] == iBlockIndex)) {
            m_pLoader->m_BlocksHeight[iBlockIndex * 2 + 1] = fCalcHeight;
          } else {
            m_pLoader->m_BlocksHeight.push_back((FX_FLOAT)iBlockIndex);
            m_pLoader->m_BlocksHeight.push_back(fCalcHeight);
          }
        }
        return true;
      }
      fCalcHeight = fLinePos;
      return true;
    }
    fLinePos += fLineHeight;
  }
  return false;
}
int32_t CXFA_TextLayout::CountBlocks() const {
  int32_t iCount = m_Blocks.GetSize() / 2;
  return iCount > 0 ? iCount : 1;
}

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

  m_pBreak.reset(CreateBreak(false));
  FX_FLOAT fLinePos = 0;
  m_iLines = 0;
  m_fMaxWidth = 0;
  Loader(defaultSize, fLinePos, false);
  if (fLinePos < 0.1f)
    fLinePos = m_textParser.GetFontSize(m_pTextProvider, nullptr);

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

bool CXFA_TextLayout::Layout(const CFX_SizeF& size, FX_FLOAT* fHeight) {
  if (size.x < 1)
    return false;

  Unload();
  m_pBreak.reset(CreateBreak(true));
  if (m_pLoader) {
    m_pLoader->m_iTotalLines = -1;
    m_pLoader->m_iChar = 0;
  }
  m_iLines = 0;
  FX_FLOAT fLinePos = 0;
  Loader(size, fLinePos, true);
  UpdateAlign(size.y, fLinePos);
  m_pTabstopContext.reset();
  if (fHeight)
    *fHeight = fLinePos;
  return true;
}

bool CXFA_TextLayout::Layout(int32_t iBlock) {
  if (!m_pLoader || iBlock < 0 || iBlock >= CountBlocks())
    return false;
  if (m_pLoader->m_fWidth < 1)
    return false;

  m_pLoader->m_iTotalLines = -1;
  m_iLines = 0;
  FX_FLOAT fLinePos = 0;
  CXFA_Node* pNode = nullptr;
  CFX_SizeF szText(m_pLoader->m_fWidth, m_pLoader->m_fHeight);
  int32_t iCount = m_Blocks.GetSize();
  int32_t iBlocksHeightCount =
      pdfium::CollectionSize<int32_t>(m_pLoader->m_BlocksHeight);
  iBlocksHeightCount /= 2;
  if (iBlock < iBlocksHeightCount)
    return true;
  if (iBlock == iBlocksHeightCount) {
    Unload();
    m_pBreak.reset(CreateBreak(true));
    fLinePos = m_pLoader->m_fStartLineOffset;
    for (int32_t i = 0; i < iBlocksHeightCount; i++) {
      fLinePos -= m_pLoader->m_BlocksHeight[i * 2 + 1];
    }
    m_pLoader->m_iChar = 0;
    if (iCount > 1)
      m_pLoader->m_iTotalLines = m_Blocks.ElementAt(iBlock * 2 + 1);
    Loader(szText, fLinePos, true);
    if (iCount == 0 && m_pLoader->m_fStartLineOffset < 0.1f)
      UpdateAlign(szText.y, fLinePos);
  } else if (m_pTextDataNode) {
    iBlock *= 2;
    if (iBlock < iCount - 2)
      m_pLoader->m_iTotalLines = m_Blocks.ElementAt(iBlock + 1);
    m_pBreak->Reset();
    if (m_bRichText) {
      CFDE_XMLNode* pContainerNode = GetXMLContainerNode();
      if (!pContainerNode) {
        return true;
      }
      CFDE_XMLNode* pXMLNode = m_pLoader->m_pXMLNode;
      if (!pXMLNode)
        return true;
      CFDE_XMLNode* pSaveXMLNode = m_pLoader->m_pXMLNode;
      for (; pXMLNode;
           pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling)) {
        if (!LoadRichText(pXMLNode, szText, fLinePos, m_pLoader->m_pParentStyle,
                          true)) {
          break;
        }
      }
      while (!pXMLNode) {
        pXMLNode = pSaveXMLNode->GetNodeItem(CFDE_XMLNode::Parent);
        if (pXMLNode == pContainerNode)
          break;
        if (!LoadRichText(pXMLNode, szText, fLinePos, m_pLoader->m_pParentStyle,
                          true, nullptr, false)) {
          break;
        }
        pSaveXMLNode = pXMLNode;
        pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling);
        if (!pXMLNode)
          continue;
        for (; pXMLNode;
             pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling)) {
          if (!LoadRichText(pXMLNode, szText, fLinePos,
                            m_pLoader->m_pParentStyle, true)) {
            break;
          }
        }
      }
    } else {
      pNode = m_pLoader->m_pNode;
      if (!pNode)
        return true;
      LoadText(pNode, szText, fLinePos, true);
    }
  }
  if (iBlock == iCount) {
    m_pTabstopContext.reset();
    m_pLoader.reset();
  }
  return true;
}
void CXFA_TextLayout::ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex) {
  if (!m_pLoader) {
    return;
  }
  int32_t iCountHeight = m_pLoader->m_lineHeights.GetSize();
  if (iCountHeight == 0) {
    return;
  }
  bool bEndItem = true;
  int32_t iBlockCount = m_Blocks.GetSize();
  FX_FLOAT fLinePos = m_pLoader->m_fStartLineOffset;
  int32_t iLineIndex = 0;
  if (iBlockIndex > 0) {
    int32_t iBlockHeightCount =
        pdfium::CollectionSize<int32_t>(m_pLoader->m_BlocksHeight);
    iBlockHeightCount /= 2;
    if (iBlockHeightCount >= iBlockIndex) {
      for (int32_t i = 0; i < iBlockIndex; i++) {
        fLinePos -= m_pLoader->m_BlocksHeight[i * 2 + 1];
      }
    } else {
      fLinePos = 0;
    }
    iLineIndex = m_Blocks[iBlockCount - 1] + m_Blocks[iBlockCount - 2];
  }
  int32_t i = 0;
  for (i = iLineIndex; i < iCountHeight; i++) {
    FX_FLOAT fLineHeight = m_pLoader->m_lineHeights.ElementAt(i);
    if (fLinePos + fLineHeight - rtText.height > 0.001) {
      m_Blocks.Add(iLineIndex);
      m_Blocks.Add(i - iLineIndex);
      bEndItem = false;
      break;
    }
    fLinePos += fLineHeight;
  }
  if (iCountHeight > 0 && (i - iLineIndex) > 0 && bEndItem) {
    m_Blocks.Add(iLineIndex);
    m_Blocks.Add(i - iLineIndex);
  }
}
bool CXFA_TextLayout::DrawString(CFX_RenderDevice* pFxDevice,
                                 const CFX_Matrix& tmDoc2Device,
                                 const CFX_RectF& rtClip,
                                 int32_t iBlock) {
  if (!pFxDevice)
    return false;

  std::unique_ptr<CFDE_RenderDevice> pDevice(
      new CFDE_RenderDevice(pFxDevice, false));
  pDevice->SaveState();
  pDevice->SetClipRect(rtClip);

  std::unique_ptr<CFDE_Brush> pSolidBrush(new CFDE_Brush);
  std::unique_ptr<CFDE_Pen> pPen(new CFDE_Pen);
  if (m_pieceLines.GetSize() == 0) {
    int32_t iBlockCount = CountBlocks();
    for (int32_t i = 0; i < iBlockCount; i++) {
      Layout(i);
    }
  }
  FXTEXT_CHARPOS* pCharPos = nullptr;
  int32_t iCharCount = 0;
  int32_t iLineStart = 0;
  int32_t iPieceLines = m_pieceLines.GetSize();
  int32_t iCount = m_Blocks.GetSize();
  if (iCount > 0) {
    iBlock *= 2;
    if (iBlock < iCount) {
      iLineStart = m_Blocks.ElementAt(iBlock);
      iPieceLines = m_Blocks.ElementAt(iBlock + 1);
    } else {
      iPieceLines = 0;
    }
  }
  for (int32_t i = 0; i < iPieceLines; i++) {
    if (i + iLineStart >= m_pieceLines.GetSize()) {
      break;
    }
    CXFA_PieceLine* pPieceLine = m_pieceLines.GetAt(i + iLineStart);
    int32_t iPieces = pPieceLine->m_textPieces.GetSize();
    int32_t j = 0;
    for (j = 0; j < iPieces; j++) {
      const XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(j);
      int32_t iChars = pPiece->iChars;
      if (iCharCount < iChars) {
        FX_Free(pCharPos);
        pCharPos = FX_Alloc(FXTEXT_CHARPOS, iChars);
        iCharCount = iChars;
      }
      FXSYS_memset(pCharPos, 0, iCharCount * sizeof(FXTEXT_CHARPOS));
      RenderString(pDevice.get(), pSolidBrush.get(), pPieceLine, j, pCharPos,
                   tmDoc2Device);
    }
    for (j = 0; j < iPieces; j++) {
      RenderPath(pDevice.get(), pPen.get(), pPieceLine, j, pCharPos,
                 tmDoc2Device);
    }
  }
  pDevice->RestoreState();
  FX_Free(pCharPos);
  return iPieceLines > 0;
}
void CXFA_TextLayout::UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom) {
  fHeight -= fBottom;
  if (fHeight < 0.1f) {
    return;
  }
  switch (m_textParser.GetVAlign(m_pTextProvider)) {
    case XFA_ATTRIBUTEENUM_Middle:
      fHeight /= 2.0f;
      break;
    case XFA_ATTRIBUTEENUM_Bottom:
      break;
    default:
      return;
  }
  int32_t iCount = m_pieceLines.GetSize();
  for (int32_t i = 0; i < iCount; i++) {
    CXFA_PieceLine* pPieceLine = m_pieceLines.GetAt(i);
    int32_t iPieces = pPieceLine->m_textPieces.GetSize();
    for (int32_t j = 0; j < iPieces; j++) {
      XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(j);
      CFX_RectF& rect = pPiece->rtPiece;
      rect.top += fHeight;
    }
  }
}
bool CXFA_TextLayout::Loader(const CFX_SizeF& szText,
                             FX_FLOAT& fLinePos,
                             bool bSavePieces) {
  if (!m_pAllocator) {
    m_pAllocator = IFX_MemoryAllocator::Create(FX_ALLOCTYPE_Static, 256, 0);
  }
  GetTextDataNode();
  if (!m_pTextDataNode)
    return true;

  if (m_bRichText) {
    CFDE_XMLNode* pXMLContainer = GetXMLContainerNode();
    if (pXMLContainer) {
      if (!m_textParser.IsParsed()) {
        m_textParser.DoParse(pXMLContainer, m_pTextProvider);
      }
      IFDE_CSSComputedStyle* pRootStyle =
          m_textParser.CreateRootStyle(m_pTextProvider);
      LoadRichText(pXMLContainer, szText, fLinePos, pRootStyle, bSavePieces);
      pRootStyle->Release();
    }
  } else {
    LoadText(m_pTextDataNode, szText, fLinePos, bSavePieces);
  }
  return true;
}
void CXFA_TextLayout::LoadText(CXFA_Node* pNode,
                               const CFX_SizeF& szText,
                               FX_FLOAT& fLinePos,
                               bool bSavePieces) {
  InitBreak(szText.x);
  CXFA_Para para = m_pTextProvider->GetParaNode();
  FX_FLOAT fSpaceAbove = 0;
  if (para) {
    fSpaceAbove = para.GetSpaceAbove();
    if (fSpaceAbove < 0.1f) {
      fSpaceAbove = 0;
    }
    int32_t verAlign = para.GetVerticalAlign();
    switch (verAlign) {
      case XFA_ATTRIBUTEENUM_Top:
      case XFA_ATTRIBUTEENUM_Middle:
      case XFA_ATTRIBUTEENUM_Bottom: {
        fLinePos += fSpaceAbove;
        break;
      }
    }
  }
  CFX_WideString wsText = pNode->GetContent();
  wsText.TrimRight(L" ");
  bool bRet = AppendChar(wsText, fLinePos, fSpaceAbove, bSavePieces);
  if (bRet && m_pLoader) {
    m_pLoader->m_pNode = pNode;
  } else {
    EndBreak(FX_RTFBREAK_ParagraphBreak, fLinePos, bSavePieces);
  }
}
bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
                                   const CFX_SizeF& szText,
                                   FX_FLOAT& fLinePos,
                                   IFDE_CSSComputedStyle* pParentStyle,
                                   bool bSavePieces,
                                   CXFA_LinkUserData* pLinkData,
                                   bool bEndBreak,
                                   bool bIsOl,
                                   int32_t iLiCount) {
  if (!pXMLNode) {
    return false;
  }
  CXFA_TextParseContext* pContext =
      m_textParser.GetParseContextFromMap(pXMLNode);
  FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_None;
  bool bContentNode = false;
  FX_FLOAT fSpaceBelow = 0;
  IFDE_CSSComputedStyle* pStyle = nullptr;
  CFX_WideString wsName;
  if (bEndBreak) {
    bool bCurOl = false;
    bool bCurLi = false;
    CFDE_XMLElement* pElement = nullptr;
    if (pContext) {
      if (m_bBlockContinue ||
          (m_pLoader && pXMLNode == m_pLoader->m_pXMLNode)) {
        m_bBlockContinue = true;
      }
      if (pXMLNode->GetType() == FDE_XMLNODE_Text) {
        bContentNode = true;
      } else if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
        pElement = static_cast<CFDE_XMLElement*>(pXMLNode);
        pElement->GetLocalTagName(wsName);
      }
      if (wsName == FX_WSTRC(L"ol")) {
        bIsOl = true;
        bCurOl = true;
      }
      if (m_bBlockContinue || bContentNode == false) {
        eDisplay = pContext->GetDisplay();
        if (eDisplay != FDE_CSSDISPLAY_Block &&
            eDisplay != FDE_CSSDISPLAY_Inline &&
            eDisplay != FDE_CSSDISPLAY_ListItem) {
          return true;
        }
        pStyle = m_textParser.ComputeStyle(pXMLNode, pParentStyle);
        InitBreak(bContentNode ? pParentStyle : pStyle, eDisplay, szText.x,
                  pXMLNode, pParentStyle);
        if ((eDisplay == FDE_CSSDISPLAY_Block ||
             eDisplay == FDE_CSSDISPLAY_ListItem) &&
            pStyle &&
            (wsName.IsEmpty() ||
             (wsName != FX_WSTRC(L"body") && wsName != FX_WSTRC(L"html") &&
              wsName != FX_WSTRC(L"ol") && wsName != FX_WSTRC(L"ul")))) {
          const FDE_CSSRECT* pRect =
              pStyle->GetBoundaryStyles()->GetMarginWidth();
          if (pRect) {
            fLinePos += pRect->top.GetValue();
            fSpaceBelow = pRect->bottom.GetValue();
          }
        }
        if (wsName == FX_WSTRC(L"a")) {
          CFX_WideString wsLinkContent;
          ASSERT(pElement);
          pElement->GetString(L"href", wsLinkContent);
          if (!wsLinkContent.IsEmpty()) {
            pLinkData = FXTARGET_NewWith(m_pAllocator.get()) CXFA_LinkUserData(
                m_pAllocator.get(),
                wsLinkContent.GetBuffer(wsLinkContent.GetLength()));
            wsLinkContent.ReleaseBuffer(wsLinkContent.GetLength());
          }
        }
        int32_t iTabCount =
            m_textParser.CountTabs(bContentNode ? pParentStyle : pStyle);
        bool bSpaceRun =
            m_textParser.IsSpaceRun(bContentNode ? pParentStyle : pStyle);
        CFX_WideString wsText;
        if (bContentNode && iTabCount == 0) {
          static_cast<CFDE_XMLText*>(pXMLNode)->GetText(wsText);
        } else if (wsName == FX_WSTRC(L"br")) {
          wsText = L'\n';
        } else if (wsName == FX_WSTRC(L"li")) {
          bCurLi = true;
          if (bIsOl) {
            wsText.Format(L"%d.  ", iLiCount);
          } else {
            wsText = 0x00B7 + FX_WSTRC(L"  ");
          }
        } else if (!bContentNode) {
          if (iTabCount > 0) {
            while (iTabCount-- > 0)
              wsText += L'\t';
          } else {
            m_textParser.GetEmbbedObj(m_pTextProvider, pXMLNode, wsText);
          }
        }
        int32_t iLength = wsText.GetLength();
        if (iLength > 0 && bContentNode && !bSpaceRun) {
          ProcessText(wsText);
        }
        if (m_pLoader) {
          if (wsText.GetLength() > 0 &&
              (m_pLoader->m_dwFlags & XFA_LOADERCNTXTFLG_FILTERSPACE)) {
            wsText.TrimLeft(0x20);
          }
          if (FDE_CSSDISPLAY_Block == eDisplay) {
            m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE;
          } else if (FDE_CSSDISPLAY_Inline == eDisplay &&
                     (m_pLoader->m_dwFlags & XFA_LOADERCNTXTFLG_FILTERSPACE)) {
            m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE;
          } else if (wsText.GetLength() > 0 &&
                     (0x20 == wsText.GetAt(wsText.GetLength() - 1))) {
            m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE;
          } else if (wsText.GetLength() != 0) {
            m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE;
          }
        }
        if (wsText.GetLength() > 0) {
          if (!m_pLoader || m_pLoader->m_iChar == 0) {
            if (pLinkData) {
              pLinkData->Retain();
            }
            CXFA_TextUserData* pUserData = FXTARGET_NewWith(m_pAllocator.get())
                CXFA_TextUserData(m_pAllocator.get(),
                                  bContentNode ? pParentStyle : pStyle,
                                  pLinkData);
            m_pBreak->SetUserData(pUserData);
          }
          if (AppendChar(wsText, fLinePos, 0, bSavePieces)) {
            if (m_pLoader) {
              m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE;
            }
            if (IsEnd(bSavePieces)) {
              if (m_pLoader && m_pLoader->m_iTotalLines > -1) {
                m_pLoader->m_pXMLNode = pXMLNode;
                m_pLoader->m_pParentStyle = pParentStyle;
              }
              if (pStyle)
                pStyle->Release();
              return false;
            }
            return true;
          }
        }
      }
    }
    bool ret = true;
    for (CFDE_XMLNode* pChildNode =
             pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild);
         pChildNode;
         pChildNode = pChildNode->GetNodeItem(CFDE_XMLNode::NextSibling)) {
      if (bCurOl) {
        iLiCount++;
      }
      ret = LoadRichText(pChildNode, szText, fLinePos,
                         pContext ? pStyle : pParentStyle, bSavePieces,
                         pLinkData, true, bIsOl, iLiCount);
      if (ret == false) {
        return false;
      }
    }
    if (m_pLoader) {
      if (FDE_CSSDISPLAY_Block == eDisplay) {
        m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE;
      }
    }
    if (bCurLi) {
      EndBreak(FX_RTFBREAK_LineBreak, fLinePos, bSavePieces);
    }
  } else {
    if (pContext) {
      eDisplay = pContext->GetDisplay();
    }
  }
  if (m_bBlockContinue) {
    if (pContext && !bContentNode) {
      uint32_t dwStatus = (eDisplay == FDE_CSSDISPLAY_Block)
                              ? FX_RTFBREAK_ParagraphBreak
                              : FX_RTFBREAK_PieceBreak;
      EndBreak(dwStatus, fLinePos, bSavePieces);
      if (eDisplay == FDE_CSSDISPLAY_Block) {
        fLinePos += fSpaceBelow;
        if (m_pTabstopContext) {
          m_pTabstopContext->RemoveAll();
        }
      }
      if (wsName == FX_WSTRC(L"a")) {
        if (pLinkData) {
          pLinkData->Release();
          pLinkData = nullptr;
        }
      }
      if (IsEnd(bSavePieces)) {
        if (pStyle) {
          pStyle->Release();
        }
        if (m_pLoader && m_pLoader->m_iTotalLines > -1) {
          m_pLoader->m_pXMLNode =
              pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling);
          m_pLoader->m_pParentStyle = pParentStyle;
        }
        return false;
      }
    }
  }
  if (pStyle)
    pStyle->Release();
  return true;
}
bool CXFA_TextLayout::AppendChar(const CFX_WideString& wsText,
                                 FX_FLOAT& fLinePos,
                                 FX_FLOAT fSpaceAbove,
                                 bool bSavePieces) {
  uint32_t dwStatus = 0;
  int32_t iChar = 0;
  if (m_pLoader) {
    iChar = m_pLoader->m_iChar;
  }
  int32_t iLength = wsText.GetLength();
  for (int32_t i = iChar; i < iLength; i++) {
    FX_WCHAR wch = wsText.GetAt(i);
    if (wch == 0xA0) {
      wch = 0x20;
    }
    if ((dwStatus = m_pBreak->AppendChar(wch)) > FX_RTFBREAK_PieceBreak) {
      AppendTextLine(dwStatus, fLinePos, bSavePieces);
      if (IsEnd(bSavePieces)) {
        if (m_pLoader)
          m_pLoader->m_iChar = i;
        return true;
      }
      if (dwStatus == FX_RTFBREAK_ParagraphBreak && m_bRichText) {
        fLinePos += fSpaceAbove;
      }
    }
  }
  if (m_pLoader) {
    m_pLoader->m_iChar = 0;
  }
  return false;
}
bool CXFA_TextLayout::IsEnd(bool bSavePieces) {
  if (!bSavePieces) {
    return false;
  }
  if (m_pLoader && m_pLoader->m_iTotalLines > 0) {
    return m_iLines >= m_pLoader->m_iTotalLines;
  }
  return false;
}
void CXFA_TextLayout::ProcessText(CFX_WideString& wsText) {
  int32_t iLen = wsText.GetLength();
  if (iLen == 0) {
    return;
  }
  FX_WCHAR* psz = wsText.GetBuffer(iLen);
  int32_t iTrimLeft = 0;
  FX_WCHAR wch = 0, wPrev = 0;
  for (int32_t i = 0; i < iLen; i++) {
    wch = psz[i];
    if (wch < 0x20) {
      wch = 0x20;
    }
    if (wch == 0x20 && wPrev == 0x20) {
      continue;
    }
    wPrev = wch;
    psz[iTrimLeft++] = wch;
  }
  wsText.ReleaseBuffer(iLen);
  wsText = wsText.Left(iTrimLeft);
}
void CXFA_TextLayout::EndBreak(uint32_t dwStatus,
                               FX_FLOAT& fLinePos,
                               bool bSavePieces) {
  dwStatus = m_pBreak->EndBreak(dwStatus);
  if (dwStatus > FX_RTFBREAK_PieceBreak) {
    AppendTextLine(dwStatus, fLinePos, bSavePieces, true);
  }
}
void CXFA_TextLayout::DoTabstops(IFDE_CSSComputedStyle* pStyle,
                                 CXFA_PieceLine* pPieceLine) {
  if (!m_pTabstopContext || m_pTabstopContext->m_iTabCount == 0) {
    return;
  }
  if (!pStyle || !pPieceLine) {
    return;
  }
  int32_t iPieces = pPieceLine->m_textPieces.GetSize();
  if (iPieces == 0) {
    return;
  }
  XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(iPieces - 1);
  int32_t& iTabstopsIndex = m_pTabstopContext->m_iTabIndex;
  int32_t iCount = m_textParser.CountTabs(pStyle);
  if (iTabstopsIndex > m_pTabstopContext->m_iTabCount - 1) {
    return;
  }
  if (iCount > 0) {
    iTabstopsIndex++;
    m_pTabstopContext->m_bTabstops = true;
    FX_FLOAT fRight = 0;
    if (iPieces > 1) {
      XFA_TextPiece* p = pPieceLine->m_textPieces.GetAt(iPieces - 2);
      fRight = p->rtPiece.right();
    }
    m_pTabstopContext->m_fTabWidth =
        pPiece->rtPiece.width + pPiece->rtPiece.left - fRight;
  } else if (iTabstopsIndex > -1) {
    FX_FLOAT fLeft = 0;
    if (m_pTabstopContext->m_bTabstops) {
      XFA_TABSTOPS* pTabstops =
          m_pTabstopContext->m_tabstops.GetDataPtr(iTabstopsIndex);
      uint32_t dwAlign = pTabstops->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->pszText[i] == L'.') {
            break;
          }
          fLeft += pPiece->pWidths[i] / 20000.0f;
        }
      }
      m_pTabstopContext->m_fLeft =
          std::min(fLeft, m_pTabstopContext->m_fTabWidth);
      m_pTabstopContext->m_bTabstops = false;
      m_pTabstopContext->m_fTabWidth = 0;
    }
    pPiece->rtPiece.left -= m_pTabstopContext->m_fLeft;
  }
}
void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus,
                                     FX_FLOAT& fLinePos,
                                     bool bSavePieces,
                                     bool bEndBreak) {
  int32_t iPieces = m_pBreak->CountBreakPieces();
  if (iPieces < 1) {
    return;
  }
  IFDE_CSSComputedStyle* pStyle = nullptr;
  if (bSavePieces) {
    CXFA_PieceLine* pPieceLine =
        FXTARGET_NewWith(m_pAllocator.get()) CXFA_PieceLine;
    m_pieceLines.Add(pPieceLine);
    if (m_pTabstopContext) {
      m_pTabstopContext->Reset();
    }
    FX_FLOAT fLineStep = 0, fBaseLine = 0;
    int32_t i = 0;
    for (i = 0; i < iPieces; i++) {
      const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i);
      CXFA_TextUserData* pUserData = (CXFA_TextUserData*)pPiece->m_pUserData;
      if (pUserData)
        pStyle = pUserData->m_pStyle;
      FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f;
      XFA_TextPiece* pTP = FXTARGET_NewWith(m_pAllocator.get()) XFA_TextPiece();
      pTP->pszText =
          (FX_WCHAR*)m_pAllocator->Alloc(pPiece->m_iChars * sizeof(FX_WCHAR));
      pTP->pWidths =
          (int32_t*)m_pAllocator->Alloc(pPiece->m_iChars * sizeof(int32_t));
      pTP->iChars = pPiece->m_iChars;
      pPiece->GetString(pTP->pszText);
      pPiece->GetWidths(pTP->pWidths);
      pTP->iBidiLevel = pPiece->m_iBidiLevel;
      pTP->iHorScale = pPiece->m_iHorizontalScale;
      pTP->iVerScale = pPiece->m_iVerticalScale;
      m_textParser.GetUnderline(m_pTextProvider, pStyle, pTP->iUnderline,
                                pTP->iPeriod);
      m_textParser.GetLinethrough(m_pTextProvider, pStyle, pTP->iLineThrough);
      pTP->dwColor = m_textParser.GetColor(m_pTextProvider, pStyle);
      pTP->pFont = m_textParser.GetFont(m_pTextProvider, pStyle);
      pTP->fFontSize = m_textParser.GetFontSize(m_pTextProvider, pStyle);
      pTP->rtPiece.left = pPiece->m_iStartPos / 20000.0f;
      pTP->rtPiece.width = pPiece->m_iWidth / 20000.0f;
      pTP->rtPiece.height = (FX_FLOAT)pPiece->m_iFontSize * fVerScale / 20.0f;
      FX_FLOAT fBaseLineTemp =
          m_textParser.GetBaseline(m_pTextProvider, pStyle);
      pTP->rtPiece.top = fBaseLineTemp;
      pPieceLine->m_textPieces.Add(pTP);
      FX_FLOAT fLineHeight = m_textParser.GetLineHeight(
          m_pTextProvider, pStyle, m_iLines == 0, fVerScale);
      if (fBaseLineTemp > 0) {
        FX_FLOAT fLineHeightTmp = fBaseLineTemp + pTP->rtPiece.height;
        if (fLineHeight < fLineHeightTmp) {
          fLineHeight = fLineHeightTmp;
        } else {
          fBaseLineTemp = 0;
        }
      } else if (fBaseLine < -fBaseLineTemp) {
        fBaseLine = -fBaseLineTemp;
      }
      fLineStep = std::max(fLineStep, fLineHeight);
      if (pUserData && pUserData->m_pLinkData) {
        pUserData->m_pLinkData->Retain();
        pTP->pLinkData = pUserData->m_pLinkData;
      } else {
        pTP->pLinkData = nullptr;
      }
      DoTabstops(pStyle, pPieceLine);
    }
    for (i = 0; i < iPieces; i++) {
      XFA_TextPiece* pTP = pPieceLine->m_textPieces.GetAt(i);
      FX_FLOAT& fTop = pTP->rtPiece.top;
      FX_FLOAT fBaseLineTemp = fTop;
      fTop = fLinePos + fLineStep - pTP->rtPiece.height - fBaseLineTemp;
      fTop = std::max(0.0f, fTop);
    }
    fLinePos += fLineStep + fBaseLine;
  } else {
    FX_FLOAT fLineStep = 0;
    FX_FLOAT fLineWidth = 0;
    for (int32_t i = 0; i < iPieces; i++) {
      const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i);
      CXFA_TextUserData* pUserData = (CXFA_TextUserData*)pPiece->m_pUserData;
      if (pUserData)
        pStyle = pUserData->m_pStyle;
      FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f;
      FX_FLOAT fBaseLine = m_textParser.GetBaseline(m_pTextProvider, pStyle);
      FX_FLOAT fLineHeight = m_textParser.GetLineHeight(
          m_pTextProvider, pStyle, m_iLines == 0, fVerScale);
      if (fBaseLine > 0) {
        FX_FLOAT fLineHeightTmp =
            fBaseLine + (FX_FLOAT)pPiece->m_iFontSize * fVerScale / 20.0f;
        if (fLineHeight < fLineHeightTmp) {
          fLineHeight = fLineHeightTmp;
        }
      }
      fLineStep = std::max(fLineStep, fLineHeight);
      fLineWidth += pPiece->m_iWidth / 20000.0f;
    }
    fLinePos += fLineStep;
    m_fMaxWidth = std::max(m_fMaxWidth, fLineWidth);
    if (m_pLoader && m_pLoader->m_bSaveLineHeight) {
      FX_FLOAT fHeight = fLinePos - m_pLoader->m_fLastPos;
      m_pLoader->m_fLastPos = fLinePos;
      m_pLoader->m_lineHeights.Add(fHeight);
    }
  }
  if (pStyle) {
    pStyle->Retain();
  }
  m_pBreak->ClearBreakPieces();
  if (dwStatus == FX_RTFBREAK_ParagraphBreak) {
    m_pBreak->Reset();
    if (!pStyle && bEndBreak) {
      CXFA_Para para = m_pTextProvider->GetParaNode();
      if (para) {
        FX_FLOAT fStartPos = para.GetMarginLeft();
        FX_FLOAT fIndent = para.GetTextIndent();
        if (fIndent > 0) {
          fStartPos += fIndent;
        }
        FX_FLOAT fSpaceBelow = para.GetSpaceBelow();
        if (fSpaceBelow < 0.1f) {
          fSpaceBelow = 0;
        }
        m_pBreak->SetLineStartPos(fStartPos);
        fLinePos += fSpaceBelow;
      }
    }
  }
  if (pStyle) {
    FX_FLOAT fStart = 0;
    const FDE_CSSRECT* pRect = pStyle->GetBoundaryStyles()->GetMarginWidth();
    if (pRect) {
      fStart = pRect->left.GetValue();
    }
    FX_FLOAT fTextIndent =
        pStyle->GetParagraphStyles()->GetTextIndent().GetValue();
    if (fTextIndent < 0) {
      fStart -= fTextIndent;
    }
    m_pBreak->SetLineStartPos(fStart);
    pStyle->Release();
  }
  m_iLines++;
}
void CXFA_TextLayout::RenderString(CFDE_RenderDevice* pDevice,
                                   CFDE_Brush* pBrush,
                                   CXFA_PieceLine* pPieceLine,
                                   int32_t iPiece,
                                   FXTEXT_CHARPOS* pCharPos,
                                   const CFX_Matrix& tmDoc2Device) {
  const XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(iPiece);
  int32_t iCount = GetDisplayPos(pPiece, pCharPos);
  if (iCount > 0) {
    pBrush->SetColor(pPiece->dwColor);
    pDevice->DrawString(pBrush, pPiece->pFont, pCharPos, iCount,
                        pPiece->fFontSize, &tmDoc2Device);
  }
  pPieceLine->m_charCounts.Add(iCount);
}

void CXFA_TextLayout::RenderPath(CFDE_RenderDevice* pDevice,
                                 CFDE_Pen* pPen,
                                 CXFA_PieceLine* pPieceLine,
                                 int32_t iPiece,
                                 FXTEXT_CHARPOS* pCharPos,
                                 const CFX_Matrix& tmDoc2Device) {
  XFA_TextPiece* pPiece = pPieceLine->m_textPieces.GetAt(iPiece);
  bool bNoUnderline = pPiece->iUnderline < 1 || pPiece->iUnderline > 2;
  bool bNoLineThrough = pPiece->iLineThrough < 1 || pPiece->iLineThrough > 2;
  if (bNoUnderline && bNoLineThrough) {
    return;
  }
  pPen->SetColor(pPiece->dwColor);
  std::unique_ptr<CFDE_Path> pPath(new CFDE_Path);
  int32_t iChars = GetDisplayPos(pPiece, pCharPos);
  if (iChars > 0) {
    CFX_PointF pt1, pt2;
    FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f;
    if (pPiece->iPeriod == XFA_ATTRIBUTEENUM_Word) {
      for (int32_t i = 0; i < pPiece->iUnderline; i++) {
        for (int32_t j = 0; j < iChars; j++) {
          pt1.x = pCharPos[j].m_OriginX;
          pt2.x =
              pt1.x + pCharPos[j].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
          pt1.y = pt2.y = fEndY;
          pPath->AddLine(pt1, pt2);
        }
        fEndY += 2.0f;
      }
    } else {
      pt1.x = pCharPos[0].m_OriginX;
      pt2.x =
          pCharPos[iChars - 1].m_OriginX +
          pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
      for (int32_t i = 0; i < pPiece->iUnderline; i++) {
        pt1.y = pt2.y = fEndY;
        pPath->AddLine(pt1, pt2);
        fEndY += 2.0f;
      }
    }
    fEndY = pCharPos[0].m_OriginY - pPiece->rtPiece.height * 0.25f;
    pt1.x = pCharPos[0].m_OriginX;
    pt2.x = pCharPos[iChars - 1].m_OriginX +
            pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
    for (int32_t i = 0; i < pPiece->iLineThrough; i++) {
      pt1.y = pt2.y = fEndY;
      pPath->AddLine(pt1, pt2);
      fEndY += 2.0f;
    }
  } else {
    if (bNoLineThrough &&
        (bNoUnderline || pPiece->iPeriod != XFA_ATTRIBUTEENUM_All)) {
      return;
    }
    int32_t iCharsTmp = 0;
    int32_t iPiecePrev = iPiece, iPieceNext = iPiece;
    while (iPiecePrev > 0) {
      iPiecePrev--;
      iCharsTmp = pPieceLine->m_charCounts.GetAt(iPiecePrev);
      if (iCharsTmp > 0) {
        break;
      }
    }
    if (iCharsTmp == 0) {
      return;
    }
    iCharsTmp = 0;
    int32_t iPieces = pPieceLine->m_textPieces.GetSize();
    while (iPieceNext < iPieces - 1) {
      iPieceNext++;
      iCharsTmp = pPieceLine->m_charCounts.GetAt(iPieceNext);
      if (iCharsTmp > 0) {
        break;
      }
    }
    if (iCharsTmp == 0) {
      return;
    }
    FX_FLOAT fOrgX = 0.0f, fEndX = 0.0f;
    pPiece = pPieceLine->m_textPieces.GetAt(iPiecePrev);
    iChars = GetDisplayPos(pPiece, pCharPos);
    if (iChars < 1) {
      return;
    }
    fOrgX = pCharPos[iChars - 1].m_OriginX +
            pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
    pPiece = pPieceLine->m_textPieces.GetAt(iPieceNext);
    iChars = GetDisplayPos(pPiece, pCharPos);
    if (iChars < 1) {
      return;
    }
    fEndX = pCharPos[0].m_OriginX;
    CFX_PointF pt1, pt2;
    pt1.x = fOrgX, pt2.x = fEndX;
    FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f;
    for (int32_t i = 0; i < pPiece->iUnderline; i++) {
      pt1.y = pt2.y = fEndY;
      pPath->AddLine(pt1, pt2);
      fEndY += 2.0f;
    }
    fEndY = pCharPos[0].m_OriginY - pPiece->rtPiece.height * 0.25f;
    for (int32_t i = 0; i < pPiece->iLineThrough; i++) {
      pt1.y = pt2.y = fEndY;
      pPath->AddLine(pt1, pt2);
      fEndY += 2.0f;
    }
  }
  pDevice->DrawPath(pPen, 1, pPath.get(), &tmDoc2Device);
}

int32_t CXFA_TextLayout::GetDisplayPos(const XFA_TextPiece* pPiece,
                                       FXTEXT_CHARPOS* pCharPos,
                                       bool bCharCode) {
  if (!pPiece) {
    return 0;
  }
  FX_RTFTEXTOBJ tr;
  if (!ToRun(pPiece, tr)) {
    return 0;
  }
  return m_pBreak->GetDisplayPos(&tr, pCharPos, bCharCode);
}
bool CXFA_TextLayout::ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ& tr) {
  int32_t iLength = pPiece->iChars;
  if (iLength < 1) {
    return false;
  }
  tr.pStr = pPiece->pszText;
  tr.pFont = pPiece->pFont;
  tr.pRect = &pPiece->rtPiece;
  tr.pWidths = pPiece->pWidths;
  tr.iLength = iLength;
  tr.fFontSize = pPiece->fFontSize;
  tr.iBidiLevel = pPiece->iBidiLevel;
  tr.iCharRotation = 0;
  tr.wLineBreakChar = L'\n';
  tr.iVerticalScale = pPiece->iVerScale;
  tr.dwLayoutStyles = FX_RTFLAYOUTSTYLE_ExpandTab;
  tr.iHorizontalScale = pPiece->iHorScale;
  return true;
}

CXFA_LinkUserData::CXFA_LinkUserData(IFX_MemoryAllocator* pAllocator,
                                     FX_WCHAR* pszText)
    : m_pAllocator(pAllocator), m_dwRefCount(1), m_wsURLContent(pszText) {}

CXFA_LinkUserData::~CXFA_LinkUserData() {}

uint32_t CXFA_LinkUserData::Retain() {
  return ++m_dwRefCount;
}

uint32_t CXFA_LinkUserData::Release() {
  uint32_t dwRefCount = --m_dwRefCount;
  if (dwRefCount <= 0)
    FXTARGET_DeleteWith(CXFA_LinkUserData, m_pAllocator, this);
  return dwRefCount;
}

const FX_WCHAR* CXFA_LinkUserData::GetLinkURL() {
  return m_wsURLContent.c_str();
}

CXFA_TextUserData::CXFA_TextUserData(IFX_MemoryAllocator* pAllocator,
                                     IFDE_CSSComputedStyle* pStyle)
    : m_pStyle(pStyle),
      m_pLinkData(nullptr),
      m_pAllocator(pAllocator),
      m_dwRefCount(0) {
  ASSERT(m_pAllocator);
  if (m_pStyle)
    m_pStyle->Retain();
}

CXFA_TextUserData::CXFA_TextUserData(IFX_MemoryAllocator* pAllocator,
                                     IFDE_CSSComputedStyle* pStyle,
                                     CXFA_LinkUserData* pLinkData)
    : m_pStyle(pStyle),
      m_pLinkData(pLinkData),
      m_pAllocator(pAllocator),
      m_dwRefCount(0) {
  ASSERT(m_pAllocator);
  if (m_pStyle)
    m_pStyle->Retain();
}

CXFA_TextUserData::~CXFA_TextUserData() {
  if (m_pStyle)
    m_pStyle->Release();
  if (m_pLinkData)
    m_pLinkData->Release();
}

uint32_t CXFA_TextUserData::Retain() {
  return ++m_dwRefCount;
}

uint32_t CXFA_TextUserData::Release() {
  uint32_t dwRefCount = --m_dwRefCount;
  if (dwRefCount == 0)
    FXTARGET_DeleteWith(CXFA_TextUserData, m_pAllocator, this);
  return dwRefCount;
}

CXFA_PieceLine::CXFA_PieceLine() {}

CXFA_PieceLine::~CXFA_PieceLine() {}

CXFA_TextTabstopsContext::CXFA_TextTabstopsContext()
    : m_iTabCount(0),
      m_iTabIndex(-1),
      m_bTabstops(false),
      m_fTabWidth(0),
      m_fLeft(0) {}

CXFA_TextTabstopsContext::~CXFA_TextTabstopsContext() {}

void CXFA_TextTabstopsContext::Append(uint32_t dwAlign, FX_FLOAT fTabstops) {
  int32_t i = 0;
  for (i = 0; i < m_iTabCount; i++) {
    XFA_TABSTOPS* pTabstop = m_tabstops.GetDataPtr(i);
    if (fTabstops < pTabstop->fTabstops) {
      break;
    }
  }
  m_tabstops.InsertSpaceAt(i, 1);
  XFA_TABSTOPS tabstop;
  tabstop.dwAlign = dwAlign;
  tabstop.fTabstops = fTabstops;
  m_tabstops.SetAt(i, tabstop);
  m_iTabCount++;
}

void CXFA_TextTabstopsContext::RemoveAll() {
  m_tabstops.RemoveAll();
  m_iTabCount = 0;
}

void CXFA_TextTabstopsContext::Reset() {
  m_iTabIndex = -1;
  m_bTabstops = false;
  m_fTabWidth = 0;
  m_fLeft = 0;
}
