Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use objc2 for determining whether font smoothing is enabled #69

Merged
merged 4 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@ freetype-rs = "0.36.0"
pkg-config = "0.3"

[target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.25.0"
core-foundation = "0.9.3"
core-text = "20.1.0"
core-graphics = "0.23.1"
core-foundation-sys = "0.8.4"
objc = "0.2.7"
once_cell = "1.12"
objc2 = "0.5.1"
objc2-foundation = { version = "0.2.2", features = [
"NSString",
"NSUserDefaults",
"NSValue",
] }

[target.'cfg(windows)'.dependencies]
dwrote = { version = "0.11" }
Expand Down
44 changes: 26 additions & 18 deletions src/darwin/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
//! Font rendering based on CoreText.

use std::collections::HashMap;
use std::ffi::c_char;
use std::ffi::CStr;
use std::iter;
use std::path::PathBuf;
use std::ptr;

use cocoa::base::{id, nil};
use cocoa::foundation::{NSInteger, NSString, NSUserDefaults};

use core_foundation::array::{CFArray, CFIndex};
use core_foundation::base::{CFType, ItemRef, TCFType};
use core_foundation::number::{CFNumber, CFNumberRef};
Expand All @@ -28,10 +24,10 @@ use core_text::font_descriptor::{
self, kCTFontColorGlyphsTrait, kCTFontDefaultOrientation, kCTFontEnabledAttribute,
CTFontDescriptor, SymbolicTraitAccessors,
};
use objc2::rc::{autoreleasepool, Retained};
use objc2_foundation::{ns_string, NSNumber, NSObject, NSObjectProtocol, NSString, NSUserDefaults};

use log::{trace, warn};
use objc::rc::autoreleasepool;
use objc::{class, msg_send, sel, sel_impl};
use once_cell::sync::Lazy;

pub mod byte_order;
Expand Down Expand Up @@ -274,30 +270,42 @@ fn descriptors_for_family(family: &str) -> Vec<Descriptor> {
// other integer, or a missing value (the default), or a value of any other type, as leaving it
// enabled.
static FONT_SMOOTHING_ENABLED: Lazy<bool> = Lazy::new(|| {
autoreleasepool(|| unsafe {
let key = NSString::alloc(nil).init_str("AppleFontSmoothing");
let value: id = msg_send![id::standardUserDefaults(), objectForKey: key];
autoreleasepool(|_| {
let value = unsafe {
NSUserDefaults::standardUserDefaults().objectForKey(ns_string!("AppleFontSmoothing"))
};

if msg_send![value, isKindOfClass: class!(NSNumber)] {
let num_type: *const c_char = msg_send![value, objCType];
if num_type.is_null() {
return true;
}
let value = match value {
Some(value) => value,
None => return true,
};

// SAFETY: The values in `NSUserDefaults` are always subclasses of
// `NSObject`.
let value: Retained<NSObject> = unsafe { Retained::cast(value) };

if value.is_kind_of::<NSNumber>() {
// SAFETY: Just checked that the value is a NSNumber
let value: Retained<NSNumber> = unsafe { Retained::cast(value) };
chrisduerr marked this conversation as resolved.
Show resolved Hide resolved

// NSNumber's objCType method returns one of these strings depending on the size:
// q = quad (long long), l = long, i = int, s = short.
// This is done to reject booleans, which are NSNumbers with an objCType of "c", but
// macOS does not treat them the same as an integer 0 or 1 for this setting,
// it just ignores it.
let int_specifiers: [&[u8]; 4] = [b"q", b"l", b"i", b"s"];
if !int_specifiers.contains(&CStr::from_ptr(num_type).to_bytes()) {

let encoding = unsafe { CStr::from_ptr(value.objCType().as_ptr()).to_bytes() };
if !int_specifiers.contains(&encoding) {
return true;
}

let smoothing: NSInteger = msg_send![value, integerValue];
let smoothing = value.integerValue();
smoothing != 0
} else if msg_send![value, isKindOfClass: class!(NSString)] {
let smoothing: NSInteger = msg_send![value, integerValue];
} else if value.is_kind_of::<NSString>() {
// SAFETY: Just checked that the value is a NSString
let value: Retained<NSString> = unsafe { Retained::cast(value) };
let smoothing = unsafe { value.integerValue() };
smoothing != 0
} else {
true
Expand Down
2 changes: 1 addition & 1 deletion src/ft/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ impl FreeTypeLoader {
font_key: FontKey,
) -> Result<Option<FontKey>, Error> {
if let Some(ft_face_location) = pattern.ft_face_location(0) {
if self.faces.get(&font_key).is_some() {
if self.faces.contains_key(&font_key) {
return Ok(Some(font_key));
}

Expand Down
Loading