From 67e556e3becd73a547e09c1c1de8f4b3873d3648 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Tue, 21 May 2024 12:47:15 +0200 Subject: [PATCH] fonts: Depend directly on `freetype-sys` (#32318) Instead of depending on `rust-freetype`, depend directly on `freetype-sys` which is a transitive dependency. This provides almost everything we need (apart from one function call). This will help us eliminate one crate in the dependency chain. --- Cargo.lock | 2 +- Cargo.toml | 1 + components/gfx/Cargo.toml | 2 +- components/gfx/platform/freetype/font.rs | 67 +++++++++---------- .../gfx/platform/freetype/library_handle.rs | 15 ++--- 5 files changed, 40 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba9de569e56..9debc09e09c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2027,7 +2027,7 @@ dependencies = [ "euclid", "fnv", "fontsan", - "freetype", + "freetype-sys", "gfx_traits", "harfbuzz-sys", "ipc-channel", diff --git a/Cargo.toml b/Cargo.toml index 17e01a50b41..8cc19a2cdf9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ encoding_rs = "0.8" env_logger = "0.10" euclid = "0.22" fnv = "1.0" +freetype-sys = "0.20" fxhash = "0.2" getopts = "0.2.11" gfx_traits = { path = "components/shared/gfx" } diff --git a/components/gfx/Cargo.toml b/components/gfx/Cargo.toml index ca580f4495f..196cd3958e1 100644 --- a/components/gfx/Cargo.toml +++ b/components/gfx/Cargo.toml @@ -56,7 +56,7 @@ core-text = "20.1" [target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies] harfbuzz-sys = { version = "0.6", features = ["bundled"] } -freetype = "0.7" +freetype-sys = { workspace = true } servo_allocator = { path = "../allocator" } [target.'cfg(all(target_os = "linux", not(target_env = "ohos")))'.dependencies] diff --git a/components/gfx/platform/freetype/font.rs b/components/gfx/platform/freetype/font.rs index 027f7bd39b8..1fa1a07fc3d 100644 --- a/components/gfx/platform/freetype/font.rs +++ b/components/gfx/platform/freetype/font.rs @@ -8,16 +8,14 @@ use std::sync::Arc; use std::{mem, ptr}; use app_units::Au; -use freetype::freetype::{ - FT_Done_Face, FT_F26Dot6, FT_Face, FT_Fixed, FT_Get_Char_Index, FT_Get_Kerning, - FT_Get_Sfnt_Table, FT_GlyphSlot, FT_Int32, FT_Kerning_Mode, FT_Load_Glyph, FT_Load_Sfnt_Table, - FT_Long, FT_MulFix, FT_New_Memory_Face, FT_Pos, FT_Select_Size, FT_Set_Char_Size, FT_Sfnt_Tag, - FT_Short, FT_SizeRec, FT_Size_Metrics, FT_UInt, FT_ULong, FT_UShort, FT_Vector, - FT_FACE_FLAG_COLOR, FT_FACE_FLAG_FIXED_SIZES, FT_FACE_FLAG_SCALABLE, FT_LOAD_COLOR, - FT_LOAD_DEFAULT, FT_STYLE_FLAG_ITALIC, +use freetype_sys::{ + ft_sfnt_head, ft_sfnt_os2, FT_Byte, FT_Done_Face, FT_Error, FT_F26Dot6, FT_Face, FT_Fixed, + FT_Get_Char_Index, FT_Get_Kerning, FT_Get_Sfnt_Table, FT_GlyphSlot, FT_Int32, FT_Load_Glyph, + FT_Long, FT_MulFix, FT_New_Memory_Face, FT_Pos, FT_Select_Size, FT_Set_Char_Size, FT_Short, + FT_SizeRec, FT_Size_Metrics, FT_UInt, FT_ULong, FT_UShort, FT_Vector, FT_FACE_FLAG_COLOR, + FT_FACE_FLAG_FIXED_SIZES, FT_FACE_FLAG_SCALABLE, FT_KERNING_DEFAULT, FT_LOAD_COLOR, + FT_LOAD_DEFAULT, FT_STYLE_FLAG_ITALIC, TT_OS2, }; -use freetype::succeeded; -use freetype::tt_os2::TT_OS2; use log::debug; use parking_lot::ReentrantMutex; use style::computed_values::font_stretch::T as FontStretch; @@ -95,7 +93,7 @@ impl Drop for PlatformFont { // should be protected by a mutex. // See https://freetype.org/freetype2/docs/reference/ft2-library_setup.html. let _guard = FreeTypeLibraryHandle::get().lock(); - if !succeeded(FT_Done_Face(*face)) { + if FT_Done_Face(*face) != 0 { panic!("FT_Done_Face failed"); } } @@ -117,7 +115,7 @@ fn create_face(data: Arc>, face_index: u32) -> Result FontMetrics { let face_ptr = *self.face.lock(); - let face = unsafe { *face_ptr }; + let face = unsafe { &*face_ptr }; // face.size is a *c_void in the bindings, presumably to avoid recursive structural types let freetype_size: &FT_SizeRec = unsafe { mem::transmute(&(*face.size)) }; @@ -281,8 +279,7 @@ impl PlatformFontMethods for PlatformFont { // scalable outlines". If it's an sfnt, we can get units_per_EM from the 'head' table // instead; otherwise, we don't have a unitsPerEm value so we can't compute y_scale and // x_scale. - let head = - unsafe { FT_Get_Sfnt_Table(face_ptr, FT_Sfnt_Tag::FT_SFNT_HEAD) as *mut TtHeader }; + let head = unsafe { FT_Get_Sfnt_Table(face_ptr, ft_sfnt_head) as *mut TtHeader }; if !head.is_null() && unsafe { (*head).table_version != 0xffff } { // Bug 1267909 - Even if the font is not explicitly scalable, if the face has color // bitmaps, it should be treated as scalable and scaled to the desired size. Metrics @@ -381,18 +378,12 @@ impl PlatformFontMethods for PlatformFont { unsafe { // Get the length let mut len = 0; - if !succeeded(FT_Load_Sfnt_Table(*face, tag, 0, ptr::null_mut(), &mut len)) { + if 0 != FT_Load_Sfnt_Table(*face, tag, 0, ptr::null_mut(), &mut len) { return None; } // Get the bytes let mut buf = vec![0u8; len as usize]; - if !succeeded(FT_Load_Sfnt_Table( - *face, - tag, - 0, - buf.as_mut_ptr(), - &mut len, - )) { + if 0 != FT_Load_Sfnt_Table(*face, tag, 0, buf.as_mut_ptr(), &mut len) { return None; } Some(FontTable { buffer: buf }) @@ -438,7 +429,7 @@ impl FreeTypeFaceHelpers for FT_Face { if self.scalable() { let size_in_fixed_point = (requested_size.to_f64_px() * 64.0 + 0.5) as FT_F26Dot6; let result = unsafe { FT_Set_Char_Size(self, size_in_fixed_point, 0, 72, 72) }; - if !succeeded(result) { + if 0 != result { return Err("FT_Set_Char_Size failed"); } return Ok(requested_size); @@ -469,7 +460,7 @@ impl FreeTypeFaceHelpers for FT_Face { } } - if succeeded(unsafe { FT_Select_Size(self, best_index) }) { + if 0 == unsafe { FT_Select_Size(self, best_index) } { Ok(Au::from_f64_px(best_size.1 as f64 / 64.0)) } else { Err("FT_Select_Size failed") @@ -483,7 +474,7 @@ impl FreeTypeFaceHelpers for FT_Face { // Linux distros use by default, and is a better // default than no hinting. // TODO(gw): Make this configurable. - load_flags |= FT_LOAD_TARGET_LIGHT; + load_flags |= FT_LOAD_TARGET_LIGHT as i32; let face_flags = unsafe { (*self).face_flags }; if (face_flags & (FT_FACE_FLAG_FIXED_SIZES as FT_Long)) != 0 { @@ -497,20 +488,12 @@ impl FreeTypeFaceHelpers for FT_Face { } fn has_table(self, tag: FontTableTag) -> bool { - unsafe { - succeeded(FT_Load_Sfnt_Table( - self, - tag as FT_ULong, - 0, - ptr::null_mut(), - &mut 0, - )) - } + unsafe { 0 == FT_Load_Sfnt_Table(self, tag as FT_ULong, 0, ptr::null_mut(), &mut 0) } } fn os2_table(self) -> Option { unsafe { - let os2 = FT_Get_Sfnt_Table(self, FT_Sfnt_Tag::FT_SFNT_OS2) as *mut TT_OS2; + let os2 = FT_Get_Sfnt_Table(self, ft_sfnt_os2) as *mut TT_OS2; let valid = !os2.is_null() && (*os2).version != 0xffff; if !valid { @@ -555,3 +538,13 @@ struct TtHeader { index_to_loc_format: FT_Short, glyph_data_format: FT_Short, } + +extern "C" { + fn FT_Load_Sfnt_Table( + face: FT_Face, + tag: FT_ULong, + offset: FT_Long, + buffer: *mut FT_Byte, + length: *mut FT_ULong, + ) -> FT_Error; +} diff --git a/components/gfx/platform/freetype/library_handle.rs b/components/gfx/platform/freetype/library_handle.rs index bcd8b2e4865..13a7ee2389f 100644 --- a/components/gfx/platform/freetype/library_handle.rs +++ b/components/gfx/platform/freetype/library_handle.rs @@ -7,10 +7,9 @@ use std::ptr; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::OnceLock; -use freetype::freetype::{ - FT_Add_Default_Modules, FT_Done_Library, FT_Library, FT_Memory, FT_MemoryRec_, FT_New_Library, +use freetype_sys::{ + FT_Add_Default_Modules, FT_Done_Library, FT_Library, FT_Memory, FT_MemoryRec, FT_New_Library, }; -use freetype::succeeded; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use parking_lot::Mutex; use servo_allocator::libc_compat::{free, malloc, realloc}; @@ -93,16 +92,16 @@ impl FreeTypeLibraryHandle { /// See . pub(crate) fn get() -> &'static Mutex { FREETYPE_LIBRARY_HANDLE.get_or_init(|| { - let freetype_memory = Box::into_raw(Box::new(FT_MemoryRec_ { + let freetype_memory = Box::into_raw(Box::new(FT_MemoryRec { user: ptr::null_mut(), - alloc: Some(ft_alloc), - free: Some(ft_free), - realloc: Some(ft_realloc), + alloc: ft_alloc, + free: ft_free, + realloc: ft_realloc, })); unsafe { let mut freetype_library: FT_Library = ptr::null_mut(); let result = FT_New_Library(freetype_memory, &mut freetype_library); - if !succeeded(result) { + if 0 != result { panic!("Unable to initialize FreeType library"); } FT_Add_Default_Modules(freetype_library);