[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>>