// 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/src/fxfa/src/app/xfa_textlayout.h"

#include <algorithm>

#include "core/include/fxcrt/fx_ext.h"
#include "xfa/src/fdp/include/fde_pen.h"
#include "xfa/src/fgas/include/fx_alg.h"
#include "xfa/src/fgas/include/fx_cpg.h"
#include "xfa/src/fxfa/src/app/xfa_ffapp.h"
#include "xfa/src/fxfa/src/app/xfa_ffdoc.h"
#include "xfa/src/fxfa/src/app/xfa_fontmgr.h"

CXFA_CSSTagProvider::~CXFA_CSSTagProvider() {
  FX_POSITION pos = m_Attributes.GetStartPosition();
  while (pos) {
    CFX_WideString *pName = NULL, *pValue = NULL;
    m_Attributes.GetNextAssoc(pos, (void*&)pName, (void*&)pValue);
    delete pName;
    delete pValue;
  }
}
void CXFA_CSSTagProvider::GetNextAttribute(FX_POSITION& pos,
                                           CFX_WideStringC& wsAttr,
                                           CFX_WideStringC& wsValue) {
  if (pos == NULL) {
    return;
  }
  CFX_WideString* pName = NULL;
  CFX_WideString* pValue = NULL;
  m_Attributes.GetNextAssoc(pos, (void*&)pName, (void*&)pValue);
  wsAttr = *pName;
  wsValue = *pValue;
}
void CXFA_CSSTagProvider::SetAttribute(const CFX_WideString& wsAttr,
                                       const CFX_WideString& wsValue) {
  CFX_WideString* pName = new CFX_WideString();
  CFX_WideString* pValue = new CFX_WideString();
  *pName = wsAttr;
  *pValue = wsValue;
  m_Attributes.SetAt(pName, pValue);
}
void CXFA_TextParseContext::SetDecls(const IFDE_CSSDeclaration** ppDeclArray,
                                     int32_t iDeclCount) {
  if (iDeclCount <= 0 || ppDeclArray == NULL) {
    return;
  }
  m_dwMatchedDecls = iDeclCount;
  m_ppMatchedDecls = FX_Alloc(IFDE_CSSDeclaration*, iDeclCount);
  FXSYS_memcpy(m_ppMatchedDecls, ppDeclArray,
               iDeclCount * sizeof(IFDE_CSSDeclaration*));
}
CXFA_TextParser::~CXFA_TextParser() {
  if (m_pUASheet)
    m_pUASheet->Release();
  if (m_pSelector)
    m_pSelector->Release();
  if (m_pAllocator)
    m_pAllocator->Release();
  FX_POSITION ps = m_mapXMLNodeToParseContext.GetStartPosition();
  while (ps) {
    IFDE_XMLNode* pXMLNode;
    CXFA_TextParseContext* pParseContext;
    m_mapXMLNodeToParseContext.GetNextAssoc(ps, pXMLNode, pParseContext);
    if (pParseContext)
      FXTARGET_DeleteWith(CXFA_TextParseContext, m_pAllocator, pParseContext);
  }
  m_mapXMLNodeToParseContext.RemoveAll();
}
void CXFA_TextParser::Reset() {
  FX_POSITION ps = m_mapXMLNodeToParseContext.GetStartPosition();
  while (ps) {
    IFDE_XMLNode* pXMLNode;
    CXFA_TextParseContext* pParseContext;
    m_mapXMLNodeToParseContext.GetNextAssoc(ps, pXMLNode, pParseContext);
    if (pParseContext)
      FXTARGET_DeleteWith(CXFA_TextParseContext, m_pAllocator, pParseContext);
  }
  m_mapXMLNodeToParseContext.RemoveAll();
  if (m_pAllocator) {
    m_pAllocator->Release();
    m_pAllocator = NULL;
  }
}
void CXFA_TextParser::InitCSSData(IXFA_TextProvider* pTextProvider) {
  if (pTextProvider == NULL) {
    return;
  }
  if (m_pSelector == NULL) {
    CXFA_FFDoc* pDoc = pTextProvider->GetDocNode();
    IFX_FontMgr* pFontMgr = pDoc->GetApp()->GetFDEFontMgr();
    FXSYS_assert(pFontMgr);
    m_pSelector = IFDE_CSSStyleSelector::Create();
    m_pSelector->SetFontMgr(pFontMgr);
    FX_FLOAT fFontSize = 10;
    CXFA_Font font = pTextProvider->GetFontNode();
    if (font) {
      fFontSize = font.GetFontSize();
    }
    m_pSelector->SetDefFontSize(fFontSize);
  }
  if (m_pUASheet == NULL) {
    m_pUASheet = LoadDefaultSheetStyle();
    m_pSelector->SetStyleSheet(FDE_CSSSTYLESHEETGROUP_UserAgent, m_pUASheet);
    m_pSelector->UpdateStyleIndex(FDE_CSSMEDIATYPE_ALL);
  }
}
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(
    IXFA_TextProvider* pTextProvider) {
  CXFA_Font font = pTextProvider->GetFontNode();
  CXFA_Para para = pTextProvider->GetParaNode();
  IFDE_CSSComputedStyle* pStyle = m_pSelector->CreateComputedStyle(NULL);
  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 hAlgin = FDE_CSSTEXTALIGN_Left;
    switch (para.GetHorizontalAlign()) {
      case XFA_ATTRIBUTEENUM_Center:
        hAlgin = FDE_CSSTEXTALIGN_Center;
        break;
      case XFA_ATTRIBUTEENUM_Right:
        hAlgin = FDE_CSSTEXTALIGN_Right;
        break;
      case XFA_ATTRIBUTEENUM_Justify:
        hAlgin = FDE_CSSTEXTALIGN_Justify;
        break;
      case XFA_ATTRIBUTEENUM_JustifyAll:
        hAlgin = FDE_CSSTEXTALIGN_JustifyAll;
        break;
    }
    pParaStyle->SetTextAlign(hAlgin);
    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);
    FX_DWORD 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);
  FXSYS_assert(pNewStyle);
  if (pParentStyle) {
    IFDE_CSSParagraphStyle* pParaStyle = pParentStyle->GetParagraphStyles();
    FX_DWORD 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(
    IFDE_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->AddRef();
  CXFA_CSSTagProvider tagProvider;
  ParseTagInfo(pXMLNode, tagProvider);
  if (tagProvider.m_bContent)
    return nullptr;
  IFDE_CSSComputedStyle* pStyle = CreateStyle(pParentStyle);
  IFDE_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(IFDE_XMLNode* pXMLContainer,
                              IXFA_TextProvider* pTextProvider) {
  if (pXMLContainer == NULL || pTextProvider == NULL || m_pAllocator) {
    return;
  }
  m_pAllocator =
      FX_CreateAllocator(FX_ALLOCTYPE_Fixed, 32, sizeof(CXFA_CSSTagProvider));
  InitCSSData(pTextProvider);
  IFDE_CSSComputedStyle* pRootStyle = CreateRootStyle(pTextProvider);
  ParseRichText(pXMLContainer, pRootStyle);
  pRootStyle->Release();
}
void CXFA_TextParser::ParseRichText(IFDE_XMLNode* pXMLNode,
                                    IFDE_CSSComputedStyle* pParentStyle) {
  if (pXMLNode == NULL) {
    return;
  }
  CXFA_CSSTagProvider tagProvider;
  ParseTagInfo(pXMLNode, tagProvider);
  if (!tagProvider.m_bTagAviliable) {
    return;
  }
  IFDE_CSSComputedStyle* pNewStyle = NULL;
  if ((tagProvider.GetTagName() != FX_WSTRC(L"body")) ||
      (tagProvider.GetTagName() != FX_WSTRC(L"html"))) {
    CXFA_TextParseContext* pTextContext =
        FXTARGET_NewWith(m_pAllocator) CXFA_TextParseContext;
    FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_Inline;
    if (!tagProvider.m_bContent) {
      pNewStyle = CreateStyle(pParentStyle);
      IFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator();
      pCSSAccel->OnEnterTag(&tagProvider);
      CFDE_CSSDeclarationArray DeclArray;
      int32_t iMatchedDecls =
          m_pSelector->MatchDeclarations(&tagProvider, DeclArray);
      const IFDE_CSSDeclaration** ppMatchDecls =
          (const IFDE_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 (IFDE_XMLNode* pXMLChild =
           pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
       pXMLChild;
       pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
    ParseRichText(pXMLChild, pNewStyle);
  }
  if (pNewStyle)
    pNewStyle->Release();
}
void CXFA_TextParser::ParseTagInfo(IFDE_XMLNode* pXMLNode,
                                   CXFA_CSSTagProvider& tagProvider) {
  static const FX_DWORD s_XFATagName[] = {
      0x61,       0x62,       0x69,       0x70,       0x0001f714,
      0x00022a55, 0x000239bb, 0x00025881, 0x0bd37faa, 0x0bd37fb8,
      0xa73e3af2, 0xb182eaae, 0xdb8ac455,
  };
  CFX_WideString wsName;
  if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
    IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode;
    pXMLElement->GetLocalTagName(wsName);
    tagProvider.SetTagNameObj(wsName);
    FX_DWORD dwHashCode =
        FX_HashCode_String_GetW(wsName, wsName.GetLength(), TRUE);
    static const int32_t s_iCount = sizeof(s_XFATagName) / sizeof(FX_DWORD);
    CFX_DSPATemplate<FX_DWORD> lookup;
    tagProvider.m_bTagAviliable =
        lookup.Lookup(dwHashCode, s_XFATagName, s_iCount) > -1;
    CFX_WideString wsValue;
    pXMLElement->GetString(FX_WSTRC(L"style").GetPtr(), wsValue);
    if (!wsValue.IsEmpty()) {
      tagProvider.SetAttribute(FX_WSTRC(L"style"), wsValue);
    }
  } else if (pXMLNode->GetType() == FDE_XMLNODE_Text) {
    tagProvider.m_bTagAviliable = TRUE;
    tagProvider.m_bContent = TRUE;
  }
}
int32_t CXFA_TextParser::GetVAlgin(IXFA_TextProvider* pTextProvider) const {
  int32_t iAlign = XFA_ATTRIBUTEENUM_Top;
  CXFA_Para para = pTextProvider->GetParaNode();
  if (para) {
    iAlign = para.GetVerticalAlign();
  }
  return iAlign;
}
FX_FLOAT CXFA_TextParser::GetTabInterval(IFDE_CSSComputedStyle* pStyle) const {
  CFX_WideString wsValue;
  if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"tab-interval"), wsValue)) {
    CXFA_Measurement ms(wsValue);
    return ms.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;
}
IFX_Font* CXFA_TextParser::GetFont(IXFA_TextProvider* pTextProvider,
                                   IFDE_CSSComputedStyle* pStyle) const {
  CFX_WideStringC wsFamily = FX_WSTRC(L"Courier");
  FX_DWORD 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(IXFA_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(IXFA_TextProvider* pTextProvider,
                                     IFDE_CSSComputedStyle* pStyle,
                                     IFDE_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(IFDE_XMLNode::Parent);
    }
  }
  if (CXFA_Font font = pTextProvider->GetFontNode()) {
    return static_cast<int32_t>(font.GetHorizontalScale());
  }
  return 100;
}
int32_t CXFA_TextParser::GetVerScale(IXFA_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(IXFA_TextProvider* pTextProvider,
                                   IFDE_CSSComputedStyle* pStyle,
                                   int32_t& iUnderline,
                                   int32_t& iPeriod) const {
  iUnderline = 0;
  iPeriod = XFA_ATTRIBUTEENUM_All;
  if (pStyle) {
    FX_DWORD 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(IXFA_TextProvider* pTextProvider,
                                     IFDE_CSSComputedStyle* pStyle,
                                     int32_t& iLinethrough) const {
  if (pStyle) {
    FX_DWORD 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(IXFA_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(IXFA_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(IXFA_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(IXFA_TextProvider* pTextProvider,
                                      IFDE_XMLNode* pXMLNode,
                                      CFX_WideString& wsValue) {
  wsValue.Empty();
  if (pXMLNode == NULL) {
    return FALSE;
  }
  FX_BOOL bRet = FALSE;
  if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
    IFDE_XMLElement* pElement = (IFDE_XMLElement*)pXMLNode;
    CFX_WideString wsAttr;
    pElement->GetString(FX_WSTRC(L"xfa:embed").GetPtr(), wsAttr);
    if (wsAttr.IsEmpty()) {
      return FALSE;
    }
    if (wsAttr.GetAt(0) == L'#') {
      wsAttr.Delete(0);
    }
    CFX_WideString ws;
    pElement->GetString(FX_WSTRC(L"xfa:embedType").GetPtr(), 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.Empty();
    pElement->GetString(FX_WSTRC(L"xfa:embedMode").GetPtr(), 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(
    IFDE_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 == NULL || pTabstopContext == NULL) {
    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;
  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 == ' ') {
          FX_DWORD dwHashCode =
              FX_HashCode_String_GetW(wsAlign, wsAlign.GetLength(), TRUE);
          CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast));
          FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt);
          pTabstopContext->Append(dwHashCode, fPos);
          wsAlign.Empty();
          eStatus = XFA_TABSTOPSSTATUS_None;
        }
        iCur++;
        break;
      default:
        break;
    }
  }
  if (!wsAlign.IsEmpty()) {
    FX_DWORD dwHashCode =
        FX_HashCode_String_GetW(wsAlign, wsAlign.GetLength(), 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(IXFA_TextProvider* pTextProvider)
    : m_bHasBlock(FALSE),
      m_pTextProvider(pTextProvider),
      m_pTextDataNode(nullptr),
      m_bRichText(FALSE),
      m_pAllocator(nullptr),
      m_pBreak(nullptr),
      m_pLoader(nullptr),
      m_iLines(0),
      m_fMaxWidth(0),
      m_pTabstopContext(nullptr),
      m_bBlockContinue(TRUE) {
  FXSYS_assert(m_pTextProvider);
}
CXFA_TextLayout::~CXFA_TextLayout() {
  m_textParser.Reset();
  delete m_pLoader;
  delete m_pTabstopContext;
  Unload();
}
void CXFA_TextLayout::Unload() {
  int32_t iCount = m_pieceLines.GetSize();
  for (int32_t i = 0; i < iCount; i++) {
    CXFA_PieceLine* pLine = m_pieceLines.GetAt(i);
    FXTARGET_DeleteWith(CXFA_PieceLine, m_pAllocator, pLine);
  }
  m_pieceLines.RemoveAll();
  if (m_pBreak) {
    m_pBreak->Release();
    m_pBreak = NULL;
  }
  if (m_pAllocator) {
    m_pAllocator->Release();
    m_pAllocator = NULL;
  }
}
const CXFA_PieceLineArray* CXFA_TextLayout::GetPieceLines() {
  return &m_pieceLines;
}
void CXFA_TextLayout::GetTextDataNode() {
  if (m_pTextProvider == NULL) {
    return;
  }
  CXFA_Node* pNode = m_pTextProvider->GetTextNode(m_bRichText);
  if (pNode && m_bRichText) {
    m_textParser.Reset();
  }
  m_pTextDataNode = pNode;
}
IFDE_XMLNode* CXFA_TextLayout::GetXMLContainerNode() {
  IFDE_XMLNode* pXMLContainer = NULL;
  if (m_bRichText) {
    IFDE_XMLNode* pXMLRoot = m_pTextDataNode->GetXMLMappingNode();
    if (!pXMLRoot) {
      return pXMLContainer;
    }
    for (IFDE_XMLNode* pXMLChild =
             pXMLRoot->GetNodeItem(IFDE_XMLNode::FirstChild);
         pXMLChild;
         pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
      if (pXMLChild->GetType() == FDE_XMLNODE_Element) {
        IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLChild;
        CFX_WideString wsTag;
        pXMLElement->GetLocalTagName(wsTag);
        if (wsTag.Equal(FX_WSTRC(L"body")) || wsTag.Equal(FX_WSTRC(L"html"))) {
          pXMLContainer = pXMLChild;
          break;
        }
      }
    }
  }
  return pXMLContainer;
}
IFX_RTFBreak* CXFA_TextLayout::CreateBreak(FX_BOOL bDefault) {
  FX_DWORD dwStyle = FX_RTFLAYOUTSTYLE_ExpandTab;
  if (!bDefault) {
    dwStyle |= FX_RTFLAYOUTSTYLE_Pagination;
  }
  IFX_RTFBreak* pBreak = IFX_RTFBreak::Create(0);
  pBreak->SetLayoutStyles(dwStyle);
  pBreak->SetLineBreakChar(L'\n');
  pBreak->SetLineBreakTolerance(1);
  pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, NULL));
  pBreak->SetFontSize(m_textParser.GetFontSize(m_pTextProvider, NULL));
  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, NULL);
  m_pBreak->SetFontSize(fFontSize);
  m_pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, NULL));
  m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f);
}
void CXFA_TextLayout::InitBreak(IFDE_CSSComputedStyle* pStyle,
                                FDE_CSSDISPLAY eDisplay,
                                FX_FLOAT fLineWidth,
                                IFDE_XMLNode* pXMLNode,
                                IFDE_CSSComputedStyle* pParentStyle) {
  if (pStyle == NULL) {
    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 == NULL) {
      m_pTabstopContext = new CXFA_TextTabstopsContext;
    }
    m_textParser.GetTabstops(pStyle, m_pTabstopContext);
    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.Empty();
  if (m_bRichText) {
  } else {
    wsText = m_pTextDataNode->GetContent();
  }
  return wsText.GetLength();
}
FX_FLOAT CXFA_TextLayout::GetLayoutHeight() {
  if (m_pLoader == NULL) {
    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 == NULL) {
    m_pLoader = 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 == NULL) {
    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.GetVAlgin(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;
  }
  if (m_pBreak)
    m_pBreak->Release();

  m_pBreak = 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, NULL);
  }
  if (m_pTabstopContext) {
    delete m_pTabstopContext;
    m_pTabstopContext = NULL;
  }
  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 = 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);
  if (m_pTabstopContext) {
    delete m_pTabstopContext;
    m_pTabstopContext = NULL;
  }
  if (fHeight) {
    *fHeight = fLinePos;
  }
  return TRUE;
}
FX_BOOL CXFA_TextLayout::Layout(int32_t iBlock) {
  if (m_pLoader == NULL || 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 = NULL;
  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 = 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) {
      IFDE_XMLNode* pContainerNode = GetXMLContainerNode();
      if (!pContainerNode) {
        return TRUE;
      }
      IFDE_XMLNode* pXMLNode = m_pLoader->m_pXMLNode;
      if (pXMLNode == NULL) {
        return TRUE;
      }
      IFDE_XMLNode* pSaveXMLNode = m_pLoader->m_pXMLNode;
      for (; pXMLNode;
           pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
        FX_BOOL bFlag = LoadRichText(pXMLNode, szText, fLinePos,
                                     m_pLoader->m_pParentStyle, TRUE);
        if (!bFlag) {
          break;
        }
      }
      while (pXMLNode == NULL) {
        pXMLNode = pSaveXMLNode->GetNodeItem(IFDE_XMLNode::Parent);
        if (pXMLNode == pContainerNode) {
          break;
        }
        FX_BOOL bFlag =
            LoadRichText(pXMLNode, szText, fLinePos, m_pLoader->m_pParentStyle,
                         TRUE, NULL, FALSE);
        if (!bFlag) {
          break;
        }
        pSaveXMLNode = pXMLNode;
        pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling);
        if (!pXMLNode) {
          continue;
        }
        for (; pXMLNode;
             pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
          FX_BOOL bFlag = LoadRichText(pXMLNode, szText, fLinePos,
                                       m_pLoader->m_pParentStyle, TRUE);
          if (!bFlag) {
            break;
          }
        }
      }
    } else {
      pNode = m_pLoader->m_pNode;
      if (pNode == NULL) {
        return TRUE;
      }
      LoadText(pNode, szText, fLinePos, TRUE);
    }
  }
  if (iBlock == iCount) {
    delete m_pTabstopContext;
    m_pTabstopContext = nullptr;
    delete m_pLoader;
    m_pLoader = nullptr;
  }
  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) {
  IFDE_RenderDevice* pDevice = IFDE_RenderDevice::Create(pFxDevice);
  if (pDevice == NULL) {
    return FALSE;
  }
  FDE_HDEVICESTATE state = pDevice->SaveState();
  pDevice->SetClipRect(rtClip);
  IFDE_SolidBrush* pSolidBrush =
      (IFDE_SolidBrush*)IFDE_Brush::Create(FDE_BRUSHTYPE_Solid);
  IFDE_Pen* pPen = IFDE_Pen::Create();
  FXSYS_assert(pDevice);
  FXSYS_assert(pSolidBrush);
  FXSYS_assert(pPen);
  if (m_pieceLines.GetSize() == 0) {
    int32_t iBlockCount = CountBlocks();
    for (int32_t i = 0; i < iBlockCount; i++) {
      Layout(i);
    }
  }
  FXTEXT_CHARPOS* pCharPos = NULL;
  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, pSolidBrush, pPieceLine, j, pCharPos, tmDoc2Device);
    }
    for (j = 0; j < iPieces; j++) {
      RenderPath(pDevice, pPen, pPieceLine, j, pCharPos, tmDoc2Device);
    }
  }
  pDevice->RestoreState(state);
  FX_Free(pCharPos);
  pSolidBrush->Release();
  pPen->Release();
  pDevice->Release();
  return iPieceLines;
}
void CXFA_TextLayout::UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom) {
  fHeight -= fBottom;
  if (fHeight < 0.1f) {
    return;
  }
  switch (m_textParser.GetVAlgin(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 == NULL) {
    m_pAllocator = FX_CreateAllocator(FX_ALLOCTYPE_Static, 256, 0);
  }
  GetTextDataNode();
  if (m_pTextDataNode == NULL) {
    return TRUE;
  }
  if (m_bRichText) {
    IFDE_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(IFDE_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 == NULL) {
    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 = NULL;
  CFX_WideString wsName;
  if (bEndBreak) {
    FX_BOOL bCurOl = FALSE;
    FX_BOOL bCurLi = FALSE;
    IFDE_XMLElement* pElement = NULL;
    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 = (IFDE_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;
          FXSYS_assert(pElement);
          pElement->GetString(FX_WSTRC(L"href").GetPtr(), wsLinkContent);
          if (!wsLinkContent.IsEmpty()) {
            pLinkData = FXTARGET_NewWith(m_pAllocator) CXFA_LinkUserData(
                m_pAllocator,
                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) {
          ((IFDE_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 == NULL || m_pLoader->m_iChar == 0) {
            if (pLinkData) {
              pLinkData->AddRef();
            }
            CXFA_TextUserData* pUserData = FXTARGET_NewWith(m_pAllocator)
                CXFA_TextUserData(m_pAllocator,
                                  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 (IFDE_XMLNode* pChildNode =
             pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
         pChildNode;
         pChildNode = pChildNode->GetNodeItem(IFDE_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) {
      FX_DWORD 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(IFDE_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) {
  FX_DWORD 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(FX_DWORD 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 == NULL || m_pTabstopContext->m_iTabCount == 0) {
    return;
  }
  if (pStyle == NULL || pPieceLine == NULL) {
    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);
      FX_DWORD dwAlgin = pTabstops->dwAlign;
      if (dwAlgin == FX_HashCode_String_GetW(L"center", 6)) {
        fLeft = pPiece->rtPiece.width / 2.0f;
      } else if (dwAlgin == FX_HashCode_String_GetW(L"right", 5) ||
                 dwAlgin == FX_HashCode_String_GetW(L"before", 6)) {
        fLeft = pPiece->rtPiece.width;
      } else if (dwAlgin == FX_HashCode_String_GetW(L"decimal", 7)) {
        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(FX_DWORD dwStatus,
                                     FX_FLOAT& fLinePos,
                                     FX_BOOL bSavePieces,
                                     FX_BOOL bEndBreak) {
  int32_t iPieces = m_pBreak->CountBreakPieces();
  if (iPieces < 1) {
    return;
  }
  IFDE_CSSComputedStyle* pStyle = NULL;
  if (bSavePieces) {
    CXFA_PieceLine* pPieceLine = FXTARGET_NewWith(m_pAllocator) 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 =
          (XFA_TEXTPIECE*)m_pAllocator->Alloc(sizeof(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->AddRef();
        pTP->pLinkData = pUserData->m_pLinkData;
      } else {
        pTP->pLinkData = NULL;
      }
      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->AddRef();
  }
  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(IFDE_RenderDevice* pDevice,
                                   IFDE_SolidBrush* 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(IFDE_RenderDevice* pDevice,
                                 IFDE_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);
  IFDE_Path* pPath = IFDE_Path::Create();
  int32_t iChars = GetDisplayPos(pPiece, pCharPos);
  if (iChars > 0) {
    CFX_PointF pt1, pt2;
    FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f;
    int32_t i = 0;
    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 (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)) {
      goto XFA_RenderPathRet;
    }
    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) {
      goto XFA_RenderPathRet;
    }
    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) {
      goto XFA_RenderPathRet;
    }
    FX_FLOAT fOrgX = 0.0f, fEndX = 0.0f;
    pPiece = pPieceLine->m_textPieces.GetAt(iPiecePrev);
    iChars = GetDisplayPos(pPiece, pCharPos);
    if (iChars < 1) {
      goto XFA_RenderPathRet;
    }
    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) {
      goto XFA_RenderPathRet;
    }
    fEndX = pCharPos[0].m_OriginX;
    CFX_PointF pt1, pt2;
    pt1.x = fOrgX, pt2.x = fEndX;
    FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f;
    int32_t i = 0;
    for (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 (i = 0; i < pPiece->iLineThrough; i++) {
      pt1.y = pt2.y = fEndY;
      pPath->AddLine(pt1, pt2);
      fEndY += 2.0f;
    }
  }
  pDevice->DrawPath(pPen, 1, pPath, &tmDoc2Device);
XFA_RenderPathRet:
  pPath->Release();
}
int32_t CXFA_TextLayout::GetDisplayPos(const XFA_TEXTPIECE* pPiece,
                                       FXTEXT_CHARPOS* pCharPos,
                                       FX_BOOL bCharCode) {
  if (pPiece == NULL) {
    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;
}
