summaryrefslogtreecommitdiff
path: root/core/fxcrt/fx_arabic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fxcrt/fx_arabic.cpp')
-rw-r--r--core/fxcrt/fx_arabic.cpp650
1 files changed, 339 insertions, 311 deletions
diff --git a/core/fxcrt/fx_arabic.cpp b/core/fxcrt/fx_arabic.cpp
index 76f2e38663..70e8e6a709 100644
--- a/core/fxcrt/fx_arabic.cpp
+++ b/core/fxcrt/fx_arabic.cpp
@@ -12,8 +12,93 @@
#include "core/fxcrt/fx_ucd.h"
#include "third_party/base/stl_util.h"
+#define FX_BIDIMAXLEVEL 61
+
namespace {
+struct FX_ARBFORMTABLE {
+ uint16_t wIsolated;
+ uint16_t wFinal;
+ uint16_t wInitial;
+ uint16_t wMedial;
+};
+
+struct FX_ARAALEF {
+ uint16_t wAlef;
+ uint16_t wIsolated;
+};
+
+struct FX_ARASHADDA {
+ uint16_t wShadda;
+ 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},
@@ -235,383 +320,287 @@ const int32_t gc_FX_BidiAddLevel[][4] = {
{1, 0, 1, 1},
};
+const FX_ARBFORMTABLE* GetArabicFormTable(wchar_t unicode) {
+ if (unicode < 0x622 || unicode > 0x6d5)
+ return nullptr;
+ return g_FX_ArabicFormTables + unicode - 0x622;
+}
+
const FX_ARBFORMTABLE* ParseChar(const CFX_Char* pTC,
- wchar_t& wChar,
- FX_CHARTYPE& eType) {
+ wchar_t* wChar,
+ FX_CHARTYPE* eType) {
if (!pTC) {
- eType = FX_CHARTYPE_Unknown;
- wChar = 0xFEFF;
+ *eType = FX_CHARTYPE_Unknown;
+ *wChar = 0xFEFF;
return nullptr;
}
- eType = pTC->GetCharType();
- wChar = (wchar_t)pTC->m_wCharCode;
- const FX_ARBFORMTABLE* pFT = FX_GetArabicFormTable(wChar);
- if (!pFT || eType >= FX_CHARTYPE_ArabicNormal)
- eType = FX_CHARTYPE_Unknown;
+
+ *eType = pTC->GetCharType();
+ *wChar = static_cast<wchar_t>(pTC->m_wCharCode);
+ const FX_ARBFORMTABLE* pFT = GetArabicFormTable(*wChar);
+ if (!pFT || *eType >= FX_CHARTYPE_ArabicNormal)
+ *eType = FX_CHARTYPE_Unknown;
return pFT;
}
-} // namespace
-
-const FX_ARBFORMTABLE* FX_GetArabicFormTable(wchar_t unicode) {
- if (unicode < 0x622 || unicode > 0x6d5) {
- return nullptr;
- }
- return g_FX_ArabicFormTables + unicode - 0x622;
-}
-wchar_t FX_GetArabicFromAlefTable(wchar_t alef) {
- static const int32_t s_iAlefCount =
- sizeof(gs_FX_AlefTable) / sizeof(FX_ARAALEF);
- for (int32_t iStart = 0; iStart < s_iAlefCount; iStart++) {
+wchar_t GetArabicFromAlefTable(wchar_t alef) {
+ static const size_t s_iAlefCount = FX_ArraySize(gs_FX_AlefTable);
+ for (size_t iStart = 0; iStart < s_iAlefCount; iStart++) {
const FX_ARAALEF& v = gs_FX_AlefTable[iStart];
- if (v.wAlef == alef) {
+ if (v.wAlef == alef)
return v.wIsolated;
- }
}
return alef;
}
-wchar_t FX_GetArabicFromShaddaTable(wchar_t shadda) {
- static const int32_t s_iShaddaCount =
- sizeof(gs_FX_ShaddaTable) / sizeof(FX_ARASHADDA);
- for (int32_t iStart = 0; iStart < s_iShaddaCount; iStart++) {
- const FX_ARASHADDA& v = gs_FX_ShaddaTable[iStart];
- if (v.wShadda == shadda) {
- return v.wIsolated;
- }
- }
- return shadda;
-}
-namespace pdfium {
-namespace arabic {
-
-wchar_t GetFormChar(wchar_t wch, wchar_t prev, wchar_t next) {
- CFX_Char c(wch, kTextLayoutCodeProperties[(uint16_t)wch]);
- CFX_Char p(prev, kTextLayoutCodeProperties[(uint16_t)prev]);
- CFX_Char n(next, kTextLayoutCodeProperties[(uint16_t)next]);
- return GetFormChar(&c, &p, &n);
-}
+class CFX_BidiLine {
+ public:
+ void BidiLine(std::vector<CFX_Char>* chars,
+ int32_t iCount,
+ int32_t iBaseLevel) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
+ if (iCount < 2)
+ return;
-wchar_t GetFormChar(const CFX_Char* cur,
- const CFX_Char* prev,
- const CFX_Char* next) {
- FX_CHARTYPE eCur;
- wchar_t wCur;
- const FX_ARBFORMTABLE* ft = ParseChar(cur, wCur, eCur);
- if (eCur < FX_CHARTYPE_ArabicAlef || eCur >= FX_CHARTYPE_ArabicNormal) {
- return wCur;
- }
- FX_CHARTYPE ePrev;
- wchar_t wPrev;
- ParseChar(prev, wPrev, ePrev);
- if (wPrev == 0x0644 && eCur == FX_CHARTYPE_ArabicAlef) {
- return 0xFEFF;
+ Classify(chars, iCount, false);
+ ResolveExplicit(chars, iCount, iBaseLevel);
+ ResolveWeak(chars, iCount, iBaseLevel);
+ ResolveNeutrals(chars, iCount, iBaseLevel);
+ ResolveImplicit(chars, iCount);
+ Classify(chars, iCount, true);
+ ResolveWhitespace(chars, iCount, iBaseLevel);
+ Reorder(chars, iCount, iBaseLevel);
+ Position(chars, iCount);
}
- FX_CHARTYPE eNext;
- wchar_t wNext;
- ParseChar(next, wNext, eNext);
- bool bAlef = (eNext == FX_CHARTYPE_ArabicAlef && wCur == 0x644);
- if (ePrev < FX_CHARTYPE_ArabicAlef) {
- if (bAlef) {
- return FX_GetArabicFromAlefTable(wNext);
- }
- return (eNext < FX_CHARTYPE_ArabicAlef) ? ft->wIsolated : ft->wInitial;
- }
- if (bAlef) {
- wCur = FX_GetArabicFromAlefTable(wNext);
- return (ePrev != FX_CHARTYPE_ArabicDistortion) ? wCur : ++wCur;
- }
- if (ePrev == FX_CHARTYPE_ArabicAlef || ePrev == FX_CHARTYPE_ArabicSpecial) {
- return (eNext < FX_CHARTYPE_ArabicAlef) ? ft->wIsolated : ft->wInitial;
- }
- return (eNext < FX_CHARTYPE_ArabicAlef) ? ft->wFinal : ft->wMedial;
-}
-} // namespace arabic
-} // namespace pdfium
-
-void FX_BidiReverseString(CFX_WideString& wsText,
- int32_t iStart,
- int32_t iCount) {
- ASSERT(iStart > -1 && iStart < wsText.GetLength());
- ASSERT(iCount >= 0 && iStart + iCount <= wsText.GetLength());
- wchar_t wch;
- wchar_t* pStart = const_cast<wchar_t*>(wsText.c_str());
- pStart += iStart;
- wchar_t* pEnd = pStart + iCount - 1;
- while (pStart < pEnd) {
- wch = *pStart;
- *pStart++ = *pEnd;
- *pEnd-- = wch;
+ 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 FX_BidiGetDeferredNeutrals(int32_t iAction, int32_t iLevel) {
- iAction = (iAction >> 4) & 0xF;
- if (iAction == (FX_BIDINEUTRALACTION_En >> 4)) {
- return FX_BidiDirection(iLevel);
- } else {
- return iAction;
- }
-}
+ int32_t GetResolvedType(int32_t val) { return val & 0x0F; }
-int32_t FX_BidiGetResolvedNeutrals(int32_t iAction) {
- iAction = (iAction & 0xF);
- if (iAction == FX_BIDINEUTRALACTION_In) {
- return 0;
- } else {
+ 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 FX_BidiReorderLevel(int32_t iBaseLevel,
- CFX_WideString& wsText,
- const CFX_ArrayTemplate<int32_t>& levels,
- int32_t iStart,
- bool bReverse) {
- ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
- ASSERT(wsText.GetLength() == levels.GetSize());
- ASSERT(iStart >= 0 && iStart < wsText.GetLength());
- int32_t iSize = wsText.GetLength();
- if (iSize < 1) {
- return 0;
- }
- bReverse = bReverse || FX_IsOdd(iBaseLevel);
- int32_t i = iStart, iLevel;
- for (; i < iSize; i++) {
- if ((iLevel = levels.GetAt(i)) == iBaseLevel) {
- continue;
- }
- if (iLevel < iBaseLevel) {
- break;
- }
- i += FX_BidiReorderLevel(iBaseLevel + 1, wsText, levels, i, bReverse) - 1;
- }
- int32_t iCount = i - iStart;
- if (bReverse && iCount > 1) {
- FX_BidiReverseString(wsText, iStart, iCount);
- }
- return iCount;
-}
-void FX_BidiReorder(int32_t iBaseLevel,
- CFX_WideString& wsText,
- const CFX_ArrayTemplate<int32_t>& levels) {
- ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
- ASSERT(wsText.GetLength() == levels.GetSize());
- int32_t iSize = wsText.GetLength();
- if (iSize < 1) {
- return;
- }
- int32_t i = 0;
- while (i < iSize) {
- i += FX_BidiReorderLevel(iBaseLevel, wsText, levels, i, false);
+ int32_t GetResolvedNeutrals(int32_t iAction) {
+ iAction &= 0xF;
+ return iAction == FX_BNAIn ? 0 : iAction;
}
-}
-class CFX_BidiLineTemplate {
- public:
- void FX_BidiReverseString(std::vector<CFX_Char>& chars,
- int32_t iStart,
- int32_t iCount) {
- ASSERT(pdfium::IndexInBounds(chars, iStart));
- ASSERT(pdfium::IndexInBounds(chars, iCount));
- ASSERT(iStart + iCount <= pdfium::CollectionSize<int32_t>(chars));
- std::reverse(chars.begin() + iStart, chars.begin() + iStart + iCount);
+ void ReverseString(std::vector<CFX_Char>* chars,
+ int32_t iStart,
+ int32_t iCount) {
+ ASSERT(pdfium::IndexInBounds(*chars, iStart));
+ ASSERT(pdfium::IndexInBounds(*chars, iCount));
+ ASSERT(iStart + iCount <= pdfium::CollectionSize<int32_t>(*chars));
+ std::reverse(chars->begin() + iStart, chars->begin() + iStart + iCount);
}
- void FX_BidiSetDeferredRun(std::vector<CFX_Char>& chars,
- bool bClass,
- int32_t iStart,
- int32_t iCount,
- int32_t iValue) {
- ASSERT(pdfium::IndexInBounds(chars, iStart));
+ void SetDeferredRun(std::vector<CFX_Char>* chars,
+ bool bClass,
+ int32_t iStart,
+ int32_t iCount,
+ int32_t iValue) {
+ ASSERT(pdfium::IndexInBounds(*chars, iStart));
ASSERT(iStart - iCount > -1);
int32_t iLast = iStart - iCount;
if (bClass) {
for (int32_t i = iStart - 1; i >= iLast; i--)
- chars[i].m_iBidiClass = (int16_t)iValue;
- } else {
- for (int32_t i = iStart - 1; i >= iLast; i--)
- chars[i].m_iBidiLevel = (int16_t)iValue;
+ (*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 FX_BidiClassify(std::vector<CFX_Char>& chars, int32_t iCount, bool bWS) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
+ 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++) {
- chars[i].m_iBidiClass =
- (int16_t)(chars[i].m_dwCharProps & FX_BIDICLASSBITSMASK) >>
+ (*chars)[i].m_iBidiClass =
+ static_cast<int16_t>((*chars)[i].m_dwCharProps &
+ FX_BIDICLASSBITSMASK) >>
FX_BIDICLASSBITS;
}
- } else {
- for (int32_t i = 0; i < iCount; i++) {
- chars[i].m_iBidiClass = (int16_t)
- gc_FX_BidiNTypes[(chars[i].m_dwCharProps & FX_BIDICLASSBITSMASK) >>
- FX_BIDICLASSBITS];
- }
+ return;
+ }
+
+ for (int32_t i = 0; i < iCount; i++) {
+ (*chars)[i].m_iBidiClass = static_cast<int16_t>(
+ gc_FX_BidiNTypes[((*chars)[i].m_dwCharProps & FX_BIDICLASSBITSMASK) >>
+ FX_BIDICLASSBITS]);
}
}
- void FX_BidiResolveExplicit(std::vector<CFX_Char>& chars,
- int32_t iCount,
- int32_t iBaseLevel) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
+ void ResolveExplicit(std::vector<CFX_Char>* chars,
+ int32_t iCount,
+ int32_t iBaseLevel) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
for (int32_t i = 0; i < iCount; i++)
- chars[i].m_iBidiLevel = static_cast<int16_t>(iBaseLevel);
+ (*chars)[i].m_iBidiLevel = static_cast<int16_t>(iBaseLevel);
}
- void FX_BidiResolveWeak(std::vector<CFX_Char>& chars,
- int32_t iCount,
- int32_t iBaseLevel) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
+ void ResolveWeak(std::vector<CFX_Char>* chars,
+ int32_t iCount,
+ int32_t iBaseLevel) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
iCount--;
- if (iCount < 1) {
+ if (iCount < 1)
return;
- }
- CFX_Char *pTC, *pTCNext;
+
int32_t iLevelCur = iBaseLevel;
int32_t iState = FX_IsOdd(iBaseLevel) ? FX_BWSxr : FX_BWSxl;
- int32_t i = 0, iNum = 0, iClsCur, iClsRun, iClsNew, iAction;
+ 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];
+ CFX_Char* pTC = &(*chars)[i];
iClsCur = pTC->m_iBidiClass;
if (iClsCur == FX_BIDICLASS_BN) {
pTC->m_iBidiLevel = (int16_t)iLevelCur;
if (i == iCount && iLevelCur != iBaseLevel) {
- iClsCur = FX_BidiDirection(iLevelCur);
+ iClsCur = Direction(iLevelCur);
pTC->m_iBidiClass = (int16_t)iClsCur;
} else if (i < iCount) {
- pTCNext = &chars[i + 1];
+ 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 = iLevelNext;
- if (iLevelCur > iLevelNew) {
- iLevelNew = iLevelCur;
- }
- pTC->m_iBidiLevel = (int16_t)iLevelNew;
- iClsCur = FX_BidiDirection(iLevelNew);
- pTC->m_iBidiClass = (int16_t)iClsCur;
+ 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) {
+ if (iNum > 0)
iNum++;
- }
continue;
}
} else {
- if (iNum > 0) {
+ if (iNum > 0)
iNum++;
- }
continue;
}
}
+
ASSERT(iClsCur <= FX_BIDICLASS_BN);
iAction = gc_FX_BidiWeakActions[iState][iClsCur];
- iClsRun = FX_BidiGetDeferredType(iAction);
- if (iClsRun != FX_BIDIWEAKACTION_XX && iNum > 0) {
- FX_BidiSetDeferredRun(chars, true, i, iNum, iClsRun);
+ iClsRun = GetDeferredType(iAction);
+ if (iClsRun != FX_BWAXX && iNum > 0) {
+ SetDeferredRun(chars, true, i, iNum, iClsRun);
iNum = 0;
}
- iClsNew = FX_BidiGetResolvedType(iAction);
- if (iClsNew != FX_BIDIWEAKACTION_XX) {
- pTC->m_iBidiClass = (int16_t)iClsNew;
- }
- if (FX_BIDIWEAKACTION_IX & iAction) {
+ 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 = FX_BidiDirection(iBaseLevel);
- iClsRun = FX_BidiGetDeferredType(gc_FX_BidiWeakActions[iState][iClsCur]);
- if (iClsRun != FX_BIDIWEAKACTION_XX) {
- FX_BidiSetDeferredRun(chars, true, i, iNum, iClsRun);
- }
+ iClsCur = Direction(iBaseLevel);
+ iClsRun = GetDeferredType(gc_FX_BidiWeakActions[iState][iClsCur]);
+ if (iClsRun != FX_BWAXX)
+ SetDeferredRun(chars, true, i, iNum, iClsRun);
}
}
- void FX_BidiResolveNeutrals(std::vector<CFX_Char>& chars,
- int32_t iCount,
- int32_t iBaseLevel) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
+ void ResolveNeutrals(std::vector<CFX_Char>* chars,
+ int32_t iCount,
+ int32_t iBaseLevel) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
iCount--;
- if (iCount < 1) {
+ if (iCount < 1)
return;
- }
+
CFX_Char* pTC;
int32_t iLevel = iBaseLevel;
int32_t iState = FX_IsOdd(iBaseLevel) ? FX_BNSr : FX_BNSl;
- int32_t i = 0, iNum = 0, iClsCur, iClsRun, iClsNew, iAction;
+ 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];
+ pTC = &(*chars)[i];
iClsCur = pTC->m_iBidiClass;
if (iClsCur == FX_BIDICLASS_BN) {
- if (iNum) {
+ if (iNum)
iNum++;
- }
continue;
}
+
ASSERT(iClsCur < FX_BIDICLASS_AL);
iAction = gc_FX_BidiNeutralActions[iState][iClsCur];
- iClsRun = FX_BidiGetDeferredNeutrals(iAction, iLevel);
+ iClsRun = GetDeferredNeutrals(iAction, iLevel);
if (iClsRun != FX_BIDICLASS_N && iNum > 0) {
- FX_BidiSetDeferredRun(chars, true, i, iNum, iClsRun);
+ SetDeferredRun(chars, true, i, iNum, iClsRun);
iNum = 0;
}
- iClsNew = FX_BidiGetResolvedNeutrals(iAction);
- if (iClsNew != FX_BIDICLASS_N) {
+
+ iClsNew = GetResolvedNeutrals(iAction);
+ if (iClsNew != FX_BIDICLASS_N)
pTC->m_iBidiClass = (int16_t)iClsNew;
- }
- if (FX_BIDINEUTRALACTION_In & iAction) {
+ if (FX_BNAIn & iAction)
iNum++;
- }
+
iState = gc_FX_BidiNeutralStates[iState][iClsCur];
iLevel = pTC->m_iBidiLevel;
}
if (iNum > 0) {
- iClsCur = FX_BidiDirection(iLevel);
- iClsRun = FX_BidiGetDeferredNeutrals(
- gc_FX_BidiNeutralActions[iState][iClsCur], iLevel);
- if (iClsRun != FX_BIDICLASS_N) {
- FX_BidiSetDeferredRun(chars, true, i, iNum, iClsRun);
- }
+ iClsCur = Direction(iLevel);
+ iClsRun = GetDeferredNeutrals(gc_FX_BidiNeutralActions[iState][iClsCur],
+ iLevel);
+ if (iClsRun != FX_BIDICLASS_N)
+ SetDeferredRun(chars, true, i, iNum, iClsRun);
}
}
- void FX_BidiResolveImplicit(std::vector<CFX_Char>& chars, int32_t iCount) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
+ 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) {
+ 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;
+ int32_t iLevel = (*chars)[i].m_iBidiLevel;
iLevel += gc_FX_BidiAddLevel[FX_IsOdd(iLevel)][iCls - 1];
- chars[i].m_iBidiLevel = (int16_t)iLevel;
+ (*chars)[i].m_iBidiLevel = (int16_t)iLevel;
}
}
- void FX_BidiResolveWhitespace(std::vector<CFX_Char>& chars,
- int32_t iCount,
- int32_t iBaseLevel) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
+ void ResolveWhitespace(std::vector<CFX_Char>* chars,
+ int32_t iCount,
+ int32_t iBaseLevel) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
- if (iCount < 1) {
+ if (iCount < 1)
return;
- }
+
iCount--;
int32_t iLevel = iBaseLevel;
- int32_t i = 0, iNum = 0;
+ int32_t i = 0;
+ int32_t iNum = 0;
for (; i <= iCount; i++) {
- switch (chars[i].m_iBidiClass) {
+ switch ((*chars)[i].m_iBidiClass) {
case FX_BIDICLASS_WS:
iNum++;
break;
@@ -621,95 +610,134 @@ class CFX_BidiLineTemplate {
case FX_BIDICLASS_RLO:
case FX_BIDICLASS_PDF:
case FX_BIDICLASS_BN:
- chars[i].m_iBidiLevel = (int16_t)iLevel;
+ (*chars)[i].m_iBidiLevel = (int16_t)iLevel;
iNum++;
break;
case FX_BIDICLASS_S:
case FX_BIDICLASS_B:
- if (iNum > 0) {
- FX_BidiSetDeferredRun(chars, false, i, iNum, iBaseLevel);
- }
- chars[i].m_iBidiLevel = (int16_t)iBaseLevel;
+ if (iNum > 0)
+ SetDeferredRun(chars, false, i, iNum, iBaseLevel);
+
+ (*chars)[i].m_iBidiLevel = static_cast<int16_t>(iBaseLevel);
iNum = 0;
break;
default:
iNum = 0;
break;
}
- iLevel = chars[i].m_iBidiLevel;
- }
- if (iNum > 0) {
- FX_BidiSetDeferredRun(chars, false, i, iNum, iBaseLevel);
+ iLevel = (*chars)[i].m_iBidiLevel;
}
+ if (iNum > 0)
+ SetDeferredRun(chars, false, i, iNum, iBaseLevel);
}
- int32_t FX_BidiReorderLevel(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));
+ 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) {
+
+ 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;
+ int32_t iLevel = (*chars)[i].m_iBidiLevel;
if (iLevel == iBaseLevel)
continue;
if (iLevel < iBaseLevel)
break;
- i += FX_BidiReorderLevel(chars, iCount, iBaseLevel + 1, i, bReverse) - 1;
+ i += ReorderLevel(chars, iCount, iBaseLevel + 1, i, bReverse) - 1;
}
int32_t iNum = i - iStart;
- if (bReverse && iNum > 1) {
- FX_BidiReverseString(chars, iStart, iNum);
- }
+ if (bReverse && iNum > 1)
+ ReverseString(chars, iStart, iNum);
+
return iNum;
}
- void FX_BidiReorder(std::vector<CFX_Char>& chars,
- int32_t iCount,
- int32_t iBaseLevel) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
+ void Reorder(std::vector<CFX_Char>* chars,
+ int32_t iCount,
+ int32_t iBaseLevel) {
+ ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(*chars));
ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
int32_t i = 0;
- while (i < iCount) {
- i += FX_BidiReorderLevel(chars, iCount, iBaseLevel, i, false);
- }
+ while (i < iCount)
+ i += ReorderLevel(chars, iCount, iBaseLevel, i, false);
}
- void FX_BidiPosition(std::vector<CFX_Char>& chars, int32_t iCount) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
+ 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;
+ (*chars)[(*chars)[i].m_iBidiPos].m_iBidiOrder = i;
}
+};
- void FX_BidiLine(std::vector<CFX_Char>& chars,
- int32_t iCount,
- int32_t iBaseLevel) {
- ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars));
- if (iCount < 2) {
- return;
- }
- FX_BidiClassify(chars, iCount, false);
- FX_BidiResolveExplicit(chars, iCount, iBaseLevel);
- FX_BidiResolveWeak(chars, iCount, iBaseLevel);
- FX_BidiResolveNeutrals(chars, iCount, iBaseLevel);
- FX_BidiResolveImplicit(chars, iCount);
- FX_BidiClassify(chars, iCount, true);
- FX_BidiResolveWhitespace(chars, iCount, iBaseLevel);
- FX_BidiReorder(chars, iCount, iBaseLevel);
- FX_BidiPosition(chars, iCount);
+} // namespace
+
+namespace pdfium {
+namespace arabic {
+
+wchar_t GetFormChar(wchar_t wch, wchar_t prev, wchar_t next) {
+ CFX_Char c(wch, kTextLayoutCodeProperties[static_cast<uint16_t>(wch)]);
+ CFX_Char p(prev, kTextLayoutCodeProperties[static_cast<uint16_t>(prev)]);
+ CFX_Char n(next, kTextLayoutCodeProperties[static_cast<uint16_t>(next)]);
+ return GetFormChar(&c, &p, &n);
+}
+
+wchar_t GetFormChar(const CFX_Char* cur,
+ const CFX_Char* prev,
+ const CFX_Char* next) {
+ FX_CHARTYPE eCur;
+ wchar_t wCur;
+ const FX_ARBFORMTABLE* ft = ParseChar(cur, &wCur, &eCur);
+ if (eCur < FX_CHARTYPE_ArabicAlef || eCur >= FX_CHARTYPE_ArabicNormal)
+ return wCur;
+
+ FX_CHARTYPE ePrev;
+ wchar_t wPrev;
+ ParseChar(prev, &wPrev, &ePrev);
+ if (wPrev == 0x0644 && eCur == FX_CHARTYPE_ArabicAlef)
+ return 0xFEFF;
+
+ FX_CHARTYPE eNext;
+ wchar_t wNext;
+ ParseChar(next, &wNext, &eNext);
+ bool bAlef = (eNext == FX_CHARTYPE_ArabicAlef && wCur == 0x644);
+ if (ePrev < FX_CHARTYPE_ArabicAlef) {
+ if (bAlef)
+ return GetArabicFromAlefTable(wNext);
+ return (eNext < FX_CHARTYPE_ArabicAlef) ? ft->wIsolated : ft->wInitial;
}
-};
-void FX_BidiLine(std::vector<CFX_Char>& chars,
- int32_t iCount,
- int32_t iBaseLevel) {
- CFX_BidiLineTemplate blt;
- blt.FX_BidiLine(chars, iCount, iBaseLevel);
+ if (bAlef) {
+ wCur = GetArabicFromAlefTable(wNext);
+ return (ePrev != FX_CHARTYPE_ArabicDistortion) ? wCur : ++wCur;
+ }
+
+ if (ePrev == FX_CHARTYPE_ArabicAlef || ePrev == FX_CHARTYPE_ArabicSpecial)
+ return (eNext < FX_CHARTYPE_ArabicAlef) ? ft->wIsolated : ft->wInitial;
+ return (eNext < FX_CHARTYPE_ArabicAlef) ? ft->wFinal : ft->wMedial;
+}
+
+} // namespace arabic
+} // namespace pdfium
+
+wchar_t FX_GetArabicFromShaddaTable(wchar_t shadda) {
+ static const size_t s_iShaddaCount = FX_ArraySize(gs_FX_ShaddaTable);
+ for (size_t iStart = 0; iStart < s_iShaddaCount; iStart++) {
+ const FX_ARASHADDA& v = gs_FX_ShaddaTable[iStart];
+ if (v.wShadda == shadda)
+ return v.wIsolated;
+ }
+ return shadda;
+}
+
+void FX_BidiLine(std::vector<CFX_Char>* chars, int32_t iCount) {
+ CFX_BidiLine blt;
+ blt.BidiLine(chars, iCount, 0);
}