summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/fxcrt/fx_bidi.cpp520
1 files changed, 258 insertions, 262 deletions
diff --git a/core/fxcrt/fx_bidi.cpp b/core/fxcrt/fx_bidi.cpp
index 669fc5bd88..caf12fa8dd 100644
--- a/core/fxcrt/fx_bidi.cpp
+++ b/core/fxcrt/fx_bidi.cpp
@@ -230,316 +230,313 @@ const int32_t gc_FX_BidiAddLevel[][4] = {
{1, 0, 1, 1},
};
-class CFX_BidiLine {
- public:
- void BidiLine(std::vector<CFX_Char>* chars, size_t iCount) {
- ASSERT(iCount <= chars->size());
- 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 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 GetDeferredType(int32_t val) {
+ return (val >> 4) & 0x0F;
+}
- int32_t GetResolvedType(int32_t val) { return val & 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 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;
- }
+int32_t GetResolvedNeutrals(int32_t iAction) {
+ iAction &= 0xF;
+ return iAction == FX_BNAIn ? 0 : iAction;
+}
- void ReverseString(std::vector<CFX_Char>* chars,
- size_t iStart,
- size_t iCount) {
- ASSERT(pdfium::IndexInBounds(*chars, iStart));
- ASSERT(iStart + iCount <= chars->size());
+void ReverseString(std::vector<CFX_Char>* chars, size_t iStart, size_t iCount) {
+ ASSERT(pdfium::IndexInBounds(*chars, iStart));
+ ASSERT(iStart + iCount <= chars->size());
- std::reverse(chars->begin() + iStart, chars->begin() + iStart + iCount);
- }
+ std::reverse(chars->begin() + iStart, chars->begin() + iStart + iCount);
+}
- void SetDeferredRun(std::vector<CFX_Char>* chars,
- bool bClass,
- size_t iStart,
- size_t iCount,
- int32_t iValue) {
- ASSERT(iStart <= chars->size());
- ASSERT(iStart >= iCount);
-
- size_t iLast = iStart - iCount;
- for (size_t i = iStart - 1; i >= iLast; --i) {
- if (bClass)
- (*chars)[i].m_iBidiClass = static_cast<int16_t>(iValue);
- else
- (*chars)[i].m_iBidiLevel = static_cast<int16_t>(iValue);
-
- if (i == 0)
- break;
- }
+void SetDeferredRun(std::vector<CFX_Char>* chars,
+ bool bClass,
+ size_t iStart,
+ size_t iCount,
+ int32_t iValue) {
+ ASSERT(iStart <= chars->size());
+ ASSERT(iStart >= iCount);
+
+ size_t iLast = iStart - iCount;
+ for (size_t i = iStart - 1; i >= iLast; --i) {
+ if (bClass)
+ (*chars)[i].m_iBidiClass = static_cast<int16_t>(iValue);
+ else
+ (*chars)[i].m_iBidiLevel = static_cast<int16_t>(iValue);
+
+ if (i == 0)
+ break;
}
+}
- void Classify(std::vector<CFX_Char>* chars, size_t iCount, bool bWS) {
- if (bWS) {
- for (size_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;
- }
-
+void Classify(std::vector<CFX_Char>* chars, size_t iCount, bool bWS) {
+ if (bWS) {
for (size_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]);
+ cur.m_iBidiClass =
+ static_cast<int16_t>(cur.char_props() & FX_BIDICLASSBITSMASK) >>
+ FX_BIDICLASSBITS;
}
+ return;
}
- void ResolveExplicit(std::vector<CFX_Char>* chars, size_t iCount) {
- for (size_t i = 0; i < iCount; ++i)
- (*chars)[i].m_iBidiLevel = 0;
+ for (size_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, size_t iCount) {
+ for (size_t i = 0; i < iCount; ++i)
+ (*chars)[i].m_iBidiLevel = 0;
+}
- void ResolveWeak(std::vector<CFX_Char>* chars, size_t iCount) {
- if (iCount <= 1)
- return;
- --iCount;
-
- int32_t iLevelCur = 0;
- int32_t iState = FX_BWSxl;
- size_t iNum = 0;
- int32_t iClsCur;
- int32_t iClsRun;
- int32_t iClsNew;
- size_t i = 0;
- 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;
- }
+void ResolveWeak(std::vector<CFX_Char>* chars, size_t iCount) {
+ if (iCount <= 1)
+ return;
+ --iCount;
+
+ int32_t iLevelCur = 0;
+ int32_t iState = FX_BWSxl;
+ size_t iNum = 0;
+ int32_t iClsCur;
+ int32_t iClsRun;
+ int32_t iClsNew;
+ size_t i = 0;
+ 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;
}
- }
- if (iClsCur > FX_BIDICLASS_BN)
+ } else {
+ if (iNum > 0)
+ ++iNum;
continue;
-
- int32_t 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)
- return;
+ if (iClsCur > FX_BIDICLASS_BN)
+ continue;
- iClsCur = Direction(0);
- iClsRun = GetDeferredType(gc_FX_BidiWeakActions[iState][iClsCur]);
- if (iClsRun != FX_BWAXX)
+ int32_t 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;
- void ResolveNeutrals(std::vector<CFX_Char>* chars, size_t iCount) {
- if (iCount <= 1)
- return;
- --iCount;
-
- CFX_Char* pTC;
- int32_t iLevel = 0;
- int32_t iState = FX_BNSl;
- size_t i = 0;
- size_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;
- }
- if (iClsCur >= FX_BIDICLASS_AL)
- continue;
+ iState = gc_FX_BidiWeakStates[iState][iClsCur];
+ }
+ if (iNum == 0)
+ return;
- 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;
- }
+ iClsCur = Direction(0);
+ iClsRun = GetDeferredType(gc_FX_BidiWeakActions[iState][iClsCur]);
+ if (iClsRun != FX_BWAXX)
+ SetDeferredRun(chars, true, i, iNum, iClsRun);
+}
- iClsNew = GetResolvedNeutrals(iAction);
- if (iClsNew != FX_BIDICLASS_N)
- pTC->m_iBidiClass = (int16_t)iClsNew;
- if (FX_BNAIn & iAction)
+void ResolveNeutrals(std::vector<CFX_Char>* chars, size_t iCount) {
+ if (iCount <= 1)
+ return;
+ --iCount;
+
+ CFX_Char* pTC;
+ int32_t iLevel = 0;
+ int32_t iState = FX_BNSl;
+ size_t i = 0;
+ size_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;
-
- iState = gc_FX_BidiNeutralStates[iState][iClsCur];
- iLevel = pTC->m_iBidiLevel;
+ continue;
}
- if (iNum == 0)
- return;
+ if (iClsCur >= FX_BIDICLASS_AL)
+ continue;
- iClsCur = Direction(iLevel);
- iClsRun =
- GetDeferredNeutrals(gc_FX_BidiNeutralActions[iState][iClsCur], iLevel);
- if (iClsRun != FX_BIDICLASS_N)
+ 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;
+ }
- 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 == FX_BIDICLASS_BN)
- continue;
- if (iCls <= FX_BIDICLASS_ON || iCls >= FX_BIDICLASS_AL)
- continue;
+ iClsNew = GetResolvedNeutrals(iAction);
+ if (iClsNew != FX_BIDICLASS_N)
+ pTC->m_iBidiClass = (int16_t)iClsNew;
+ if (FX_BNAIn & iAction)
+ ++iNum;
- int32_t iLevel = (*chars)[i].m_iBidiLevel;
- iLevel += gc_FX_BidiAddLevel[FX_IsOdd(iLevel)][iCls - 1];
- (*chars)[i].m_iBidiLevel = (int16_t)iLevel;
- }
+ iState = gc_FX_BidiNeutralStates[iState][iClsCur];
+ iLevel = pTC->m_iBidiLevel;
}
+ if (iNum == 0)
+ return;
+
+ iClsCur = Direction(iLevel);
+ iClsRun =
+ GetDeferredNeutrals(gc_FX_BidiNeutralActions[iState][iClsCur], iLevel);
+ if (iClsRun != FX_BIDICLASS_N)
+ SetDeferredRun(chars, true, i, iNum, iClsRun);
+}
- void ResolveWhitespace(std::vector<CFX_Char>* chars, size_t iCount) {
- if (iCount <= 1)
- return;
- iCount--;
-
- int32_t iLevel = 0;
- size_t i = 0;
- size_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 = static_cast<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);
+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 == FX_BIDICLASS_BN)
+ continue;
+ if (iCls <= FX_BIDICLASS_ON || iCls >= FX_BIDICLASS_AL)
+ continue;
+
+ int32_t iLevel = (*chars)[i].m_iBidiLevel;
+ iLevel += gc_FX_BidiAddLevel[FX_IsOdd(iLevel)][iCls - 1];
+ (*chars)[i].m_iBidiLevel = (int16_t)iLevel;
}
+}
- size_t ReorderLevel(std::vector<CFX_Char>* chars,
- size_t iCount,
- int32_t iBaseLevel,
- size_t iStart,
- bool bReverse) {
- ASSERT(iBaseLevel >= 0 && iBaseLevel <= kBidiMaxLevel);
- ASSERT(iStart < iCount);
-
- if (iCount < 1)
- return 0;
-
- bReverse = bReverse || FX_IsOdd(iBaseLevel);
- size_t i = iStart;
- for (; i < iCount; ++i) {
- int32_t iLevel = (*chars)[i].m_iBidiLevel;
- if (iLevel == iBaseLevel)
- continue;
- if (iLevel < iBaseLevel)
+void ResolveWhitespace(std::vector<CFX_Char>* chars, size_t iCount) {
+ if (iCount <= 1)
+ return;
+ iCount--;
+
+ int32_t iLevel = 0;
+ size_t i = 0;
+ size_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 = static_cast<int16_t>(iLevel);
+ ++iNum;
break;
+ case FX_BIDICLASS_S:
+ case FX_BIDICLASS_B:
+ if (iNum > 0)
+ SetDeferredRun(chars, false, i, iNum, 0);
- i += ReorderLevel(chars, iCount, iBaseLevel + 1, i, bReverse) - 1;
+ (*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);
+}
- size_t iNum = i - iStart;
- if (bReverse && iNum > 1)
- ReverseString(chars, iStart, iNum);
+size_t ReorderLevel(std::vector<CFX_Char>* chars,
+ size_t iCount,
+ int32_t iBaseLevel,
+ size_t iStart,
+ bool bReverse) {
+ ASSERT(iBaseLevel >= 0 && iBaseLevel <= kBidiMaxLevel);
+ ASSERT(iStart < iCount);
+
+ if (iCount < 1)
+ return 0;
+
+ bReverse = bReverse || FX_IsOdd(iBaseLevel);
+ size_t i = iStart;
+ for (; i < iCount; ++i) {
+ int32_t iLevel = (*chars)[i].m_iBidiLevel;
+ if (iLevel == iBaseLevel)
+ continue;
+ if (iLevel < iBaseLevel)
+ break;
- return iNum;
+ i += ReorderLevel(chars, iCount, iBaseLevel + 1, i, bReverse) - 1;
}
- void Reorder(std::vector<CFX_Char>* chars, size_t iCount) {
- for (size_t i = 0; i < iCount;)
- i += ReorderLevel(chars, iCount, 0, i, false);
- }
+ size_t iNum = i - iStart;
+ if (bReverse && iNum > 1)
+ ReverseString(chars, iStart, iNum);
- void Position(std::vector<CFX_Char>* chars, size_t iCount) {
- for (size_t i = 0; i < iCount; ++i) {
- if ((*chars)[i].m_iBidiPos > iCount)
- continue;
+ return iNum;
+}
- (*chars)[(*chars)[i].m_iBidiPos].m_iBidiOrder = i;
- }
+void Reorder(std::vector<CFX_Char>* chars, size_t iCount) {
+ for (size_t i = 0; i < iCount;)
+ i += ReorderLevel(chars, iCount, 0, i, false);
+}
+
+void Position(std::vector<CFX_Char>* chars, size_t iCount) {
+ for (size_t i = 0; i < iCount; ++i) {
+ if ((*chars)[i].m_iBidiPos > iCount)
+ continue;
+
+ (*chars)[(*chars)[i].m_iBidiPos].m_iBidiOrder = i;
}
-};
+}
+void BidiLine(std::vector<CFX_Char>* chars, size_t iCount) {
+ ASSERT(iCount <= chars->size());
+ 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);
+}
#endif // PDF_ENABLE_XFA
} // namespace
@@ -622,7 +619,6 @@ void CFX_BidiString::SetOverallDirectionRight() {
#ifdef PDF_ENABLE_XFA
void FX_BidiLine(std::vector<CFX_Char>* chars, size_t iCount) {
- CFX_BidiLine blt;
- blt.BidiLine(chars, iCount);
+ BidiLine(chars, iCount);
}
#endif // PDF_ENABLE_XFA