summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2017-08-31 14:26:25 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-08-31 18:46:24 +0000
commit235818f45eda6fd47114c076bfa818b2ef3ba894 (patch)
treed83d4160bc27048fd53778364a2917496855e948
parentf8763bb449273667ef5ff11a0fa491e3e8b46136 (diff)
downloadpdfium-235818f45eda6fd47114c076bfa818b2ef3ba894.tar.xz
Move bidi code to fx_bidi
This CL moves the BIDI code from fx_arabic to fx_bidi and conditionally compiles based on XFA. Change-Id: Iaba60486f03e48f0816d60e365a58a8622bc8254 Reviewed-on: https://pdfium-review.googlesource.com/12713 Commit-Queue: dsinclair <dsinclair@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org>
-rw-r--r--core/fxcrt/fx_arabic.cpp499
-rw-r--r--core/fxcrt/fx_arabic.h1
-rw-r--r--core/fxcrt/fx_bidi.cpp510
-rw-r--r--core/fxcrt/fx_bidi.h8
-rw-r--r--xfa/fgas/layout/cfx_rtfbreak.cpp1
-rw-r--r--xfa/fgas/layout/cfx_txtbreak.cpp1
6 files changed, 521 insertions, 499 deletions
diff --git a/core/fxcrt/fx_arabic.cpp b/core/fxcrt/fx_arabic.cpp
index a4a65e2cad..d9804ba4a9 100644
--- a/core/fxcrt/fx_arabic.cpp
+++ b/core/fxcrt/fx_arabic.cpp
@@ -9,12 +9,10 @@
#include <algorithm>
#include <vector>
-#include "core/fxcrt/fx_extension.h"
+#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/fx_ucd.h"
#include "third_party/base/stl_util.h"
-#define FX_BIDIMAXLEVEL 61
-
namespace {
struct FX_ARBFORMTABLE {
@@ -34,72 +32,6 @@ struct FX_ARASHADDA {
uint16_t wIsolated;
};
-enum FX_BIDIWEAKSTATE {
- FX_BWSxa = 0,
- FX_BWSxr,
- FX_BWSxl,
- FX_BWSao,
- FX_BWSro,
- FX_BWSlo,
- FX_BWSrt,
- FX_BWSlt,
- FX_BWScn,
- FX_BWSra,
- FX_BWSre,
- FX_BWSla,
- FX_BWSle,
- FX_BWSac,
- FX_BWSrc,
- FX_BWSrs,
- FX_BWSlc,
- FX_BWSls,
- FX_BWSret,
- FX_BWSlet
-};
-
-enum FX_BIDIWEAKACTION {
- FX_BWAIX = 0x100,
- FX_BWAXX = 0x0F,
- FX_BWAxxx = (0x0F << 4) + 0x0F,
- FX_BWAxIx = 0x100 + FX_BWAxxx,
- FX_BWAxxN = (0x0F << 4) + FX_BIDICLASS_ON,
- FX_BWAxxE = (0x0F << 4) + FX_BIDICLASS_EN,
- FX_BWAxxA = (0x0F << 4) + FX_BIDICLASS_AN,
- FX_BWAxxR = (0x0F << 4) + FX_BIDICLASS_R,
- FX_BWAxxL = (0x0F << 4) + FX_BIDICLASS_L,
- FX_BWANxx = (FX_BIDICLASS_ON << 4) + 0x0F,
- FX_BWAAxx = (FX_BIDICLASS_AN << 4) + 0x0F,
- FX_BWAExE = (FX_BIDICLASS_EN << 4) + FX_BIDICLASS_EN,
- FX_BWANIx = (FX_BIDICLASS_ON << 4) + 0x0F + 0x100,
- FX_BWANxN = (FX_BIDICLASS_ON << 4) + FX_BIDICLASS_ON,
- FX_BWANxR = (FX_BIDICLASS_ON << 4) + FX_BIDICLASS_R,
- FX_BWANxE = (FX_BIDICLASS_ON << 4) + FX_BIDICLASS_EN,
- FX_BWAAxA = (FX_BIDICLASS_AN << 4) + FX_BIDICLASS_AN,
- FX_BWANxL = (FX_BIDICLASS_ON << 4) + FX_BIDICLASS_L,
- FX_BWALxL = (FX_BIDICLASS_L << 4) + FX_BIDICLASS_L,
- FX_BWAxIL = (0x0F << 4) + FX_BIDICLASS_L + 0x100,
- FX_BWAAxR = (FX_BIDICLASS_AN << 4) + FX_BIDICLASS_R,
- FX_BWALxx = (FX_BIDICLASS_L << 4) + 0x0F,
-};
-
-enum FX_BIDINEUTRALSTATE {
- FX_BNSr = 0,
- FX_BNSl,
- FX_BNSrn,
- FX_BNSln,
- FX_BNSa,
- FX_BNSna
-};
-
-enum FX_BIDINEUTRALACTION {
- FX_BNAnL = FX_BIDICLASS_L,
- FX_BNAEn = (FX_BIDICLASS_AN << 4),
- FX_BNARn = (FX_BIDICLASS_R << 4),
- FX_BNALn = (FX_BIDICLASS_L << 4),
- FX_BNAIn = FX_BWAIX,
- FX_BNALnL = (FX_BIDICLASS_L << 4) + FX_BIDICLASS_L,
-};
-
const FX_ARBFORMTABLE g_FX_ArabicFormTables[] = {
{0xFE81, 0xFE82, 0xFE81, 0xFE82}, {0xFE83, 0xFE84, 0xFE83, 0xFE84},
{0xFE85, 0xFE86, 0xFE85, 0xFE86}, {0xFE87, 0xFE88, 0xFE87, 0xFE88},
@@ -205,122 +137,6 @@ const FX_ARASHADDA gs_FX_ShaddaTable[] = {
{0x064F, 0xFC61}, {0x0650, 0xFC62},
};
-const int32_t gc_FX_BidiNTypes[] = {
- FX_BIDICLASS_N, FX_BIDICLASS_L, FX_BIDICLASS_R, FX_BIDICLASS_AN,
- FX_BIDICLASS_EN, FX_BIDICLASS_AL, FX_BIDICLASS_NSM, FX_BIDICLASS_CS,
- FX_BIDICLASS_ES, FX_BIDICLASS_ET, FX_BIDICLASS_BN, FX_BIDICLASS_BN,
- FX_BIDICLASS_N, FX_BIDICLASS_B, FX_BIDICLASS_RLO, FX_BIDICLASS_RLE,
- FX_BIDICLASS_LRO, FX_BIDICLASS_LRE, FX_BIDICLASS_PDF, FX_BIDICLASS_ON,
-};
-
-const int32_t gc_FX_BidiWeakStates[][10] = {
- {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWSxa,
- FX_BWSao, FX_BWSao, FX_BWSao},
- {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSxr,
- FX_BWSro, FX_BWSro, FX_BWSrt},
- {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSxl,
- FX_BWSlo, FX_BWSlo, FX_BWSlt},
- {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWSao,
- FX_BWSao, FX_BWSao, FX_BWSao},
- {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSro,
- FX_BWSro, FX_BWSro, FX_BWSrt},
- {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlo,
- FX_BWSlo, FX_BWSlo, FX_BWSlt},
- {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSrt,
- FX_BWSro, FX_BWSro, FX_BWSrt},
- {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlt,
- FX_BWSlo, FX_BWSlo, FX_BWSlt},
- {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWScn,
- FX_BWSac, FX_BWSao, FX_BWSao},
- {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSra,
- FX_BWSrc, FX_BWSro, FX_BWSrt},
- {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSre,
- FX_BWSrs, FX_BWSrs, FX_BWSret},
- {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSla,
- FX_BWSlc, FX_BWSlo, FX_BWSlt},
- {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSle,
- FX_BWSls, FX_BWSls, FX_BWSlet},
- {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWSao,
- FX_BWSao, FX_BWSao, FX_BWSao},
- {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSro,
- FX_BWSro, FX_BWSro, FX_BWSrt},
- {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSro,
- FX_BWSro, FX_BWSro, FX_BWSrt},
- {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlo,
- FX_BWSlo, FX_BWSlo, FX_BWSlt},
- {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlo,
- FX_BWSlo, FX_BWSlo, FX_BWSlt},
- {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSret,
- FX_BWSro, FX_BWSro, FX_BWSret},
- {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlet,
- FX_BWSlo, FX_BWSlo, FX_BWSlet},
-};
-
-const int32_t gc_FX_BidiWeakActions[][10] = {
- {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxA, FX_BWAxxR,
- FX_BWAxxR, FX_BWAxxN, FX_BWAxxN, FX_BWAxxN},
- {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
- FX_BWAxxR, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
- {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
- FX_BWAxxL, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
- {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxA, FX_BWAxxR,
- FX_BWAxxN, FX_BWAxxN, FX_BWAxxN, FX_BWAxxN},
- {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
- FX_BWAxxN, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
- {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
- FX_BWAxxN, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
- {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAExE, FX_BWANxR,
- FX_BWAxIx, FX_BWANxN, FX_BWANxN, FX_BWAxIx},
- {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWALxL, FX_BWANxR,
- FX_BWAxIx, FX_BWANxN, FX_BWANxN, FX_BWAxIx},
- {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxA, FX_BWAxxR,
- FX_BWAxxA, FX_BWAxIx, FX_BWAxxN, FX_BWAxxN},
- {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
- FX_BWAxxA, FX_BWAxIx, FX_BWAxxN, FX_BWAxIx},
- {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
- FX_BWAxxE, FX_BWAxIx, FX_BWAxIx, FX_BWAxxE},
- {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
- FX_BWAxxA, FX_BWAxIx, FX_BWAxxN, FX_BWAxIx},
- {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
- FX_BWAxxL, FX_BWAxIx, FX_BWAxIx, FX_BWAxxL},
- {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAAxx, FX_BWAAxA, FX_BWANxR,
- FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANxN},
- {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAAxx, FX_BWANxE, FX_BWANxR,
- FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
- {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAExE, FX_BWANxR,
- FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
- {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAAxx, FX_BWANxL, FX_BWANxR,
- FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
- {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWALxL, FX_BWANxR,
- FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
- {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
- FX_BWAxxE, FX_BWAxxN, FX_BWAxxN, FX_BWAxxE},
- {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
- FX_BWAxxL, FX_BWAxxN, FX_BWAxxN, FX_BWAxxL},
-};
-
-const int32_t gc_FX_BidiNeutralStates[][5] = {
- {FX_BNSrn, FX_BNSl, FX_BNSr, FX_BNSr, FX_BNSr},
- {FX_BNSln, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
- {FX_BNSrn, FX_BNSl, FX_BNSr, FX_BNSr, FX_BNSr},
- {FX_BNSln, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
- {FX_BNSna, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
- {FX_BNSna, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
-};
-const int32_t gc_FX_BidiNeutralActions[][5] = {
- {FX_BNAIn, 0, 0, 0, 0},
- {FX_BNAIn, 0, 0, 0, FX_BIDICLASS_L},
- {FX_BNAIn, FX_BNAEn, FX_BNARn, FX_BNARn, FX_BNARn},
- {FX_BNAIn, FX_BNALn, FX_BNAEn, FX_BNAEn, FX_BNALnL},
- {FX_BNAIn, 0, 0, 0, FX_BIDICLASS_L},
- {FX_BNAIn, FX_BNAEn, FX_BNARn, FX_BNARn, FX_BNAEn},
-};
-
-const int32_t gc_FX_BidiAddLevel[][4] = {
- {0, 1, 2, 2},
- {1, 0, 1, 1},
-};
-
const FX_ARBFORMTABLE* GetArabicFormTable(wchar_t unicode) {
if (unicode < 0x622 || unicode > 0x6d5)
return nullptr;
@@ -355,314 +171,6 @@ wchar_t GetArabicFromAlefTable(wchar_t alef) {
return alef;
}
-class CFX_BidiLine {
- public:
- void BidiLine(std::vector<CFX_Char>* chars, int32_t iCount) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
- if (iCount < 2)
- return;
-
- Classify(chars, iCount, false);
- ResolveExplicit(chars, iCount);
- ResolveWeak(chars, iCount);
- ResolveNeutrals(chars, iCount);
- ResolveImplicit(chars, iCount);
- Classify(chars, iCount, true);
- ResolveWhitespace(chars, iCount);
- Reorder(chars, iCount);
- Position(chars, iCount);
- }
-
- private:
- int32_t Direction(int32_t val) {
- return FX_IsOdd(val) ? FX_BIDICLASS_R : FX_BIDICLASS_L;
- }
-
- int32_t GetDeferredType(int32_t val) { return (val >> 4) & 0x0F; }
-
- int32_t GetResolvedType(int32_t val) { return val & 0x0F; }
-
- int32_t GetDeferredNeutrals(int32_t iAction, int32_t iLevel) {
- iAction = (iAction >> 4) & 0xF;
- if (iAction == (FX_BNAEn >> 4))
- return Direction(iLevel);
- return iAction;
- }
-
- int32_t GetResolvedNeutrals(int32_t iAction) {
- iAction &= 0xF;
- return iAction == FX_BNAIn ? 0 : iAction;
- }
-
- void ReverseString(std::vector<CFX_Char>* chars,
- int32_t iStart,
- int32_t iCount) {
- ASSERT(pdfium::IndexInBounds(*chars, iStart));
- ASSERT(iCount >= 0 &&
- iStart + iCount <= pdfium::CollectionSize<int32_t>(*chars));
- std::reverse(chars->begin() + iStart, chars->begin() + iStart + iCount);
- }
-
- void SetDeferredRun(std::vector<CFX_Char>* chars,
- bool bClass,
- int32_t iStart,
- int32_t iCount,
- int32_t iValue) {
- ASSERT(iStart >= 0 && iStart <= pdfium::CollectionSize<int32_t>(*chars));
- ASSERT(iStart - iCount > -1);
- int32_t iLast = iStart - iCount;
- if (bClass) {
- for (int32_t i = iStart - 1; i >= iLast; i--)
- (*chars)[i].m_iBidiClass = static_cast<int16_t>(iValue);
- return;
- }
-
- for (int32_t i = iStart - 1; i >= iLast; i--)
- (*chars)[i].m_iBidiLevel = static_cast<int16_t>(iValue);
- }
-
- void Classify(std::vector<CFX_Char>* chars, int32_t iCount, bool bWS) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
- if (bWS) {
- for (int32_t i = 0; i < iCount; i++) {
- CFX_Char& cur = (*chars)[i];
- cur.m_iBidiClass =
- static_cast<int16_t>(cur.char_props() & FX_BIDICLASSBITSMASK) >>
- FX_BIDICLASSBITS;
- }
- return;
- }
-
- for (int32_t i = 0; i < iCount; i++) {
- CFX_Char& cur = (*chars)[i];
- cur.m_iBidiClass = static_cast<int16_t>(
- gc_FX_BidiNTypes[(cur.char_props() & FX_BIDICLASSBITSMASK) >>
- FX_BIDICLASSBITS]);
- }
- }
-
- void ResolveExplicit(std::vector<CFX_Char>* chars, int32_t iCount) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
- for (int32_t i = 0; i < iCount; i++)
- (*chars)[i].m_iBidiLevel = 0;
- }
-
- void ResolveWeak(std::vector<CFX_Char>* chars, int32_t iCount) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
- iCount--;
- if (iCount < 1)
- return;
-
- int32_t iLevelCur = 0;
- int32_t iState = FX_BWSxl;
- int32_t i = 0;
- int32_t iNum = 0;
- int32_t iClsCur;
- int32_t iClsRun;
- int32_t iClsNew;
- int32_t iAction;
- for (; i <= iCount; i++) {
- CFX_Char* pTC = &(*chars)[i];
- iClsCur = pTC->m_iBidiClass;
- if (iClsCur == FX_BIDICLASS_BN) {
- pTC->m_iBidiLevel = (int16_t)iLevelCur;
- if (i == iCount && iLevelCur != 0) {
- iClsCur = Direction(iLevelCur);
- pTC->m_iBidiClass = (int16_t)iClsCur;
- } else if (i < iCount) {
- CFX_Char* pTCNext = &(*chars)[i + 1];
- int32_t iLevelNext, iLevelNew;
- iClsNew = pTCNext->m_iBidiClass;
- iLevelNext = pTCNext->m_iBidiLevel;
- if (iClsNew != FX_BIDICLASS_BN && iLevelCur != iLevelNext) {
- iLevelNew = std::max(iLevelNext, iLevelCur);
- pTC->m_iBidiLevel = static_cast<int16_t>(iLevelNew);
- iClsCur = Direction(iLevelNew);
- pTC->m_iBidiClass = static_cast<int16_t>(iClsCur);
- iLevelCur = iLevelNext;
- } else {
- if (iNum > 0)
- iNum++;
- continue;
- }
- } else {
- if (iNum > 0)
- iNum++;
- continue;
- }
- }
-
- ASSERT(iClsCur <= FX_BIDICLASS_BN);
- iAction = gc_FX_BidiWeakActions[iState][iClsCur];
- iClsRun = GetDeferredType(iAction);
- if (iClsRun != FX_BWAXX && iNum > 0) {
- SetDeferredRun(chars, true, i, iNum, iClsRun);
- iNum = 0;
- }
- iClsNew = GetResolvedType(iAction);
- if (iClsNew != FX_BWAXX)
- pTC->m_iBidiClass = static_cast<int16_t>(iClsNew);
- if (FX_BWAIX & iAction)
- iNum++;
-
- iState = gc_FX_BidiWeakStates[iState][iClsCur];
- }
- if (iNum > 0) {
- iClsCur = Direction(0);
- iClsRun = GetDeferredType(gc_FX_BidiWeakActions[iState][iClsCur]);
- if (iClsRun != FX_BWAXX)
- SetDeferredRun(chars, true, i, iNum, iClsRun);
- }
- }
-
- void ResolveNeutrals(std::vector<CFX_Char>* chars, int32_t iCount) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
- iCount--;
- if (iCount < 1)
- return;
-
- CFX_Char* pTC;
- int32_t iLevel = 0;
- int32_t iState = FX_BNSl;
- int32_t i = 0;
- int32_t iNum = 0;
- int32_t iClsCur;
- int32_t iClsRun;
- int32_t iClsNew;
- int32_t iAction;
- for (; i <= iCount; i++) {
- pTC = &(*chars)[i];
- iClsCur = pTC->m_iBidiClass;
- if (iClsCur == FX_BIDICLASS_BN) {
- if (iNum)
- iNum++;
- continue;
- }
-
- ASSERT(iClsCur < FX_BIDICLASS_AL);
- iAction = gc_FX_BidiNeutralActions[iState][iClsCur];
- iClsRun = GetDeferredNeutrals(iAction, iLevel);
- if (iClsRun != FX_BIDICLASS_N && iNum > 0) {
- SetDeferredRun(chars, true, i, iNum, iClsRun);
- iNum = 0;
- }
-
- iClsNew = GetResolvedNeutrals(iAction);
- if (iClsNew != FX_BIDICLASS_N)
- pTC->m_iBidiClass = (int16_t)iClsNew;
- if (FX_BNAIn & iAction)
- iNum++;
-
- iState = gc_FX_BidiNeutralStates[iState][iClsCur];
- iLevel = pTC->m_iBidiLevel;
- }
- if (iNum > 0) {
- iClsCur = Direction(iLevel);
- iClsRun = GetDeferredNeutrals(gc_FX_BidiNeutralActions[iState][iClsCur],
- iLevel);
- if (iClsRun != FX_BIDICLASS_N)
- SetDeferredRun(chars, true, i, iNum, iClsRun);
- }
- }
-
- void ResolveImplicit(std::vector<CFX_Char>* chars, int32_t iCount) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
- for (int32_t i = 0; i < iCount; i++) {
- int32_t iCls = (*chars)[i].m_iBidiClass;
- if (iCls == FX_BIDICLASS_BN)
- continue;
-
- ASSERT(iCls > FX_BIDICLASS_ON && iCls < FX_BIDICLASS_AL);
- int32_t iLevel = (*chars)[i].m_iBidiLevel;
- iLevel += gc_FX_BidiAddLevel[FX_IsOdd(iLevel)][iCls - 1];
- (*chars)[i].m_iBidiLevel = (int16_t)iLevel;
- }
- }
-
- void ResolveWhitespace(std::vector<CFX_Char>* chars, int32_t iCount) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
- if (iCount < 1)
- return;
-
- iCount--;
- int32_t iLevel = 0;
- int32_t i = 0;
- int32_t iNum = 0;
- for (; i <= iCount; i++) {
- switch ((*chars)[i].m_iBidiClass) {
- case FX_BIDICLASS_WS:
- iNum++;
- break;
- case FX_BIDICLASS_RLE:
- case FX_BIDICLASS_LRE:
- case FX_BIDICLASS_LRO:
- case FX_BIDICLASS_RLO:
- case FX_BIDICLASS_PDF:
- case FX_BIDICLASS_BN:
- (*chars)[i].m_iBidiLevel = (int16_t)iLevel;
- iNum++;
- break;
- case FX_BIDICLASS_S:
- case FX_BIDICLASS_B:
- if (iNum > 0)
- SetDeferredRun(chars, false, i, iNum, 0);
-
- (*chars)[i].m_iBidiLevel = 0;
- iNum = 0;
- break;
- default:
- iNum = 0;
- break;
- }
- iLevel = (*chars)[i].m_iBidiLevel;
- }
- if (iNum > 0)
- SetDeferredRun(chars, false, i, iNum, 0);
- }
-
- int32_t ReorderLevel(std::vector<CFX_Char>* chars,
- int32_t iCount,
- int32_t iBaseLevel,
- int32_t iStart,
- bool bReverse) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
- ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
- ASSERT(iStart >= 0 && iStart < iCount);
-
- if (iCount < 1)
- return 0;
-
- bReverse = bReverse || FX_IsOdd(iBaseLevel);
- int32_t i = iStart;
- for (; i < iCount; i++) {
- int32_t iLevel = (*chars)[i].m_iBidiLevel;
- if (iLevel == iBaseLevel)
- continue;
- if (iLevel < iBaseLevel)
- break;
- i += ReorderLevel(chars, iCount, iBaseLevel + 1, i, bReverse) - 1;
- }
- int32_t iNum = i - iStart;
- if (bReverse && iNum > 1)
- ReverseString(chars, iStart, iNum);
-
- return iNum;
- }
-
- void Reorder(std::vector<CFX_Char>* chars, int32_t iCount) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
- int32_t i = 0;
- while (i < iCount)
- i += ReorderLevel(chars, iCount, 0, i, false);
- }
-
- void Position(std::vector<CFX_Char>* chars, int32_t iCount) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
- for (int32_t i = 0; i < iCount; ++i)
- (*chars)[(*chars)[i].m_iBidiPos].m_iBidiOrder = i;
- }
-};
-
} // namespace
namespace pdfium {
@@ -722,8 +230,3 @@ wchar_t FX_GetArabicFromShaddaTable(wchar_t shadda) {
}
return shadda;
}
-
-void FX_BidiLine(std::vector<CFX_Char>* chars, int32_t iCount) {
- CFX_BidiLine blt;
- blt.BidiLine(chars, iCount);
-}
diff --git a/core/fxcrt/fx_arabic.h b/core/fxcrt/fx_arabic.h
index 32021c358f..9d23b1557d 100644
--- a/core/fxcrt/fx_arabic.h
+++ b/core/fxcrt/fx_arabic.h
@@ -24,6 +24,5 @@ wchar_t GetFormChar(const CFX_Char* cur,
} // namespace pdfium
wchar_t FX_GetArabicFromShaddaTable(wchar_t shadda);
-void FX_BidiLine(std::vector<CFX_Char>* chars, int32_t iCount);
#endif // CORE_FXCRT_FX_ARABIC_H_
diff --git a/core/fxcrt/fx_bidi.cpp b/core/fxcrt/fx_bidi.cpp
index 25544546d3..8b20cfbf46 100644
--- a/core/fxcrt/fx_bidi.cpp
+++ b/core/fxcrt/fx_bidi.cpp
@@ -11,6 +11,509 @@
#include "core/fxcrt/fx_ucd.h"
#include "third_party/base/ptr_util.h"
+#ifdef PDF_ENABLE_XFA
+#include "core/fxcrt/fx_extension.h"
+
+namespace {
+
+#ifndef NDEBUG
+constexpr int32_t kBidiMaxLevel = 61;
+#endif // NDEBUG
+
+enum FX_BIDIWEAKSTATE {
+ FX_BWSxa = 0,
+ FX_BWSxr,
+ FX_BWSxl,
+ FX_BWSao,
+ FX_BWSro,
+ FX_BWSlo,
+ FX_BWSrt,
+ FX_BWSlt,
+ FX_BWScn,
+ FX_BWSra,
+ FX_BWSre,
+ FX_BWSla,
+ FX_BWSle,
+ FX_BWSac,
+ FX_BWSrc,
+ FX_BWSrs,
+ FX_BWSlc,
+ FX_BWSls,
+ FX_BWSret,
+ FX_BWSlet
+};
+
+enum FX_BIDIWEAKACTION {
+ FX_BWAIX = 0x100,
+ FX_BWAXX = 0x0F,
+ FX_BWAxxx = (0x0F << 4) + 0x0F,
+ FX_BWAxIx = 0x100 + FX_BWAxxx,
+ FX_BWAxxN = (0x0F << 4) + FX_BIDICLASS_ON,
+ FX_BWAxxE = (0x0F << 4) + FX_BIDICLASS_EN,
+ FX_BWAxxA = (0x0F << 4) + FX_BIDICLASS_AN,
+ FX_BWAxxR = (0x0F << 4) + FX_BIDICLASS_R,
+ FX_BWAxxL = (0x0F << 4) + FX_BIDICLASS_L,
+ FX_BWANxx = (FX_BIDICLASS_ON << 4) + 0x0F,
+ FX_BWAAxx = (FX_BIDICLASS_AN << 4) + 0x0F,
+ FX_BWAExE = (FX_BIDICLASS_EN << 4) + FX_BIDICLASS_EN,
+ FX_BWANIx = (FX_BIDICLASS_ON << 4) + 0x0F + 0x100,
+ FX_BWANxN = (FX_BIDICLASS_ON << 4) + FX_BIDICLASS_ON,
+ FX_BWANxR = (FX_BIDICLASS_ON << 4) + FX_BIDICLASS_R,
+ FX_BWANxE = (FX_BIDICLASS_ON << 4) + FX_BIDICLASS_EN,
+ FX_BWAAxA = (FX_BIDICLASS_AN << 4) + FX_BIDICLASS_AN,
+ FX_BWANxL = (FX_BIDICLASS_ON << 4) + FX_BIDICLASS_L,
+ FX_BWALxL = (FX_BIDICLASS_L << 4) + FX_BIDICLASS_L,
+ FX_BWAxIL = (0x0F << 4) + FX_BIDICLASS_L + 0x100,
+ FX_BWAAxR = (FX_BIDICLASS_AN << 4) + FX_BIDICLASS_R,
+ FX_BWALxx = (FX_BIDICLASS_L << 4) + 0x0F,
+};
+
+enum FX_BIDINEUTRALSTATE {
+ FX_BNSr = 0,
+ FX_BNSl,
+ FX_BNSrn,
+ FX_BNSln,
+ FX_BNSa,
+ FX_BNSna
+};
+
+enum FX_BIDINEUTRALACTION {
+ FX_BNAnL = FX_BIDICLASS_L,
+ FX_BNAEn = (FX_BIDICLASS_AN << 4),
+ FX_BNARn = (FX_BIDICLASS_R << 4),
+ FX_BNALn = (FX_BIDICLASS_L << 4),
+ FX_BNAIn = FX_BWAIX,
+ FX_BNALnL = (FX_BIDICLASS_L << 4) + FX_BIDICLASS_L,
+};
+
+const int32_t gc_FX_BidiNTypes[] = {
+ FX_BIDICLASS_N, FX_BIDICLASS_L, FX_BIDICLASS_R, FX_BIDICLASS_AN,
+ FX_BIDICLASS_EN, FX_BIDICLASS_AL, FX_BIDICLASS_NSM, FX_BIDICLASS_CS,
+ FX_BIDICLASS_ES, FX_BIDICLASS_ET, FX_BIDICLASS_BN, FX_BIDICLASS_BN,
+ FX_BIDICLASS_N, FX_BIDICLASS_B, FX_BIDICLASS_RLO, FX_BIDICLASS_RLE,
+ FX_BIDICLASS_LRO, FX_BIDICLASS_LRE, FX_BIDICLASS_PDF, FX_BIDICLASS_ON,
+};
+
+const int32_t gc_FX_BidiWeakStates[][10] = {
+ {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWSxa,
+ FX_BWSao, FX_BWSao, FX_BWSao},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSxr,
+ FX_BWSro, FX_BWSro, FX_BWSrt},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSxl,
+ FX_BWSlo, FX_BWSlo, FX_BWSlt},
+ {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWSao,
+ FX_BWSao, FX_BWSao, FX_BWSao},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSro,
+ FX_BWSro, FX_BWSro, FX_BWSrt},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlo,
+ FX_BWSlo, FX_BWSlo, FX_BWSlt},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSrt,
+ FX_BWSro, FX_BWSro, FX_BWSrt},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlt,
+ FX_BWSlo, FX_BWSlo, FX_BWSlt},
+ {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWScn,
+ FX_BWSac, FX_BWSao, FX_BWSao},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSra,
+ FX_BWSrc, FX_BWSro, FX_BWSrt},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSre,
+ FX_BWSrs, FX_BWSrs, FX_BWSret},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSla,
+ FX_BWSlc, FX_BWSlo, FX_BWSlt},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSle,
+ FX_BWSls, FX_BWSls, FX_BWSlet},
+ {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWSao,
+ FX_BWSao, FX_BWSao, FX_BWSao},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSro,
+ FX_BWSro, FX_BWSro, FX_BWSrt},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSro,
+ FX_BWSro, FX_BWSro, FX_BWSrt},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlo,
+ FX_BWSlo, FX_BWSlo, FX_BWSlt},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlo,
+ FX_BWSlo, FX_BWSlo, FX_BWSlt},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSret,
+ FX_BWSro, FX_BWSro, FX_BWSret},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlet,
+ FX_BWSlo, FX_BWSlo, FX_BWSlet},
+};
+
+const int32_t gc_FX_BidiWeakActions[][10] = {
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxA, FX_BWAxxR,
+ FX_BWAxxR, FX_BWAxxN, FX_BWAxxN, FX_BWAxxN},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
+ FX_BWAxxR, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
+ FX_BWAxxL, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxA, FX_BWAxxR,
+ FX_BWAxxN, FX_BWAxxN, FX_BWAxxN, FX_BWAxxN},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
+ FX_BWAxxN, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
+ FX_BWAxxN, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAExE, FX_BWANxR,
+ FX_BWAxIx, FX_BWANxN, FX_BWANxN, FX_BWAxIx},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWALxL, FX_BWANxR,
+ FX_BWAxIx, FX_BWANxN, FX_BWANxN, FX_BWAxIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxA, FX_BWAxxR,
+ FX_BWAxxA, FX_BWAxIx, FX_BWAxxN, FX_BWAxxN},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
+ FX_BWAxxA, FX_BWAxIx, FX_BWAxxN, FX_BWAxIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
+ FX_BWAxxE, FX_BWAxIx, FX_BWAxIx, FX_BWAxxE},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
+ FX_BWAxxA, FX_BWAxIx, FX_BWAxxN, FX_BWAxIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
+ FX_BWAxxL, FX_BWAxIx, FX_BWAxIx, FX_BWAxxL},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAAxx, FX_BWAAxA, FX_BWANxR,
+ FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANxN},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAAxx, FX_BWANxE, FX_BWANxR,
+ FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAExE, FX_BWANxR,
+ FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAAxx, FX_BWANxL, FX_BWANxR,
+ FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWALxL, FX_BWANxR,
+ FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
+ FX_BWAxxE, FX_BWAxxN, FX_BWAxxN, FX_BWAxxE},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
+ FX_BWAxxL, FX_BWAxxN, FX_BWAxxN, FX_BWAxxL},
+};
+
+const int32_t gc_FX_BidiNeutralStates[][5] = {
+ {FX_BNSrn, FX_BNSl, FX_BNSr, FX_BNSr, FX_BNSr},
+ {FX_BNSln, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
+ {FX_BNSrn, FX_BNSl, FX_BNSr, FX_BNSr, FX_BNSr},
+ {FX_BNSln, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
+ {FX_BNSna, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
+ {FX_BNSna, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
+};
+const int32_t gc_FX_BidiNeutralActions[][5] = {
+ {FX_BNAIn, 0, 0, 0, 0},
+ {FX_BNAIn, 0, 0, 0, FX_BIDICLASS_L},
+ {FX_BNAIn, FX_BNAEn, FX_BNARn, FX_BNARn, FX_BNARn},
+ {FX_BNAIn, FX_BNALn, FX_BNAEn, FX_BNAEn, FX_BNALnL},
+ {FX_BNAIn, 0, 0, 0, FX_BIDICLASS_L},
+ {FX_BNAIn, FX_BNAEn, FX_BNARn, FX_BNARn, FX_BNAEn},
+};
+
+const int32_t gc_FX_BidiAddLevel[][4] = {
+ {0, 1, 2, 2},
+ {1, 0, 1, 1},
+};
+
+class CFX_BidiLine {
+ public:
+ void BidiLine(std::vector<CFX_Char>* chars, int32_t iCount) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
+ if (iCount < 2)
+ return;
+
+ Classify(chars, iCount, false);
+ ResolveExplicit(chars, iCount);
+ ResolveWeak(chars, iCount);
+ ResolveNeutrals(chars, iCount);
+ ResolveImplicit(chars, iCount);
+ Classify(chars, iCount, true);
+ ResolveWhitespace(chars, iCount);
+ Reorder(chars, iCount);
+ Position(chars, iCount);
+ }
+
+ private:
+ int32_t Direction(int32_t val) {
+ return FX_IsOdd(val) ? FX_BIDICLASS_R : FX_BIDICLASS_L;
+ }
+
+ int32_t GetDeferredType(int32_t val) { return (val >> 4) & 0x0F; }
+
+ int32_t GetResolvedType(int32_t val) { return val & 0x0F; }
+
+ int32_t GetDeferredNeutrals(int32_t iAction, int32_t iLevel) {
+ iAction = (iAction >> 4) & 0xF;
+ if (iAction == (FX_BNAEn >> 4))
+ return Direction(iLevel);
+ return iAction;
+ }
+
+ int32_t GetResolvedNeutrals(int32_t iAction) {
+ iAction &= 0xF;
+ return iAction == FX_BNAIn ? 0 : iAction;
+ }
+
+ void ReverseString(std::vector<CFX_Char>* chars,
+ int32_t iStart,
+ int32_t iCount) {
+ ASSERT(pdfium::IndexInBounds(*chars, iStart));
+ ASSERT(iCount >= 0 &&
+ iStart + iCount <= pdfium::CollectionSize<int32_t>(*chars));
+ std::reverse(chars->begin() + iStart, chars->begin() + iStart + iCount);
+ }
+
+ void SetDeferredRun(std::vector<CFX_Char>* chars,
+ bool bClass,
+ int32_t iStart,
+ int32_t iCount,
+ int32_t iValue) {
+ ASSERT(iStart >= 0 && iStart <= pdfium::CollectionSize<int32_t>(*chars));
+ ASSERT(iStart - iCount > -1);
+ int32_t iLast = iStart - iCount;
+ if (bClass) {
+ for (int32_t i = iStart - 1; i >= iLast; i--)
+ (*chars)[i].m_iBidiClass = static_cast<int16_t>(iValue);
+ return;
+ }
+
+ for (int32_t i = iStart - 1; i >= iLast; i--)
+ (*chars)[i].m_iBidiLevel = static_cast<int16_t>(iValue);
+ }
+
+ void Classify(std::vector<CFX_Char>* chars, int32_t iCount, bool bWS) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
+ if (bWS) {
+ for (int32_t i = 0; i < iCount; i++) {
+ CFX_Char& cur = (*chars)[i];
+ cur.m_iBidiClass =
+ static_cast<int16_t>(cur.char_props() & FX_BIDICLASSBITSMASK) >>
+ FX_BIDICLASSBITS;
+ }
+ return;
+ }
+
+ for (int32_t i = 0; i < iCount; i++) {
+ CFX_Char& cur = (*chars)[i];
+ cur.m_iBidiClass = static_cast<int16_t>(
+ gc_FX_BidiNTypes[(cur.char_props() & FX_BIDICLASSBITSMASK) >>
+ FX_BIDICLASSBITS]);
+ }
+ }
+
+ void ResolveExplicit(std::vector<CFX_Char>* chars, int32_t iCount) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
+ for (int32_t i = 0; i < iCount; i++)
+ (*chars)[i].m_iBidiLevel = 0;
+ }
+
+ void ResolveWeak(std::vector<CFX_Char>* chars, int32_t iCount) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
+ iCount--;
+ if (iCount < 1)
+ return;
+
+ int32_t iLevelCur = 0;
+ int32_t iState = FX_BWSxl;
+ int32_t i = 0;
+ int32_t iNum = 0;
+ int32_t iClsCur;
+ int32_t iClsRun;
+ int32_t iClsNew;
+ int32_t iAction;
+ for (; i <= iCount; i++) {
+ CFX_Char* pTC = &(*chars)[i];
+ iClsCur = pTC->m_iBidiClass;
+ if (iClsCur == FX_BIDICLASS_BN) {
+ pTC->m_iBidiLevel = (int16_t)iLevelCur;
+ if (i == iCount && iLevelCur != 0) {
+ iClsCur = Direction(iLevelCur);
+ pTC->m_iBidiClass = (int16_t)iClsCur;
+ } else if (i < iCount) {
+ CFX_Char* pTCNext = &(*chars)[i + 1];
+ int32_t iLevelNext, iLevelNew;
+ iClsNew = pTCNext->m_iBidiClass;
+ iLevelNext = pTCNext->m_iBidiLevel;
+ if (iClsNew != FX_BIDICLASS_BN && iLevelCur != iLevelNext) {
+ iLevelNew = std::max(iLevelNext, iLevelCur);
+ pTC->m_iBidiLevel = static_cast<int16_t>(iLevelNew);
+ iClsCur = Direction(iLevelNew);
+ pTC->m_iBidiClass = static_cast<int16_t>(iClsCur);
+ iLevelCur = iLevelNext;
+ } else {
+ if (iNum > 0)
+ iNum++;
+ continue;
+ }
+ } else {
+ if (iNum > 0)
+ iNum++;
+ continue;
+ }
+ }
+
+ ASSERT(iClsCur <= FX_BIDICLASS_BN);
+ iAction = gc_FX_BidiWeakActions[iState][iClsCur];
+ iClsRun = GetDeferredType(iAction);
+ if (iClsRun != FX_BWAXX && iNum > 0) {
+ SetDeferredRun(chars, true, i, iNum, iClsRun);
+ iNum = 0;
+ }
+ iClsNew = GetResolvedType(iAction);
+ if (iClsNew != FX_BWAXX)
+ pTC->m_iBidiClass = static_cast<int16_t>(iClsNew);
+ if (FX_BWAIX & iAction)
+ iNum++;
+
+ iState = gc_FX_BidiWeakStates[iState][iClsCur];
+ }
+ if (iNum > 0) {
+ iClsCur = Direction(0);
+ iClsRun = GetDeferredType(gc_FX_BidiWeakActions[iState][iClsCur]);
+ if (iClsRun != FX_BWAXX)
+ SetDeferredRun(chars, true, i, iNum, iClsRun);
+ }
+ }
+
+ void ResolveNeutrals(std::vector<CFX_Char>* chars, int32_t iCount) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
+ iCount--;
+ if (iCount < 1)
+ return;
+
+ CFX_Char* pTC;
+ int32_t iLevel = 0;
+ int32_t iState = FX_BNSl;
+ int32_t i = 0;
+ int32_t iNum = 0;
+ int32_t iClsCur;
+ int32_t iClsRun;
+ int32_t iClsNew;
+ int32_t iAction;
+ for (; i <= iCount; i++) {
+ pTC = &(*chars)[i];
+ iClsCur = pTC->m_iBidiClass;
+ if (iClsCur == FX_BIDICLASS_BN) {
+ if (iNum)
+ iNum++;
+ continue;
+ }
+
+ ASSERT(iClsCur < FX_BIDICLASS_AL);
+ iAction = gc_FX_BidiNeutralActions[iState][iClsCur];
+ iClsRun = GetDeferredNeutrals(iAction, iLevel);
+ if (iClsRun != FX_BIDICLASS_N && iNum > 0) {
+ SetDeferredRun(chars, true, i, iNum, iClsRun);
+ iNum = 0;
+ }
+
+ iClsNew = GetResolvedNeutrals(iAction);
+ if (iClsNew != FX_BIDICLASS_N)
+ pTC->m_iBidiClass = (int16_t)iClsNew;
+ if (FX_BNAIn & iAction)
+ iNum++;
+
+ iState = gc_FX_BidiNeutralStates[iState][iClsCur];
+ iLevel = pTC->m_iBidiLevel;
+ }
+ if (iNum > 0) {
+ iClsCur = Direction(iLevel);
+ iClsRun = GetDeferredNeutrals(gc_FX_BidiNeutralActions[iState][iClsCur],
+ iLevel);
+ if (iClsRun != FX_BIDICLASS_N)
+ SetDeferredRun(chars, true, i, iNum, iClsRun);
+ }
+ }
+
+ void ResolveImplicit(std::vector<CFX_Char>* chars, int32_t iCount) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
+ for (int32_t i = 0; i < iCount; i++) {
+ int32_t iCls = (*chars)[i].m_iBidiClass;
+ if (iCls == FX_BIDICLASS_BN)
+ continue;
+
+ ASSERT(iCls > FX_BIDICLASS_ON && iCls < FX_BIDICLASS_AL);
+ int32_t iLevel = (*chars)[i].m_iBidiLevel;
+ iLevel += gc_FX_BidiAddLevel[FX_IsOdd(iLevel)][iCls - 1];
+ (*chars)[i].m_iBidiLevel = (int16_t)iLevel;
+ }
+ }
+
+ void ResolveWhitespace(std::vector<CFX_Char>* chars, int32_t iCount) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
+ if (iCount < 1)
+ return;
+
+ iCount--;
+ int32_t iLevel = 0;
+ int32_t i = 0;
+ int32_t iNum = 0;
+ for (; i <= iCount; i++) {
+ switch ((*chars)[i].m_iBidiClass) {
+ case FX_BIDICLASS_WS:
+ iNum++;
+ break;
+ case FX_BIDICLASS_RLE:
+ case FX_BIDICLASS_LRE:
+ case FX_BIDICLASS_LRO:
+ case FX_BIDICLASS_RLO:
+ case FX_BIDICLASS_PDF:
+ case FX_BIDICLASS_BN:
+ (*chars)[i].m_iBidiLevel = (int16_t)iLevel;
+ iNum++;
+ break;
+ case FX_BIDICLASS_S:
+ case FX_BIDICLASS_B:
+ if (iNum > 0)
+ SetDeferredRun(chars, false, i, iNum, 0);
+
+ (*chars)[i].m_iBidiLevel = 0;
+ iNum = 0;
+ break;
+ default:
+ iNum = 0;
+ break;
+ }
+ iLevel = (*chars)[i].m_iBidiLevel;
+ }
+ if (iNum > 0)
+ SetDeferredRun(chars, false, i, iNum, 0);
+ }
+
+ int32_t ReorderLevel(std::vector<CFX_Char>* chars,
+ int32_t iCount,
+ int32_t iBaseLevel,
+ int32_t iStart,
+ bool bReverse) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
+ ASSERT(iBaseLevel >= 0 && iBaseLevel <= kBidiMaxLevel);
+ ASSERT(iStart >= 0 && iStart < iCount);
+
+ if (iCount < 1)
+ return 0;
+
+ bReverse = bReverse || FX_IsOdd(iBaseLevel);
+ int32_t i = iStart;
+ for (; i < iCount; i++) {
+ int32_t iLevel = (*chars)[i].m_iBidiLevel;
+ if (iLevel == iBaseLevel)
+ continue;
+ if (iLevel < iBaseLevel)
+ break;
+ i += ReorderLevel(chars, iCount, iBaseLevel + 1, i, bReverse) - 1;
+ }
+ int32_t iNum = i - iStart;
+ if (bReverse && iNum > 1)
+ ReverseString(chars, iStart, iNum);
+
+ return iNum;
+ }
+
+ void Reorder(std::vector<CFX_Char>* chars, int32_t iCount) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
+ int32_t i = 0;
+ while (i < iCount)
+ i += ReorderLevel(chars, iCount, 0, i, false);
+ }
+
+ void Position(std::vector<CFX_Char>* chars, int32_t iCount) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
+ for (int32_t i = 0; i < iCount; ++i)
+ (*chars)[(*chars)[i].m_iBidiPos].m_iBidiOrder = i;
+ }
+};
+
+} // namespace
+
+#endif // PDF_ENABLE_XFA
+
CFX_BidiChar::CFX_BidiChar()
: m_CurrentSegment({0, 0, NEUTRAL}), m_LastSegment({0, 0, NEUTRAL}) {}
@@ -83,3 +586,10 @@ void CFX_BidiString::SetOverallDirectionRight() {
m_eOverallDirection = CFX_BidiChar::RIGHT;
}
}
+
+#ifdef PDF_ENABLE_XFA
+void FX_BidiLine(std::vector<CFX_Char>* chars, int32_t iCount) {
+ CFX_BidiLine blt;
+ blt.BidiLine(chars, iCount);
+}
+#endif // PDF_ENABLE_XFA
diff --git a/core/fxcrt/fx_bidi.h b/core/fxcrt/fx_bidi.h
index d5e0bd3f62..0dc426b57a 100644
--- a/core/fxcrt/fx_bidi.h
+++ b/core/fxcrt/fx_bidi.h
@@ -13,6 +13,10 @@
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/fx_system.h"
+#ifdef PDF_ENABLE_XFA
+#include "core/fxcrt/cfx_char.h"
+#endif // PDF_ENABLE_XFA
+
// Processes characters and group them into segments based on text direction.
class CFX_BidiChar {
public:
@@ -72,4 +76,8 @@ class CFX_BidiString {
CFX_BidiChar::Direction m_eOverallDirection;
};
+#if PDF_ENABLE_XFA
+void FX_BidiLine(std::vector<CFX_Char>* chars, int32_t iCount);
+#endif // PDF_ENABLE_XFA
+
#endif // CORE_FXCRT_FX_BIDI_H_
diff --git a/xfa/fgas/layout/cfx_rtfbreak.cpp b/xfa/fgas/layout/cfx_rtfbreak.cpp
index 45acae5bc4..a097361d95 100644
--- a/xfa/fgas/layout/cfx_rtfbreak.cpp
+++ b/xfa/fgas/layout/cfx_rtfbreak.cpp
@@ -9,6 +9,7 @@
#include <algorithm>
#include "core/fxcrt/fx_arabic.h"
+#include "core/fxcrt/fx_bidi.h"
#include "third_party/base/stl_util.h"
#include "xfa/fgas/font/cfgas_gefont.h"
#include "xfa/fgas/layout/cfx_linebreak.h"
diff --git a/xfa/fgas/layout/cfx_txtbreak.cpp b/xfa/fgas/layout/cfx_txtbreak.cpp
index 42365af127..3ba7640904 100644
--- a/xfa/fgas/layout/cfx_txtbreak.cpp
+++ b/xfa/fgas/layout/cfx_txtbreak.cpp
@@ -9,6 +9,7 @@
#include <algorithm>
#include "core/fxcrt/fx_arabic.h"
+#include "core/fxcrt/fx_bidi.h"
#include "core/fxcrt/fx_memory.h"
#include "third_party/base/ptr_util.h"
#include "xfa/fde/cfde_texteditengine.h"