summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xfa/fgas/font/fgas_fontutils.cpp33
1 files changed, 17 insertions, 16 deletions
diff --git a/xfa/fgas/font/fgas_fontutils.cpp b/xfa/fgas/font/fgas_fontutils.cpp
index 2cf56ce7ca..b4adaa85bd 100644
--- a/xfa/fgas/font/fgas_fontutils.cpp
+++ b/xfa/fgas/font/fgas_fontutils.cpp
@@ -1868,22 +1868,23 @@ const FGAS_FontInfo g_XFAFontsMap[] = {
} // namespace
-const FGAS_FONTUSB* FGAS_GetUnicodeBitField(wchar_t wUnicode) {
- int32_t iEnd = sizeof(g_FXGdiFontUSBTable) / sizeof(FGAS_FONTUSB) - 1;
- ASSERT(iEnd >= 0);
-
- int32_t iStart = 0;
- int32_t iMid;
- do {
- iMid = (iStart + iEnd) / 2;
- const FGAS_FONTUSB& usb = g_FXGdiFontUSBTable[iMid];
- if (wUnicode < usb.wStartUnicode)
- iEnd = iMid - 1;
- else if (wUnicode > usb.wEndUnicode)
- iStart = iMid + 1;
- else
- return &usb;
- } while (iStart <= iEnd);
+const FGAS_FONTUSB* FGAS_GetUnicodeBitField(wchar_t unicode) {
+ // This search is trying to find the entry where the unicode character falls
+ // bewtween start and end. std::upper_bound needs to be used here instead of
+ // lower_bound, because they return the first value that meets the
+ // requirement, as though they are linearly searching. For lower_bound this
+ // means the first element less then the value, and for upper_bound this means
+ // the first element greater then the value. Since the entries are sorted in
+ // ascending order, the correct entry is the first one with an end greater,
+ // aka after, the value.
+ auto* result = std::upper_bound(
+ std::begin(g_FXGdiFontUSBTable), std::end(g_FXGdiFontUSBTable), unicode,
+ [](const wchar_t unicode, const FGAS_FONTUSB& iter) {
+ return iter.wEndUnicode > unicode;
+ });
+ if (result != std::end(g_FXGdiFontUSBTable) &&
+ result->wStartUnicode <= unicode && result->wEndUnicode >= unicode)
+ return result;
return nullptr;
}