Make CFX_Char::m_iBidiClass an FX_BIDICLASS enum type
Change-Id: Ia46890741d9d5bf3111db6ff38046ecbcd4f27f2
Reviewed-on: https://pdfium-review.googlesource.com/c/48192
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcrt/cfx_char.h b/core/fxcrt/cfx_char.h
index f275887..8ccdad4 100644
--- a/core/fxcrt/cfx_char.h
+++ b/core/fxcrt/cfx_char.h
@@ -30,10 +30,10 @@
int16_t vertical_scale() const { return m_iVerticalScale; }
CFX_BreakType m_dwStatus = CFX_BreakType::None;
+ FX_BIDICLASS m_iBidiClass = FX_BIDICLASS::kON;
uint8_t m_nBreakType = 0;
uint32_t m_dwCharStyles = 0;
int32_t m_iCharWidth = 0;
- int16_t m_iBidiClass = 0;
uint16_t m_iBidiLevel = 0;
uint16_t m_iBidiPos = 0;
uint16_t m_iBidiOrder = 0;
diff --git a/core/fxcrt/fx_bidi.cpp b/core/fxcrt/fx_bidi.cpp
index 88e561c..4106ff6 100644
--- a/core/fxcrt/fx_bidi.cpp
+++ b/core/fxcrt/fx_bidi.cpp
@@ -50,6 +50,10 @@
#define PACK_NIBBLES(hi, lo) \
((static_cast<uint32_t>(hi) << 4) + static_cast<uint32_t>(lo))
+// NOTE: Range of FX_BIDICLASS prevents encoding all possible values in this
+// manner, but the ones used manage to fit. Except that I suspect that 0xF
+// was intended to be used as a sentinel, even though it also means kRLE.
+// TODO(tsepez): pick a better representation.
enum FX_BIDIWEAKACTION {
FX_BWAIX = 0x100,
FX_BWAXX = 0x0F,
@@ -207,7 +211,7 @@
{FX_BNAIn, FX_BNAEn, FX_BNARn, FX_BNARn, FX_BNAEn},
};
-const int32_t gc_FX_BidiAddLevel[][4] = {
+const uint8_t gc_FX_BidiAddLevel[2][4] = {
{0, 1, 2, 2},
{1, 0, 1, 1},
};
@@ -216,24 +220,21 @@
return FX_IsOdd(val) ? FX_BIDICLASS::kR : FX_BIDICLASS::kL;
}
-int32_t GetDeferredType(int32_t val) {
- return (val >> 4) & 0x0F;
+FX_BIDICLASS GetDeferredType(int32_t val) {
+ return static_cast<FX_BIDICLASS>((val >> 4) & 0x0F);
}
-int32_t GetResolvedType(int32_t val) {
- return val & 0x0F;
+FX_BIDICLASS GetResolvedType(int32_t val) {
+ return static_cast<FX_BIDICLASS>(val & 0x0F);
}
-int32_t GetDeferredNeutrals(int32_t iAction, int32_t iLevel) {
- iAction = (iAction >> 4) & 0xF;
- if (iAction == (FX_BNAEn >> 4))
- return static_cast<uint32_t>(Direction(iLevel));
- return iAction;
+FX_BIDICLASS GetDeferredNeutrals(int32_t iAction, int32_t iLevel) {
+ FX_BIDICLASS eClass = GetDeferredType(iAction);
+ return eClass == FX_BIDICLASS::kAN ? Direction(iLevel) : eClass;
}
-int32_t GetResolvedNeutrals(int32_t iAction) {
- iAction &= 0xF;
- return iAction == FX_BNAIn ? 0 : iAction;
+FX_BIDICLASS GetResolvedNeutrals(int32_t iAction) {
+ return GetResolvedType(iAction);
}
void ReverseString(std::vector<CFX_Char>* chars, size_t iStart, size_t iCount) {
@@ -246,13 +247,13 @@
void SetDeferredRunClass(std::vector<CFX_Char>* chars,
size_t iStart,
size_t iCount,
- int32_t iValue) {
+ FX_BIDICLASS eValue) {
ASSERT(iStart <= chars->size());
ASSERT(iStart >= iCount);
size_t iLast = iStart - iCount;
for (size_t i = iStart; i > iLast; --i)
- (*chars)[i - 1].m_iBidiClass = static_cast<int16_t>(iValue);
+ (*chars)[i - 1].m_iBidiClass = eValue;
}
void SetDeferredRunLevel(std::vector<CFX_Char>* chars,
@@ -271,7 +272,7 @@
if (bWS) {
for (size_t i = 0; i < iCount; ++i) {
CFX_Char& cur = (*chars)[i];
- cur.m_iBidiClass = static_cast<int16_t>(FX_GetBidiClass(cur.char_code()));
+ cur.m_iBidiClass = FX_GetBidiClass(cur.char_code());
}
return;
}
@@ -279,8 +280,7 @@
for (size_t i = 0; i < iCount; ++i) {
CFX_Char& cur = (*chars)[i];
cur.m_iBidiClass =
- static_cast<int16_t>(gc_FX_BidiNTypes[static_cast<size_t>(
- FX_GetBidiClass(cur.char_code()))]);
+ gc_FX_BidiNTypes[static_cast<size_t>(FX_GetBidiClass(cur.char_code()))];
}
}
@@ -297,29 +297,28 @@
int32_t iLevelCur = 0;
int32_t iState = FX_BWSxl;
size_t iNum = 0;
- int32_t iClsCur;
- int32_t iClsRun;
- int32_t iClsNew;
+ FX_BIDICLASS eClsCur;
+ FX_BIDICLASS eClsRun;
+ FX_BIDICLASS eClsNew;
size_t i = 0;
for (; i <= iCount; ++i) {
CFX_Char* pTC = &(*chars)[i];
- iClsCur = pTC->m_iBidiClass;
- if (iClsCur == static_cast<int32_t>(FX_BIDICLASS::kBN)) {
+ eClsCur = pTC->m_iBidiClass;
+ if (eClsCur == FX_BIDICLASS::kBN) {
pTC->m_iBidiLevel = (int16_t)iLevelCur;
if (i == iCount && iLevelCur != 0) {
- iClsCur = static_cast<int32_t>(Direction(iLevelCur));
- pTC->m_iBidiClass = (int16_t)iClsCur;
+ eClsCur = Direction(iLevelCur);
+ pTC->m_iBidiClass = eClsCur;
} else if (i < iCount) {
CFX_Char* pTCNext = &(*chars)[i + 1];
int32_t iLevelNext, iLevelNew;
- iClsNew = pTCNext->m_iBidiClass;
+ eClsNew = pTCNext->m_iBidiClass;
iLevelNext = pTCNext->m_iBidiLevel;
- if (iClsNew != static_cast<int32_t>(FX_BIDICLASS::kBN) &&
- iLevelCur != iLevelNext) {
+ if (eClsNew != FX_BIDICLASS::kBN && iLevelCur != iLevelNext) {
iLevelNew = std::max(iLevelNext, iLevelCur);
pTC->m_iBidiLevel = static_cast<int16_t>(iLevelNew);
- iClsCur = static_cast<int32_t>(Direction(iLevelNew));
- pTC->m_iBidiClass = static_cast<int16_t>(iClsCur);
+ eClsCur = Direction(iLevelNew);
+ pTC->m_iBidiClass = eClsCur;
iLevelCur = iLevelNext;
} else {
if (iNum > 0)
@@ -332,30 +331,32 @@
continue;
}
}
- if (iClsCur > static_cast<int32_t>(FX_BIDICLASS::kBN))
+ if (eClsCur > FX_BIDICLASS::kBN)
continue;
- int32_t iAction = gc_FX_BidiWeakActions[iState][iClsCur];
- iClsRun = GetDeferredType(iAction);
- if (iClsRun != FX_BWAXX && iNum > 0) {
- SetDeferredRunClass(chars, i, iNum, iClsRun);
+ int32_t iAction =
+ gc_FX_BidiWeakActions[iState][static_cast<size_t>(eClsCur)];
+ eClsRun = GetDeferredType(iAction);
+ if (eClsRun != static_cast<FX_BIDICLASS>(0xF) && iNum > 0) {
+ SetDeferredRunClass(chars, i, iNum, eClsRun);
iNum = 0;
}
- iClsNew = GetResolvedType(iAction);
- if (iClsNew != FX_BWAXX)
- pTC->m_iBidiClass = static_cast<int16_t>(iClsNew);
+ eClsNew = GetResolvedType(iAction);
+ if (eClsNew != static_cast<FX_BIDICLASS>(0xF))
+ pTC->m_iBidiClass = eClsNew;
if (FX_BWAIX & iAction)
++iNum;
- iState = gc_FX_BidiWeakStates[iState][iClsCur];
+ iState = gc_FX_BidiWeakStates[iState][static_cast<size_t>(eClsCur)];
}
if (iNum == 0)
return;
- iClsCur = static_cast<int32_t>(Direction(0));
- iClsRun = GetDeferredType(gc_FX_BidiWeakActions[iState][iClsCur]);
- if (iClsRun != FX_BWAXX)
- SetDeferredRunClass(chars, i, iNum, iClsRun);
+ eClsCur = Direction(0);
+ eClsRun = GetDeferredType(
+ gc_FX_BidiWeakActions[iState][static_cast<size_t>(eClsCur)]);
+ if (eClsRun != static_cast<FX_BIDICLASS>(0xF))
+ SetDeferredRunClass(chars, i, iNum, eClsRun);
}
void ResolveNeutrals(std::vector<CFX_Char>* chars, size_t iCount) {
@@ -368,58 +369,57 @@
int32_t iState = FX_BNSl;
size_t i = 0;
size_t iNum = 0;
- int32_t iClsCur;
- int32_t iClsRun;
- int32_t iClsNew;
+ FX_BIDICLASS eClsCur;
+ FX_BIDICLASS eClsRun;
+ FX_BIDICLASS eClsNew;
int32_t iAction;
for (; i <= iCount; ++i) {
pTC = &(*chars)[i];
- iClsCur = pTC->m_iBidiClass;
- if (iClsCur == static_cast<int32_t>(FX_BIDICLASS::kBN)) {
+ eClsCur = pTC->m_iBidiClass;
+ if (eClsCur == FX_BIDICLASS::kBN) {
if (iNum)
++iNum;
continue;
}
- if (iClsCur >= static_cast<int32_t>(FX_BIDICLASS::kAL))
+ if (eClsCur >= FX_BIDICLASS::kAL)
continue;
- iAction = gc_FX_BidiNeutralActions[iState][iClsCur];
- iClsRun = GetDeferredNeutrals(iAction, iLevel);
- if (iClsRun != static_cast<int32_t>(FX_BIDICLASS::kN) && iNum > 0) {
- SetDeferredRunClass(chars, i, iNum, iClsRun);
+ iAction = gc_FX_BidiNeutralActions[iState][static_cast<size_t>(eClsCur)];
+ eClsRun = GetDeferredNeutrals(iAction, iLevel);
+ if (eClsRun != FX_BIDICLASS::kN && iNum > 0) {
+ SetDeferredRunClass(chars, i, iNum, eClsRun);
iNum = 0;
}
- iClsNew = GetResolvedNeutrals(iAction);
- if (iClsNew != static_cast<int32_t>(FX_BIDICLASS::kN))
- pTC->m_iBidiClass = (int16_t)iClsNew;
+ eClsNew = GetResolvedNeutrals(iAction);
+ if (eClsNew != FX_BIDICLASS::kN)
+ pTC->m_iBidiClass = eClsNew;
if (FX_BNAIn & iAction)
++iNum;
- iState = gc_FX_BidiNeutralStates[iState][iClsCur];
+ iState = gc_FX_BidiNeutralStates[iState][static_cast<size_t>(eClsCur)];
iLevel = pTC->m_iBidiLevel;
}
if (iNum == 0)
return;
- iClsCur = static_cast<int32_t>(Direction(iLevel));
- iClsRun =
- GetDeferredNeutrals(gc_FX_BidiNeutralActions[iState][iClsCur], iLevel);
- if (iClsRun != static_cast<int32_t>(FX_BIDICLASS::kN))
- SetDeferredRunClass(chars, i, iNum, iClsRun);
+ eClsCur = Direction(iLevel);
+ eClsRun = GetDeferredNeutrals(
+ gc_FX_BidiNeutralActions[iState][static_cast<size_t>(eClsCur)], iLevel);
+ if (eClsRun != FX_BIDICLASS::kN)
+ SetDeferredRunClass(chars, i, iNum, eClsRun);
}
void ResolveImplicit(std::vector<CFX_Char>* chars, size_t iCount) {
for (size_t i = 0; i < iCount; ++i) {
- int32_t iCls = (*chars)[i].m_iBidiClass;
- if (iCls == static_cast<int32_t>(FX_BIDICLASS::kBN) ||
- iCls <= static_cast<int32_t>(FX_BIDICLASS::kON) ||
- iCls >= static_cast<int32_t>(FX_BIDICLASS::kAL)) {
+ FX_BIDICLASS eCls = (*chars)[i].m_iBidiClass;
+ if (eCls == FX_BIDICLASS::kBN || eCls <= FX_BIDICLASS::kON ||
+ eCls >= FX_BIDICLASS::kAL) {
continue;
}
- 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 +=
+ gc_FX_BidiAddLevel[FX_IsOdd((*chars)[i].m_iBidiLevel)]
+ [static_cast<size_t>(eCls) - 1];
}
}
diff --git a/core/fxcrt/fx_unicode.h b/core/fxcrt/fx_unicode.h
index f1a1966..a889304 100644
--- a/core/fxcrt/fx_unicode.h
+++ b/core/fxcrt/fx_unicode.h
@@ -9,6 +9,7 @@
#include "core/fxcrt/fx_system.h"
+// NOTE: Order matters, less-than/greater-than comparisons are used.
enum class FX_BIDICLASS : uint8_t {
kON = 0, // Other Neutral
kL = 1, // Left Letter