mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
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.
This commit is contained in:
parent
1bcb4787d2
commit
67e556e3be
5 changed files with 40 additions and 47 deletions
|
@ -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]
|
||||
|
|
|
@ -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<Vec<u8>>, face_index: u32) -> Result<FT_Face, &'static
|
|||
&mut face,
|
||||
);
|
||||
|
||||
if !succeeded(result) || face.is_null() {
|
||||
if 0 != result || face.is_null() {
|
||||
return Err("Could not create FreeType face");
|
||||
}
|
||||
|
||||
|
@ -211,7 +209,7 @@ impl PlatformFontMethods for PlatformFont {
|
|||
*face,
|
||||
first_glyph,
|
||||
second_glyph,
|
||||
FT_Kerning_Mode::FT_KERNING_DEFAULT as FT_UInt,
|
||||
FT_KERNING_DEFAULT,
|
||||
&mut delta,
|
||||
);
|
||||
}
|
||||
|
@ -228,7 +226,7 @@ impl PlatformFontMethods for PlatformFont {
|
|||
|
||||
let load_flags = face.glyph_load_flags();
|
||||
let result = unsafe { FT_Load_Glyph(*face, glyph as FT_UInt, load_flags) };
|
||||
if !succeeded(result) {
|
||||
if 0 != result {
|
||||
debug!("Unable to load glyph {}. reason: {:?}", glyph, result);
|
||||
return None;
|
||||
}
|
||||
|
@ -243,7 +241,7 @@ impl PlatformFontMethods for PlatformFont {
|
|||
|
||||
fn metrics(&self) -> 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<OS2Table> {
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 <https://freetype.org/freetype2/docs/reference/ft2-library_setup.html>.
|
||||
pub(crate) fn get() -> &'static Mutex<FreeTypeLibraryHandle> {
|
||||
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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue