在MacOS上有效选择和调整字体大小

时间:2018-04-19 15:45:31

标签: objective-c macos fonts

结合许多其他示例,我已经提出了这个通用(用于我的目的)功能,以便在MacOS上使用Objective C选择和调整字体大小:

NSFont *FitSysFont(NSString *text, int w, int h, WORD flags, CGSize *fontsize) {

    int     i, len;
    NSFont  *fnt;
    CGSize  size;
    NSString *fntName;

    NSMutableDictionary *attribs = [[NSMutableDictionary alloc] init];
    NSRange strRange = [text rangeOfString:text];
    len = (int)[text length];
    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:text];

    i = 8;

    if( flags & ST_FIXED ) {
        if( flags & ST_BOLD ) {
            if( flags & ST_ITALIC ) fntName = @"Courier-BoldOblique";
            else fntName = @"Courier-Bold";
        } else if( flags & ST_ITALIC ) {
            fntName = @"Courier-Oblique";
        } else fntName = @"Courier";
    } else {
        if( flags & ST_SERIF ) {
            if( flags & ST_BOLD ) {
                if( flags & ST_ITALIC ) fntName = @"Times-BoldItalic";
                else fntName = @"Times-Bold";
            } else if( flags & ST_ITALIC ) {
                fntName = @"Times-Italic";
            } else fntName = @"Times";
        } else {
            if( flags & ST_BOLD ) {
                if( flags & ST_ITALIC ) fntName = @"Helvetica-BoldOblique";
                else fntName = @"Helvetica-Bold";
            } else if( flags & ST_ITALIC ) {
                fntName = @"Helvetica-Oblique";
            } else fntName = @"Helvetica";
        }
    }
    do {
        ++i;
        [string beginEditing];
        [string addAttribute:NSFontAttributeName value:[NSFont fontWithName:fntName size:(CGFloat)i] range:strRange];
        [string endEditing];
        fnt = [NSFont fontWithName:fntName size:i];
        [attribs setObject:fnt forKey:NSFontAttributeName];
        size = [text sizeWithAttributes:attribs];
    } while( len && size.width<w && size.height<h );
    do {
        --i;
        [string beginEditing];
        [string addAttribute:NSFontAttributeName value:[NSFont fontWithName:fntName size:(CGFloat)i] range:strRange];
        [string endEditing];
        fnt = [NSFont fontWithName:fntName size:i];
        [attribs setObject:fnt forKey:NSFontAttributeName];
        size = [text sizeWithAttributes:attribs];
    } while( i>4 && (size.width>=w && size.height>=h );

    if( fontsize!=NULL ) {
        fontsize->width = size.width;
        fontsize->height = size.height;
    }
    return fnt;
}

它旨在选择具有给定特征的字体(由&#39;标记&#39;以及&#39;和&#39; h&#39;参数指定)这样&#39;文本&#39; string将使用返回的字体适合给定的宽度和高度矩形。它通过连续尝试越来越大的字体来实现这一点,直到文本对于矩形(宽度或高度)变得太大,然后向下缩放直到文本再次适合(可能只有一个&#34;缩小&#34;将发生)。 ST_FIXED,ST_SERIF,ST_ITALIC,ST_BOLD是我在其他地方指定的#defines。

我的主要问题是我的NSThisAnd序列是否正确? (我对字典和属性,它们的生命周期和设置要求的理解仍在开发中......)另外,[string beginEditing] / [String endEditing]是否需要在循环中?或者可以安全地将它们移到外面,在这对环的顶部和底部有一对?或者是否有更简单的方法来确定完全避免do循环的字体大小?

1 个答案:

答案 0 :(得分:1)

您根本不需要string变量。你操纵它的属性,但你从不使用结果。当然,这也意味着您不需要strRange

假设您正在使用自动引用计数(ARC),其余部分看起来没问题。如果不是,则需要发布attribs(如果不删除,则string。)