Core Text

RSS for tag

Create text layouts, optimize font handling, and access font metrics and glyph data using Core Text.

Core Text Documentation

Posts under Core Text tag

19 Posts
Sort by:
Post not yet marked as solved
0 Replies
98 Views
Hello, I'm trying to get a better understanding of the SMS.db tables and fields. Does anybody have a document that describes each table and the fields within that table? I'd like to understand what each field in the Messages Table is used for but it would be a bonus if the is info is also available for the other tables contained in the SMS.db as well.
Posted
by ED2017.
Last updated
.
Post not yet marked as solved
1 Replies
179 Views
When running my app from Xcode Umlauts are all of a sudden broken in several places. The app has been out in the public w/o similar issues for years. For example, this is the result when entering a filename in my NSDocument-based app: So far I could only observe the bug when launching under Sonoma from Xcode but I'm worried this might be a general issue for users of the app running the release build. Any ideas about what happened in macOS 14.4..? Cheers, Jay
Posted
by JayMcBee.
Last updated
.
Post not yet marked as solved
0 Replies
151 Views
Starting with the macOS version 14.x.x and TextKit1, selecting multiple lines of text triggers a text replacement bug: some of the text on one of the selected lines inadvertently replaces a portion of the selected text. For example, the bug is exhibited when selecting the following lines: Carnaroli, Maratelli, or Vialone Nano are best Vialone Nano cooks quickly – watch it! It also absorbs condiments nicely. Avoid Baldo, Originario, Ribe and Roma To trigger the bug, select the three line paragraph using either the cursor or shift with arrow keys. Notice that a portion of the selected text was replaced. Command-Z to undo will allow you to repeat the undesired behavior. In this case, "e Nano cooks quickly - " is replaced by "Baldo, Originario, Ribe." This does not occur with all strings or selected strings, but in cases where it does occur, it is perfectly reproducible. It does not occur on iOS. Pasteboard contents are irrelevant. After triggering the bug repeatedly, at some point it stops occurring. Why does this bug occur? How can it be fixed? Here is some sample code to reproduce the issue. @end @implementation TestNoteViewController - (void)viewDidLoad { [super viewDidLoad]; [self createTextView]; } - (void)createTextView { NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:self.note.text attributes:nil]; NSTextStorage *textStorage = [NSTextStorage new]; [textStorage appendAttributedString:attrString]; CGRect newTextViewRect = self.view.bounds; // Create the layout manager NSLayoutManager *layoutManager = [NSLayoutManager new]; [textStorage addLayoutManager:layoutManager]; // Create a text container NSTextContainer *container = [[NSTextContainer alloc] initWithSize:CGSizeMake(newTextViewRect.size.width, CGFLOAT_MAX)]; [layoutManager addTextContainer:container]; // Create and place a text view UITextView *textView = [[UITextView alloc] initWithFrame:newTextViewRect textContainer:container]; [self.view addSubview:textView]; textView.translatesAutoresizingMaskIntoConstraints = NO; UILayoutGuide *safeArea = textView.superview.safeAreaLayoutGuide; [textView.leadingAnchor constraintEqualToAnchor:safeArea.leadingAnchor].active = YES; [textView.trailingAnchor constraintEqualToAnchor:safeArea.trailingAnchor].active = YES; [textView.topAnchor constraintEqualToAnchor:safeArea.topAnchor].active = YES; [textView.bottomAnchor constraintEqualToAnchor:textView.superview.bottomAnchor].active = YES; } @end
Posted Last updated
.
Post not yet marked as solved
2 Replies
231 Views
Hello, First time poster. Was wondering if someone might know the answer to this. So I wanted to use a fancy font in my iPhone app for a title. The following code works fine, but the font I really want is “Apple Chancery” but it will not show up on the iPhone, even though this font is default on all Mac books. Any ideas why that font will not work? Thanks… Text("(whiskyname)") .frame(width: 350, height:56) .background(Color.blue.opacity(0.3)).border(Color.black, width: 3) .cornerRadius(5) .font(.custom("Snell Roundhand", fixedSize: 45)) .foregroundColor(.black) .bold()
Posted
by z4cruzn.
Last updated
.
Post not yet marked as solved
9 Replies
1.3k Views
Hello After updating my/our devices to iOS 17 (or XCode 15, not entirely sure), the custom fonts in our application have started randomly not working. Usually it will happen after the app has been in the background for a while. What happens is that: The fonts either don't load at all. For icon fonts, this means a lot of question marks. The fonts get swapped around, meaning regular text (Roboto, custom font) starts rendering using the icon font (Font Awesome). I can tell because I recognize the font from development. I have no idea how to reproduce it. I tried simulating the memory warning on the simulator, but that doesn't trigger it. It did not happen when building for iOS 16 and I did not change any font logic since then. It still does not happen on devices running iOS 17 but on versions of the app built with XCode 14. Some debug info: XCode: 15.0.1 (15A507) iOS: 17.1.1 (real device, I have not observed it on Simulator) We load the custom fonts from a proprietary SPM package: fileprivate static func registerFont(fontName: String, ext: String = "otf") { guard let fontURL = Bundle.module.url(forResource: fontName, withExtension: ext), let fontDataProvider = CGDataProvider(url: fontURL as CFURL), let font = CGFont(fontDataProvider) else { fatalError("Couldn't create font from filename: \(fontName).\(ext)") } var error: Unmanaged<CFError>? CTFontManagerRegisterGraphicsFont(font, &error) } public static func registerFonts() { registerFont(fontName: "Font Awesome 6 Brands-Regular-400") registerFont(fontName: "Font Awesome 6 Duotone-Solid-900") registerFont(fontName: "Font Awesome 6 Pro-Light-300") registerFont(fontName: "Font Awesome 6 Pro-Regular-400") registerFont(fontName: "Font Awesome 6 Pro-Solid-900") registerFont(fontName: "Font Awesome 6 Pro-Thin-100") registerFont(fontName: "Font Awesome 6 Sharp-Light-300") registerFont(fontName: "Font Awesome 6 Sharp-Regular-400") registerFont(fontName: "Font Awesome 6 Sharp-Solid-900") registerFont(fontName: "Roboto-Medium", ext: "ttf") registerFont(fontName: "Roboto-Regular", ext: "ttf") registerFont(fontName: "RobotoMono-Regular", ext: "ttf") } // Similar methods for all font types and icons: @objc public static func getDefaultFont(size: CGFloat) -> UIFont { return UIFont.init(name: "Roboto-Regular", size: size) ?? UIFont.systemFont(ofSize: size); } This code is the called in didFinishLaunching, and it would crash the app if it failed: FontHandler.registerFonts() To reiterate, all the fonts work when launching the app. Restarting the app always fixes it, which, combined with the fact that they get swapped around, leads me to believe that it's some kind of font caching issue. We use the fonts in code-only (no storyboards or xibs ever). A font would be loaded like this: let label = UILabel() label.font = FontHandler.getDefaultFont(size: 15) The font files ship with the SPM package itself, which contains the FontHandler class used above. import PackageDescription let package = Package( name: "MyPackageName", defaultLocalization: "en", platforms: [ .iOS(.v11) ], products: [ .library( name: "MyPackageName", targets: ["MyPackageName"]), ], targets: [ .target( name: "MyPackageName", resources: [ .process("Fonts") ]), .testTarget( name: "MyPackageNameTests", dependencies: ["MyPackageName"]), ] )
Posted
by nickdnk.
Last updated
.
Post not yet marked as solved
0 Replies
273 Views
Hello! I am developing an ebook reader iOS app that uses c/c++ codec as a page renderer. The codec uses TrueType as a font rendering engine that requires access to .ttf (or .ttc) files. Currently, I supply TrueType with fonts embedded in the app package, so they lay within the app sandbox. The codec supports the whole unicode plane and many languages that ebooks may use, but the fonts I supply don't have some of the important glyphs (i.e. katakana or hangul). I see that iOS has its own font storage, located in /System/Library/Fonts/ directory. The codec is able to parse this directory and read .ttf files located inside, using these fonts as a fallback in the case when the supplied fonts can't draw certain glyphs. I use opendir and fopen(in "rb" mode) as a way to read the data, and it works well. Does this type of access to the system directory violate the sandbox rule for an app distribution, and, if yes, is there a way to get access to stored .ttf files not violating the mentioned rule?
Posted
by Tarasus.
Last updated
.
Post not yet marked as solved
0 Replies
350 Views
Hi, I have used some custom Arabic fonts in UITextView to render some Arabic fonts. On iOS 17 the following code is not giving me the correct position of the tapped text in some special cases. Following the code i am using with the TapGestureRecognizer. @objc func arabicTextViewTapped(_ sender: UITapGestureRecognizer) { let attributedString = NSMutableAttributedString(attributedString: arabicTextView.attributedText) attributedString.removeAttribute(.backgroundColor, range: NSRange(location: 0, length: attributedString.length)) let touchPosition = sender.location(in: sender.view) guard let textPosition = arabicTextView.closestPosition(to: touchPosition), let textRange = arabicTextView.tokenizer .rangeEnclosingPosition(textPosition, with: .word, inDirection: .init(rawValue: 1)) else { return } guard let text = arabicTextView.text(in: textRange) else { return } } In the image below if there is some special character (called Ramos e aukaf) as the first character (which in this case is the small first character on the second line) then this code gives the position on the first line. guard let textPosition = arabicTextView.closestPosition(to: touchPosition) In the below case, the above code works perfectly fine as small character is not the first character on the second line. Also this is only happening on ios 17. Any help is highly appriciated.
Posted Last updated
.
Post not yet marked as solved
0 Replies
352 Views
I tried to load font using CTFontCreateWithFontDescriptor() and it behaves differently than loaded using NSFont(). Let's say the goal is to load font using CoreText that is exactly the same as using AppKit. NSTextField If I use them in NSTextField text offsets and rendering do not match. let familyName = "Helvetica" let fontSize: CGFloat = 30 let string = "Hello, World! gÖ,|#" // Load font using AppKit let font1 = NSFont(name: familyName, size: fontSize)! // Load font using CoreText API let font2 = CTFontCreateWithFontDescriptor(CTFontDescriptorCreateWithAttributes([ kCTFontFamilyNameAttribute: familyName, kCTFontSizeAttribute: fontSize, ] as [CFString : Any] as CFDictionary), 0, nil) as NSFont // Setup text fields let field1 = NSTextField() let field2 = NSTextField() field1.setAsLabel() field2.setAsLabel() field1.font = font1 field2.font = font2 field1.stringValue = string field2.stringValue = string NSAttributedString If I use them in NSAttributedString bounding box height of text is different: let bounds1 = NSAttributedString(string: string, attributes: [ .font: font1 ]).boundingRect(with: .infinity) let bounds2 = NSAttributedString(string: string, attributes: [ .font: font2 ]).boundingRect(with: .infinity) print(bounds1) // Prints: (0.0, -7.0, 252.3486328125, 37.0) print(bounds2) // Prints: (0.0, -7.0, 252.3486328125, 31.0) Investigation I compared fonts, font attributes, traits, feature settings, even binary font tables but I didn't find any difference. It seems like there is something inside that alters behaviour. I found that if I add .usesDeviceMetrics option to NSAttributedString bounds getter, it returns the same result but also completely different frame. let bounds1 = NSAttributedString(string: "Hello, World! gÖ,|#", attributes: [.font: font1]).boundingRect(with: .infinity, options: [.usesDeviceMetrics]) let bounds2 = NSAttributedString(string: "Hello, World! gÖ,|#", attributes: [.font: font2]).boundingRect(with: .infinity, options: [.usesDeviceMetrics]) print(bounds1) // Prints: (2.3583984375, -6.6357421875, 249.9609375, 33.837890625) print(bounds2) // Prints: (2.3583984375, -6.6357421875, 249.9609375, 33.837890625) Question How to load a font using CoreText in a way that NSFont does? Minor question: Why does NSTextField set it's frame origin to -2.0? Just extensions I used in code above: extension CGSize { public static var infinity: Self { .init(width: CGFloat.infinity, height: CGFloat.infinity) } } extension NSTextField { func setAsLabel() { translatesAutoresizingMaskIntoConstraints = false isBezeled = false isBordered = false isEditable = false isSelectable = false drawsBackground = false } }
Posted
by eSeverus.
Last updated
.
Post not yet marked as solved
2 Replies
621 Views
In iOS 17, when I try to use CTFramesetterSuggestFrameSizeWithConstraints to obtain the size of a text, if the system-provided bold font is used, the resulting rectangular area may not be sufficient to accommodate the text. The provided example code is not allowing me to display the complete text within the CTFrame. code: NSString *testString = @"《测试》"; CFStringRef cfTestString = CFStringCreateWithCString(kCFAllocatorDefault, [testString cStringUsingEncoding:NSUTF8StringEncoding], kCFStringEncodingUTF8); UIFont *uiFont = [UIFont boldSystemFontOfSize:50.0]; UIFontDescriptor *fontDescriptor = uiFont.fontDescriptor; CTFontDescriptorRef ctFontDescriptor = (__bridge CTFontDescriptorRef)fontDescriptor; CTFontRef ct_font = CTFontCreateWithFontDescriptor(ctFontDescriptor, uiFont.pointSize, NULL); CGFloat color_components[4] = {1.0, 1.0, 1.0, 1.0}; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGColorRef cgColor = CGColorCreate(colorSpace, color_components); CTParagraphStyleSetting styleSetting; styleSetting.spec = kCTParagraphStyleSpecifierAlignment; CTTextAlignment ctAlignment = kCTTextAlignmentCenter; styleSetting.value = &ctAlignment; styleSetting.valueSize = sizeof(kCTTextAlignmentCenter); CTParagraphStyleRef ctParagraphStyle = CTParagraphStyleCreate(&styleSetting, 1); const void* keys[] = {kCTFontAttributeName, kCTForegroundColorAttributeName, kCTParagraphStyleAttributeName}; const void* values[] = {ct_font, cgColor, ctParagraphStyle}; CFDictionaryRef attr = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFAttributedStringRef cfAttributedString = CFAttributedStringCreate(kCFAllocatorDefault, cfTestString, attr); CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(cfAttributedString); CGSize constraints = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX); CGSize stringSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 0), NULL, constraints, NULL); float width = ceil(stringSize.width); float height = ceil(stringSize.height); CGPathRef path = CGPathCreateWithRect(CGRectMake(0.0, 0.0, width, height), NULL); CTFrameRef cfFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL); CFRange stringRange = CTFrameGetStringRange(cfFrame); CFRange visibleStringRange = CTFrameGetVisibleStringRange(cfFrame); NSLog(@"stringRange.location: %@ stringRange.length: %@", @(stringRange.location), @(stringRange.length)); NSLog(@"visibleStringRange.location: %@ visibleStringRange.length: %@", @(visibleStringRange.location), @(visibleStringRange.length)); log: stringRange.location: 0 stringRange.length: 4 visibleStringRange.location: 0 visibleStringRange.length: 2
Posted
by JoeJone.
Last updated
.
Post not yet marked as solved
0 Replies
365 Views
Hi guys, I have imported font (I have added in info.plist) and I use this code to import in all of project: struct swim_targetApp: App { var body: some Scene { WindowGroup { ContentView() .environment(\.font, Font.custom("SFCompactRounded-Regular", size: 16)) .environment(\.font, Font.custom("SFCompactRounded-Ultralight", size: 16)) .environment(\.font, Font.custom("SFCompactRounded-Thin", size: 16)) .environment(\.font, Font.custom("SFCompactRounded-Light", size: 16)) .environment(\.font, Font.custom("SFCompactRounded-Medium", size: 16)) .environment(\.font, Font.custom("SFCompactRounded-Semibold", size: 16)) .environment(\.font, Font.custom("SFCompactRounded-Bold", size: 16)) .environment(\.font, Font.custom("SFCompactRounded-Heavy", size: 16)) .environment(\.font, Font.custom("SFCompactRounded-Black", size: 16)) } } } But .title, .title3, navigationBarTitle don't use my custom font (ex 1, 2 in screenshot), but in another parts working fine (ex 3 in screenshot). Can you help me? Thank you ;)
Posted
by gatfil.
Last updated
.
Post not yet marked as solved
3 Replies
1.8k Views
When using an exclusion path with an UITextView, the text view is not properly wrapping the words for the first and last line in the example shown (lower text). It does render properly using word-wrap with Core Text (top example).(Hmm - the image link I provided in the HTML here works with the preview, but not the post. The example image is at: http i.stack.imgur.com/Z91ge.pngHere is the code for the UITextView (both this and the Core Text example use the same size bezier path, and both use the appropriate corresponding font and paragraph settings; wrap by word and centered):NSString *testText = @"Text Kit exclusion paths ..."; / UIBezierPath *viewPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 280, 280)]; UIBezierPath *shapePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(10, 10, 265, 265)]; viewPath.usesEvenOddFillRule = true; shapePath.usesEvenOddFillRule = true; [shapePath appendPath:viewPath]; NSMutableAttributedString *title = [[NSMutableAttributedString alloc]initWithString:testText]; UIFont *font = [UIFont fontWithName:@"BradleyHandITCTT-Bold" size:14]; [title addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, title.length)]; [title addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, title.length)]; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; [paragraphStyle setAlignment:NSTextAlignmentCenter]; [paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping]; [title addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, title.length)]; UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0.0, 370.0, 280, 280)]; textView.textContainerInset = UIEdgeInsetsMake(0,0,0,0); textView.textContainer.exclusionPaths = @[shapePath]; [textView.textContainer setLineBreakMode:NSLineBreakByWordWrapping]; textView.contentInset = UIEdgeInsetsMake(0,0,0,0); textView.attributedText = title; textView.backgroundColor = [UIColor clearColor];It is worth noting that the Text Kit is respecting the word wrapping rules except for the first and (possibly last) line where the text does not actually fit. I need this to work with a UITextView because text entry is required, or I would be done with my Core Text example.I have tried everything I can think of to reliably work-around the issue. I don't fully understand how UITextView is working with Core Text (or I would expect to get the same results which I don’t), so any suggestions would be greatly appreciated.
Posted
by 3DTOPO.
Last updated
.
Post not yet marked as solved
0 Replies
395 Views
In macOS 14, NSAttributedString.Key.verticalGlyphForm has been deprecated. This key was previously used for rendering text vertically, particularly in languages like Chinese, Japanese, and Korean. I'm curious about the reasons behind its deprecation and would appreciate insights into alternative methods for displaying vertical text.
Posted
by oden-oden.
Last updated
.
Post not yet marked as solved
0 Replies
443 Views
Dear experts, I get glyphs from the system font using CTFontGetGlyphsForCharacters, something like this: UIFont* uifont = [UIFont monospacedDigitSystemFontOfSize: s weight: w]; CTFontRef font = (__bridge CTFontRef)uifont; CTFontGetGlyphsForCharacters(font, ....); The characters that I ask for are basically latin-1 plus a few others. The app is not localised for Chinese. When I change the phone's default language to Chinese, this code gets glyphs for most characters OK but it fails for a few punctuation symbols: 91 = [ 93 = ] 183 = middle dot 8220 = left double curly quote 8221 = right double curly quote Can anyone guess what's going on here? What's special about those characters? Thanks, Phil.
Posted
by endecotp.
Last updated
.
Post not yet marked as solved
1 Replies
719 Views
I have a Mac app, Notenik, written with AppKit, that dynamically generates an Edit view that is used to edit multiple fields for a Note. Sometimes, depending on a user's request, multiple NSTextViews end up appearing within the same parent view (a tab, if that matters). Lately I and some of my users have noticed that, when moving from one NSTextView to another (either by tabbing or by clicking), the cursor initially fails to appear. Once the user starts editing within the NSTextView, the cursor appears and acts normally. And this doesn't occur when moving from an ordinary text field to an NSTextView -- only when moving from one NSTextView to another. But it is troubling and confusing to users that the cursor initially disappears. I'm not sure exactly when this started happening, but it has not been happening for very long. Although I make frequent updates to the app, this section of code has had no recent changes, so I am at a loss to explain this behavior, or to correct it. Any help would be appreciated.
Posted
by hbowie.
Last updated
.
Post not yet marked as solved
0 Replies
475 Views
Hey, Maybe someone can explain me why NSLayoutManager is giving me "unstable" layout? It's like it decides to include line-height-multiple of 1.2 sometimes: We're doing some custom text rendering and if I change font size by a bit (or other property), then suddenly there is this extra text spacing. What we noticed so far is that there is something special about the first font that was set on NSTextStorage, in that case text has no extra spacing. Once you change it to slightly modified font else - the extra spacing is introduced. It's not NSParagraphStyle.lineHeightMultiple - if I set it to something non default then it acts as extra, but doesn't solve the "layout instability" issue. Any clue what's causing this? or how to make it to be stable?
Posted
by _Paulius_.
Last updated
.
Post not yet marked as solved
2 Replies
779 Views
Hi everyone, (you can answer in french) I’m french-rookie in xcode, and I have a problem: I’m trying to choice my custom font to add it in my Main.storyboard button, but it not works. I have my « Font provided by application » line in my Info.plist, with the name of my font in [0] (See images below) When I’m on storyboard button, I chose « custom » in font selector, then display font list but my custom font doesn’t appear. I already tried to install the font in my mac, but still stucked, nothing change 😭 Could you help me please? Thanks a lot (I specify that I scrupulously followed the way of doing explained on the Apple official page: Adding a Custom Font to Your App )
Posted Last updated
.
Post not yet marked as solved
1 Replies
733 Views
Hi, guys。 When I used SwiftUI to build the app, I used a custom font in the project to display emojis (the font ttf file has 23.7M). When using custom fonts, the code is as follows: ContentView will load slowly。 struct ContentView: View { var body: some View { NavigationView { List { ForEach(0..<100, id: \.self) { i in Text(verbatim: "\u{1fa84}") .font(.custom("NotoColorEmoji", size: 18)) .foregroundColor(.secondary) } } .frame(height: 400) } } } It takes about 3 seconds for the app to start and display the page. If commented out .font(.custom("NotoColorEmoji", size: 18)), everything will be fine So how to improve performance or preload the ttf font file? I wrote a demo in here,Is there any good way to solve this problem?
Posted
by coderyjy.
Last updated
.