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

fontique: Update to objc2 0.6 and new CoreFoundation bindings #252

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

waywardmonkeys
Copy link
Contributor

The objc2 family of crates now provides bindings for CoreFoundation and CoreText (and much more), so we can use these rather than the old core-foundation and core-text crates.

This also simplifies some of the code. One simplification assumes that CTFontCreateUIFontForLanguage won't fail.

@waywardmonkeys
Copy link
Contributor Author

@madsmtm This may be of interest to you as well.

{
desc = ui_desc;
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't think we needed to get the UI front, then get the descriptor from that, then get a font from that descriptor. If we want a UI font, can't we just use the UI font that get from CTFontCreateUIFontForLanguage?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems plausible, not sure why it's done that way right now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At some point, this was more involved and tried to select a font with specific properties thus a descriptor was required. The simplification looks good to me.

};
let locale = locale.map(CFString::from_str);
let base_font = if prefer_ui {
unsafe { CTFontCreateUIFontForLanguage(CTFontUIFontType::System, 0.0, None).unwrap() }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this can't fail. I could be wrong?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, since we are giving no language then presumably it is never going to fail in practice... though it is technically fallible.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you always get the last resort font when matching fails but I try to avoid unwraps in cases where I can’t be 100% certain. My general philosophy is that libraries should never panic, particularly in cases like this where the user has no control over the behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will adjust this to remove the unwrap.

unsafe {
let attrs = CFDictionaryCreate(None, null_mut(), null_mut(), 0, null(), null());
let desc = CTFontDescriptorCreateWithAttributes(&attrs.unwrap());
CTFontCreateWithFontDescriptor(&desc, 0.0, null())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is interesting that we don't pass any attributes here. What is the font that gets returned from this sort of thing?

Copy link
Member

@xorgy xorgy Jan 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe in practice it gets you 12pt San Francisco (or Helvetica back-when). CTFontCreateWithFontDescriptor takes an unspecified descriptor as an opportunity to default on every field. It defaults to an ordinary text font.

objc2-foundation = { version = "0.2.2", features = ["NSArray", "NSEnumerator", "NSPathUtilities", "NSString"], optional = true }
objc2-foundation = { version = "0.3.0", optional = true, default-features = false, features = ["alloc", "NSArray", "NSEnumerator", "NSPathUtilities", "NSString"] }
objc2-core-foundation = { version = "0.3.0", optional = true, default-features = false, features = ["CFBase"] }
objc2-core-text = { version = "0.3.0", optional = true }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still need to turn off default-features here and then update and re-format the above.

The `objc2` family of crates now provides bindings for CoreFoundation
and CoreText (and much more), so we can use these rather than the
old `core-foundation` and `core-text` crates.

This also simplifies some of the code. One simplification assumes
that `CTFontCreateUIFontForLanguage` won't fail.
Copy link

@madsmtm madsmtm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot say anything about the specifics of the API (I kinda just do the bindings), but otherwise it looks good 👍.

Btw, I hope you didn't decide to stray away from using CFDictionary for the attributes just because we don't provide a nice binding for creating those yet? If so, that's definitely unfortunate, then I'd rather that you wait with using objc2-core-graphics until we provide feature-parity (I don't want people to use the crates when their usage ends up less flexible ;) ).

@waywardmonkeys
Copy link
Contributor Author

I cannot say anything about the specifics of the API (I kinda just do the bindings), but otherwise it looks good 👍.

I wanted your input on if I was using them correctly and maybe whether or not there is something that could be better (now or in the future).

Btw, I hope you didn't decide to stray away from using CFDictionary for the attributes just because we don't provide a nice binding for creating those yet? If so, that's definitely unfortunate, then I'd rather that you wait with using objc2-core-graphics until we provide feature-parity (I don't want people to use the crates when their usage ends up less flexible ;) ).

Nope! We weren't passing in any actual attributes in the old code either, so there's no functional change there really.

@DJMcNab
Copy link
Member

DJMcNab commented Jan 27, 2025

I can't meaningfully review this code. I'm happy to formalise the approval from Mads, if needed.

@DJMcNab DJMcNab removed their request for review January 27, 2025 09:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants