[fpdfdoc] Refactor GetAutoFontSize() to use std::lower_bound

1.Replaced manual binary search with std::lower_bound.

2.Add const std::array support to make_span in span.h

Fixed: 381999806
Change-Id: Icdb0617a59108b78e535b22154ba1c4314c8dd35
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/126991
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfdoc/cpvt_variabletext.cpp b/core/fpdfdoc/cpvt_variabletext.cpp
index 0a69f1a..e865df5 100644
--- a/core/fpdfdoc/cpvt_variabletext.cpp
+++ b/core/fpdfdoc/cpvt_variabletext.cpp
@@ -19,6 +19,7 @@
 #include "core/fxcrt/compiler_specific.h"
 #include "core/fxcrt/fx_codepage.h"
 #include "core/fxcrt/fx_safe_types.h"
+#include "core/fxcrt/span.h"
 #include "core/fxcrt/stl_util.h"
 
 namespace {
@@ -767,27 +768,33 @@
 }
 
 float CPVT_VariableText::GetAutoFontSize() {
-  int32_t nTotal = sizeof(kFontSizeSteps) / sizeof(uint8_t);
-  if (IsMultiLine())
-    nTotal /= 4;
-  if (nTotal <= 0)
-    return 0;
-  if (GetPlateWidth() <= 0)
-    return 0;
+  constexpr size_t kFullSize = kFontSizeSteps.size();
+  constexpr size_t kQuarterSize = kFullSize / 4;
 
-  // TODO(tsepez): replace with std::lower_bound().
-  int32_t nLeft = 0;
-  int32_t nRight = nTotal - 1;
-  int32_t nMid = nTotal / 2;
-  while (nLeft <= nRight) {
-    if (IsBigger(kFontSizeSteps[nMid])) {
-      nRight = nMid - 1;
-    } else {
-      nLeft = nMid + 1;
-    }
-    nMid = (nLeft + nRight) / 2;
+  static_assert(kFullSize >= 4,
+                "kFontSizeSteps.size() must be at least 4 to ensure "
+                "kQuarterSize is not zero.");
+
+  if (GetPlateWidth() <= 0) {
+    return 0;
   }
-  return static_cast<float>(kFontSizeSteps[nMid]);
+
+  size_t span_size = IsMultiLine() ? kQuarterSize : kFullSize;
+  auto font_span = pdfium::make_span(kFontSizeSteps).first(span_size);
+
+  constexpr bool kUnusedValue = true;
+  auto it = std::lower_bound(
+      font_span.begin(), font_span.end(), kUnusedValue,
+      [this](uint8_t font_size, bool) { return !IsBigger(font_size); });
+
+  if (it == font_span.end()) {
+    return static_cast<float>(font_span.back());
+  }
+
+  if (it == font_span.begin()) {
+    return static_cast<float>(*it);
+  }
+  return static_cast<float>(font_span[it - font_span.begin() - 1]);
 }
 
 bool CPVT_VariableText::IsBigger(float fFontSize) const {
diff --git a/core/fxcrt/span.h b/core/fxcrt/span.h
index bb9b066..604b001 100644
--- a/core/fxcrt/span.h
+++ b/core/fxcrt/span.h
@@ -392,6 +392,11 @@
   return span<T>(array);
 }
 
+template <typename T, size_t N>
+constexpr span<const T> make_span(const std::array<T, N>& array) noexcept {
+  return span<const T>(const_cast<std::array<T, N>&>(array));
+}
+
 template <typename Container,
           typename T = typename Container::value_type,
           typename = internal::EnableIfSpanCompatibleContainer<Container, T>>