2010-08-31 73 views
3

我想要做什麼:使用NSLayoutManager佈局文本,並將它的NSTextContainer設置爲字符串數組中最寬字符串的寬度(glyph-wise)。如何正確確定屬性字符串的寬度

我的問題是:用於確定總「字形寬度」的方法似乎是不正確的,因爲當我渲染文本時,它會打包。

我做了一個實驗,使用32個字符的字符串與摩納哥12點字體和長度報告爲224.0,但文本將只停止包裝如果長度設置爲234.0。

此代碼演示了我上面所說的內容,並在計算出的字形寬度的右側顯示了一條垂直線。

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

回答

1

你看過這個類別的NSString和NSAttributedString NS(Attributed)String+Geometrics

如果它不是你正在尋找的東西,你可能會看到他們正在做的一些計算尺寸。