diff options
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | components/gfx/Cargo.toml | 1 | ||||
-rw-r--r-- | components/gfx/font.rs | 2 | ||||
-rw-r--r-- | components/gfx/font_cache_thread.rs | 13 | ||||
-rw-r--r-- | components/gfx/font_context.rs | 18 | ||||
-rw-r--r-- | components/gfx/font_template.rs | 18 | ||||
-rw-r--r-- | components/gfx/platform/freetype/font.rs | 37 | ||||
-rw-r--r-- | components/gfx/platform/freetype/font_context.rs | 136 | ||||
-rw-r--r-- | components/gfx/platform/freetype/library_handle.rs | 116 | ||||
-rw-r--r-- | components/gfx/platform/macos/font.rs | 2 | ||||
-rw-r--r-- | components/gfx/platform/macos/font_context.rs | 17 | ||||
-rw-r--r-- | components/gfx/platform/mod.rs | 13 | ||||
-rw-r--r-- | components/gfx/platform/windows/font.rs | 2 | ||||
-rw-r--r-- | components/gfx/platform/windows/font_context.rs | 10 | ||||
-rw-r--r-- | components/gfx/tests/font_context.rs | 8 | ||||
-rw-r--r-- | components/gfx/tests/font_template.rs | 5 |
16 files changed, 152 insertions, 247 deletions
diff --git a/Cargo.lock b/Cargo.lock index a9b79df93cf..f2278ff4d7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1949,6 +1949,7 @@ dependencies = [ "log", "malloc_size_of", "net_traits", + "parking_lot", "range", "serde", "servo_allocator", diff --git a/components/gfx/Cargo.toml b/components/gfx/Cargo.toml index 114e727d041..976687b953e 100644 --- a/components/gfx/Cargo.toml +++ b/components/gfx/Cargo.toml @@ -27,6 +27,7 @@ libc = { workspace = true } log = { workspace = true } malloc_size_of = { workspace = true } net_traits = { workspace = true } +parking_lot = { workspace = true } range = { path = "../range" } serde = { workspace = true } servo_arc = { workspace = true } diff --git a/components/gfx/font.rs b/components/gfx/font.rs index 6916b2e5261..f01f916d4ba 100644 --- a/components/gfx/font.rs +++ b/components/gfx/font.rs @@ -28,7 +28,6 @@ use crate::font_cache_thread::FontIdentifier; use crate::font_context::{FontContext, FontSource}; use crate::font_template::FontTemplateDescriptor; use crate::platform::font::{FontHandle, FontTable}; -use crate::platform::font_context::FontContextHandle; pub use crate::platform::font_list::fallback_font_families; use crate::platform::font_template::FontTemplateData; use crate::text::glyph::{ByteIndex, GlyphData, GlyphId, GlyphStore}; @@ -56,7 +55,6 @@ static TEXT_SHAPING_PERFORMANCE_COUNTER: AtomicUsize = AtomicUsize::new(0); pub trait FontHandleMethods: Sized { fn new_from_template( - fctx: &FontContextHandle, template: Arc<FontTemplateData>, pt_size: Option<Au>, ) -> Result<Self, &'static str>; diff --git a/components/gfx/font_cache_thread.rs b/components/gfx/font_cache_thread.rs index 5808295a4a3..a5c6a2b0974 100644 --- a/components/gfx/font_cache_thread.rs +++ b/components/gfx/font_cache_thread.rs @@ -26,7 +26,6 @@ use webrender_api::{FontInstanceKey, FontKey}; use crate::font::{FontFamilyDescriptor, FontFamilyName, FontSearchScope}; use crate::font_context::FontSource; use crate::font_template::{FontTemplate, FontTemplateDescriptor}; -use crate::platform::font_context::FontContextHandle; use crate::platform::font_list::{ for_each_available_family, for_each_variation, system_default_family, LocalFontIdentifier, SANS_SERIF_FONT_FAMILY, @@ -75,13 +74,12 @@ impl FontTemplates { pub fn find_font_for_style( &mut self, desc: &FontTemplateDescriptor, - fctx: &FontContextHandle, ) -> Option<Arc<FontTemplateData>> { // TODO(Issue #189): optimize lookup for // regular/bold/italic/bolditalic with fixed offsets and a // static decision table for fallback between these values. for template in &mut self.templates { - let maybe_template = template.data_for_descriptor(fctx, desc); + let maybe_template = template.data_for_descriptor(desc); if maybe_template.is_some() { return maybe_template; } @@ -91,8 +89,7 @@ impl FontTemplates { // TODO(#190): Do a better job. let (mut best_template_data, mut best_distance) = (None, f32::MAX); for template in &mut self.templates { - if let Some((template_data, distance)) = - template.data_for_approximate_descriptor(fctx, desc) + if let Some((template_data, distance)) = template.data_for_approximate_descriptor(desc) { if distance < best_distance { best_template_data = Some(template_data); @@ -159,7 +156,6 @@ struct FontCache { generic_fonts: HashMap<FontFamilyName, LowercaseString>, local_families: HashMap<LowercaseString, FontTemplates>, web_families: HashMap<LowercaseString, FontTemplates>, - font_context: FontContextHandle, core_resource_thread: CoreResourceThread, webrender_api: Box<dyn WebrenderApi>, webrender_fonts: HashMap<FontIdentifier, FontKey>, @@ -404,7 +400,7 @@ impl FontCache { // TODO(Issue #192: handle generic font families, like 'serif' and 'sans-serif'. // if such family exists, try to match style to a font - s.find_font_for_style(template_descriptor, &self.font_context) + s.find_font_for_style(template_descriptor) } else { debug!( "FontList: Couldn't find font family with name={}", @@ -423,7 +419,7 @@ impl FontCache { if self.web_families.contains_key(&family_name) { let templates = self.web_families.get_mut(&family_name).unwrap(); - templates.find_font_for_style(template_descriptor, &self.font_context) + templates.find_font_for_style(template_descriptor) } else { None } @@ -498,7 +494,6 @@ impl FontCacheThread { generic_fonts, local_families: HashMap::new(), web_families: HashMap::new(), - font_context: FontContextHandle::default(), core_resource_thread, webrender_api, webrender_fonts: HashMap::new(), diff --git a/components/gfx/font_context.rs b/components/gfx/font_context.rs index c7f2eaef530..d316ceb50c1 100644 --- a/components/gfx/font_context.rs +++ b/components/gfx/font_context.rs @@ -12,7 +12,6 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use app_units::Au; use fnv::FnvHasher; use log::debug; -use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use servo_arc::Arc; use style::computed_values::font_variant_caps::T as FontVariantCaps; use style::properties::style_structs::Font as FontStyleStruct; @@ -24,7 +23,6 @@ use crate::font::{ use crate::font_cache_thread::FontTemplateInfo; use crate::font_template::FontTemplateDescriptor; use crate::platform::font::FontHandle; -pub use crate::platform::font_context::FontContextHandle; static SMALL_CAPS_SCALE_FACTOR: f32 = 0.8; // Matches FireFox (see gfxFont.h) @@ -48,7 +46,6 @@ pub trait FontSource { /// required. #[derive(Debug)] pub struct FontContext<S: FontSource> { - platform_handle: FontContextHandle, font_source: S, // TODO: The font context holds a strong ref to the cached fonts @@ -66,9 +63,7 @@ pub struct FontContext<S: FontSource> { impl<S: FontSource> FontContext<S> { pub fn new(font_source: S) -> FontContext<S> { #[allow(clippy::default_constructed_unit_structs)] - let handle = FontContextHandle::default(); FontContext { - platform_handle: handle, font_source, font_cache: HashMap::new(), font_template_cache: HashMap::new(), @@ -217,11 +212,7 @@ impl<S: FontSource> FontContext<S> { descriptor: FontDescriptor, synthesized_small_caps: Option<FontRef>, ) -> Result<Font, &'static str> { - let handle = FontHandle::new_from_template( - &self.platform_handle, - info.font_template, - Some(descriptor.pt_size), - )?; + let handle = FontHandle::new_from_template(info.font_template, Some(descriptor.pt_size))?; let font_instance_key = self .font_source @@ -235,13 +226,6 @@ impl<S: FontSource> FontContext<S> { } } -impl<S: FontSource> MallocSizeOf for FontContext<S> { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - // FIXME(njn): Measure other fields eventually. - self.platform_handle.size_of(ops) - } -} - #[derive(Debug, Eq, Hash, PartialEq)] struct FontCacheKey { font_descriptor: FontDescriptor, diff --git a/components/gfx/font_template.rs b/components/gfx/font_template.rs index 00d95159632..66db059db13 100644 --- a/components/gfx/font_template.rs +++ b/components/gfx/font_template.rs @@ -15,7 +15,6 @@ use style::values::computed::font::FontWeight; use crate::font::FontHandleMethods; use crate::font_cache_thread::FontIdentifier; use crate::platform::font::FontHandle; -use crate::platform::font_context::FontContextHandle; use crate::platform::font_template::FontTemplateData; /// Describes how to select a font from a given family. This is very basic at the moment and needs @@ -130,10 +129,7 @@ impl FontTemplate { } /// Get the descriptor. Returns `None` when instantiating the data fails. - pub fn descriptor( - &mut self, - font_context: &FontContextHandle, - ) -> Option<FontTemplateDescriptor> { + pub fn descriptor(&mut self) -> Option<FontTemplateDescriptor> { // The font template data can be unloaded when nothing is referencing // it (via the Weak reference to the Arc above). However, if we have // already loaded a font, store the style information about it separately, @@ -141,7 +137,7 @@ impl FontTemplate { // without having to reload the font (unless it is an actual match). self.descriptor.or_else(|| { - if self.instantiate(font_context).is_err() { + if self.instantiate().is_err() { return None; }; @@ -155,10 +151,9 @@ impl FontTemplate { /// Get the data for creating a font if it matches a given descriptor. pub fn data_for_descriptor( &mut self, - fctx: &FontContextHandle, requested_desc: &FontTemplateDescriptor, ) -> Option<Arc<FontTemplateData>> { - self.descriptor(fctx).and_then(|descriptor| { + self.descriptor().and_then(|descriptor| { if *requested_desc == descriptor { self.data().ok() } else { @@ -171,23 +166,22 @@ impl FontTemplate { /// descriptor, if the font can be loaded. pub fn data_for_approximate_descriptor( &mut self, - font_context: &FontContextHandle, requested_descriptor: &FontTemplateDescriptor, ) -> Option<(Arc<FontTemplateData>, f32)> { - self.descriptor(font_context).and_then(|descriptor| { + self.descriptor().and_then(|descriptor| { self.data() .ok() .map(|data| (data, descriptor.distance_from(requested_descriptor))) }) } - fn instantiate(&mut self, font_context: &FontContextHandle) -> Result<(), &'static str> { + fn instantiate(&mut self) -> Result<(), &'static str> { if !self.is_valid { return Err("Invalid font template"); } let data = self.data().map_err(|_| "Could not get FontTemplate data")?; - let handle = FontHandleMethods::new_from_template(font_context, data, None); + let handle = FontHandleMethods::new_from_template(data, None); self.is_valid = handle.is_ok(); let handle: FontHandle = handle?; self.descriptor = Some(FontTemplateDescriptor::new( diff --git a/components/gfx/platform/freetype/font.rs b/components/gfx/platform/freetype/font.rs index 024b3c563e1..44e51bc218c 100644 --- a/components/gfx/platform/freetype/font.rs +++ b/components/gfx/platform/freetype/font.rs @@ -10,7 +10,7 @@ use std::{mem, ptr}; use app_units::Au; use freetype::freetype::{ FT_Done_Face, FT_F26Dot6, FT_Face, FT_FaceRec, FT_Get_Char_Index, FT_Get_Kerning, - FT_Get_Postscript_Name, FT_Get_Sfnt_Table, FT_GlyphSlot, FT_Int32, FT_Kerning_Mode, FT_Library, + FT_Get_Postscript_Name, FT_Get_Sfnt_Table, FT_GlyphSlot, FT_Int32, FT_Kerning_Mode, FT_Load_Glyph, FT_Load_Sfnt_Table, FT_Long, FT_New_Face, FT_New_Memory_Face, FT_Set_Char_Size, FT_Sfnt_Tag, FT_SizeRec, FT_Size_Metrics, FT_UInt, FT_ULong, FT_Vector, FT_STYLE_FLAG_ITALIC, }; @@ -22,12 +22,12 @@ use style::computed_values::font_weight::T as FontWeight; use style::values::computed::font::FontStyle; use super::c_str_to_string; +use super::library_handle::FreeTypeLibraryHandle; use crate::font::{ FontHandleMethods, FontMetrics, FontTableMethods, FontTableTag, FractionalPixel, GPOS, GSUB, KERN, }; use crate::font_cache_thread::FontIdentifier; -use crate::platform::font_context::FontContextHandle; use crate::platform::font_template::FontTemplateData; use crate::text::glyph::GlyphId; use crate::text::util::fixed_to_float; @@ -76,9 +76,6 @@ pub struct FontHandle { // if the font is created using FT_Memory_Face. font_data: Arc<FontTemplateData>, face: FT_Face, - // `context_handle` is unused, but here to ensure that the underlying - // FreeTypeLibraryHandle is not dropped. - context_handle: FontContextHandle, can_do_fast_shaping: bool, } @@ -86,6 +83,10 @@ impl Drop for FontHandle { fn drop(&mut self) { assert!(!self.face.is_null()); unsafe { + // The FreeType documentation says that both `FT_New_Face` and `FT_Done_Face` + // 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(self.face)) { panic!("FT_Done_Face failed"); } @@ -93,20 +94,17 @@ impl Drop for FontHandle { } } -fn create_face( - lib: FT_Library, - template: &FontTemplateData, - pt_size: Option<Au>, -) -> Result<FT_Face, &'static str> { +fn create_face(template: &FontTemplateData, pt_size: Option<Au>) -> Result<FT_Face, &'static str> { unsafe { let mut face: FT_Face = ptr::null_mut(); let face_index = 0 as FT_Long; + let library = FreeTypeLibraryHandle::get().lock(); let result = match template.identifier { FontIdentifier::Web(_) => { let bytes = template.bytes(); FT_New_Memory_Face( - lib, + library.freetype_library, bytes.as_ptr(), bytes.len() as FT_Long, face_index, @@ -120,7 +118,12 @@ fn create_face( // https://github.com/servo/servo/pull/20506#issuecomment-378838800 let filename = CString::new(&*local_identifier.path).expect("filename contains NUL byte!"); - FT_New_Face(lib, filename.as_ptr(), face_index, &mut face) + FT_New_Face( + library.freetype_library, + filename.as_ptr(), + face_index, + &mut face, + ) }, }; @@ -138,21 +141,13 @@ fn create_face( impl FontHandleMethods for FontHandle { fn new_from_template( - fctx: &FontContextHandle, template: Arc<FontTemplateData>, pt_size: Option<Au>, ) -> Result<FontHandle, &'static str> { - let ft_ctx: FT_Library = fctx.ctx.ctx; - if ft_ctx.is_null() { - return Err("Null FT_Library"); - } - - let face = create_face(ft_ctx, &template, pt_size)?; - + let face = create_face(&template, pt_size)?; let mut handle = FontHandle { face, font_data: template, - context_handle: fctx.clone(), can_do_fast_shaping: false, }; // TODO (#11310): Implement basic support for GPOS and GSUB. diff --git a/components/gfx/platform/freetype/font_context.rs b/components/gfx/platform/freetype/font_context.rs deleted file mode 100644 index b08ff552261..00000000000 --- a/components/gfx/platform/freetype/font_context.rs +++ /dev/null @@ -1,136 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -use std::os::raw::{c_long, c_void}; -use std::ptr; -use std::rc::Rc; - -use freetype::freetype::{ - 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 servo_allocator::libc_compat::{free, malloc, realloc}; -use servo_allocator::usable_size; - -// We pass a |User| struct -- via an opaque |void*| -- to FreeType each time a new instance is -// created. FreeType passes it back to the ft_alloc/ft_realloc/ft_free callbacks. We use it to -// record the memory usage of each FreeType instance. -pub struct User { - size: usize, -} - -extern "C" fn ft_alloc(mem: FT_Memory, req_size: c_long) -> *mut c_void { - unsafe { - let ptr = malloc(req_size as usize); - let ptr = ptr as *mut c_void; // libc::c_void vs std::os::raw::c_void - let actual_size = usable_size(ptr); - let user = (*mem).user as *mut User; - (*user).size += actual_size; - ptr - } -} - -extern "C" fn ft_free(mem: FT_Memory, ptr: *mut c_void) { - unsafe { - let actual_size = usable_size(ptr); - let user = (*mem).user as *mut User; - (*user).size -= actual_size; - free(ptr as *mut _); - } -} - -extern "C" fn ft_realloc( - mem: FT_Memory, - _old_size: c_long, - new_req_size: c_long, - old_ptr: *mut c_void, -) -> *mut c_void { - unsafe { - let old_actual_size = usable_size(old_ptr); - let new_ptr = realloc(old_ptr as *mut _, new_req_size as usize); - let new_ptr = new_ptr as *mut c_void; - let new_actual_size = usable_size(new_ptr); - let user = (*mem).user as *mut User; - (*user).size += new_actual_size; - (*user).size -= old_actual_size; - new_ptr - } -} - -// A |*mut User| field in a struct triggers a "use of `#[derive]` with a raw pointer" warning from -// rustc. But using a typedef avoids this, so... -pub type UserPtr = *mut User; - -// WARNING: We need to be careful how we use this struct. See the comment about Rc<> in -// FontContextHandle. -#[derive(Clone, Debug)] -pub struct FreeTypeLibraryHandle { - pub ctx: FT_Library, - mem: FT_Memory, - user: UserPtr, -} - -impl Drop for FreeTypeLibraryHandle { - #[allow(unused)] - fn drop(&mut self) { - assert!(!self.ctx.is_null()); - unsafe { - FT_Done_Library(self.ctx); - Box::from_raw(self.mem); - Box::from_raw(self.user); - } - } -} - -impl MallocSizeOf for FreeTypeLibraryHandle { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - unsafe { - (*self.user).size + - ops.malloc_size_of(self.ctx as *const _) + - ops.malloc_size_of(self.mem as *const _) + - ops.malloc_size_of(self.user as *const _) - } - } -} - -#[derive(Clone, Debug)] -pub struct FontContextHandle { - // WARNING: FreeTypeLibraryHandle contains raw pointers, is clonable, and also implements - // `Drop`. This field needs to be Rc<> to make sure that the `drop` function is only called - // once, otherwise we'll get crashes. Yuk. - pub ctx: Rc<FreeTypeLibraryHandle>, -} - -impl MallocSizeOf for FontContextHandle { - fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { - self.ctx.size_of(ops) - } -} - -impl Default for FontContextHandle { - fn default() -> Self { - let user = Box::into_raw(Box::new(User { size: 0 })); - let mem = Box::into_raw(Box::new(FT_MemoryRec_ { - user: user as *mut c_void, - alloc: Some(ft_alloc), - free: Some(ft_free), - realloc: Some(ft_realloc), - })); - unsafe { - let mut ctx: FT_Library = ptr::null_mut(); - - let result = FT_New_Library(mem, &mut ctx); - if !succeeded(result) { - panic!("Unable to initialize FreeType library"); - } - - FT_Add_Default_Modules(ctx); - - FontContextHandle { - ctx: Rc::new(FreeTypeLibraryHandle { ctx, mem, user }), - } - } - } -} diff --git a/components/gfx/platform/freetype/library_handle.rs b/components/gfx/platform/freetype/library_handle.rs new file mode 100644 index 00000000000..bcd8b2e4865 --- /dev/null +++ b/components/gfx/platform/freetype/library_handle.rs @@ -0,0 +1,116 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use std::os::raw::{c_long, c_void}; +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::succeeded; +use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; +use parking_lot::Mutex; +use servo_allocator::libc_compat::{free, malloc, realloc}; +use servo_allocator::usable_size; + +static FREETYPE_MEMORY_USAGE: AtomicUsize = AtomicUsize::new(0); +static FREETYPE_LIBRARY_HANDLE: OnceLock<Mutex<FreeTypeLibraryHandle>> = OnceLock::new(); + +extern "C" fn ft_alloc(_: FT_Memory, req_size: c_long) -> *mut c_void { + unsafe { + let pointer = malloc(req_size as usize); + FREETYPE_MEMORY_USAGE.fetch_add(usable_size(pointer), Ordering::Relaxed); + pointer + } +} + +extern "C" fn ft_free(_: FT_Memory, pointer: *mut c_void) { + unsafe { + FREETYPE_MEMORY_USAGE.fetch_sub(usable_size(pointer), Ordering::Relaxed); + free(pointer as *mut _); + } +} + +extern "C" fn ft_realloc( + _: FT_Memory, + _old_size: c_long, + new_req_size: c_long, + old_pointer: *mut c_void, +) -> *mut c_void { + unsafe { + FREETYPE_MEMORY_USAGE.fetch_sub(usable_size(old_pointer), Ordering::Relaxed); + let new_pointer = realloc(old_pointer, new_req_size as usize); + FREETYPE_MEMORY_USAGE.fetch_add(usable_size(new_pointer), Ordering::Relaxed); + new_pointer + } +} + +/// A FreeType library handle to be used for creating and dropping FreeType font faces. +/// It is very important that this handle lives as long as the faces themselves, which +/// is why only one of these is created for the entire execution of Servo and never +/// dropped during execution. +#[derive(Clone, Debug)] +pub(crate) struct FreeTypeLibraryHandle { + pub freetype_library: FT_Library, + freetype_memory: FT_Memory, +} + +unsafe impl Sync for FreeTypeLibraryHandle {} +unsafe impl Send for FreeTypeLibraryHandle {} + +impl Drop for FreeTypeLibraryHandle { + #[allow(unused)] + fn drop(&mut self) { + assert!(!self.freetype_library.is_null()); + unsafe { + FT_Done_Library(self.freetype_library); + Box::from_raw(self.freetype_memory); + } + } +} + +impl MallocSizeOf for FreeTypeLibraryHandle { + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + unsafe { + FREETYPE_MEMORY_USAGE.load(Ordering::Relaxed) + + ops.malloc_size_of(self.freetype_library as *const _) + + ops.malloc_size_of(self.freetype_memory as *const _) + } + } +} + +impl FreeTypeLibraryHandle { + /// Get the shared FreeType library handle. This is protected by a mutex because according to + /// the FreeType documentation: + /// + /// > [Since 2.5.6] In multi-threaded applications it is easiest to use one FT_Library object per + /// > thread. In case this is too cumbersome, a single FT_Library object across threads is possible + /// > also, as long as a mutex lock is used around FT_New_Face and FT_Done_Face. + /// + /// 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_ { + user: ptr::null_mut(), + alloc: Some(ft_alloc), + free: Some(ft_free), + realloc: Some(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) { + panic!("Unable to initialize FreeType library"); + } + FT_Add_Default_Modules(freetype_library); + Mutex::new(FreeTypeLibraryHandle { + freetype_library, + freetype_memory, + }) + } + }) + } +} diff --git a/components/gfx/platform/macos/font.rs b/components/gfx/platform/macos/font.rs index f8088b24412..3e355c7d1ce 100644 --- a/components/gfx/platform/macos/font.rs +++ b/components/gfx/platform/macos/font.rs @@ -27,7 +27,6 @@ use crate::font::{ }; use crate::font_cache_thread::FontIdentifier; use crate::platform::font_template::FontTemplateData; -use crate::platform::macos::font_context::FontContextHandle; use crate::text::glyph::GlyphId; const KERN_PAIR_LEN: usize = 6; @@ -158,7 +157,6 @@ impl fmt::Debug for CachedKernTable { impl FontHandleMethods for FontHandle { fn new_from_template( - _fctx: &FontContextHandle, template: Arc<FontTemplateData>, pt_size: Option<Au>, ) -> Result<FontHandle, &'static str> { diff --git a/components/gfx/platform/macos/font_context.rs b/components/gfx/platform/macos/font_context.rs deleted file mode 100644 index b296ce6738b..00000000000 --- a/components/gfx/platform/macos/font_context.rs +++ /dev/null @@ -1,17 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; - -#[derive(Clone, Debug, Default)] -pub struct FontContextHandle { - // this is a placeholder until NSFontManager or whatever is bound in here. - _ctx: (), -} - -impl MallocSizeOf for FontContextHandle { - fn size_of(&self, _: &mut MallocSizeOfOps) -> usize { - 0 - } -} diff --git a/components/gfx/platform/mod.rs b/components/gfx/platform/mod.rs index cc4d28ee575..6e3d191529e 100644 --- a/components/gfx/platform/mod.rs +++ b/components/gfx/platform/mod.rs @@ -3,13 +3,11 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #[cfg(any(target_os = "linux", target_os = "android"))] -pub use crate::platform::freetype::{font, font_context}; -#[cfg(any(target_os = "linux", target_os = "android"))] -pub use crate::platform::freetype::{font_list, font_template}; +pub use crate::platform::freetype::{font, font_list, font_template, library_handle}; #[cfg(target_os = "macos")] -pub use crate::platform::macos::{font, font_context, font_list, font_template}; +pub use crate::platform::macos::{font, font_list, font_template}; #[cfg(target_os = "windows")] -pub use crate::platform::windows::{font, font_context, font_list, font_template}; +pub use crate::platform::windows::{font, font_list, font_template}; #[cfg(any(target_os = "linux", target_os = "android"))] mod freetype { @@ -27,7 +25,6 @@ mod freetype { } pub mod font; - pub mod font_context; #[cfg(target_os = "linux")] pub mod font_list; @@ -39,14 +36,13 @@ mod freetype { #[cfg(target_os = "android")] pub use self::android::font_list; - #[cfg(any(target_os = "linux", target_os = "android"))] pub mod font_template; + pub mod library_handle; } #[cfg(target_os = "macos")] mod macos { pub mod font; - pub mod font_context; pub mod font_list; pub mod font_template; } @@ -54,7 +50,6 @@ mod macos { #[cfg(target_os = "windows")] mod windows { pub mod font; - pub mod font_context; pub mod font_list; pub mod font_template; } diff --git a/components/gfx/platform/windows/font.rs b/components/gfx/platform/windows/font.rs index 3ec4c73ecf8..03b82022068 100644 --- a/components/gfx/platform/windows/font.rs +++ b/components/gfx/platform/windows/font.rs @@ -23,7 +23,6 @@ use crate::font::{ }; use crate::font_cache_thread::FontIdentifier; use crate::platform::font_template::FontTemplateData; -use crate::platform::windows::font_context::FontContextHandle; use crate::text::glyph::GlyphId; // 1em = 12pt = 16px, assuming 72 points per inch and 96 px per inch @@ -228,7 +227,6 @@ impl FontHandle {} impl FontHandleMethods for FontHandle { fn new_from_template( - _: &FontContextHandle, template: Arc<FontTemplateData>, pt_size: Option<Au>, ) -> Result<Self, &'static str> { diff --git a/components/gfx/platform/windows/font_context.rs b/components/gfx/platform/windows/font_context.rs deleted file mode 100644 index a67a366fc11..00000000000 --- a/components/gfx/platform/windows/font_context.rs +++ /dev/null @@ -1,10 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -use malloc_size_of::malloc_size_of_is_0; - -#[derive(Clone, Debug, Default)] -pub struct FontContextHandle; - -malloc_size_of_is_0!(FontContextHandle); diff --git a/components/gfx/tests/font_context.rs b/components/gfx/tests/font_context.rs index 3447493399d..24965e272f1 100644 --- a/components/gfx/tests/font_context.rs +++ b/components/gfx/tests/font_context.rs @@ -14,7 +14,7 @@ use gfx::font::{ fallback_font_families, FontDescriptor, FontFamilyDescriptor, FontFamilyName, FontSearchScope, }; use gfx::font_cache_thread::{FontIdentifier, FontTemplateInfo, FontTemplates}; -use gfx::font_context::{FontContext, FontContextHandle, FontSource}; +use gfx::font_context::{FontContext, FontSource}; use gfx::font_template::FontTemplateDescriptor; use servo_arc::Arc; use servo_atoms::Atom; @@ -30,7 +30,6 @@ use style::values::generics::font::LineHeight; use webrender_api::{FontInstanceKey, FontKey, IdNamespace}; struct TestFontSource { - handle: FontContextHandle, families: HashMap<String, FontTemplates>, find_font_count: Rc<Cell<isize>>, } @@ -52,7 +51,6 @@ impl TestFontSource { families.insert(fallback_font_families(None)[0].to_owned(), fallback); TestFontSource { - handle: FontContextHandle::default(), families, find_font_count: Rc::new(Cell::new(0)), } @@ -90,12 +88,10 @@ impl FontSource for TestFontSource { template_descriptor: FontTemplateDescriptor, family_descriptor: FontFamilyDescriptor, ) -> Option<FontTemplateInfo> { - let handle = &self.handle; - self.find_font_count.set(self.find_font_count.get() + 1); self.families .get_mut(family_descriptor.name()) - .and_then(|family| family.find_font_for_style(&template_descriptor, handle)) + .and_then(|family| family.find_font_for_style(&template_descriptor)) .map(|template| FontTemplateInfo { font_template: template, font_key: FontKey(IdNamespace(0), 0), diff --git a/components/gfx/tests/font_template.rs b/components/gfx/tests/font_template.rs index 1c8420bc45c..d35c3607497 100644 --- a/components/gfx/tests/font_template.rs +++ b/components/gfx/tests/font_template.rs @@ -11,7 +11,6 @@ fn test_font_template_descriptor() { use std::path::PathBuf; use gfx::font_cache_thread::FontIdentifier; - use gfx::font_context::FontContextHandle; use gfx::font_template::{FontTemplate, FontTemplateDescriptor}; use servo_url::ServoUrl; use style::values::computed::font::{FontStretch, FontStyle, FontWeight}; @@ -35,9 +34,7 @@ fn test_font_template_descriptor() { ) .unwrap(); - let context = FontContextHandle::default(); - - template.descriptor(&context).unwrap() + template.descriptor().unwrap() } assert_eq!( |