What I want to do: layout text using NSLayoutManager and set its NSTextContainer to the width of the widest line (glyph-wise) in the string array.
What is my problem: the methods for determining the overall "glyph width" seem incorrect, because when I render the text that it wraps.
I conducted an experiment using a 32-character string with a Monaco 12 font, and the length is specified as 224.0, but the text will only stop when the length is set to 234.0.
This code demonstrates what I said above and shows a vertical line to the right of the calculated 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];
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;
}