What I want to do: layout text using NSLayoutManager and set its NSTextContainer to the width of the widest string (glyph-wise) in an array of strings.
What my problem is: The methods for determining the total 'glyph-width' seem to be incorrect because when I render the text it wraps.
I did an experiment using a 32 character string with the Monaco 12 point font and the length is reported as 224.0, but the text will only stop wrapping if the length is set to 234.0.
This code demonstrates what I said above and shows a vertical line on the right of the computed glyph-width.
- (void)drawRect:(NSRect)rect {
NSRect bounds = [self bounds];
[[NSColor whiteColor] drawSwatchInRect: bounds];
[[NSColor blackColor] setStroke];
[[NSBezierPath bezierPathWithRect: bounds] stroke];
NSMutableParagraphStyle *thisParagraphStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
[thisParagraphStyle setLineBreakMode: NSLineBreakByCharWrapping];
[thisParagraphStyle setAlignment: NSLeftTextAlignment];
NSFont *fontUsed = [NSFont fontWithName: @"Monaco" size: 12];
NSDictionary *glyphAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
fontUsed, NSFontAttributeName,
thisParagraphStyle, NSParagraphStyleAttributeName,
[NSColor blackColor], NSForegroundColorAttributeName,
NULL];
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithString:@"00112233445566778899001122334455\n00112233445566778899001122334455\n00112233445566778899001122334455\n00112233445566778899001122334455\n"];
[textStorage setAttributes: glyphAttributes range: NSMakeRange(0, [textStorage length])];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
NSSize textContainerSize;
textContainerSize.width = [@"00112233445566778899001122334455" sizeWithAttributes: glyphAttributes].width;
textContainerSize.height = bounds.size.height;
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize: textContainerSize];
[layoutManager addTextContainer:textContainer];
[textContainer release];
[textStorage addLayoutManager:layoutManager];
[layoutManager release];
NSRange glyphRange = [layoutManager glyphRangeForTextContainer: textContainer];
[layoutManager drawGlyphsForGlyphRange: glyphRange atPoint: NSMakePoint(0.0 , 0.0)];
[textStorage release];
[thisParagraphStyle release];
// Indicate right text boundary from computed width
NSBezierPath *rightTextBoundary = [NSBezierPath bezierPath];
[rightTextBoundary moveToPoint: NSMakePoint(textContainerSize.width, 0.0)];
[rightTextBoundary lineToPoint: NSMakePoint(textContainerSize.width, bounds.size.height-1)];
[rightTextBoundary stroke];
NSLog(@"View width: %f", bounds.size.width);
NSLog(@"Calculated width1: %f", textContainerSize.width);
NSLog(@"Calculated width2: %f\n\n", [@"00112233445566778899001122334455" boundingRectWithSize: NSMakeSize(FLT_MAX, FLT_MAX)
options: NSStringDrawingUsesDeviceMetrics
attributes: glyphAttributes].size.width);
}
- (BOOL) isFlipped {
return YES;
}