diff --git a/core-graphics/src/font.rs b/core-graphics/src/font.rs index 11ebe30a1..5bdf86f2b 100644 --- a/core-graphics/src/font.rs +++ b/core-graphics/src/font.rs @@ -7,7 +7,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core_foundation::base::{CFRelease, CFRetain, CFTypeID, TCFType}; +use core_foundation::base::{CFRelease, CFRetain, CFType, CFTypeID, TCFType}; use core_foundation::array::{CFArray, CFArrayRef}; use core_foundation::data::{CFData, CFDataRef}; use core_foundation::number::CFNumber; @@ -122,6 +122,25 @@ impl CGFont { None } } + + pub fn copy_variations(&self) -> Option> { + let variations = unsafe { CGFontCopyVariations(self.as_ptr()) }; + if !variations.is_null() { + Some(unsafe { TCFType::wrap_under_create_rule(variations) }) + } else { + None + } + } + + pub fn copy_variation_axis(&self) -> Option>> { + unsafe { + let axes = CGFontCopyVariationAxes(self.as_ptr()); + if axes.is_null() { + return None; + } + Some(TCFType::wrap_under_create_rule(axes)) + } + } } #[link(name = "CoreGraphics", kind = "framework")] @@ -153,4 +172,6 @@ extern { fn CGFontCopyTableTags(font: ::sys::CGFontRef) -> CFArrayRef; fn CGFontCopyTableForTag(font: ::sys::CGFontRef, tag: u32) -> CFDataRef; + fn CGFontCopyVariations(font: ::sys::CGFontRef) -> CFDictionaryRef; + fn CGFontCopyVariationAxes(font: ::sys::CGFontRef) -> CFArrayRef; } diff --git a/core-text/src/font.rs b/core-text/src/font.rs index ebe6d580f..88f7f860e 100644 --- a/core-text/src/font.rs +++ b/core-text/src/font.rs @@ -741,4 +741,38 @@ fn copy_system_font() { assert!(matching.attributes().find(CFString::from_static_string("NSFontSizeAttribute")).is_none()); assert_eq!(small.postscript_name(), cgfont.postscript_name()); -} \ No newline at end of file +} + +#[test] +fn variations_dict() { + let mut vals_str: Vec<(CFString, CFNumber)> = Vec::new(); + let system_font = unsafe { + CTFont::wrap_under_create_rule( + CTFontCreateUIFontForLanguage(kCTFontEmphasizedSystemDetailFontType, 19., std::ptr::null()) + ) + }; + let font = system_font.copy_to_CGFont(); + vals_str.push((CFString::new("Weight"), (700.).into()) ); + let vars = CFDictionary::from_CFType_pairs(&vals_str); + let var_font = CGFont::create_copy_from_variations(&font, &vars).unwrap(); + match macos_version() { + (10, 11, _) => { + assert!(font.copy_variation_axis().is_none()); + return; + } + _ => {} + } + let vars = var_font.copy_variations().unwrap(); + let ct_font = new_from_CGFont_with_variations(&var_font.clone(), 19., &vars); + + // check if our variations worked + let var = ct_font.copy_descriptor().attributes().find(CFString::from_static_string("NSCTFontVariationAttribute")) + .unwrap() + .downcast::() + .unwrap(); + let var: CFDictionary = unsafe { std::mem::transmute(var) }; + match macos_version() { + (10, 12, _) => assert!(var.find(CFNumber::from(0x77676874)).is_none()), // XXX: I'm not sure why this is + _ => assert!(var.find(CFNumber::from(0x77676874)).is_some()), + } +}