Encapsulate FT_Get_Sfnt_Table() calls
Implement various getters in CFX_Face to satisfy existing
FT_Get_Sfnt_Table() uses in the code base.
Bug: pdfium:2037
Change-Id: Ie25f93ada0da61e323ef7e36323a36e839f0846b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/114794
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Dominik Röttsches <drott@chromium.org>
diff --git a/core/fxge/android/cfpf_skiafontmgr.cpp b/core/fxge/android/cfpf_skiafontmgr.cpp
index 08d7d17..59db044 100644
--- a/core/fxge/android/cfpf_skiafontmgr.cpp
+++ b/core/fxge/android/cfpf_skiafontmgr.cpp
@@ -199,16 +199,14 @@
FPF_SKIACHARSET_Symbol,
};
-uint32_t FPF_SkiaGetFaceCharset(TT_OS2* pOS2) {
- uint32_t dwCharset = 0;
- if (pOS2) {
- for (int32_t i = 0; i < 32; i++) {
- if (pOS2->ulCodePageRange1 & (1 << i))
- dwCharset |= kFPFSkiaFontCharsets[i];
+uint32_t FPF_SkiaGetFaceCharset(uint32_t code_range) {
+ uint32_t charset = 0;
+ for (int32_t i = 0; i < 32; i++) {
+ if (code_range & (1 << i)) {
+ charset |= kFPFSkiaFontCharsets[i];
}
}
- dwCharset |= FPF_SKIACHARSET_Default;
- return dwCharset;
+ return charset;
}
} // namespace
@@ -389,21 +387,26 @@
if (face->IsFixedWidth()) {
dwStyle |= FXFONT_FIXED_PITCH;
}
- TT_OS2* pOS2 =
- static_cast<TT_OS2*>(FT_Get_Sfnt_Table(face->GetRec(), ft_sfnt_os2));
- if (pOS2) {
- if (pOS2->ulCodePageRange1 & (1 << 31))
+
+ uint32_t charset = FPF_SKIACHARSET_Default;
+ absl::optional<std::array<uint32_t, 2>> code_page_range =
+ face->GetOs2CodePageRange();
+ if (code_page_range.has_value()) {
+ if (code_page_range.value()[0] & (1 << 31)) {
dwStyle |= FXFONT_SYMBOLIC;
- if (pOS2->panose[0] == 2) {
- uint8_t uSerif = pOS2->panose[1];
- if ((uSerif > 1 && uSerif < 10) || uSerif > 13)
- dwStyle |= FXFONT_SERIF;
+ }
+ charset |= FPF_SkiaGetFaceCharset(code_page_range.value()[0]);
+ }
+
+ absl::optional<std::array<uint8_t, 2>> panose = face->GetOs2Panose();
+ if (panose.has_value() && panose.value()[0] == 2) {
+ uint8_t serif = panose.value()[1];
+ if ((serif > 1 && serif < 10) || serif > 13) {
+ dwStyle |= FXFONT_SERIF;
}
}
- if (pOS2 && (pOS2->ulCodePageRange1 & (1 << 31)))
- dwStyle |= FXFONT_SYMBOLIC;
return std::make_unique<CFPF_SkiaPathFont>(
- file, face->GetFamilyName(), dwStyle, face->GetRec()->face_index,
- FPF_SkiaGetFaceCharset(pOS2), face->GetRec()->num_glyphs);
+ file, face->GetFamilyName(), dwStyle, face->GetRec()->face_index, charset,
+ face->GetRec()->num_glyphs);
}
diff --git a/core/fxge/cfx_face.cpp b/core/fxge/cfx_face.cpp
index c9bcd33..a5b5994 100644
--- a/core/fxge/cfx_face.cpp
+++ b/core/fxge/cfx_face.cpp
@@ -332,6 +332,34 @@
return pdfium::base::checked_cast<size_t>(length);
}
+absl::optional<std::array<uint32_t, 4>> CFX_Face::GetOs2UnicodeRange() {
+ auto* os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(GetRec(), FT_SFNT_OS2));
+ if (!os2) {
+ return absl::nullopt;
+ }
+ return std::array<uint32_t, 4>{static_cast<uint32_t>(os2->ulUnicodeRange1),
+ static_cast<uint32_t>(os2->ulUnicodeRange2),
+ static_cast<uint32_t>(os2->ulUnicodeRange3),
+ static_cast<uint32_t>(os2->ulUnicodeRange4)};
+}
+
+absl::optional<std::array<uint32_t, 2>> CFX_Face::GetOs2CodePageRange() {
+ auto* os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(GetRec(), FT_SFNT_OS2));
+ if (!os2) {
+ return absl::nullopt;
+ }
+ return std::array<uint32_t, 2>{static_cast<uint32_t>(os2->ulCodePageRange1),
+ static_cast<uint32_t>(os2->ulCodePageRange2)};
+}
+
+absl::optional<std::array<uint8_t, 2>> CFX_Face::GetOs2Panose() {
+ auto* os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(GetRec(), FT_SFNT_OS2));
+ if (!os2) {
+ return absl::nullopt;
+ }
+ return std::array<uint8_t, 2>{os2->panose[0], os2->panose[1]};
+}
+
std::unique_ptr<CFX_GlyphBitmap> CFX_Face::RenderGlyph(const CFX_Font* pFont,
uint32_t glyph_index,
bool bFontStyle,
diff --git a/core/fxge/cfx_face.h b/core/fxge/cfx_face.h
index 4a0ee5d..6c57504 100644
--- a/core/fxge/cfx_face.h
+++ b/core/fxge/cfx_face.h
@@ -7,6 +7,7 @@
#include <stdint.h>
+#include <array>
#include <memory>
#include "build/build_config.h"
@@ -72,6 +73,10 @@
// it is large enough to hold the data.
size_t GetSfntTable(uint32_t table, pdfium::span<uint8_t> buffer);
+ absl::optional<std::array<uint32_t, 4>> GetOs2UnicodeRange();
+ absl::optional<std::array<uint32_t, 2>> GetOs2CodePageRange();
+ absl::optional<std::array<uint8_t, 2>> GetOs2Panose();
+
std::unique_ptr<CFX_GlyphBitmap> RenderGlyph(const CFX_Font* pFont,
uint32_t glyph_index,
bool bFontStyle,
diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp
index 1bb2375..bef5532 100644
--- a/xfa/fgas/font/cfgas_fontmgr.cpp
+++ b/xfa/fgas/font/cfgas_fontmgr.cpp
@@ -21,6 +21,7 @@
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/span_util.h"
#include "core/fxge/cfx_font.h"
#include "core/fxge/cfx_fontmapper.h"
#include "core/fxge/cfx_fontmgr.h"
@@ -431,25 +432,6 @@
return results;
}
-void GetUSBCSB(FXFT_FaceRec* pFace, uint32_t* USB, uint32_t* CSB) {
- TT_OS2* pOS2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(pFace, ft_sfnt_os2));
- if (!pOS2) {
- USB[0] = 0;
- USB[1] = 0;
- USB[2] = 0;
- USB[3] = 0;
- CSB[0] = 0;
- CSB[1] = 0;
- return;
- }
- USB[0] = static_cast<uint32_t>(pOS2->ulUnicodeRange1);
- USB[1] = static_cast<uint32_t>(pOS2->ulUnicodeRange2);
- USB[2] = static_cast<uint32_t>(pOS2->ulUnicodeRange3);
- USB[3] = static_cast<uint32_t>(pOS2->ulUnicodeRange4);
- CSB[0] = static_cast<uint32_t>(pOS2->ulCodePageRange1);
- CSB[1] = static_cast<uint32_t>(pOS2->ulCodePageRange2);
-}
-
uint32_t GetFlags(const RetainPtr<CFX_Face>& face) {
uint32_t flags = 0;
if (face->IsBold()) {
@@ -462,17 +444,18 @@
flags |= FXFONT_FIXED_PITCH;
}
- TT_OS2* pOS2 =
- static_cast<TT_OS2*>(FT_Get_Sfnt_Table(face->GetRec(), ft_sfnt_os2));
- if (!pOS2)
- return flags;
-
- if (pOS2->ulCodePageRange1 & (1 << 31))
+ absl::optional<std::array<uint32_t, 2>> code_page_range =
+ face->GetOs2CodePageRange();
+ if (code_page_range.has_value() && (code_page_range.value()[0] & (1 << 31))) {
flags |= FXFONT_SYMBOLIC;
- if (pOS2->panose[0] == 2) {
- uint8_t uSerif = pOS2->panose[1];
- if ((uSerif > 1 && uSerif < 10) || uSerif > 13)
+ }
+
+ absl::optional<std::array<uint8_t, 2>> panose = face->GetOs2Panose();
+ if (panose.has_value() && panose.value()[0] == 2) {
+ uint8_t serif = panose.value()[1];
+ if ((serif > 1 && serif < 10) || serif > 13) {
flags |= FXFONT_SERIF;
+ }
}
return flags;
}
@@ -737,7 +720,25 @@
auto pFont = std::make_unique<CFGAS_FontDescriptor>();
pFont->m_dwFontStyles |= GetFlags(pFace);
- GetUSBCSB(pFace->GetRec(), pFont->m_dwUsb, pFont->m_dwCsb);
+ // TODO(crbug.com/pdfium/2085): Use make_span() in fewer places after updating
+ // pdfium::span.
+ absl::optional<std::array<uint32_t, 4>> unicode_range =
+ pFace->GetOs2UnicodeRange();
+ auto usb_span = pdfium::make_span(pFont->m_dwUsb);
+ if (unicode_range.has_value()) {
+ fxcrt::spancpy(usb_span, pdfium::make_span(unicode_range.value()));
+ } else {
+ fxcrt::spanclr(usb_span);
+ }
+
+ absl::optional<std::array<uint32_t, 2>> code_page_range =
+ pFace->GetOs2CodePageRange();
+ auto csb_span = pdfium::make_span(pFont->m_dwCsb);
+ if (code_page_range.has_value()) {
+ fxcrt::spancpy(csb_span, pdfium::make_span(code_page_range.value()));
+ } else {
+ fxcrt::spanclr(csb_span);
+ }
static constexpr uint32_t kNameTag =
CFX_FontMapper::MakeTag('n', 'a', 'm', 'e');