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 the new objc2 CoreFoundation/Text bindings #252

Merged
merged 1 commit into from
Feb 17, 2025

Conversation

waywardmonkeys
Copy link
Contributor

@waywardmonkeys waywardmonkeys commented Jan 24, 2025

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.

@waywardmonkeys
Copy link
Contributor Author

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

};
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.

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
@tomcur tomcur added this to the 0.3 Release milestone Feb 6, 2025
@waywardmonkeys waywardmonkeys marked this pull request as ready for review February 7, 2025 16:58
@waywardmonkeys waywardmonkeys changed the title fontique: Update to objc2 0.6 and new CoreFoundation bindings fontique: Update to the new objc2 CoreFoundation/Text bindings Feb 16, 2025
@waywardmonkeys
Copy link
Contributor Author

Updated to remove the unwrap. Moved some stuff back to the top level to clean it up. The diff is terrible to read, sorry.

Copy link
Member

@DJMcNab DJMcNab left a comment

Choose a reason for hiding this comment

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

Largely formalising @madsmtm's previous approval

Copy link
Member

@tomcur tomcur left a comment

Choose a reason for hiding this comment

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

I believe this is correct. I left one allocation nit as inline comment. (Edit: never mind, it made no difference.)

let text = CFString::from_str(text);
let text_range = CFRange {
location: 0,
length: unsafe { CFStringGetLength(&text) },
Copy link
Member

Choose a reason for hiding this comment

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

Out of interest, is this the same as (before shadowing) text.chars().count()?

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 honesty don't know.

Copy link
Member

Choose a reason for hiding this comment

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

I think it would be: text.chars().map(char::len_utf16).sum() (docs)

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.
@waywardmonkeys waywardmonkeys added this pull request to the merge queue Feb 17, 2025
Merged via the queue into linebender:main with commit 2d177d2 Feb 17, 2025
21 checks passed
@waywardmonkeys waywardmonkeys deleted the update-objc2 branch February 17, 2025 13:51
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.

6 participants