kCTSuperscriptAttributeName不支持使用下标和上标

时间:2021-12-08 20:11:32

kCTSuperscriptAttributeName不支持使用下标和上标

I am using this code for displaying subscript and superscript in label but it not working.

我正在使用这段代码在label中显示下标和上标,但它不起作用。

I create a category for NSAttributedString.

我为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 个解决方案

#1


3  

The problem is that many fonts either do not define super- and subscript variants, or have some rather funky (speak wrong) metrics for it.

问题是,许多字体要么不定义超和下标变体,要么有一些相当时髦(说错了)的度量标准。

A possible workaround is to fake it, like with the method below (in a category on NSMutableAttributedString). It has some shortcomings though:

一种可能的解决方法是伪造它,就像下面的方法一样(在NSMutableAttributedString的一个类别中)。但它也有一些缺点:

  • The stroke width isn't perfect, especially for larger font sizes
  • 笔划宽度并不完美,尤其是对于较大的字体
  • It is somewhat harder to undo
  • 这有点难以撤销
  • The calculated size and offset may not be perfect for some fonts
  • 计算的尺寸和偏移量可能不适合某些字体。

On the plus side this should work for all fonts, and if needed can be tweaked for specific purposes.

从好的方面来说,这应该适用于所有字体,如果需要,可以针对特定的目的进行调整。

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

#1


3  

The problem is that many fonts either do not define super- and subscript variants, or have some rather funky (speak wrong) metrics for it.

问题是,许多字体要么不定义超和下标变体,要么有一些相当时髦(说错了)的度量标准。

A possible workaround is to fake it, like with the method below (in a category on NSMutableAttributedString). It has some shortcomings though:

一种可能的解决方法是伪造它,就像下面的方法一样(在NSMutableAttributedString的一个类别中)。但它也有一些缺点:

  • The stroke width isn't perfect, especially for larger font sizes
  • 笔划宽度并不完美,尤其是对于较大的字体
  • It is somewhat harder to undo
  • 这有点难以撤销
  • The calculated size and offset may not be perfect for some fonts
  • 计算的尺寸和偏移量可能不适合某些字体。

On the plus side this should work for all fonts, and if needed can be tweaked for specific purposes.

从好的方面来说,这应该适用于所有字体,如果需要,可以针对特定的目的进行调整。

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