From 235818f45eda6fd47114c076bfa818b2ef3ba894 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Thu, 31 Aug 2017 14:26:25 -0400 Subject: 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 Reviewed-by: Tom Sepez --- core/fxcrt/fx_arabic.cpp | 499 +------------------------------------- core/fxcrt/fx_arabic.h | 1 - core/fxcrt/fx_bidi.cpp | 510 +++++++++++++++++++++++++++++++++++++++ core/fxcrt/fx_bidi.h | 8 + xfa/fgas/layout/cfx_rtfbreak.cpp | 1 + xfa/fgas/layout/cfx_txtbreak.cpp | 1 + 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 #include -#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* chars, int32_t iCount) { - ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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* chars, - int32_t iStart, - int32_t iCount) { - ASSERT(pdfium::IndexInBounds(*chars, iStart)); - ASSERT(iCount >= 0 && - iStart + iCount <= pdfium::CollectionSize(*chars)); - std::reverse(chars->begin() + iStart, chars->begin() + iStart + iCount); - } - - void SetDeferredRun(std::vector* chars, - bool bClass, - int32_t iStart, - int32_t iCount, - int32_t iValue) { - ASSERT(iStart >= 0 && iStart <= pdfium::CollectionSize(*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(iValue); - return; - } - - for (int32_t i = iStart - 1; i >= iLast; i--) - (*chars)[i].m_iBidiLevel = static_cast(iValue); - } - - void Classify(std::vector* chars, int32_t iCount, bool bWS) { - ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*chars)); - if (bWS) { - for (int32_t i = 0; i < iCount; i++) { - CFX_Char& cur = (*chars)[i]; - cur.m_iBidiClass = - static_cast(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( - gc_FX_BidiNTypes[(cur.char_props() & FX_BIDICLASSBITSMASK) >> - FX_BIDICLASSBITS]); - } - } - - void ResolveExplicit(std::vector* chars, int32_t iCount) { - ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*chars)); - for (int32_t i = 0; i < iCount; i++) - (*chars)[i].m_iBidiLevel = 0; - } - - void ResolveWeak(std::vector* chars, int32_t iCount) { - ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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(iLevelNew); - iClsCur = Direction(iLevelNew); - pTC->m_iBidiClass = static_cast(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(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* chars, int32_t iCount) { - ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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* chars, int32_t iCount) { - ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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* chars, int32_t iCount) { - ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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* chars, - int32_t iCount, - int32_t iBaseLevel, - int32_t iStart, - bool bReverse) { - ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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* chars, int32_t iCount) { - ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*chars)); - int32_t i = 0; - while (i < iCount) - i += ReorderLevel(chars, iCount, 0, i, false); - } - - void Position(std::vector* chars, int32_t iCount) { - ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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* 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* 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* chars, int32_t iCount) { + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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* chars, + int32_t iStart, + int32_t iCount) { + ASSERT(pdfium::IndexInBounds(*chars, iStart)); + ASSERT(iCount >= 0 && + iStart + iCount <= pdfium::CollectionSize(*chars)); + std::reverse(chars->begin() + iStart, chars->begin() + iStart + iCount); + } + + void SetDeferredRun(std::vector* chars, + bool bClass, + int32_t iStart, + int32_t iCount, + int32_t iValue) { + ASSERT(iStart >= 0 && iStart <= pdfium::CollectionSize(*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(iValue); + return; + } + + for (int32_t i = iStart - 1; i >= iLast; i--) + (*chars)[i].m_iBidiLevel = static_cast(iValue); + } + + void Classify(std::vector* chars, int32_t iCount, bool bWS) { + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*chars)); + if (bWS) { + for (int32_t i = 0; i < iCount; i++) { + CFX_Char& cur = (*chars)[i]; + cur.m_iBidiClass = + static_cast(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( + gc_FX_BidiNTypes[(cur.char_props() & FX_BIDICLASSBITSMASK) >> + FX_BIDICLASSBITS]); + } + } + + void ResolveExplicit(std::vector* chars, int32_t iCount) { + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*chars)); + for (int32_t i = 0; i < iCount; i++) + (*chars)[i].m_iBidiLevel = 0; + } + + void ResolveWeak(std::vector* chars, int32_t iCount) { + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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(iLevelNew); + iClsCur = Direction(iLevelNew); + pTC->m_iBidiClass = static_cast(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(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* chars, int32_t iCount) { + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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* chars, int32_t iCount) { + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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* chars, int32_t iCount) { + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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* chars, + int32_t iCount, + int32_t iBaseLevel, + int32_t iStart, + bool bReverse) { + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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* chars, int32_t iCount) { + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*chars)); + int32_t i = 0; + while (i < iCount) + i += ReorderLevel(chars, iCount, 0, i, false); + } + + void Position(std::vector* chars, int32_t iCount) { + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize(*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* 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* 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 #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 #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" -- cgit v1.2.3