author | Jonathan Kew <jkew@mozilla.com> |
Wed, 27 Oct 2021 14:37:40 +0000 (2021-10-27) | |
changeset 597047 | b5086513fe50f9598db2391f8cb021425033fadd |
parent 597046 | 0ad5486182ffdf455a0c0285b87780e7c39e5244 |
child 597086 | 39022aacb0e43d8c1777eec6ba6cfbad690038b1 |
push id | 38919 |
push user | archaeopteryx@coole-files.de |
push date | Wed, 27 Oct 2021 15:06:08 +0000 (2021-10-27) |
treeherder | mozilla-central@b5086513fe50 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jrmuizel, RyanVM |
bugs | 1732629 |
milestone | 95.0a1 |
first release with | nightly mac
b5086513fe50
/
95.0a1
/
20211027150608
/
files
nightly linux32
nightly linux64
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly mac
95.0a1
/
20211027150608
/
pushlog to previous
|
--- a/Cargo.lock +++ b/Cargo.lock @@ -5568,16 +5568,17 @@ dependencies = [ "byteorder", "core-foundation", "core-graphics", "core-text", "derive_more", "dwrote", "etagere", "euclid", + "foreign-types", "freetype", "fxhash", "gleam", "glslopt", "lazy_static", "libc", "log", "malloc_size_of_derive",
--- a/gfx/wr/Cargo.lock +++ b/gfx/wr/Cargo.lock @@ -1676,16 +1676,17 @@ dependencies = [ "byteorder", "core-foundation 0.9.0", "core-graphics 0.22.0", "core-text", "derive_more", "dwrote", "etagere", "euclid", + "foreign-types", "freetype", "fxhash", "gleam 0.13.1", "glslopt", "lazy_static", "libc", "log", "malloc_size_of_derive",
--- a/gfx/wr/webrender/Cargo.toml +++ b/gfx/wr/webrender/Cargo.toml @@ -64,8 +64,9 @@ libc = "0.2" [target.'cfg(target_os = "windows")'.dependencies] dwrote = "0.11" [target.'cfg(target_os = "macos")'.dependencies] core-foundation = "0.9" core-graphics = "0.22" core-text = { version = "19", default-features = false } objc = "0.2" +foreign-types = "0.3.0"
--- a/gfx/wr/webrender/src/lib.rs +++ b/gfx/wr/webrender/src/lib.rs @@ -66,16 +66,18 @@ extern crate malloc_size_of_derive; #[macro_use] extern crate serde; #[macro_use] extern crate tracy_rs; #[macro_use] extern crate derive_more; extern crate malloc_size_of; extern crate svg_fmt; +#[cfg(target_os = "macos")] +extern crate foreign_types; #[macro_use] mod profiler; mod batch; mod border; mod box_shadow; #[cfg(any(feature = "capture", feature = "replay"))]
--- a/gfx/wr/webrender/src/platform/macos/font.rs +++ b/gfx/wr/webrender/src/platform/macos/font.rs @@ -14,28 +14,32 @@ use core_graphics::base::{kCGBitmapByteO use core_graphics::color_space::CGColorSpace; use core_graphics::context::CGContext; use core_graphics::context::{CGBlendMode, CGTextDrawingMode}; use core_graphics::font::{CGFont, CGGlyph}; use core_graphics::geometry::{CGAffineTransform, CGPoint, CGSize}; use core_graphics::geometry::{CG_AFFINE_TRANSFORM_IDENTITY, CGRect}; use core_text::{self, font_descriptor::CTFontDescriptorCreateCopyWithAttributes}; use core_text::font::{CTFont, CTFontRef}; -use core_text::font_descriptor::{CTFontDescriptor, CTFontSymbolicTraits}; +use core_text::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef, CTFontSymbolicTraits}; use core_text::font_descriptor::{kCTFontDefaultOrientation, kCTFontColorGlyphsTrait}; use euclid::default::Size2D; use crate::gamma_lut::{ColorLut, GammaLut}; use crate::glyph_rasterizer::{FontInstance, FontTransform, GlyphKey}; use crate::glyph_rasterizer::{GlyphFormat, GlyphRasterError, GlyphRasterResult, RasterizedGlyph}; use crate::internal_types::{FastHashMap, ResourceCacheError}; use std::collections::hash_map::Entry; use std::sync::Arc; +use foreign_types::ForeignType; const INITIAL_CG_CONTEXT_SIDE_LENGTH: u32 = 32; +// Needed for calling CGFontCopyVariationAxes manually. +type CGFontRef = *mut <CGFont as ForeignType>::CType; + // We prefer to create CTFonts from a CTFontDescriptor, but that doesn't work in the case // of hidden system fonts on recent macOS versions, so for those we will instead use a // native CGFont as the basis. enum DescOrFont { Desc(CTFontDescriptor), Font(CGFont), } @@ -214,50 +218,71 @@ fn get_glyph_metrics( rasterized_descent: -bottom, advance: advance.width as f32, } } #[link(name = "ApplicationServices", kind = "framework")] extern { static kCTFontVariationAxisIdentifierKey: CFStringRef; - static kCTFontVariationAxisNameKey: CFStringRef; static kCTFontVariationAxisMinimumValueKey: CFStringRef; static kCTFontVariationAxisMaximumValueKey: CFStringRef; static kCTFontVariationAxisDefaultValueKey: CFStringRef; static kCTFontVariationAttribute: CFStringRef; + static kCGFontVariationAxisName: CFStringRef; fn CTFontCopyVariationAxes(font: CTFontRef) -> CFArrayRef; + fn CGFontCopyVariationAxes(font: CGFontRef) -> CFArrayRef; } fn new_ct_font_with_variations(desc_or_font: &DescOrFont, size: f64, variations: &[FontVariation]) -> CTFont { unsafe { let ct_font = match desc_or_font { DescOrFont::Desc(ct_font_desc) => core_text::font::new_from_descriptor(ct_font_desc, size), DescOrFont::Font(cg_font) => core_text::font::new_from_CGFont(cg_font, size) }; if variations.is_empty() { return ct_font; } - let axes_ref = CTFontCopyVariationAxes(ct_font.as_concrete_TypeRef()); - if axes_ref.is_null() { + + // We get the axes from Core Text in order to get the tags. + let ct_axes_ref = CTFontCopyVariationAxes(ct_font.as_concrete_TypeRef()); + if ct_axes_ref.is_null() { return ct_font; } - let axes: CFArray<CFDictionary> = TCFType::wrap_under_create_rule(axes_ref); + let ct_axes: CFArray<CFDictionary> = TCFType::wrap_under_create_rule(ct_axes_ref); + + // And get them from Core Graphics to get non-localized names. + let cg_font = match desc_or_font { + DescOrFont::Desc(_) => ct_font.copy_to_CGFont(), + DescOrFont::Font(cg_font) => cg_font.clone(), + }; + let cg_axes_ref = CGFontCopyVariationAxes(cg_font.as_ptr()); + if cg_axes_ref.is_null() { + return ct_font; + } + let cg_axes: CFArray<CFDictionary> = TCFType::wrap_under_create_rule(cg_axes_ref); + + // Bail out if the array lengths don't match. + if ct_axes.len() != cg_axes.len() { + return ct_font; + } + // We collect the values with either number or string keys, depending whether // we're going to instantiate the CTFont from a descriptor or a CGFont. // It'd probably be better to switch the CGFont-related APIs to expect numbers, // but that's left for a future cleanup. let mut vals: Vec<(CFNumber, CFNumber)> = Vec::with_capacity(variations.len() as usize); let mut vals_str: Vec<(CFString, CFNumber)> = Vec::with_capacity(variations.len() as usize); - for axis in axes.iter() { - if !axis.instance_of::<CFDictionary>() { + + for (ct_axis, cg_axis) in ct_axes.iter().zip(cg_axes.iter()) { + if !ct_axis.instance_of::<CFDictionary>() { return ct_font; } - let tag_val = match axis.find(kCTFontVariationAxisIdentifierKey as *const _) { + let tag_val = match ct_axis.find(kCTFontVariationAxisIdentifierKey as *const _) { Some(tag_ptr) => { let tag: CFNumber = TCFType::wrap_under_get_rule(*tag_ptr as CFNumberRef); if !tag.instance_of::<CFNumber>() { return ct_font; } match tag.to_i64() { Some(val) => val, None => return ct_font, @@ -265,51 +290,51 @@ fn new_ct_font_with_variations(desc_or_f } None => return ct_font, }; let mut val = match variations.iter().find(|variation| (variation.tag as i64) == tag_val) { Some(variation) => variation.value as f64, None => continue, }; - let name: CFString = match axis.find(kCTFontVariationAxisNameKey as *const _) { + let name: CFString = match cg_axis.find(kCGFontVariationAxisName as *const _) { Some(name_ptr) => TCFType::wrap_under_get_rule(*name_ptr as CFStringRef), None => return ct_font, }; if !name.instance_of::<CFString>() { return ct_font; } - let min_val = match axis.find(kCTFontVariationAxisMinimumValueKey as *const _) { + let min_val = match ct_axis.find(kCTFontVariationAxisMinimumValueKey as *const _) { Some(min_ptr) => { let min: CFNumber = TCFType::wrap_under_get_rule(*min_ptr as CFNumberRef); if !min.instance_of::<CFNumber>() { return ct_font; } match min.to_f64() { Some(val) => val, None => return ct_font, } } None => return ct_font, }; - let max_val = match axis.find(kCTFontVariationAxisMaximumValueKey as *const _) { + let max_val = match ct_axis.find(kCTFontVariationAxisMaximumValueKey as *const _) { Some(max_ptr) => { let max: CFNumber = TCFType::wrap_under_get_rule(*max_ptr as CFNumberRef); if !max.instance_of::<CFNumber>() { return ct_font; } match max.to_f64() { Some(val) => val, None => return ct_font, } } None => return ct_font, }; - let def_val = match axis.find(kCTFontVariationAxisDefaultValueKey as *const _) { + let def_val = match ct_axis.find(kCTFontVariationAxisDefaultValueKey as *const _) { Some(def_ptr) => { let def: CFNumber = TCFType::wrap_under_get_rule(*def_ptr as CFNumberRef); if !def.instance_of::<CFNumber>() { return ct_font; } match def.to_f64() { Some(val) => val, None => return ct_font, @@ -1010,17 +1035,16 @@ fn CFData_wrapping_arc_vec(buffer: Arc<V }); let data_ref = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ptr, len, allocator.as_CFTypeRef()); TCFType::wrap_under_create_rule(data_ref) } } fn create_font_descriptor(cf_data: CFData) -> Result<CTFontDescriptor, ()> { - use core_text::font_descriptor::CTFontDescriptorRef; use core_foundation::data::CFDataRef; extern { pub fn CTFontManagerCreateFontDescriptorFromData(data: CFDataRef) -> CTFontDescriptorRef; } unsafe { let ct_font_descriptor_ref = CTFontManagerCreateFontDescriptorFromData(cf_data.as_concrete_TypeRef()); if ct_font_descriptor_ref.is_null() { return Err(());