diff --git a/Cargo.lock b/Cargo.lock index 0cffbd7325a8..253c44db29bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5753,6 +5753,8 @@ dependencies = [ "app_units", "bitflags", "byteorder", + "core-foundation", + "core-graphics", "crossbeam-channel", "derive_more", "euclid", diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index 9f60f8066f09..c26b84f14567 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -46,6 +46,11 @@ use webrender::{ }; use wr_malloc_size_of::MallocSizeOfOps; +#[cfg(target_os = "macos")] +use core_foundation::string::CFString; +#[cfg(target_os = "macos")] +use core_graphics::font::CGFont; + extern "C" { #[cfg(target_os = "android")] fn __android_log_write(prio: c_int, tag: *const c_char, text: *const c_char) -> c_int; @@ -2293,9 +2298,20 @@ fn read_font_descriptor(bytes: &mut WrVecU8, index: u32) -> NativeFontHandle { #[cfg(target_os = "macos")] fn read_font_descriptor(bytes: &mut WrVecU8, _index: u32) -> NativeFontHandle { let chars = bytes.flush_into_vec(); - NativeFontHandle { - name: String::from_utf8(chars).unwrap() - } + let name = String::from_utf8(chars).unwrap(); + let font = match CGFont::from_name(&CFString::new(&*name)) { + Ok(font) => font, + Err(_) => { + // If for some reason we failed to load a font descriptor, then our + // only options are to either abort or substitute a fallback font. + // It is preferable to use a fallback font instead so that rendering + // can at least still proceed in some fashion without erroring. + // Lucida Grande is the fallback font in Gecko, so use that here. + CGFont::from_name(&CFString::from_static_string("Lucida Grande")) + .expect("Failed reading font descriptor and could not load fallback font") + }, + }; + NativeFontHandle(font) } #[cfg(not(any(target_os = "macos", target_os = "windows")))] diff --git a/gfx/webrender_bindings/src/moz2d_renderer.rs b/gfx/webrender_bindings/src/moz2d_renderer.rs index fabff32119b6..165000e94fe6 100644 --- a/gfx/webrender_bindings/src/moz2d_renderer.rs +++ b/gfx/webrender_bindings/src/moz2d_renderer.rs @@ -32,10 +32,6 @@ use std::sync::Arc; #[cfg(target_os = "windows")] use dwrote; -#[cfg(target_os = "macos")] -use core_foundation::string::CFString; -#[cfg(target_os = "macos")] -use core_graphics::font::CGFont; #[cfg(target_os = "macos")] use foreign_types::ForeignType; @@ -786,19 +782,7 @@ impl Moz2dBlobImageHandler { #[cfg(target_os = "macos")] fn process_native_font_handle(key: FontKey, handle: &NativeFontHandle) { - let font = match CGFont::from_name(&CFString::new(&handle.name)) { - Ok(font) => font, - Err(_) => { - // If for some reason we failed to load a font descriptor, then our - // only options are to either abort or substitute a fallback font. - // It is preferable to use a fallback font instead so that rendering - // can at least still proceed in some fashion without erroring. - // Lucida Grande is the fallback font in Gecko, so use that here. - CGFont::from_name(&CFString::from_static_string("Lucida Grande")) - .expect("Failed reading font descriptor and could not load fallback font") - }, - }; - unsafe { AddNativeFontHandle(key, font.as_ptr() as *mut c_void, 0) }; + unsafe { AddNativeFontHandle(key, handle.0.as_ptr() as *mut c_void, 0) }; } #[cfg(not(any(target_os = "macos", target_os = "windows")))] diff --git a/gfx/wr/Cargo.lock b/gfx/wr/Cargo.lock index 17a29f4676f5..d0a769c7c5ff 100644 --- a/gfx/wr/Cargo.lock +++ b/gfx/wr/Cargo.lock @@ -1719,6 +1719,8 @@ dependencies = [ "app_units", "bitflags", "byteorder", + "core-foundation 0.9.2", + "core-graphics 0.22.3", "crossbeam-channel", "derive_more", "euclid", diff --git a/gfx/wr/webrender/src/platform/macos/font.rs b/gfx/wr/webrender/src/platform/macos/font.rs index 3a034f79dcb5..e4cfd67fc39a 100644 --- a/gfx/wr/webrender/src/platform/macos/font.rs +++ b/gfx/wr/webrender/src/platform/macos/font.rs @@ -276,28 +276,16 @@ impl FontContext { // and use the descriptor for that. Normally we'd try to avoid new_from_CGFont // because that adds the CGFont to the descriptor cache which can keep the CGFont // around for a long time, but that should be ok for non-web (native) fonts. - let cf_name = CFString::new(&native_font_handle.name); + let name = native_font_handle.0.postscript_name(); // For "hidden" system fonts, whose names start with a period, // we can't instantiate CTFonts via a descriptor. We're really // supposed to use CTFontCreateUIFontForLanguage, but for now // we just use the CGFont. - let desc = if native_font_handle.name.starts_with('.') { - let cg_font = match CGFont::from_name(&cf_name) { - Ok(cg_font) => cg_font, - Err(_) => { - // If for some reason we failed to load a font descriptor, then our - // only options are to either abort or substitute a fallback font. - // It is preferable to use a fallback font instead so that rendering - // can at least still proceed in some fashion without erroring. - // Lucida Grande is the fallback font in Gecko, so use that here. - CGFont::from_name(&CFString::from_static_string("Lucida Grande")) - .expect("couldn't find font with postscript name and couldn't load fallback font") - } - }; - core_text::font::new_from_CGFont(&cg_font, 0.).copy_descriptor() + let desc = if name.to_string().starts_with('.') { + core_text::font::new_from_CGFont(&native_font_handle.0, 0.).copy_descriptor() } else { - core_text::font_descriptor::new_from_postscript_name(&cf_name) + core_text::font_descriptor::new_from_postscript_name(&name) }; self.ct_font_descs diff --git a/gfx/wr/webrender/src/resource_cache.rs b/gfx/wr/webrender/src/resource_cache.rs index f0c44c9a216c..6be35e03059a 100644 --- a/gfx/wr/webrender/src/resource_cache.rs +++ b/gfx/wr/webrender/src/resource_cache.rs @@ -1970,7 +1970,7 @@ impl ResourceCache { #[cfg(target_os = "macos")] FontTemplate::Native(ref native) => { PlainFontTemplate { - data: native.name.clone(), + data: native.0.postscript_name().to_string(), index: 0, } } diff --git a/gfx/wr/webrender_api/Cargo.toml b/gfx/wr/webrender_api/Cargo.toml index 8fe8c0151c8e..36699c8e309d 100644 --- a/gfx/wr/webrender_api/Cargo.toml +++ b/gfx/wr/webrender_api/Cargo.toml @@ -27,3 +27,7 @@ time = "0.1" malloc_size_of = { version = "0.0.1", path = "../wr_malloc_size_of", package = "wr_malloc_size_of" } peek-poke = { version = "0.2", path = "../peek-poke", features = ["extras"] } crossbeam-channel = "0.5" + +[target.'cfg(target_os = "macos")'.dependencies] +core-foundation = "0.9" +core-graphics = "0.22" diff --git a/gfx/wr/webrender_api/src/font.rs b/gfx/wr/webrender_api/src/font.rs index 3527eed27539..cf805432c4d6 100644 --- a/gfx/wr/webrender_api/src/font.rs +++ b/gfx/wr/webrender_api/src/font.rs @@ -2,7 +2,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#[cfg(target_os = "macos")] +use core_foundation::string::CFString; +#[cfg(target_os = "macos")] +use core_graphics::font::CGFont; use peek_poke::PeekPoke; +#[cfg(target_os = "macos")] +use serde::de::{self, Deserialize, Deserializer}; +#[cfg(target_os = "macos")] +use serde::ser::{Serialize, Serializer}; use std::cmp::Ordering; use std::hash::{Hash, Hasher}; #[cfg(not(target_os = "macos"))] @@ -198,9 +206,37 @@ pub struct NativeFontHandle { } #[cfg(target_os = "macos")] -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct NativeFontHandle { - pub name: String, +#[derive(Clone)] +pub struct NativeFontHandle(pub CGFont); + +#[cfg(target_os = "macos")] +impl Serialize for NativeFontHandle { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0 + .postscript_name() + .to_string() + .serialize(serializer) + } +} + +#[cfg(target_os = "macos")] +impl<'de> Deserialize<'de> for NativeFontHandle { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let postscript_name: String = Deserialize::deserialize(deserializer)?; + + match CGFont::from_name(&CFString::new(&*postscript_name)) { + Ok(font) => Ok(NativeFontHandle(font)), + Err(_) => Err(de::Error::custom( + "Couldn't find a font with that PostScript name!", + )), + } + } } #[repr(C)] diff --git a/gfx/wr/webrender_api/src/lib.rs b/gfx/wr/webrender_api/src/lib.rs index 7e61ee244db6..a3e7969f3c50 100644 --- a/gfx/wr/webrender_api/src/lib.rs +++ b/gfx/wr/webrender_api/src/lib.rs @@ -24,6 +24,10 @@ extern crate bitflags; extern crate byteorder; #[cfg(feature = "nightly")] extern crate core; +#[cfg(target_os = "macos")] +extern crate core_foundation; +#[cfg(target_os = "macos")] +extern crate core_graphics; extern crate derive_more; #[macro_use] extern crate malloc_size_of_derive;