From 243472042aa59e6dd15399c987c2dd2b1e74ac74 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 24 Jul 2018 15:55:51 -0700 Subject: [PATCH] Add several new functions to Core Graphics and Core Text for `font-kit`'s use. This bumps the major version of `core-text` since the previous version of `get_glyphs_for_characters` was unsoundly marked safe before and is now marked unsafe. --- cocoa/Cargo.toml | 4 +- core-graphics/Cargo.toml | 2 +- core-graphics/src/color_space.rs | 10 ++++ core-graphics/src/context.rs | 14 +++++ core-graphics/src/geometry.rs | 10 ++++ core-graphics/src/path.rs | 18 +++++- core-text/Cargo.toml | 4 +- core-text/src/font.rs | 97 ++++++++++++++++++++++++++++---- core-text/src/font_descriptor.rs | 2 + core-text/src/font_manager.rs | 10 +++- 10 files changed, 151 insertions(+), 20 deletions(-) diff --git a/cocoa/Cargo.toml b/cocoa/Cargo.toml index 45282d1..409f28b 100644 --- a/cocoa/Cargo.toml +++ b/cocoa/Cargo.toml @@ -4,7 +4,7 @@ name = "cocoa" description = "Bindings to Cocoa for OS X" homepage = "https://github.com/servo/core-foundation-rs" repository = "https://github.com/servo/core-foundation-rs" -version = "0.17.0" +version = "0.18.0" authors = ["The Servo Project Developers"] license = "MIT / Apache-2.0" @@ -16,5 +16,5 @@ crate-type = ["rlib"] block = "0.1" bitflags = "1.0" libc = "0.2" -core-graphics = { path = "../core-graphics", version = "0.16" } +core-graphics = { path = "../core-graphics", version = "0.17" } objc = "0.2.3" diff --git a/core-graphics/Cargo.toml b/core-graphics/Cargo.toml index 63c1b03..e9c794c 100644 --- a/core-graphics/Cargo.toml +++ b/core-graphics/Cargo.toml @@ -3,7 +3,7 @@ name = "core-graphics" description = "Bindings to Core Graphics for OS X" homepage = "https://github.com/servo/core-graphics-rs" repository = "https://github.com/servo/core-foundation-rs" -version = "0.16.0" +version = "0.17.0" authors = ["The Servo Project Developers"] license = "MIT / Apache-2.0" diff --git a/core-graphics/src/color_space.rs b/core-graphics/src/color_space.rs index 67f2504..9eef09c 100644 --- a/core-graphics/src/color_space.rs +++ b/core-graphics/src/color_space.rs @@ -34,12 +34,21 @@ impl CGColorSpace { } } + #[inline] pub fn create_device_rgb() -> CGColorSpace { unsafe { let result = CGColorSpaceCreateDeviceRGB(); CGColorSpace::from_ptr(result) } } + + #[inline] + pub fn create_device_gray() -> CGColorSpace { + unsafe { + let result = CGColorSpaceCreateDeviceGray(); + CGColorSpace::from_ptr(result) + } + } } #[link(name = "CoreGraphics", kind = "framework")] @@ -53,6 +62,7 @@ extern { pub static kCGColorSpaceGenericGrayGamma2_2: CFStringRef; fn CGColorSpaceCreateDeviceRGB() -> ::sys::CGColorSpaceRef; + fn CGColorSpaceCreateDeviceGray() -> ::sys::CGColorSpaceRef; fn CGColorSpaceCreateWithName(name: CFStringRef) -> ::sys::CGColorSpaceRef; fn CGColorSpaceGetTypeID() -> CFTypeID; } diff --git a/core-graphics/src/context.rs b/core-graphics/src/context.rs index 5f36b24..7b659cf 100644 --- a/core-graphics/src/context.rs +++ b/core-graphics/src/context.rs @@ -78,6 +78,12 @@ impl CGContext { } } + pub fn flush(&self) { + unsafe { + CGContextFlush(self.as_ptr()) + } + } + pub fn width(&self) -> size_t { unsafe { CGBitmapContextGetWidth(self.as_ptr()) @@ -102,6 +108,12 @@ impl CGContext { } } + pub fn set_gray_fill_color(&self, gray: CGFloat, alpha: CGFloat) { + unsafe { + CGContextSetGrayFillColor(self.as_ptr(), gray, alpha) + } + } + pub fn set_allows_font_smoothing(&self, allows_font_smoothing: bool) { unsafe { CGContextSetAllowsFontSmoothing(self.as_ptr(), allows_font_smoothing) @@ -252,6 +264,7 @@ extern { fn CGBitmapContextGetBytesPerRow(context: ::sys::CGContextRef) -> size_t; fn CGBitmapContextCreateImage(context: ::sys::CGContextRef) -> ::sys::CGImageRef; fn CGContextGetTypeID() -> CFTypeID; + fn CGContextFlush(c: ::sys::CGContextRef); fn CGContextSetAllowsFontSmoothing(c: ::sys::CGContextRef, allowsFontSmoothing: bool); fn CGContextSetShouldSmoothFonts(c: ::sys::CGContextRef, shouldSmoothFonts: bool); fn CGContextSetFontSmoothingStyle(c: ::sys::CGContextRef, style: c_int); @@ -271,6 +284,7 @@ extern { green: CGFloat, blue: CGFloat, alpha: CGFloat); + fn CGContextSetGrayFillColor(context: ::sys::CGContextRef, gray: CGFloat, alpha: CGFloat); fn CGContextFillRect(context: ::sys::CGContextRef, rect: CGRect); fn CGContextDrawImage(c: ::sys::CGContextRef, rect: CGRect, image: ::sys::CGImageRef); diff --git a/core-graphics/src/geometry.rs b/core-graphics/src/geometry.rs index 906c605..b22c704 100644 --- a/core-graphics/src/geometry.rs +++ b/core-graphics/src/geometry.rs @@ -140,6 +140,15 @@ impl CGRect { } } +impl PartialEq for CGRect { + #[inline] + fn eq(&self, other: &CGRect) -> bool { + unsafe { + ffi::CGRectEqualToRect(*self, *other) != 0 + } + } +} + #[repr(C)] #[derive(Clone, Copy, Debug, Default)] pub struct CGAffineTransform { @@ -184,6 +193,7 @@ mod ffi { rect: *mut CGRect) -> boolean_t; pub fn CGRectIsEmpty(rect: CGRect) -> boolean_t; pub fn CGRectIntersectsRect(rect1: CGRect, rect2: CGRect) -> boolean_t; + pub fn CGRectEqualToRect(rect1: CGRect, rect2: CGRect) -> boolean_t; pub fn CGAffineTransformInvert(t: CGAffineTransform) -> CGAffineTransform; diff --git a/core-graphics/src/path.rs b/core-graphics/src/path.rs index f25c618..dc1c804 100644 --- a/core-graphics/src/path.rs +++ b/core-graphics/src/path.rs @@ -7,13 +7,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +pub use sys::CGPathRef as SysCGPathRef; + use core_foundation::base::{CFRelease, CFRetain, CFTypeID}; use foreign_types::ForeignType; -use geometry::CGPoint; -use std::os::raw::c_void; +use geometry::{CGAffineTransform, CGPoint, CGRect}; +use libc::c_void; use std::fmt::{self, Debug, Formatter}; use std::marker::PhantomData; use std::ops::Deref; +use std::ptr; use std::slice; foreign_type! { @@ -26,6 +29,16 @@ foreign_type! { } impl CGPath { + pub fn from_rect(rect: CGRect, transform: Option<&CGAffineTransform>) -> CGPath { + unsafe { + let transform = match transform { + None => ptr::null(), + Some(transform) => transform as *const CGAffineTransform, + }; + CGPath(CGPathCreateWithRect(rect, transform)) + } + } + pub fn type_id() -> CFTypeID { unsafe { CGPathGetTypeID() @@ -110,6 +123,7 @@ type CGPathApplierFunction = unsafe extern "C" fn(info: *mut c_void, #[link(name = "CoreGraphics", kind = "framework")] extern { + fn CGPathCreateWithRect(rect: CGRect, transform: *const CGAffineTransform) -> ::sys::CGPathRef; fn CGPathApply(path: ::sys::CGPathRef, info: *mut c_void, function: CGPathApplierFunction); fn CGPathGetTypeID() -> CFTypeID; } diff --git a/core-text/Cargo.toml b/core-text/Cargo.toml index 20dc06a..94dbc2c 100644 --- a/core-text/Cargo.toml +++ b/core-text/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "core-text" -version = "11.0.0" +version = "12.0.0" authors = ["The Servo Project Developers"] description = "Bindings to the Core Text framework." license = "MIT/Apache-2.0" @@ -16,4 +16,4 @@ mountainlion = [] foreign-types = "0.3" libc = "0.2" core-foundation = { path = "../core-foundation", version = "0.6" } -core-graphics = { path = "../core-graphics", version = "0.16" } +core-graphics = { path = "../core-graphics", version = "0.17" } diff --git a/core-text/src/font.rs b/core-text/src/font.rs index 128120c..da8efb8 100644 --- a/core-text/src/font.rs +++ b/core-text/src/font.rs @@ -163,6 +163,24 @@ impl CTFont { } } + pub fn clone_with_symbolic_traits(&self, + trait_value: CTFontSymbolicTraits, + trait_mask: CTFontSymbolicTraits) + -> Option { + unsafe { + let font_ref = CTFontCreateCopyWithSymbolicTraits(self.0, + 0.0, + ptr::null(), + trait_value, + trait_mask); + if font_ref.is_null() { + None + } else { + Some(CTFont::wrap_under_create_rule(font_ref)) + } + } + } + // Names pub fn family_name(&self) -> String { unsafe { @@ -192,6 +210,20 @@ impl CTFont { } } + pub fn display_name(&self) -> String { + unsafe { + let value = get_string_by_name_key(self, kCTFontFullNameKey); + value.expect("Fonts should always have a PostScript name.") + } + } + + pub fn style_name(&self) -> String { + unsafe { + let value = get_string_by_name_key(self, kCTFontStyleNameKey); + value.expect("Fonts should always have a style name.") + } + } + pub fn all_traits(&self) -> CTFontTraits { unsafe { CTFontTraits::wrap_under_create_rule(CTFontCopyTraits(self.0)) @@ -223,6 +255,18 @@ impl CTFont { } } + pub fn slant_angle(&self) -> CGFloat { + unsafe { + CTFontGetSlantAngle(self.0) + } + } + + pub fn cap_height(&self) -> CGFloat { + unsafe { + CTFontGetCapHeight(self.0) + } + } + pub fn bounding_box(&self) -> CGRect { unsafe { CTFontGetBoundingBox(self.0) @@ -253,11 +297,12 @@ impl CTFont { } } - pub fn get_glyphs_for_characters(&self, characters: *const UniChar, glyphs: *mut CGGlyph, count: CFIndex) - -> bool { - unsafe { - CTFontGetGlyphsForCharacters(self.0, characters, glyphs, count) - } + pub unsafe fn get_glyphs_for_characters(&self, + characters: *const UniChar, + glyphs: *mut CGGlyph, + count: CFIndex) + -> bool { + CTFontGetGlyphsForCharacters(self.0, characters, glyphs, count) } pub fn get_advances_for_glyphs(&self, @@ -271,6 +316,20 @@ impl CTFont { } } + pub fn get_vertical_translations_for_glyphs(&self, + orientation: CTFontOrientation, + glyphs: *const CGGlyph, + translations: *mut CGSize, + count: CFIndex) { + unsafe { + CTFontGetVerticalTranslationsForGlyphs(self.0, + orientation, + glyphs, + translations, + count) + } + } + pub fn get_font_table(&self, tag: u32) -> Option { unsafe { let result = CTFontCopyTable(self.0, @@ -377,7 +436,7 @@ pub fn debug_font_traits(font: &CTFont) { let traits = font.all_traits(); println!("kCTFontWeightTrait: {}", traits.normalized_weight()); -// println!("kCTFontWidthTrait: {}", traits.normalized_width()); + println!("kCTFontWidthTrait: {}", traits.normalized_width()); // println!("kCTFontSlantTrait: {}", traits.normalized_slant()); } @@ -446,7 +505,12 @@ extern { //fn CTFontCreateUIFontForLanguage fn CTFontCreateCopyWithAttributes(font: CTFontRef, size: CGFloat, matrix: *const CGAffineTransform, attributes: CTFontDescriptorRef) -> CTFontRef; - //fn CTFontCreateCopyWithSymbolicTraits + fn CTFontCreateCopyWithSymbolicTraits(font: CTFontRef, + size: CGFloat, + matrix: *const CGAffineTransform, + symTraitValue: CTFontSymbolicTraits, + symTraitMask: CTFontSymbolicTraits) + -> CTFontRef; //fn CTFontCreateCopyWithFamily //fn CTFontCreateForString @@ -462,7 +526,7 @@ extern { //fn CTFontCopyPostScriptName(font: CTFontRef) -> CFStringRef; //fn CTFontCopyFamilyName(font: CTFontRef) -> CFStringRef; //fn CTFontCopyFullName(font: CTFontRef) -> CFStringRef; - //fn CTFontCopyDisplayName(font: CTFontRef) -> CFStringRef; + fn CTFontCopyDisplayName(font: CTFontRef) -> CFStringRef; fn CTFontCopyName(font: CTFontRef, nameKey: CFStringRef) -> CFStringRef; //fn CTFontCopyLocalizedName(font: CTFontRef, nameKey: CFStringRef, // language: *CFStringRef) -> CFStringRef; @@ -484,8 +548,8 @@ extern { fn CTFontGetBoundingBox(font: CTFontRef) -> CGRect; fn CTFontGetUnderlinePosition(font: CTFontRef) -> CGFloat; fn CTFontGetUnderlineThickness(font: CTFontRef) -> CGFloat; - //fn CTFontGetSlantAngle - //fn CTFontGetCapHeight + fn CTFontGetSlantAngle(font: CTFontRef) -> CGFloat; + fn CTFontGetCapHeight(font: CTFontRef) -> CGFloat; fn CTFontGetXHeight(font: CTFontRef) -> CGFloat; /* Getting Glyph Data */ @@ -498,8 +562,17 @@ extern { boundingRects: *mut CGRect, count: CFIndex) -> CGRect; - fn CTFontGetAdvancesForGlyphs(font: CTFontRef, orientation: CTFontOrientation, glyphs: *const CGGlyph, advances: *mut CGSize, count: CFIndex) -> libc::c_double; - //fn CTFontGetVerticalTranslationsForGlyphs + fn CTFontGetAdvancesForGlyphs(font: CTFontRef, + orientation: CTFontOrientation, + glyphs: *const CGGlyph, + advances: *mut CGSize, + count: CFIndex) + -> libc::c_double; + fn CTFontGetVerticalTranslationsForGlyphs(font: CTFontRef, + orientation: CTFontOrientation, + glyphs: *const CGGlyph, + translations: *mut CGSize, + count: CFIndex); /* Working With Font Variations */ fn CTFontCopyVariationAxes(font: CTFontRef) -> CFArrayRef; diff --git a/core-text/src/font_descriptor.rs b/core-text/src/font_descriptor.rs index b00a9f8..793629f 100644 --- a/core-text/src/font_descriptor.rs +++ b/core-text/src/font_descriptor.rs @@ -53,6 +53,7 @@ pub trait SymbolicTraitAccessors { fn is_expanded(&self) -> bool; fn is_condensed(&self) -> bool; fn is_monospace(&self) -> bool; + fn is_vertical(&self) -> bool; } impl SymbolicTraitAccessors for CTFontSymbolicTraits { @@ -61,6 +62,7 @@ impl SymbolicTraitAccessors for CTFontSymbolicTraits { fn is_expanded(&self) -> bool { (*self & kCTFontExpandedTrait) != 0 } fn is_condensed(&self) -> bool { (*self & kCTFontCondensedTrait) != 0 } fn is_monospace(&self) -> bool { (*self & kCTFontMonoSpaceTrait) != 0 } + fn is_vertical(&self) -> bool { (*self & kCTFontVerticalTrait) != 0 } } pub type CTFontStylisticClass = u32; diff --git a/core-text/src/font_manager.rs b/core-text/src/font_manager.rs index d9eca05..6867044 100644 --- a/core-text/src/font_manager.rs +++ b/core-text/src/font_manager.rs @@ -7,9 +7,17 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core_foundation::array::CFArrayRef; +use core_foundation::array::{CFArray, CFArrayRef}; +use core_foundation::base::TCFType; +use core_foundation::string::CFString; use core_foundation::url::CFURLRef; +pub fn copy_available_font_family_names() -> CFArray { + unsafe { + TCFType::wrap_under_create_rule(CTFontManagerCopyAvailableFontFamilyNames()) + } +} + extern { /* * CTFontManager.h