Core Text omits all remaining content and breaks rendering when truncation is enabled and after encountering a line containing only spaces

When drawing multiline text using Core Text (by preparing a paragraph and issuing a call to CTDrawFrame):

  • if truncation is enabled via a paragraph setting (spec=kCTParagraphStyleSpecifierLineBreakMode and value=kCTLineBreakByTruncatingMiddle),
  • and if one of the lines to render contains a line with spaces only (codepoint=U+0020),
  • and if the available width for rendering is less than the natural width of the line containing only spaces,

then the rendering is incomplete, all content in the lines following the spaces is omitted.

Many other codepoints cause the same problem: tabs (U+0009), no-break spaces (U+00A0), control characters ...

The issue is quite severe because the rendering can break with a simple ASCII input ! Here is a recording with a yellow text background to help see the spaces :

To reproduce :

CGContextRef ctx = [[NSGraphicsContext currentContext] CGContext];

// String to display: 3 lines, the middle one contains only spaces (40)
CFStringRef str = CFSTR("Hello World!\n                                        \nThis is a multiline example with a long line.");

// Font used for rendering
CTFontRef font = CTFontCreateWithName(CFSTR("Helvetica"), 20, nullptr);

// Paragraph style with middle truncation
CTLineBreakMode lineBreak = kCTLineBreakByTruncatingMiddle;
CTParagraphStyleSetting settings[] = {
    { kCTParagraphStyleSpecifierLineBreakMode, sizeof(CTLineBreakMode), &lineBreak }
};
CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, 1);

// Prepare text attributes
NSDictionary *attrs = @{
    (__bridge id)kCTFontAttributeName : (__bridge id)font,
    (__bridge id)kCTForegroundColorAttributeName : (__bridge id)[NSColor blackColor].CGColor,
    (__bridge id)kCTBackgroundColorAttributeName : (__bridge id)[NSColor yellowColor].CGColor,
    (__bridge id)kCTParagraphStyleAttributeName : (__bridge id)paragraphStyle,
};
NSAttributedString *attrStr =
        [[NSAttributedString alloc] initWithString:(__bridge NSString*)str attributes:attrs];

// Create framesetter
CTFramesetterRef fs = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attrStr);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, nullptr, self.bounds);
CTFrameRef frame = CTFramesetterCreateFrame(fs, CFRangeMake(0, 0), path, nullptr);

// Draw the paragraph
CTFrameDraw(frame, ctx);

This seems like a bug in Core Text, unless I was missing some additional parameter to specify before calling CTFrameDraw()?

Our engineering teams need to investigate this issue, as resolution may involve changes to Apple's software. Please file a bug report, include a small Xcode project and some directions that can be used to reproduce the problem, and post the Feedback number here once you do. If you post the Feedback number here I'll check the status next time I do a sweep of forums posts where I've suggested bug reports.

Bug Reporting: How and Why? has tips on creating your bug report.

Much appreciated! A bug report (FB20344338) was filed a few days ago, including a simple program to reproduce the issue.

Core Text omits all remaining content and breaks rendering when truncation is enabled and after encountering a line containing only spaces
 
 
Q