Encapsulate FT_Load_Sfnt_Table() calls
Implement CFX_Face::GetSfntTable() and switch FT_Load_Sfnt_Table()
callers to use it.
Bug: pdfium:2037
Change-Id: I999e5bfc485ec2995faf56eac8577da72e90164f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/114776
Reviewed-by: Dominik Röttsches <drott@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp
index 88a5686..0961ccc 100644
--- a/core/fpdfapi/font/cpdf_cidfont.cpp
+++ b/core/fpdfapi/font/cpdf_cidfont.cpp
@@ -654,17 +654,14 @@
static constexpr uint32_t kGsubTag =
CFX_FontMapper::MakeTag('G', 'S', 'U', 'B');
- FXFT_FaceRec* face = m_Font.GetFaceRec();
- unsigned long length = 0;
- int error = FT_Load_Sfnt_Table(face, kGsubTag, 0, nullptr, &length);
- if (error || !length) {
+ RetainPtr<CFX_Face> face = m_Font.GetFace();
+ size_t length = face->GetSfntTable(kGsubTag, {});
+ if (!length) {
return index;
}
FixedUninitDataVector<uint8_t> sub_data(length);
- error = FT_Load_Sfnt_Table(face, kGsubTag, 0, sub_data.writable_span().data(),
- nullptr);
- if (error) {
+ if (!face->GetSfntTable(kGsubTag, sub_data.writable_span())) {
return index;
}
diff --git a/core/fxge/android/cfpf_skiafont.cpp b/core/fxge/android/cfpf_skiafont.cpp
index ede116f..df46d94 100644
--- a/core/fxge/android/cfpf_skiafont.cpp
+++ b/core/fxge/android/cfpf_skiafont.cpp
@@ -13,7 +13,6 @@
#include "core/fxcrt/fx_system.h"
#include "core/fxge/android/cfpf_skiafontmgr.h"
#include "core/fxge/android/cfpf_skiapathfont.h"
-#include "core/fxge/freetype/fx_freetype.h"
#include "core/fxge/fx_fontencoding.h"
#include "third_party/base/numerics/safe_conversions.h"
@@ -38,10 +37,6 @@
if (!m_Face)
return 0;
- FT_ULong ulSize = pdfium::base::checked_cast<FT_ULong>(pBuffer.size());
- if (FT_Load_Sfnt_Table(m_Face->GetRec(), dwTable, 0, pBuffer.data(),
- &ulSize)) {
- return 0;
- }
- return pdfium::base::checked_cast<uint32_t>(ulSize);
+ return pdfium::base::checked_cast<uint32_t>(
+ m_Face->GetSfntTable(dwTable, pBuffer));
}
diff --git a/core/fxge/cfx_face.cpp b/core/fxge/cfx_face.cpp
index f335d42..c9bcd33 100644
--- a/core/fxge/cfx_face.cpp
+++ b/core/fxge/cfx_face.cpp
@@ -314,6 +314,24 @@
return {GetRec()->stream->base, GetRec()->stream->size};
}
+size_t CFX_Face::GetSfntTable(uint32_t table, pdfium::span<uint8_t> buffer) {
+ unsigned long length =
+ pdfium::base::checked_cast<unsigned long>(buffer.size());
+ if (length) {
+ int error = FT_Load_Sfnt_Table(GetRec(), table, 0, buffer.data(), &length);
+ if (error || length != buffer.size()) {
+ return 0;
+ }
+ return buffer.size();
+ }
+
+ int error = FT_Load_Sfnt_Table(GetRec(), table, 0, nullptr, &length);
+ if (error || !length) {
+ return 0;
+ }
+ return pdfium::base::checked_cast<size_t>(length);
+}
+
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 b9e5aba..4a0ee5d 100644
--- a/core/fxge/cfx_face.h
+++ b/core/fxge/cfx_face.h
@@ -68,6 +68,10 @@
pdfium::span<uint8_t> GetData() const;
+ // Returns the size of the data, or 0 on failure. Only write into `buffer` if
+ // it is large enough to hold the data.
+ size_t GetSfntTable(uint32_t table, pdfium::span<uint8_t> buffer);
+
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 e117b5e..1bb2375 100644
--- a/xfa/fgas/font/cfgas_fontmgr.cpp
+++ b/xfa/fgas/font/cfgas_fontmgr.cpp
@@ -739,17 +739,16 @@
GetUSBCSB(pFace->GetRec(), pFont->m_dwUsb, pFont->m_dwCsb);
- FT_ULong dwTag;
- FT_ENC_TAG(dwTag, 'n', 'a', 'm', 'e');
+ static constexpr uint32_t kNameTag =
+ CFX_FontMapper::MakeTag('n', 'a', 'm', 'e');
DataVector<uint8_t> table;
- unsigned long nLength = 0;
- unsigned int error =
- FT_Load_Sfnt_Table(pFace->GetRec(), dwTag, 0, nullptr, &nLength);
- if (error == 0 && nLength != 0) {
- table.resize(nLength);
- if (FT_Load_Sfnt_Table(pFace->GetRec(), dwTag, 0, table.data(), nullptr))
+ size_t table_size = pFace->GetSfntTable(kNameTag, table);
+ if (table_size) {
+ table.resize(table_size);
+ if (!pFace->GetSfntTable(kNameTag, table)) {
table.clear();
+ }
}
pFont->m_wsFamilyNames = GetNames(table);
pFont->m_wsFamilyNames.push_back(