kCTSuperscriptAttributeName не работает для использования нижнего и верхнего индексов - PullRequest
6 голосов
/ 23 февраля 2012

enter image description here

Я использую этот код для отображения нижнего и верхнего индекса в метке, но он не работает.

Я создаю категорию для NSAttributedString.

-(void)setSuperscript:(BOOL)isSuperscript range:(NSRange)range {
    [self removeAttribute:(NSString * )kCTSuperscriptAttributeName range:range]; // Work around for Apple leak
    [self addAttribute:(NSString*)kCTSuperscriptAttributeName value:[NSNumber numberWithInt:(isSuperscript?1:0)] range:range];
}
-(void)setSubscript:(BOOL)isSubscript range:(NSRange)range {
    [self removeAttribute:(NSString * )kCTSuperscriptAttributeName range:range]; // Work around for Apple leak
    [self addAttribute:(NSString*)kCTSuperscriptAttributeName value:[NSNumber numberWithInt:(isSubscript?-1:0)] range:range];
}

1 Ответ

3 голосов
/ 10 мая 2013

Проблема в том, что многие шрифты либо не определяют варианты супер- и подстрочных индексов, либо имеют для этого довольно прикольные (неправильно говорят) метрики.

Возможный обходной путь - подделать его, как в методениже (в категории на NSMutableAttributedString).Однако он имеет некоторые недостатки:

  • Ширина обводки не идеальна, особенно для шрифтов большего размера
  • Отменить ее несколько сложнее
  • Расчетный размер исмещение может быть не идеальным для некоторых шрифтов

С положительной стороны это должно работать для всех шрифтов и при необходимости может быть настроено для определенных целей.

- (void)fakeSuperOrSubScript:(BOOL)superscript
    range:(NSRange)range
    defaultFont:(NSFont *)defaultFont
{

    NSFontManager   *fm=[NSFontManager sharedFontManager];
    NSFont          *font=[self
        attribute:NSFontAttributeName
        atIndex:range.location
        effectiveRange:NULL
    ];

    if(!font) font=defaultFont;
    if(!font)
    {
        NSLog(@"ERROR: fakeSuperOrSubScript has no font to use!");

        return;
    }

    // Bolden font to adjust stroke width
    NSFont          *siFont=[fm convertWeight:YES ofFont:font];
    float           originalSize=[siFont pointSize];
    float           newSize=originalSize*3.0/4.0;
    float           blOffset=(superscript)?originalSize/2.0:-originalSize/4.0;

    siFont=[fm convertFont:siFont toSize:newSize];

    NSDictionary *attrs=@{
        NSFontAttributeName:            siFont,
        NSBaselineOffsetAttributeName:  @(blOffset),
    };

    [self addAttributes:attrs range:range];
}
...