Encapsulate font metrics code inside CFX_Face
Instead of directly calling FreeType code on the handle returned by
CFX_Face::GetRec(), add CFX_Face methods for reading font metrics.
Bug: pdfium:2037
Change-Id: Ida247f6c6b45143a59fd2695b6b89e797c171a80
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/107495
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Dominik Röttsches <drott@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp
index a8d14bf..f9beb2f 100644
--- a/core/fpdfapi/font/cpdf_cidfont.cpp
+++ b/core/fpdfapi/font/cpdf_cidfont.cpp
@@ -522,14 +522,15 @@
FX_RECT rect;
bool bVert = false;
int glyph_index = GlyphFromCharCode(charcode, &bVert);
- FXFT_FaceRec* face = m_Font.GetFaceRec();
+ RetainPtr<CFX_Face> face = m_Font.GetFace();
if (face) {
- if (m_Font.GetFace()->IsTricky()) {
- int err =
- FT_Load_Glyph(face, glyph_index, FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
+ FXFT_FaceRec* face_rec = face->GetRec();
+ if (face->IsTricky()) {
+ int err = FT_Load_Glyph(face_rec, glyph_index,
+ FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
if (!err) {
FT_Glyph glyph;
- err = FT_Get_Glyph(face->glyph, &glyph);
+ err = FT_Get_Glyph(face_rec->glyph, &glyph);
if (!err) {
FT_BBox cbox;
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &cbox);
@@ -537,8 +538,8 @@
const int xMax = FTPosToCBoxInt(cbox.xMax);
const int yMin = FTPosToCBoxInt(cbox.yMin);
const int yMax = FTPosToCBoxInt(cbox.yMax);
- const int pixel_size_x = face->size->metrics.x_ppem;
- const int pixel_size_y = face->size->metrics.y_ppem;
+ const int pixel_size_x = face_rec->size->metrics.x_ppem;
+ const int pixel_size_y = face_rec->size->metrics.y_ppem;
if (pixel_size_x == 0 || pixel_size_y == 0) {
rect = FX_RECT(xMin, yMax, xMax, yMin);
} else {
@@ -546,15 +547,14 @@
FX_RECT(xMin * 1000 / pixel_size_x, yMax * 1000 / pixel_size_y,
xMax * 1000 / pixel_size_x, yMin * 1000 / pixel_size_y);
}
- rect.top = std::min(rect.top,
- static_cast<int>(FXFT_Get_Face_Ascender(face)));
- rect.bottom = std::max(
- rect.bottom, static_cast<int>(FXFT_Get_Face_Descender(face)));
+ rect.top = std::min(rect.top, static_cast<int>(face->GetAscender()));
+ rect.bottom =
+ std::max(rect.bottom, static_cast<int>(face->GetDescender()));
FT_Done_Glyph(glyph);
}
}
} else {
- int err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE);
+ int err = FT_Load_Glyph(face_rec, glyph_index, FT_LOAD_NO_SCALE);
if (err == 0) {
rect = GetCharBBoxForFace(face);
if (rect.top <= kMaxRectTop)
diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp
index 5eab3cd..3c5d1b6 100644
--- a/core/fpdfapi/font/cpdf_font.cpp
+++ b/core/fpdfapi/font/cpdf_font.cpp
@@ -218,16 +218,16 @@
void CPDF_Font::CheckFontMetrics() {
if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 &&
m_FontBBox.right == 0) {
- FXFT_FaceRec* face = m_Font.GetFaceRec();
+ RetainPtr<CFX_Face> face = m_Font.GetFace();
if (face) {
// Note that `m_FontBBox` is deliberately flipped.
- const FX_RECT raw_bbox = m_Font.GetFace()->GetBBox();
+ const FX_RECT raw_bbox = face->GetBBox();
m_FontBBox.left = TT2PDF(raw_bbox.left, face);
m_FontBBox.bottom = TT2PDF(raw_bbox.top, face);
m_FontBBox.right = TT2PDF(raw_bbox.right, face);
m_FontBBox.top = TT2PDF(raw_bbox.bottom, face);
- m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face);
- m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face);
+ m_Ascent = TT2PDF(face->GetAscender(), face);
+ m_Descent = TT2PDF(face->GetDescender(), face);
} else {
bool bFirst = true;
for (int i = 0; i < 256; i++) {
@@ -408,8 +408,8 @@
}
// static
-int CPDF_Font::TT2PDF(FT_Pos m, FXFT_FaceRec* face) {
- int upm = FXFT_Get_Face_UnitsPerEM(face);
+int CPDF_Font::TT2PDF(FT_Pos m, const RetainPtr<CFX_Face>& face) {
+ int upm = face->GetUnitsPerEm();
if (upm == 0)
return pdfium::base::saturated_cast<int>(m);
@@ -418,12 +418,13 @@
}
// static
-FX_RECT CPDF_Font::GetCharBBoxForFace(FXFT_FaceRec* face) {
- pdfium::base::ClampedNumeric<FT_Pos> left = FXFT_Get_Glyph_HoriBearingX(face);
- pdfium::base::ClampedNumeric<FT_Pos> top = FXFT_Get_Glyph_HoriBearingY(face);
+FX_RECT CPDF_Font::GetCharBBoxForFace(const RetainPtr<CFX_Face>& face) {
+ FXFT_FaceRec* rec = face->GetRec();
+ pdfium::base::ClampedNumeric<FT_Pos> left = FXFT_Get_Glyph_HoriBearingX(rec);
+ pdfium::base::ClampedNumeric<FT_Pos> top = FXFT_Get_Glyph_HoriBearingY(rec);
return FX_RECT(TT2PDF(left, face), TT2PDF(top, face),
- TT2PDF(left + FXFT_Get_Glyph_Width(face), face),
- TT2PDF(top - FXFT_Get_Glyph_Height(face), face));
+ TT2PDF(left + FXFT_Get_Glyph_Width(rec), face),
+ TT2PDF(top - FXFT_Get_Glyph_Height(rec), face));
}
// static
diff --git a/core/fpdfapi/font/cpdf_font.h b/core/fpdfapi/font/cpdf_font.h
index c3ac83a..c8c46b1 100644
--- a/core/fpdfapi/font/cpdf_font.h
+++ b/core/fpdfapi/font/cpdf_font.h
@@ -139,8 +139,8 @@
CPDF_Font(CPDF_Document* pDocument, RetainPtr<CPDF_Dictionary> pFontDict);
~CPDF_Font() override;
- static int TT2PDF(FT_Pos m, FXFT_FaceRec* face);
- static FX_RECT GetCharBBoxForFace(FXFT_FaceRec* face);
+ static int TT2PDF(FT_Pos m, const RetainPtr<CFX_Face>& face);
+ static FX_RECT GetCharBBoxForFace(const RetainPtr<CFX_Face>& face);
// Commonly used wrappers for UseTTCharmap().
static bool UseTTCharmapMSUnicode(FXFT_FaceRec* face) {
diff --git a/core/fpdfapi/font/cpdf_simplefont.cpp b/core/fpdfapi/font/cpdf_simplefont.cpp
index f9f516b..dba78b6 100644
--- a/core/fpdfapi/font/cpdf_simplefont.cpp
+++ b/core/fpdfapi/font/cpdf_simplefont.cpp
@@ -76,9 +76,14 @@
}
return;
}
- FXFT_FaceRec* face = m_Font.GetFaceRec();
+ RetainPtr<CFX_Face> face = m_Font.GetFace();
+ if (!face) {
+ return;
+ }
+
+ FXFT_FaceRec* face_rec = face->GetRec();
int err =
- FT_Load_Glyph(face, glyph_index,
+ FT_Load_Glyph(face_rec, glyph_index,
FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
if (err)
return;
@@ -86,7 +91,7 @@
m_CharBBox[charcode] = GetCharBBoxForFace(face);
if (m_bUseFontWidth) {
- int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(face), face);
+ int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(face_rec), face);
if (m_CharWidth[charcode] == 0xffff) {
m_CharWidth[charcode] = TT_Width;
} else if (TT_Width && !IsEmbedded()) {
diff --git a/core/fxge/android/cfpf_skiafont.cpp b/core/fxge/android/cfpf_skiafont.cpp
index 053b1c4..47423e5 100644
--- a/core/fxge/android/cfpf_skiafont.cpp
+++ b/core/fxge/android/cfpf_skiafont.cpp
@@ -57,23 +57,20 @@
FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
return 0;
}
- return static_cast<int32_t>(
- FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
- FXFT_Get_Glyph_HoriAdvance(GetFaceRec())));
+ return static_cast<int32_t>(FPF_EM_ADJUST(
+ m_Face->GetUnitsPerEm(), FXFT_Get_Glyph_HoriAdvance(GetFaceRec())));
}
int32_t CFPF_SkiaFont::GetAscent() const {
if (!m_Face)
return 0;
- return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
- FXFT_Get_Face_Ascender(GetFaceRec()));
+ return FPF_EM_ADJUST(m_Face->GetUnitsPerEm(), m_Face->GetAscender());
}
int32_t CFPF_SkiaFont::GetDescent() const {
if (!m_Face)
return 0;
- return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
- FXFT_Get_Face_Descender(GetFaceRec()));
+ return FPF_EM_ADJUST(m_Face->GetUnitsPerEm(), m_Face->GetDescender());
}
bool CFPF_SkiaFont::GetGlyphBBox(int32_t iGlyphIndex, FX_RECT& rtBBox) {
@@ -109,7 +106,7 @@
FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
return false;
}
- const FT_UShort em = FXFT_Get_Face_UnitsPerEM(GetFaceRec());
+ const uint16_t em = m_Face->GetUnitsPerEm();
rtBBox.left = static_cast<int32_t>(
FPF_EM_ADJUST(em, FXFT_Get_Glyph_HoriBearingX(GetFaceRec())));
rtBBox.bottom = static_cast<int32_t>(
@@ -128,7 +125,7 @@
return false;
}
- const FT_UShort em = FXFT_Get_Face_UnitsPerEM(GetFaceRec());
+ const uint16_t em = m_Face->GetUnitsPerEm();
const FX_RECT raw_bbox = m_Face->GetBBox();
rtBBox.left = static_cast<int32_t>(FPF_EM_ADJUST(em, raw_bbox.left));
rtBBox.top = static_cast<int32_t>(FPF_EM_ADJUST(em, raw_bbox.top));
@@ -140,8 +137,7 @@
int32_t CFPF_SkiaFont::GetHeight() const {
if (!m_Face)
return 0;
- return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
- FXFT_Get_Face_Height(GetFaceRec()));
+ return FPF_EM_ADJUST(m_Face->GetUnitsPerEm(), m_Face->GetHeight());
}
int32_t CFPF_SkiaFont::GetItalicAngle() const {
diff --git a/core/fxge/cfx_face.cpp b/core/fxge/cfx_face.cpp
index a1a40e5..71a6ead 100644
--- a/core/fxge/cfx_face.cpp
+++ b/core/fxge/cfx_face.cpp
@@ -85,6 +85,24 @@
pdfium::base::checked_cast<int32_t>(GetRec()->bbox.yMax));
}
+uint16_t CFX_Face::GetUnitsPerEm() const {
+ return pdfium::base::checked_cast<uint16_t>(GetRec()->units_per_EM);
+}
+
+int16_t CFX_Face::GetAscender() const {
+ return pdfium::base::checked_cast<int16_t>(GetRec()->ascender);
+}
+
+int16_t CFX_Face::GetDescender() const {
+ return pdfium::base::checked_cast<int16_t>(GetRec()->descender);
+}
+
+#if BUILDFLAG(IS_ANDROID)
+int16_t CFX_Face::GetHeight() const {
+ return pdfium::base::checked_cast<int16_t>(GetRec()->height);
+}
+#endif
+
pdfium::span<uint8_t> CFX_Face::GetData() const {
return {GetRec()->stream->base, GetRec()->stream->size};
}
diff --git a/core/fxge/cfx_face.h b/core/fxge/cfx_face.h
index 5a71ad1..8040c69 100644
--- a/core/fxge/cfx_face.h
+++ b/core/fxge/cfx_face.h
@@ -5,6 +5,9 @@
#ifndef CORE_FXGE_CFX_FACE_H_
#define CORE_FXGE_CFX_FACE_H_
+#include <stdint.h>
+
+#include "build/build_config.h"
#include "core/fxcrt/bytestring.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/observed_ptr.h"
@@ -40,6 +43,12 @@
ByteString GetStyleName() const;
FX_RECT GetBBox() const;
+ uint16_t GetUnitsPerEm() const;
+ int16_t GetAscender() const;
+ int16_t GetDescender() const;
+#if BUILDFLAG(IS_ANDROID)
+ int16_t GetHeight() const;
+#endif
pdfium::span<uint8_t> GetData() const;
diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp
index fc19771..39a6445 100644
--- a/core/fxge/cfx_font.cpp
+++ b/core/fxge/cfx_font.cpp
@@ -414,8 +414,7 @@
if (horiAdvance < kThousandthMinInt || horiAdvance > kThousandthMaxInt)
return 0;
- return static_cast<int>(
- EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face->GetRec()), horiAdvance));
+ return static_cast<int>(EM_ADJUST(m_Face->GetUnitsPerEm(), horiAdvance));
}
bool CFX_Font::LoadEmbedded(pdfium::span<const uint8_t> src_span,
@@ -439,22 +438,22 @@
if (!m_Face)
return 0;
- int ascender = FXFT_Get_Face_Ascender(m_Face->GetRec());
+ int ascender = m_Face->GetAscender();
if (ascender < kThousandthMinInt || ascender > kThousandthMaxInt)
return 0;
- return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face->GetRec()), ascender);
+ return EM_ADJUST(m_Face->GetUnitsPerEm(), ascender);
}
int CFX_Font::GetDescent() const {
if (!m_Face)
return 0;
- int descender = FXFT_Get_Face_Descender(m_Face->GetRec());
+ int descender = m_Face->GetDescender();
if (descender < kThousandthMinInt || descender > kThousandthMaxInt)
return 0;
- return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face->GetRec()), descender);
+ return EM_ADJUST(m_Face->GetUnitsPerEm(), descender);
}
absl::optional<FX_RECT> CFX_Font::GetGlyphBBox(uint32_t glyph_index) {
@@ -482,12 +481,9 @@
int pixel_size_y = m_Face->GetRec()->size->metrics.y_ppem;
FX_RECT result = ScaledFXRectFromFTPos(
cbox.xMin, cbox.yMax, cbox.xMax, cbox.yMin, pixel_size_x, pixel_size_y);
- result.top =
- std::min(result.top, pdfium::base::checked_cast<int32_t>(
- FXFT_Get_Face_Ascender(m_Face->GetRec())));
+ result.top = std::min(result.top, static_cast<int>(m_Face->GetAscender()));
result.bottom =
- std::max(result.bottom, pdfium::base::checked_cast<int32_t>(
- FXFT_Get_Face_Descender(m_Face->GetRec())));
+ std::max(result.bottom, static_cast<int>(m_Face->GetDescender()));
FT_Done_Glyph(glyph);
if (FT_Set_Pixel_Sizes(m_Face->GetRec(), 0, 64) != 0)
return absl::nullopt;
@@ -496,7 +492,7 @@
constexpr int kFlag = FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
if (FT_Load_Glyph(m_Face->GetRec(), glyph_index, kFlag) != 0)
return absl::nullopt;
- int em = FXFT_Get_Face_UnitsPerEM(m_Face->GetRec());
+ int em = m_Face->GetUnitsPerEm();
return ScaledFXRectFromFTPos(FXFT_Get_Glyph_HoriBearingX(m_Face->GetRec()),
FXFT_Get_Glyph_HoriBearingY(m_Face->GetRec()) -
FXFT_Get_Glyph_Height(m_Face->GetRec()),
@@ -598,7 +594,7 @@
if (!result.has_value())
return result;
- int em = FXFT_Get_Face_UnitsPerEM(m_Face->GetRec());
+ int em = m_Face->GetUnitsPerEm();
if (em != 0) {
FX_RECT& bbox = result.value();
bbox.left = (bbox.left * 1000) / em;
@@ -645,13 +641,13 @@
FT_Load_Glyph(m_Face->GetRec(), glyph_index,
FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
FT_Pos min_width = FXFT_Get_Glyph_HoriAdvance(m_Face->GetRec()) * 1000 /
- FXFT_Get_Face_UnitsPerEM(m_Face->GetRec());
+ m_Face->GetUnitsPerEm();
coords[1] = max_param;
FT_Set_MM_Design_Coordinates(m_Face->GetRec(), 2, coords);
FT_Load_Glyph(m_Face->GetRec(), glyph_index,
FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
FT_Pos max_width = FXFT_Get_Glyph_HoriAdvance(m_Face->GetRec()) * 1000 /
- FXFT_Get_Face_UnitsPerEM(m_Face->GetRec());
+ m_Face->GetUnitsPerEm();
if (max_width == min_width) {
return;
}
diff --git a/core/fxge/freetype/fx_freetype.h b/core/fxge/freetype/fx_freetype.h
index a3274ad..f796eb3 100644
--- a/core/fxge/freetype/fx_freetype.h
+++ b/core/fxge/freetype/fx_freetype.h
@@ -65,10 +65,6 @@
#define FXFT_Get_Charmap_Encoding(charmap) (charmap)->encoding
#define FXFT_Get_Charmap_PlatformID(charmap) (charmap)->platform_id
#define FXFT_Get_Charmap_EncodingID(charmap) (charmap)->encoding_id
-#define FXFT_Get_Face_UnitsPerEM(face) (face)->units_per_EM
-#define FXFT_Get_Face_Height(face) (face)->height
-#define FXFT_Get_Face_Ascender(face) (face)->ascender
-#define FXFT_Get_Face_Descender(face) (face)->descender
#define FXFT_Get_Glyph_HoriAdvance(face) (face)->glyph->metrics.horiAdvance
#define FXFT_Get_Glyph_Outline(face) &((face)->glyph->outline)
#define FXFT_Get_Glyph_Bitmap(face) (face)->glyph->bitmap