// 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/include/fx_ext.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/include/xfa_ffapp.h"
#include "xfa/fxfa/include/xfa_ffdoc.h"
#include "xfa/fxfa/include/xfa_fontmgr.h"
#include "xfa/fxfa/parser/cxfa_measurement.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();
    IFGAS_FontMgr* pFontMgr = pDoc->GetApp()->GetFDEFontMgr();
    ASSERT(pFontMgr);
    m_pSelector.reset(new 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;
}

FX_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,
                                        FX_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;
}
FX_BOOL CXFA_TextParser::GetEmbbedObj(CXFA_TextProvider* pTextProvider,
                                      CFDE_XMLNode* pXMLNode,
                                      CFX_WideString& wsValue) {
  wsValue.clear();
  if (!pXMLNode) {
    return FALSE;
  }
  FX_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();
    }
    FX_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();
    }
    FX_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,
};
FX_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(FX_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.reset(new 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.reset(new 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;
}
FX_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.GetSize() > 0) {
      for (int32_t i = 0; i < iBlockIndex; i++) {
        fLinePos -= m_pLoader->m_BlocksHeight.ElementAt(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 (m_pLoader->m_BlocksHeight.GetSize() > iBlockIndex * 2 &&
              (m_pLoader->m_BlocksHeight.GetAt(iBlockIndex * 2) ==
               iBlockIndex)) {
            m_pLoader->m_BlocksHeight.SetAt(iBlockIndex * 2 + 1, fCalcHeight);
          } else {
            m_pLoader->m_BlocksHeight.Add((FX_FLOAT)iBlockIndex);
            m_pLoader->m_BlocksHeight.Add(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;
}

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

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

FX_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 = m_pLoader->m_BlocksHeight.GetSize();
  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.ElementAt(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;
  }
  FX_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 = m_pLoader->m_BlocksHeight.GetSize();
    iBlockHeightCount /= 2;
    if (iBlockHeightCount >= iBlockIndex) {
      for (int32_t i = 0; i < iBlockIndex; i++) {
        fLinePos -= m_pLoader->m_BlocksHeight.ElementAt(i * 2 + 1);
      }
    } else {
      fLinePos = 0;
    }
    iLineIndex = m_Blocks.ElementAt(iBlockCount - 1) +
                 m_Blocks.ElementAt(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);
  }
}
FX_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;
}
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;
    }
  }
}
FX_BOOL CXFA_TextLayout::Loader(const CFX_SizeF& szText,
                                FX_FLOAT& fLinePos,
                                FX_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,
                               FX_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" ");
  FX_BOOL bRet = AppendChar(wsText, fLinePos, fSpaceAbove, bSavePieces);
  if (bRet && m_pLoader) {
    m_pLoader->m_pNode = pNode;
  } else {
    EndBreak(FX_RTFBREAK_ParagraphBreak, fLinePos, bSavePieces);
  }
}
FX_BOOL CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode,
                                      const CFX_SizeF& szText,
                                      FX_FLOAT& fLinePos,
                                      IFDE_CSSComputedStyle* pParentStyle,
                                      FX_BOOL bSavePieces,
                                      CXFA_LinkUserData* pLinkData,
                                      FX_BOOL bEndBreak,
                                      FX_BOOL bIsOl,
                                      int32_t iLiCount) {
  if (!pXMLNode) {
    return FALSE;
  }
  CXFA_TextParseContext* pContext =
      m_textParser.GetParseContextFromMap(pXMLNode);
  FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_None;
  FX_BOOL bContentNode = FALSE;
  FX_FLOAT fSpaceBelow = 0;
  IFDE_CSSComputedStyle* pStyle = nullptr;
  CFX_WideString wsName;
  if (bEndBreak) {
    FX_BOOL bCurOl = FALSE;
    FX_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);
        FX_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;
          }
        }
      }
    }
    FX_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;
}
FX_BOOL CXFA_TextLayout::AppendChar(const CFX_WideString& wsText,
                                    FX_FLOAT& fLinePos,
                                    FX_FLOAT fSpaceAbove,
                                    FX_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;
}
FX_BOOL CXFA_TextLayout::IsEnd(FX_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,
                               FX_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,
                                     FX_BOOL bSavePieces,
                                     FX_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);
  FX_BOOL bNoUnderline = pPiece->iUnderline < 1 || pPiece->iUnderline > 2;
  FX_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,
                                       FX_BOOL bCharCode) {
  if (!pPiece) {
    return 0;
  }
  FX_RTFTEXTOBJ tr;
  if (!ToRun(pPiece, tr)) {
    return 0;
  }
  return m_pBreak->GetDisplayPos(&tr, pCharPos, bCharCode);
}
FX_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;
}
