Как правильно определить ширину приписанной строки - PullRequest
3 голосов
/ 31 августа 2010

Что я хочу сделать: разметить текст с помощью NSLayoutManager и установить его NSTextContainer равным ширине самой широкой строки (по глифу) в массиве строк.

В чем моя проблема: методы определения общей «ширины глифа» кажутся неправильными, потому что когда я рендерим текст, он переносится.

Я провел эксперимент, используя 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;
}

Ответы [ 2 ]

1 голос
/ 18 сентября 2010

Вы просматривали эту категорию для NSString и NSAttributedString NS (приписывается) String + Geometrics ?

Если это не совсем то, что вы ищете, возможно, вы сможете увидеть, что они делают для вычисления размера.

1 голос
/ 01 сентября 2010

Вы учли текстовый контейнер -lineFragmentPadding ?

...