1d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Copyright 2014 PDFium Authors. All rights reserved.
2d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Use of this source code is governed by a BSD-style license that can be
3d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// found in the LICENSE file.
4d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
5d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
7d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "xfa/fgas/layout/cfx_txtbreak.h"
8d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
9d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <algorithm>
10d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
11d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/fx_arabic.h"
12d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/fx_bidi.h"
13d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/fx_memory.h"
14d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "third_party/base/ptr_util.h"
15d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "xfa/fde/cfde_texteditengine.h"
16d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "xfa/fgas/font/cfgas_gefont.h"
17d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "xfa/fgas/layout/cfx_linebreak.h"
18d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
19d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannnamespace {
20d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
21d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool IsCtrlCode(wchar_t ch) {
22d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  uint32_t dwRet = (FX_GetUnicodeProperties(ch) & FX_CHARTYPEBITSMASK);
23d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return dwRet == FX_CHARTYPE_Tab || dwRet == FX_CHARTYPE_Control;
24d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
25d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
26d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}  // namespace
27d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
28d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCFX_TxtBreak::CFX_TxtBreak()
29d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    : CFX_Break(FX_LAYOUTSTYLE_None),
30d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      m_iAlignment(CFX_TxtLineAlignment_Left),
31d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      m_iCombWidth(360000) {}
32d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
33d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCFX_TxtBreak::~CFX_TxtBreak() {}
34d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
35d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CFX_TxtBreak::SetLineWidth(float fLineWidth) {
36d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_iLineWidth = FXSYS_round(fLineWidth * 20000.0f);
37d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ASSERT(m_iLineWidth >= 20000);
38d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
39d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
40d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CFX_TxtBreak::SetAlignment(int32_t iAlignment) {
41d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ASSERT(iAlignment >= CFX_TxtLineAlignment_Left &&
42d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann         iAlignment <= CFX_TxtLineAlignment_Justified);
43d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_iAlignment = iAlignment;
44d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
45d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
46d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CFX_TxtBreak::SetCombWidth(float fCombWidth) {
47d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_iCombWidth = FXSYS_round(fCombWidth * 20000.0f);
48d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
49d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
50d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CFX_TxtBreak::AppendChar_Combination(CFX_Char* pCurChar) {
51d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  wchar_t wch = pCurChar->char_code();
52d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  wchar_t wForm;
53d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iCharWidth = 0;
54d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pCurChar->m_iCharWidth = -1;
55d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_bCombText) {
56d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iCharWidth = m_iCombWidth;
57d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  } else {
58d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    wForm = wch;
59d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    CFX_Char* pLastChar = GetLastChar(0, false, false);
60d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (pLastChar &&
61d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        (pLastChar->m_dwCharStyles & FX_TXTCHARSTYLE_ArabicShadda) == 0) {
62d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      bool bShadda = false;
63d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (wch == 0x0651) {
64d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        wchar_t wLast = pLastChar->char_code();
65d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (wLast >= 0x064C && wLast <= 0x0650) {
66d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          wForm = FX_GetArabicFromShaddaTable(wLast);
67d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          bShadda = true;
68d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
69d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      } else if (wch >= 0x064C && wch <= 0x0650) {
70d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (pLastChar->char_code() == 0x0651) {
71d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          wForm = FX_GetArabicFromShaddaTable(wch);
72d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          bShadda = true;
73d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
74d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
75d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (bShadda) {
76d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pLastChar->m_dwCharStyles |= FX_TXTCHARSTYLE_ArabicShadda;
77d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pLastChar->m_iCharWidth = 0;
78d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pCurChar->m_dwCharStyles |= FX_TXTCHARSTYLE_ArabicShadda;
79d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
80d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
81d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!m_pFont->GetCharWidth(wForm, iCharWidth))
82d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharWidth = 0;
83d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
84d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iCharWidth *= m_iFontSize;
85d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iCharWidth = iCharWidth * m_iHorizontalScale / 100;
86d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
87d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pCurChar->m_iCharWidth = -iCharWidth;
88d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
89d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
90d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CFX_TxtBreak::AppendChar_Tab(CFX_Char* pCurChar) {
91d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_eCharType = FX_CHARTYPE_Tab;
92d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
93d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
94d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCFX_BreakType CFX_TxtBreak::AppendChar_Control(CFX_Char* pCurChar) {
95d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_eCharType = FX_CHARTYPE_Control;
96d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_BreakType dwRet = CFX_BreakType::None;
97d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_bSingleLine) {
98d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    wchar_t wch = pCurChar->char_code();
99d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    switch (wch) {
100d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case L'\v':
101d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case 0x2028:
102d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        dwRet = CFX_BreakType::Line;
103d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        break;
104d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case L'\f':
105d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        dwRet = CFX_BreakType::Page;
106d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        break;
107d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case 0x2029:
108d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        dwRet = CFX_BreakType::Paragraph;
109d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        break;
110d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      default:
111d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (wch == m_wParagraphBreakChar)
112d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          dwRet = CFX_BreakType::Paragraph;
113d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        break;
114d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
115d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (dwRet != CFX_BreakType::None)
116d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      dwRet = EndBreak(dwRet);
117d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
118d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return dwRet;
119d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
120d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
121d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCFX_BreakType CFX_TxtBreak::AppendChar_Arabic(CFX_Char* pCurChar) {
122d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  FX_CHARTYPE chartype = pCurChar->GetCharType();
123d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t& iLineWidth = m_pCurLine->m_iWidth;
124d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  wchar_t wForm;
125d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iCharWidth = 0;
126d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_Char* pLastChar = nullptr;
127d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool bAlef = false;
128d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_bCombText && m_eCharType >= FX_CHARTYPE_ArabicAlef &&
129d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      m_eCharType <= FX_CHARTYPE_ArabicDistortion) {
130d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pLastChar = GetLastChar(1, true, false);
131d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (pLastChar) {
132d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharWidth = pLastChar->m_iCharWidth;
133d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (iCharWidth > 0)
134d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        iLineWidth -= iCharWidth;
135d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
136d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      CFX_Char* pPrevChar = GetLastChar(2, true, false);
137d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wForm = pdfium::arabic::GetFormChar(pLastChar, pPrevChar, pCurChar);
138d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      bAlef = (wForm == 0xFEFF &&
139d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann               pLastChar->GetCharType() == FX_CHARTYPE_ArabicAlef);
140d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      m_pFont->GetCharWidth(wForm, iCharWidth);
141d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
142d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (wForm == 0xFEFF)
143d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        iCharWidth = m_iDefChar;
144d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
145d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharWidth *= m_iFontSize;
146d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharWidth = iCharWidth * m_iHorizontalScale / 100;
147d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pLastChar->m_iCharWidth = iCharWidth;
148d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iLineWidth += iCharWidth;
149d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharWidth = 0;
150d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
151d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
152d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
153d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_eCharType = chartype;
154d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  wForm = pdfium::arabic::GetFormChar(pCurChar, bAlef ? nullptr : pLastChar,
155d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                      nullptr);
156d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_bCombText) {
157d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iCharWidth = m_iCombWidth;
158d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  } else {
159d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pFont->GetCharWidth(wForm, iCharWidth);
160d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
161d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (wForm == 0xFEFF)
162d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharWidth = m_iDefChar;
163d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
164d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iCharWidth *= m_iFontSize;
165d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iCharWidth = iCharWidth * m_iHorizontalScale / 100;
166d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
167d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pCurChar->m_iCharWidth = iCharWidth;
168d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  iLineWidth += iCharWidth;
169d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pCurLine->m_iArabicChars++;
170d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_bSingleLine && iLineWidth > m_iLineWidth + m_iTolerance)
171d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return EndBreak(CFX_BreakType::Line);
172d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return CFX_BreakType::None;
173d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
174d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
175d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCFX_BreakType CFX_TxtBreak::AppendChar_Others(CFX_Char* pCurChar) {
176d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  FX_CHARTYPE chartype = pCurChar->GetCharType();
177d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t& iLineWidth = m_pCurLine->m_iWidth;
178d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iCharWidth = 0;
179d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_eCharType = chartype;
180d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  wchar_t wch = pCurChar->char_code();
181d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  wchar_t wForm = wch;
182d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
183d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_bCombText) {
184d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iCharWidth = m_iCombWidth;
185d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  } else {
186d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!m_pFont->GetCharWidth(wForm, iCharWidth))
187d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharWidth = m_iDefChar;
188d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
189d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iCharWidth *= m_iFontSize;
190d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iCharWidth = iCharWidth * m_iHorizontalScale / 100;
191d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
192d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
193d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  iCharWidth += m_iCharSpace;
194d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pCurChar->m_iCharWidth = iCharWidth;
195d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  iLineWidth += iCharWidth;
196d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_bSingleLine && chartype != FX_CHARTYPE_Space &&
197d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iLineWidth > m_iLineWidth + m_iTolerance) {
198d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return EndBreak(CFX_BreakType::Line);
199d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
200d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
201d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return CFX_BreakType::None;
202d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
203d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
204d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCFX_BreakType CFX_TxtBreak::AppendChar(wchar_t wch) {
205d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  uint32_t dwProps = FX_GetUnicodeProperties(wch);
206d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  FX_CHARTYPE chartype = GetCharTypeFromProp(dwProps);
207d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pCurLine->m_LineChars.emplace_back(wch, dwProps, m_iHorizontalScale,
208d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                       m_iVerticalScale);
209d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_Char* pCurChar = &m_pCurLine->m_LineChars.back();
210d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pCurChar->m_dwCharStyles = m_iAlignment | (1 << 8);
211d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
212d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_BreakType dwRet1 = CFX_BreakType::None;
213d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (chartype != FX_CHARTYPE_Combination &&
214d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      GetUnifiedCharType(m_eCharType) != GetUnifiedCharType(chartype) &&
215d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      m_eCharType != FX_CHARTYPE_Unknown &&
216d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      m_pCurLine->m_iWidth > m_iLineWidth + m_iTolerance && !m_bSingleLine &&
217d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      (m_eCharType != FX_CHARTYPE_Space || chartype != FX_CHARTYPE_Control)) {
218d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    dwRet1 = EndBreak(CFX_BreakType::Line);
219d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t iCount = m_pCurLine->CountChars();
220d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (iCount > 0)
221d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pCurChar = &m_pCurLine->m_LineChars[iCount - 1];
222d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
223d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
224d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_BreakType dwRet2 = CFX_BreakType::None;
225d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (wch == m_wParagraphBreakChar) {
226d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    // This is handled in AppendChar_Control, but it seems like \n and \r
227d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    // don't get matched as control characters so we go into AppendChar_other
228d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    // and never detect the new paragraph ...
229d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    dwRet2 = CFX_BreakType::Paragraph;
230d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  } else {
231d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    switch (chartype) {
232d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_Tab:
233d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        AppendChar_Tab(pCurChar);
234d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        break;
235d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_Control:
236d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        dwRet2 = AppendChar_Control(pCurChar);
237d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        break;
238d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_Combination:
239d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        AppendChar_Combination(pCurChar);
240d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        break;
241d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_ArabicAlef:
242d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_ArabicSpecial:
243d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_ArabicDistortion:
244d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_ArabicNormal:
245d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_ArabicForm:
246d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_Arabic:
247d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        dwRet2 = AppendChar_Arabic(pCurChar);
248d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        break;
249d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_Unknown:
250d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_Space:
251d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_Numeric:
252d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_Normal:
253d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      default:
254d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        dwRet2 = AppendChar_Others(pCurChar);
255d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        break;
256d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
257d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
258d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return std::max(dwRet1, dwRet2);
259d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
260d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
261d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool CFX_TxtBreak::EndBreak_SplitLine(CFX_BreakLine* pNextLine,
262d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                      bool bAllChars) {
263d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iCount = m_pCurLine->CountChars();
264d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool bDone = false;
265d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_Char* pTC;
266d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_bSingleLine && m_pCurLine->m_iWidth > m_iLineWidth + m_iTolerance) {
267d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pTC = m_pCurLine->GetChar(iCount - 1);
268d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    switch (pTC->GetCharType()) {
269d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_Tab:
270d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_Control:
271d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      case FX_CHARTYPE_Space:
272d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        break;
273d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      default:
274d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        SplitTextLine(m_pCurLine, pNextLine, bAllChars);
275d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        bDone = true;
276d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        break;
277d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
278d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
279d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
280d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  iCount = m_pCurLine->CountChars();
281d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_BreakPiece tp;
282d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (bAllChars && !bDone) {
283d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t iEndPos = m_pCurLine->m_iWidth;
284d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    GetBreakPos(m_pCurLine->m_LineChars, iEndPos, bAllChars, true);
285d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
286d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return false;
287d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
288d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
289d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CFX_TxtBreak::EndBreak_BidiLine(std::deque<FX_TPO>* tpos,
290d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                     CFX_BreakType dwStatus) {
291d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_BreakPiece tp;
292d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  FX_TPO tpo;
293d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_Char* pTC;
294d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  std::vector<CFX_Char>& chars = m_pCurLine->m_LineChars;
295d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iCount = m_pCurLine->CountChars();
296d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool bDone = m_pCurLine->m_iArabicChars > 0;
297d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (bDone) {
298d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    ASSERT(iCount >= 0);
299d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
300d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    size_t iBidiNum = 0;
301d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    for (size_t i = 0; i < static_cast<size_t>(iCount); ++i) {
302d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pTC = &chars[i];
303d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pTC->m_iBidiPos = static_cast<int32_t>(i);
304d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (pTC->GetCharType() != FX_CHARTYPE_Control)
305d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        iBidiNum = i;
306d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (i == 0)
307d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pTC->m_iBidiLevel = 1;
308d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
309d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    FX_BidiLine(&chars, iBidiNum + 1);
310d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
311d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
312d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (bDone) {
313d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    tp.m_dwStatus = CFX_BreakType::Piece;
314d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    tp.m_iStartPos = m_pCurLine->m_iStart;
315d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    tp.m_pChars = &m_pCurLine->m_LineChars;
316d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t iBidiLevel = -1;
317d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t iCharWidth;
318d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t i = 0;
319d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t j = -1;
320d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    while (i < iCount) {
321d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pTC = &chars[i];
322d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (iBidiLevel < 0) {
323d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        iBidiLevel = pTC->m_iBidiLevel;
324d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        tp.m_iWidth = 0;
325d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        tp.m_iBidiLevel = iBidiLevel;
326d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        tp.m_iBidiPos = pTC->m_iBidiOrder;
327d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        tp.m_dwCharStyles = pTC->m_dwCharStyles;
328d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        tp.m_iHorizontalScale = pTC->horizonal_scale();
329d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        tp.m_iVerticalScale = pTC->vertical_scale();
330d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        tp.m_dwStatus = CFX_BreakType::Piece;
331d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
332d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (iBidiLevel != pTC->m_iBidiLevel ||
333d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          pTC->m_dwStatus != CFX_BreakType::None) {
334d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (iBidiLevel == pTC->m_iBidiLevel) {
335d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          tp.m_dwStatus = pTC->m_dwStatus;
336d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          iCharWidth = pTC->m_iCharWidth;
337d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          if (iCharWidth > 0)
338d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            tp.m_iWidth += iCharWidth;
339d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
340d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          i++;
341d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
342d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        tp.m_iChars = i - tp.m_iStartChar;
343d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        m_pCurLine->m_LinePieces.push_back(tp);
344d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        tp.m_iStartPos += tp.m_iWidth;
345d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        tp.m_iStartChar = i;
346d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        tpo.index = ++j;
347d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        tpo.pos = tp.m_iBidiPos;
348d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        tpos->push_back(tpo);
349d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        iBidiLevel = -1;
350d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      } else {
351d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        iCharWidth = pTC->m_iCharWidth;
352d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (iCharWidth > 0)
353d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          tp.m_iWidth += iCharWidth;
354d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
355d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        i++;
356d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
357d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
358d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (i > tp.m_iStartChar) {
359d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      tp.m_dwStatus = dwStatus;
360d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      tp.m_iChars = i - tp.m_iStartChar;
361d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      m_pCurLine->m_LinePieces.push_back(tp);
362d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      tpo.index = ++j;
363d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      tpo.pos = tp.m_iBidiPos;
364d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      tpos->push_back(tpo);
365d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
366d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (j > -1) {
367d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (j > 0) {
368d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        std::sort(tpos->begin(), tpos->end());
369d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        int32_t iStartPos = 0;
370d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        for (i = 0; i <= j; i++) {
371d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          tpo = (*tpos)[i];
372d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          CFX_BreakPiece& ttp = m_pCurLine->m_LinePieces[tpo.index];
373d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          ttp.m_iStartPos = iStartPos;
374d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          iStartPos += ttp.m_iWidth;
375d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
376d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
377d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      m_pCurLine->m_LinePieces[j].m_dwStatus = dwStatus;
378d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
379d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  } else {
380d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    tp.m_dwStatus = dwStatus;
381d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    tp.m_iStartPos = m_pCurLine->m_iStart;
382d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    tp.m_iWidth = m_pCurLine->m_iWidth;
383d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    tp.m_iStartChar = 0;
384d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    tp.m_iChars = iCount;
385d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    tp.m_pChars = &m_pCurLine->m_LineChars;
386d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pTC = &chars[0];
387d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    tp.m_dwCharStyles = pTC->m_dwCharStyles;
388d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    tp.m_iHorizontalScale = pTC->horizonal_scale();
389d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    tp.m_iVerticalScale = pTC->vertical_scale();
390d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pCurLine->m_LinePieces.push_back(tp);
391d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    tpos->push_back({0, 0});
392d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
393d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
394d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
395d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CFX_TxtBreak::EndBreak_Alignment(const std::deque<FX_TPO>& tpos,
396d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                      bool bAllChars,
397d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                      CFX_BreakType dwStatus) {
398d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iNetWidth = m_pCurLine->m_iWidth;
399d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iGapChars = 0;
400d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool bFind = false;
401d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (auto it = tpos.rbegin(); it != tpos.rend(); ++it) {
402d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    CFX_BreakPiece& ttp = m_pCurLine->m_LinePieces[it->index];
403d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!bFind)
404d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iNetWidth = ttp.GetEndPos();
405d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
406d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    bool bArabic = FX_IsOdd(ttp.m_iBidiLevel);
407d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t j = bArabic ? 0 : ttp.m_iChars - 1;
408d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    while (j > -1 && j < ttp.m_iChars) {
409d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      const CFX_Char* pTC = ttp.GetChar(j);
410d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (pTC->m_nBreakType == FX_LBT_DIRECT_BRK)
411d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        iGapChars++;
412d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (!bFind || !bAllChars) {
413d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        FX_CHARTYPE chartype = pTC->GetCharType();
414d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (chartype == FX_CHARTYPE_Space || chartype == FX_CHARTYPE_Control) {
415d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          if (!bFind && bAllChars && pTC->m_iCharWidth > 0)
416d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            iNetWidth -= pTC->m_iCharWidth;
417d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        } else {
418d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          bFind = true;
419d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          if (!bAllChars)
420d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            break;
421d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
422d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
423d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      j += bArabic ? 1 : -1;
424d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
425d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!bAllChars && bFind)
426d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      break;
427d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
428d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
429d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iOffset = m_iLineWidth - iNetWidth;
430d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (iGapChars > 0 && m_iAlignment & CFX_TxtLineAlignment_Justified &&
431d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      dwStatus != CFX_BreakType::Paragraph) {
432d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t iStart = -1;
433d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    for (auto& tpo : tpos) {
434d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      CFX_BreakPiece& ttp = m_pCurLine->m_LinePieces[tpo.index];
435d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (iStart < -1)
436d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        iStart = ttp.m_iStartPos;
437d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      else
438d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        ttp.m_iStartPos = iStart;
439d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
440d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      for (int32_t j = 0; j < ttp.m_iChars; j++) {
441d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        CFX_Char* pTC = ttp.GetChar(j);
442d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (pTC->m_nBreakType != FX_LBT_DIRECT_BRK || pTC->m_iCharWidth < 0)
443d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          continue;
444d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
445d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        int32_t k = iOffset / iGapChars;
446d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pTC->m_iCharWidth += k;
447d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        ttp.m_iWidth += k;
448d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        iOffset -= k;
449d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        iGapChars--;
450d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (iGapChars < 1)
451d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          break;
452d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
453d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iStart += ttp.m_iWidth;
454d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
455d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  } else if (m_iAlignment & CFX_TxtLineAlignment_Center ||
456d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann             m_iAlignment & CFX_TxtLineAlignment_Right) {
457d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (m_iAlignment & CFX_TxtLineAlignment_Center &&
458d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        !(m_iAlignment & CFX_TxtLineAlignment_Right)) {
459d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iOffset /= 2;
460d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
461d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (iOffset > 0) {
462d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      for (auto& ttp : m_pCurLine->m_LinePieces)
463d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        ttp.m_iStartPos += iOffset;
464d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
465d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
466d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
467d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
468d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCFX_BreakType CFX_TxtBreak::EndBreak(CFX_BreakType dwStatus) {
469d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ASSERT(dwStatus != CFX_BreakType::None);
470d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
471d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pCurLine->m_LinePieces.empty()) {
472d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (dwStatus != CFX_BreakType::Piece)
473d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      m_pCurLine->m_LinePieces.back().m_dwStatus = dwStatus;
474d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return m_pCurLine->m_LinePieces.back().m_dwStatus;
475d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
476d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
477d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (HasLine()) {
478d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!m_Line[m_iReadyLineIndex].m_LinePieces.empty()) {
479d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (dwStatus != CFX_BreakType::Piece)
480d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        m_Line[m_iReadyLineIndex].m_LinePieces.back().m_dwStatus = dwStatus;
481d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      return m_Line[m_iReadyLineIndex].m_LinePieces.back().m_dwStatus;
482d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
483d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return CFX_BreakType::None;
484d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
485d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
486d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iCount = m_pCurLine->CountChars();
487d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (iCount < 1)
488d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return CFX_BreakType::None;
489d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
490d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pCurLine->GetChar(iCount - 1)->m_dwStatus = dwStatus;
491d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (dwStatus == CFX_BreakType::Piece)
492d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return dwStatus;
493d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
494d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_iReadyLineIndex = m_pCurLine == &m_Line[0] ? 0 : 1;
495d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_BreakLine* pNextLine = &m_Line[1 - m_iReadyLineIndex];
496d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool bAllChars = m_iAlignment > CFX_TxtLineAlignment_Right;
497d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!EndBreak_SplitLine(pNextLine, bAllChars)) {
498d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    std::deque<FX_TPO> tpos;
499d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    EndBreak_BidiLine(&tpos, dwStatus);
500d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (m_iAlignment > CFX_TxtLineAlignment_Left)
501d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      EndBreak_Alignment(tpos, bAllChars, dwStatus);
502d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
503d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
504d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pCurLine = pNextLine;
505d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_Char* pTC = GetLastChar(0, false, false);
506d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_eCharType = pTC ? pTC->GetCharType() : FX_CHARTYPE_Unknown;
507d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
508d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return dwStatus;
509d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
510d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
511d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannint32_t CFX_TxtBreak::GetBreakPos(std::vector<CFX_Char>& ca,
512d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                  int32_t& iEndPos,
513d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                  bool bAllChars,
514d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                  bool bOnlyBrk) {
515d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iLength = pdfium::CollectionSize<int32_t>(ca) - 1;
516d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (iLength < 1)
517d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return iLength;
518d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
519d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iBreak = -1;
520d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iBreakPos = -1;
521d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iIndirect = -1;
522d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iIndirectPos = -1;
523d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iLast = -1;
524d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iLastPos = -1;
525d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_bSingleLine || iEndPos <= m_iLineWidth) {
526d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!bAllChars)
527d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      return iLength;
528d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
529d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iBreak = iLength;
530d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iBreakPos = iEndPos;
531d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
532d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
533d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  FX_LINEBREAKTYPE eType;
534d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  uint32_t nCodeProp;
535d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  uint32_t nCur;
536d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  uint32_t nNext;
537d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_Char* pCur = &ca[iLength--];
538d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (bAllChars)
539d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pCur->m_nBreakType = FX_LBT_UNKNOWN;
540d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
541d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  nCodeProp = pCur->char_props();
542d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  nNext = nCodeProp & 0x003F;
543d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iCharWidth = pCur->m_iCharWidth;
544d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (iCharWidth > 0)
545d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iEndPos -= iCharWidth;
546d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
547d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  while (iLength >= 0) {
548d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pCur = &ca[iLength];
549d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    nCodeProp = pCur->char_props();
550d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    nCur = nCodeProp & 0x003F;
551d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (nNext == kBreakPropertySpace)
552d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      eType = FX_LBT_PROHIBITED_BRK;
553d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    else
554d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      eType = gs_FX_LineBreak_PairTable[nCur][nNext];
555d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (bAllChars)
556d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pCur->m_nBreakType = static_cast<uint8_t>(eType);
557d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!bOnlyBrk) {
558d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (m_bSingleLine || iEndPos <= m_iLineWidth ||
559d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          nCur == kBreakPropertySpace) {
560d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (eType == FX_LBT_DIRECT_BRK && iBreak < 0) {
561d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          iBreak = iLength;
562d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          iBreakPos = iEndPos;
563d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          if (!bAllChars)
564d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            return iLength;
565d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        } else if (eType == FX_LBT_INDIRECT_BRK && iIndirect < 0) {
566d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          iIndirect = iLength;
567d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          iIndirectPos = iEndPos;
568d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
569d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (iLast < 0) {
570d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          iLast = iLength;
571d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          iLastPos = iEndPos;
572d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
573d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
574d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharWidth = pCur->m_iCharWidth;
575d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (iCharWidth > 0)
576d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        iEndPos -= iCharWidth;
577d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
578d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    nNext = nCodeProp & 0x003F;
579d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iLength--;
580d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
581d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (bOnlyBrk)
582d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return 0;
583d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (iBreak > -1) {
584d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iEndPos = iBreakPos;
585d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return iBreak;
586d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
587d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (iIndirect > -1) {
588d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iEndPos = iIndirectPos;
589d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return iIndirect;
590d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
591d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (iLast > -1) {
592d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iEndPos = iLastPos;
593d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return iLast;
594d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
595d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return 0;
596d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
597d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
598d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CFX_TxtBreak::SplitTextLine(CFX_BreakLine* pCurLine,
599d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                 CFX_BreakLine* pNextLine,
600d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                 bool bAllChars) {
601d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ASSERT(pCurLine && pNextLine);
602d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iCount = pCurLine->CountChars();
603d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (iCount < 2)
604d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
605d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
606d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iEndPos = pCurLine->m_iWidth;
607d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  std::vector<CFX_Char>& curChars = pCurLine->m_LineChars;
608d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iCharPos = GetBreakPos(curChars, iEndPos, bAllChars, false);
609d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (iCharPos < 0)
610d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iCharPos = 0;
611d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
612d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  iCharPos++;
613d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (iCharPos >= iCount) {
614d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pNextLine->Clear();
615d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    CFX_Char* pTC = &curChars[iCharPos - 1];
616d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pTC->m_nBreakType = FX_LBT_UNKNOWN;
617d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
618d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
619d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
620d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pNextLine->m_LineChars =
621d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      std::vector<CFX_Char>(curChars.begin() + iCharPos, curChars.end());
622d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  curChars.erase(curChars.begin() + iCharPos, curChars.end());
623d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pCurLine->m_iWidth = iEndPos;
624d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_Char* pTC = &curChars[iCharPos - 1];
625d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pTC->m_nBreakType = FX_LBT_UNKNOWN;
626d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  iCount = pdfium::CollectionSize<int>(pNextLine->m_LineChars);
627d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iWidth = 0;
628d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (int32_t i = 0; i < iCount; i++) {
629d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (pNextLine->m_LineChars[i].GetCharType() >= FX_CHARTYPE_ArabicAlef) {
630d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pCurLine->m_iArabicChars--;
631d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pNextLine->m_iArabicChars++;
632d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
633d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iWidth += std::max(0, pNextLine->m_LineChars[i].m_iCharWidth);
634d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pNextLine->m_LineChars[i].m_dwStatus = CFX_BreakType::None;
635d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
636d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pNextLine->m_iWidth = iWidth;
637d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
638d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
639d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstruct FX_FORMCHAR {
640d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  uint16_t wch;
641d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  uint16_t wForm;
642d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iWidth;
643d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann};
644d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
645d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannint32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun,
646d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                    FXTEXT_CHARPOS* pCharPos) const {
647d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!pTxtRun || pTxtRun->iLength < 1)
648d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return 0;
649d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
650d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFDE_TextEditEngine* pEngine = pTxtRun->pEdtEngine;
651d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const wchar_t* pStr = pTxtRun->wsStr.c_str();
652d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t* pWidths = pTxtRun->pWidths;
653d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iLength = pTxtRun->iLength - 1;
654d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  RetainPtr<CFGAS_GEFont> pFont = pTxtRun->pFont;
655d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  uint32_t dwStyles = pTxtRun->dwStyles;
656d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_RectF rtText(*pTxtRun->pRect);
657d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool bRTLPiece = (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_OddBidiLevel) != 0;
658d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  float fFontSize = pTxtRun->fFontSize;
659d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
660d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iAscent = pFont->GetAscent();
661d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iDescent = pFont->GetDescent();
662d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iMaxHeight = iAscent - iDescent;
663d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  float fFontHeight = fFontSize;
664d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  float fAscent = fFontHeight * (float)iAscent / (float)iMaxHeight;
665d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  float fX = rtText.left;
666d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  float fY;
667d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  float fCharWidth;
668d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iHorScale = pTxtRun->iHorizontalScale;
669d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iVerScale = pTxtRun->iVerticalScale;
670d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool bSkipSpace = pTxtRun->bSkipSpace;
671d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  FX_FORMCHAR formChars[3];
672d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  float fYBase;
673d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
674d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (bRTLPiece)
675d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    fX = rtText.right();
676d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
677d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  fYBase = rtText.top + (rtText.height - fFontSize) / 2.0f;
678d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  fY = fYBase + fAscent;
679d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
680d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iCount = 0;
681d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iNext = 0;
682d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  wchar_t wPrev = 0xFEFF;
683d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  wchar_t wNext = 0xFEFF;
684d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  wchar_t wForm = 0xFEFF;
685d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  wchar_t wLast = 0xFEFF;
686d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool bShadda = false;
687d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool bLam = false;
688d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (int32_t i = 0; i <= iLength; i++) {
689d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t iWidth;
690d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    wchar_t wch;
691d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (pEngine) {
692d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wch = pEngine->GetChar(i);
693d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iWidth = pEngine->GetWidthOfChar(i);
694d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    } else {
695d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wch = *pStr++;
696d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iWidth = *pWidths++;
697d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
698d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
699d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    uint32_t dwProps = FX_GetUnicodeProperties(wch);
700d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    FX_CHARTYPE chartype = GetCharTypeFromProp(dwProps);
701d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (chartype == FX_CHARTYPE_ArabicAlef && iWidth == 0) {
702d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wPrev = 0xFEFF;
703d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wLast = wch;
704d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      continue;
705d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
706d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
707d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (chartype >= FX_CHARTYPE_ArabicAlef) {
708d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (i < iLength) {
709d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (pEngine) {
710d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          iNext = i + 1;
711d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          while (iNext <= iLength) {
712d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            wNext = pEngine->GetChar(iNext);
713d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            dwProps = FX_GetUnicodeProperties(wNext);
714d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            if ((dwProps & FX_CHARTYPEBITSMASK) != FX_CHARTYPE_Combination)
715d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              break;
716d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
717d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            iNext++;
718d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          }
719d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          if (iNext > iLength)
720d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            wNext = 0xFEFF;
721d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        } else {
722d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          int32_t j = -1;
723d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          do {
724d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            j++;
725d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            if (i + j >= iLength)
726d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              break;
727d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
728d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            wNext = pStr[j];
729d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            dwProps = FX_GetUnicodeProperties(wNext);
730d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          } while ((dwProps & FX_CHARTYPEBITSMASK) == FX_CHARTYPE_Combination);
731d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          if (i + j >= iLength)
732d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            wNext = 0xFEFF;
733d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
734d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      } else {
735d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        wNext = 0xFEFF;
736d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
737d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
738d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wForm = pdfium::arabic::GetFormChar(wch, wPrev, wNext);
739d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      bLam = (wPrev == 0x0644 && wch == 0x0644 && wNext == 0x0647);
740d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    } else if (chartype == FX_CHARTYPE_Combination) {
741d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wForm = wch;
742d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (wch >= 0x064C && wch <= 0x0651) {
743d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (bShadda) {
744d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          wForm = 0xFEFF;
745d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          bShadda = false;
746d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        } else {
747d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          wNext = 0xFEFF;
748d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          if (pEngine) {
749d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            iNext = i + 1;
750d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            if (iNext <= iLength)
751d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              wNext = pEngine->GetChar(iNext);
752d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          } else {
753d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            if (i < iLength)
754d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              wNext = *pStr;
755d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          }
756d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          if (wch == 0x0651) {
757d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            if (wNext >= 0x064C && wNext <= 0x0650) {
758d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              wForm = FX_GetArabicFromShaddaTable(wNext);
759d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              bShadda = true;
760d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            }
761d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          } else {
762d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            if (wNext == 0x0651) {
763d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              wForm = FX_GetArabicFromShaddaTable(wch);
764d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              bShadda = true;
765d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            }
766d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          }
767d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
768d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      } else {
769d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        bShadda = false;
770d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
771d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    } else if (chartype == FX_CHARTYPE_Numeric) {
772d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wForm = wch;
773d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    } else if (wch == L'.') {
774d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wForm = wch;
775d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    } else if (wch == L',') {
776d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wForm = wch;
777d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    } else if (bRTLPiece) {
778d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wForm = FX_GetMirrorChar(wch, dwProps);
779d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    } else {
780d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wForm = wch;
781d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
782d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (chartype != FX_CHARTYPE_Combination)
783d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      bShadda = false;
784d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (chartype < FX_CHARTYPE_ArabicAlef)
785d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      bLam = false;
786d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
787d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    dwProps = FX_GetUnicodeProperties(wForm);
788d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    bool bEmptyChar =
789d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        (chartype >= FX_CHARTYPE_Tab && chartype <= FX_CHARTYPE_Control);
790d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (wForm == 0xFEFF)
791d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      bEmptyChar = true;
792d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
793d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t iForms = bLam ? 3 : 1;
794d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iCount += (bEmptyChar && bSkipSpace) ? 0 : iForms;
795d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!pCharPos) {
796d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (iWidth > 0)
797d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        wPrev = wch;
798d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wLast = wch;
799d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      continue;
800d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
801d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
802d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t iCharWidth = iWidth;
803d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (iCharWidth < 0)
804d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharWidth = -iCharWidth;
805d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
806d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    iCharWidth /= iFontSize;
807d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    formChars[0].wch = wch;
808d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    formChars[0].wForm = wForm;
809d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    formChars[0].iWidth = iCharWidth;
810d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (bLam) {
811d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      formChars[1].wForm = 0x0651;
812d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharWidth = 0;
813d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pFont->GetCharWidth(0x0651, iCharWidth);
814d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      formChars[1].iWidth = iCharWidth;
815d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      formChars[2].wForm = 0x0670;
816d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharWidth = 0;
817d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pFont->GetCharWidth(0x0670, iCharWidth);
818d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      formChars[2].iWidth = iCharWidth;
819d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
820d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
821d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    for (int32_t j = 0; j < iForms; j++) {
822d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wForm = (wchar_t)formChars[j].wForm;
823d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharWidth = formChars[j].iWidth;
824d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (j > 0) {
825d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        chartype = FX_CHARTYPE_Combination;
826d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        wch = wForm;
827d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        wLast = (wchar_t)formChars[j - 1].wForm;
828d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
829d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) {
830d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pCharPos->m_GlyphIndex = pFont->GetGlyphIndex(wForm);
831d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
832d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pCharPos->m_ExtGID = pCharPos->m_GlyphIndex;
833d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#endif
834d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pCharPos->m_FontCharWidth = iCharWidth;
835d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
836d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
837d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      fCharWidth = fFontSize * iCharWidth / 1000.0f;
838d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (bRTLPiece && chartype != FX_CHARTYPE_Combination)
839d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        fX -= fCharWidth;
840d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
841d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) {
842d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pCharPos->m_Origin = CFX_PointF(fX, fY);
843d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
844d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if ((dwStyles & FX_LAYOUTSTYLE_CombText) != 0) {
845d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          int32_t iFormWidth = iCharWidth;
846d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          pFont->GetCharWidth(wForm, iFormWidth);
847d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          float fOffset = fFontSize * (iCharWidth - iFormWidth) / 2000.0f;
848d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          pCharPos->m_Origin.x += fOffset;
849d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
850d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
851d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (chartype == FX_CHARTYPE_Combination) {
852d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          CFX_Rect rtBBox;
853d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          if (pFont->GetCharBBox(wForm, &rtBBox)) {
854d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            pCharPos->m_Origin.y =
855d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                fYBase + fFontSize -
856d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                fFontSize * (float)rtBBox.height / (float)iMaxHeight;
857d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          }
858d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          if (wForm == wch && wLast != 0xFEFF) {
859d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            uint32_t dwLastProps = FX_GetUnicodeProperties(wLast);
860d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            if ((dwLastProps & FX_CHARTYPEBITSMASK) ==
861d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                FX_CHARTYPE_Combination) {
862d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              CFX_Rect rtBox;
863d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              if (pFont->GetCharBBox(wLast, &rtBox))
864d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                pCharPos->m_Origin.y -= fFontSize * rtBox.height / iMaxHeight;
865d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            }
866d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          }
867d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
868d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
869d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (!bRTLPiece && chartype != FX_CHARTYPE_Combination)
870d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        fX += fCharWidth;
871d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
872d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) {
873d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pCharPos->m_bGlyphAdjust = true;
874d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pCharPos->m_AdjustMatrix[0] = -1;
875d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pCharPos->m_AdjustMatrix[1] = 0;
876d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pCharPos->m_AdjustMatrix[2] = 0;
877d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pCharPos->m_AdjustMatrix[3] = 1;
878d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
879d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (iHorScale != 100 || iVerScale != 100) {
880d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          pCharPos->m_AdjustMatrix[0] =
881d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              pCharPos->m_AdjustMatrix[0] * iHorScale / 100.0f;
882d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          pCharPos->m_AdjustMatrix[1] =
883d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              pCharPos->m_AdjustMatrix[1] * iHorScale / 100.0f;
884d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          pCharPos->m_AdjustMatrix[2] =
885d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              pCharPos->m_AdjustMatrix[2] * iVerScale / 100.0f;
886d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          pCharPos->m_AdjustMatrix[3] =
887d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              pCharPos->m_AdjustMatrix[3] * iVerScale / 100.0f;
888d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        }
889d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        pCharPos++;
890d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
891d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
892d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (iWidth > 0)
893d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wPrev = static_cast<wchar_t>(formChars[0].wch);
894d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    wLast = wch;
895d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
896d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return iCount;
897d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
898d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
899d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::vector<CFX_RectF> CFX_TxtBreak::GetCharRects(const FX_TXTRUN* pTxtRun,
900d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                                  bool bCharBBox) const {
901d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!pTxtRun || pTxtRun->iLength < 1)
902d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return std::vector<CFX_RectF>();
903d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
904d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFDE_TextEditEngine* pEngine = pTxtRun->pEdtEngine;
905d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const wchar_t* pStr = pTxtRun->wsStr.c_str();
906d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t* pWidths = pTxtRun->pWidths;
907d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iLength = pTxtRun->iLength;
908d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_RectF rect(*pTxtRun->pRect);
909d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  float fFontSize = pTxtRun->fFontSize;
910d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iFontSize = FXSYS_round(fFontSize * 20.0f);
911d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  float fScale = fFontSize / 1000.0f;
912d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  RetainPtr<CFGAS_GEFont> pFont = pTxtRun->pFont;
913d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!pFont)
914d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    bCharBBox = false;
915d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
916d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_Rect bbox;
917d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (bCharBBox)
918d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    bCharBBox = pFont->GetBBox(&bbox);
919d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
920d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  float fLeft = std::max(0.0f, bbox.left * fScale);
921d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  float fHeight = fabs(bbox.height * fScale);
922d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool bRTLPiece = !!(pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_OddBidiLevel);
923d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool bSingleLine = !!(pTxtRun->dwStyles & FX_LAYOUTSTYLE_SingleLine);
924d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool bCombText = !!(pTxtRun->dwStyles & FX_LAYOUTSTYLE_CombText);
925d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  wchar_t wch;
926d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t iCharSize;
927d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  float fCharSize;
928d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  float fStart = bRTLPiece ? rect.right() : rect.left;
929d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
930d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  std::vector<CFX_RectF> rtArray(iLength);
931d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (int32_t i = 0; i < iLength; i++) {
932d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (pEngine) {
933d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wch = pEngine->GetChar(i);
934d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharSize = pEngine->GetWidthOfChar(i);
935d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    } else {
936d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      wch = *pStr++;
937d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharSize = *pWidths++;
938d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
939d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    fCharSize = static_cast<float>(iCharSize) / 20000.0f;
940d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    bool bRet = (!bSingleLine && IsCtrlCode(wch));
941d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!(wch == L'\v' || wch == L'\f' || wch == 0x2028 || wch == 0x2029 ||
942d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          wch == L'\n')) {
943d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      bRet = false;
944d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
945d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (bRet) {
946d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iCharSize = iFontSize * 500;
947d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      fCharSize = fFontSize / 2.0f;
948d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
949d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    rect.left = fStart;
950d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (bRTLPiece) {
951d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      rect.left -= fCharSize;
952d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      fStart -= fCharSize;
953d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    } else {
954d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      fStart += fCharSize;
955d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
956d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    rect.width = fCharSize;
957d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
958d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (bCharBBox && !bRet) {
959d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      int32_t iCharWidth = 1000;
960d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pFont->GetCharWidth(wch, iCharWidth);
961d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      float fRTLeft = 0, fCharWidth = 0;
962d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (iCharWidth > 0) {
963d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        fCharWidth = iCharWidth * fScale;
964d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        fRTLeft = fLeft;
965d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        if (bCombText)
966d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          fRTLeft = (rect.width - fCharWidth) / 2.0f;
967d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
968d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      CFX_RectF rtBBoxF;
969d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      rtBBoxF.left = rect.left + fRTLeft;
970d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      rtBBoxF.top = rect.top + (rect.height - fHeight) / 2.0f;
971d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      rtBBoxF.width = fCharWidth;
972d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      rtBBoxF.height = fHeight;
973d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      rtBBoxF.top = std::max(rtBBoxF.top, 0.0f);
974d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      rtArray[i] = rtBBoxF;
975d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      continue;
976d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
977d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    rtArray[i] = rect;
978d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
979d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return rtArray;
980d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
981d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
982d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannFX_TXTRUN::FX_TXTRUN()
983d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    : pEdtEngine(nullptr),
984d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pIdentity(nullptr),
985d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pWidths(nullptr),
986d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iLength(0),
987d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pFont(nullptr),
988d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      fFontSize(12),
989d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      dwStyles(0),
990d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iHorizontalScale(100),
991d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      iVerticalScale(100),
992d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      dwCharStyles(0),
993d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pRect(nullptr),
994d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      bSkipSpace(true) {}
995d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
996d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannFX_TXTRUN::~FX_TXTRUN() {}
997d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
998d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannFX_TXTRUN::FX_TXTRUN(const FX_TXTRUN& other) = default;
999