Add still more fontations equivalents to cfx_face.cpp This CL should put PDFium in a state where Fontations experts can make concrete recommendations. Bug: 42271123 Change-Id: If7c6c43ebce930f6ca1560beec08ef8f543c46be Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/148451 Commit-Queue: Tom Sepez <tsepez@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxge/cfx_face.cpp b/core/fxge/cfx_face.cpp index 2cd2a60..af89e48 100644 --- a/core/fxge/cfx_face.cpp +++ b/core/fxge/cfx_face.cpp
@@ -396,8 +396,10 @@ bool CFX_Face::HasGlyphNames() const { const bool ft_result = !!(GetRec()->face_flags & FT_FACE_FLAG_GLYPH_NAMES); #if defined(PDF_ENABLE_SKIA_TYPEFACE_CHECKS) - // TODO(https://crbug.com/42271123): Compute equivalent result via Skia or - // Skrifa. +#if defined(PDF_ENABLE_FONTATIONS) + pdfium::span<const uint8_t> data = GetData(); + CHECK_EQ(ft_result, skrifa::has_glyph_names(rust::Slice(data))); +#endif #endif return ft_result; } @@ -415,8 +417,11 @@ ByteString CFX_Face::GetFontFormat() { const ByteString ft_result(FT_Get_Font_Format(GetRec())); #if defined(PDF_ENABLE_SKIA_TYPEFACE_CHECKS) - // TODO(https://crbug.com/42271123): Compute equivalent result via Skia or - // Skrifa. +#if defined(PDF_ENABLE_FONTATIONS) + pdfium::span<const uint8_t> data = GetData(); + rust::String skrifa_result = skrifa::get_font_format(rust::Slice(data)); + CHECK_EQ(ft_result, ByteString(skrifa_result.c_str())); +#endif #endif return ft_result; } @@ -436,6 +441,10 @@ if (skia_typeface_) { CHECK_EQ(ft_result, skia_typeface_->isFixedPitch()); } +#if defined(PDF_ENABLE_FONTATIONS) + pdfium::span<const uint8_t> data = GetData(); + CHECK_EQ(ft_result, skrifa::is_fixed_pitch(rust::Slice(data))); +#endif #endif return ft_result; } @@ -444,8 +453,10 @@ bool CFX_Face::IsScalable() const { const bool ft_result = !!(GetRec()->face_flags & FT_FACE_FLAG_SCALABLE); #if defined(PDF_ENABLE_SKIA_TYPEFACE_CHECKS) - // TODO(https://crbug.com/42271123): Compute equivalent result via Skia or - // Skrifa. +#if defined(PDF_ENABLE_FONTATIONS) + pdfium::span<const uint8_t> data = GetData(); + CHECK_EQ(ft_result, skrifa::is_scalable(rust::Slice(data))); +#endif #endif return ft_result; } @@ -1227,8 +1238,17 @@ } } #if defined(PDF_ENABLE_SKIA_TYPEFACE_CHECKS) - // TODO(https://crbug.com/42271123): Compute equivalent result via Skia or - // Skrifa. +#if defined(PDF_ENABLE_FONTATIONS) + pdfium::span<const uint8_t> data = GetData(); + skrifa::BoundingBox bbox = + skrifa::get_glyph_bounds(rust::Slice(data), glyph_index); + const uint16_t upem = GetUnitsPerEm(); + FX_RECT skrifa_result(NormalizeFontMetric(bbox.x_min, upem), + NormalizeFontMetric(bbox.y_max, upem), + NormalizeFontMetric(bbox.x_max, upem), + NormalizeFontMetric(bbox.y_min, upem)); + // TODO(tsepez): verify results. +#endif #endif return rect; }
diff --git a/core/fxge/skrifa/src/main.rs b/core/fxge/skrifa/src/main.rs index 5fdb531..6abaac0 100644 --- a/core/fxge/skrifa/src/main.rs +++ b/core/fxge/skrifa/src/main.rs
@@ -56,6 +56,14 @@ pub y: f32, } + #[derive(Copy, Clone, PartialEq, Debug)] + pub struct BoundingBox { + pub x_min: f32, + pub y_min: f32, + pub x_max: f32, + pub y_max: f32, + } + #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct CodePageRange { pub range1: u32, @@ -118,6 +126,11 @@ fn agl_unicode_to_name(unicode: u32, name: &mut [u8]) -> bool; fn get_char_codes_and_indices(data: &[u8], max_char: u32) -> Vec<CharCodeAndIndex>; + fn has_glyph_names(data: &[u8]) -> bool; + fn is_fixed_pitch(data: &[u8]) -> bool; + fn is_scalable(data: &[u8]) -> bool; + fn get_font_format(data: &[u8]) -> String; + fn get_glyph_bounds(data: &[u8], glyph_index: u32) -> BoundingBox; } unsafe extern "C++" { @@ -496,6 +509,76 @@ results } +pub fn has_glyph_names(data: &[u8]) -> bool { + if let Ok(font) = read_fonts::FontRef::new(data) { + let glyph_names = skrifa::GlyphNames::new(&font); + return glyph_names.source() != skrifa::GlyphNameSource::Synthesized; + } + false +} + +pub fn is_fixed_pitch(data: &[u8]) -> bool { + if let Ok(font) = read_fonts::FontRef::new(data) { + use read_fonts::TableProvider; + if let Ok(post) = font.post() { + return post.is_fixed_pitch() != 0; + } + } + false +} + +pub fn is_scalable(data: &[u8]) -> bool { + if let Ok(font) = read_fonts::FontRef::new(data) { + use read_fonts::TableProvider; + return font.glyf().is_ok() || font.cff().is_ok() || font.cff2().is_ok(); + } + if read_fonts::ps::cff::CffFontRef::new(data, 0, None).is_ok() { + return true; + } + if read_fonts::ps::type1::Type1Font::new(data).is_ok() { + return true; + } + false +} + +pub fn get_font_format(data: &[u8]) -> String { + if read_fonts::ps::type1::Type1Font::new(data).is_ok() { + return "Type 1".to_string(); + } + if let Ok(font) = read_fonts::FontRef::new(data) { + use read_fonts::TableProvider; + if font.cff().is_ok() || font.cff2().is_ok() { + return "CFF".to_string(); + } + if font.glyf().is_ok() { + return "TrueType".to_string(); + } + } + if read_fonts::ps::cff::CffFontRef::new(data, 0, None).is_ok() { + return "CFF".to_string(); + } + String::new() +} + +pub fn get_glyph_bounds(data: &[u8], glyph_index: u32) -> skrifa_ffi::BoundingBox { + if let Ok(font) = read_fonts::FontRef::new(data) { + let metrics = skrifa::metrics::GlyphMetrics::new( + &font, + skrifa::instance::Size::unscaled(), + skrifa::instance::LocationRef::default(), + ); + if let Some(bbox) = metrics.bounds(skrifa::GlyphId::new(glyph_index)) { + return skrifa_ffi::BoundingBox { + x_min: bbox.x_min, + y_min: bbox.y_min, + x_max: bbox.x_max, + y_max: bbox.y_max, + }; + } + } + skrifa_ffi::BoundingBox { x_min: 0.0, y_min: 0.0, x_max: 0.0, y_max: 0.0 } +} + fn main() { skrifa_ffi::run(""); }