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