Размер шрифта в пикселях

На iPhone, как рассчитать размер символа в пикселях для заданного размера точки?

8 ответов

Решение

Размеры точек определены как 1/72 дюйма. То есть шрифт с 72 точками составляет приблизительно 1 дюйм от самого низкого снижения до самого высокого подъема. Таким образом, максимальная высота глифа в шрифте 72pt составляет около 1 дюйма.

На странице технических характеристик Apple iphone утверждается, что в настоящее время iPhone имеет разрешение 163 пикселя на дюйм. Таким образом, 72 точки - это 163 пикселя, или около 2,2639 пикселей на точку. Просто помните, что каждый глиф варьируется по высоте и ширине, так что это очень приблизительная оценка размера. Как правило, расстояние между базовыми линиями будет немного больше, чем размер шрифта, поэтому строки текста не будут сталкиваться друг с другом.

Если вам нужны точные измерения (и вы, вероятно, делаете), то вам нужно будет измерить глифы шрифта, используя информацию о метрике шрифта. Вы можете сделать это, используя дополнения USSit NSString, которые позволят вам измерить размер конкретной строки при визуализации на экране.

Чтобы сопоставить размеры шрифта (в точках) на iPhone4 с размерами шрифта (в точках) в Photoshop, необходимо установить для документа Photoshop значение 144dpi. Я провел несколько тестов, и это разрешение, которое дает результаты 1:1.

шаги:

  • Сделайте снимок экрана "Настройки" Общие "Специальные возможности" Большой текст " на iPhone4
  • Откройте скриншот в Photoshop
  • Измените разрешение с 72 точек на дюйм до 144 точек на дюйм с выключенным "Resample Image"
  • Повторите ввод текста в Photoshop (в точках), чтобы соответствовать размеру на скриншоте

Я прошел через несколько разных разрешений, в том числе 163 точек на дюйм, которые были упомянуты в ответе выше, и я обнаружил, что 144 точек на дюйм дает результаты 1:1. Я также проверил это по сравнению с нативным приложением, где я знаю размеры точек, и 144 dpi был там же.

Наш художник-график очень определенно использовал на некоторых устройствах размеры пикселей вместо размера точек. Функция ниже вернет шрифт на основе размера в пикселях. Он использует метод грубой силы, чтобы найти закрытый шрифт, но затем кэширует результаты, поэтому в следующий раз возврат будет очень быстрым. Я всегда благодарен за комментарии о том, как сделать этот код лучше. Я использую эту функцию в качестве статического члена класса в классе с именем utils. Вы можете легко вставить в любой класс, который вы используете. Надеюсь, что это поможет.

/** return a font as close to a pixel size as possible
example:
    UIFont *font = [Utils fontWithName:@"HelveticaNeue-Medium" sizeInPixels:33];
 @param fontName name of font same as UIFont fontWithName
 @param sizeInPixels size in pixels for font
 */
+(UIFont *) fontWithName:(NSString *) fontName sizeInPixels:(CGFloat) pixels {
    static NSMutableDictionary *fontDict; // to hold the font dictionary
    if ( fontName == nil ) {
        // we default to @"HelveticaNeue-Medium" for our default font
        fontName = @"HelveticaNeue-Medium";
    }
    if ( fontDict == nil ) {
        fontDict = [ @{} mutableCopy ];
    }
    // create a key string to see if font has already been created
    //
    NSString *strFontHash = [NSString stringWithFormat:@"%@-%f", fontName , pixels];
    UIFont *fnt = fontDict[strFontHash];
    if ( fnt != nil ) {
        return fnt; // we have already created this font
    }
    // lets play around and create a font that falls near the point size needed
    CGFloat pointStart = pixels/4;
    CGFloat lastHeight = -1;
    UIFont * lastFont = [UIFont fontWithName:fontName size:.5];\

    NSMutableDictionary * dictAttrs = [ @{ } mutableCopy ];
    NSString *fontCompareString = @"Mgj^";
    for ( CGFloat pnt = pointStart ; pnt < 1000 ; pnt += .5 ) {
        UIFont *font = [UIFont fontWithName:fontName size:pnt];
        if ( font == nil ) {
            NSLog(@"Unable to create font %@" , fontName );
            NSAssert(font == nil, @"font name not found in fontWithName:sizeInPixels" ); // correct the font being past in
        }
        dictAttrs[NSFontAttributeName] = font;
        CGSize cs = [fontCompareString sizeWithAttributes:dictAttrs];
        CGFloat fheight =  cs.height;
        if ( fheight == pixels  ) {
            // that will be rare but we found it
            fontDict[strFontHash] = font;
            return font;
        }
        if ( fheight > pixels ) {
            if ( lastFont == nil ) {
                fontDict[strFontHash] = font;
                return font;
            }
            // check which one is closer last height or this one
            // and return the user
            CGFloat fc1 = fabs( fheight - pixels );
            CGFloat fc2 = fabs( lastHeight  - pixels );
            // return the smallest differential
            if ( fc1 < fc2 ) {
                fontDict[strFontHash] = font;
                return font;
            } else {
                fontDict[strFontHash] = lastFont;
                return lastFont;
            }
        }
        lastFont = font;
        lastHeight = fheight;
    }
    NSAssert( false, @"Hopefully should never get here");
    return nil;
}

Я полагаю, что вы ищете UIFontNSString расширения, которые позволяют рассчитать размер строки с учетом UIFont,

Вот ссылка

В частности, sizeWithFont методы.

Самый простой способ получить высоту пикселя для данного шрифта и размера - использовать метод boundingRect в NSString. (Я использую @"Ap" здесь, чтобы убедиться, что он содержит по убыванию и по возрастанию.)

- (CGFloat)heightForFont:(UIFont *)font
{
    NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
    CGRect boundingRect = [@"Ap" boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX) options:NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:context];
    return boundingRect.size.height;
}

Вы не можете надежно преобразовать точки в пиксели, поскольку ppi (точки на дюйм) будет изменяться от монитора к монитору. Прочитайте;

http://hsivonen.iki.fi/units/

Конвертировать пиксели в очки

Тем не менее, некоторые люди собрали несколько справочных таблиц и калькуляторов, которые могут помочь вам начать;

http://www.unitconversion.org/typography/postscript-points-to-pixels-x-conversion.html

http://sureshjain.wordpress.com/2007/07/06/53/

Я добавлю их, как я понимаю их:

SizeToFit UILabel с системным шрифтом 12pt имеет высоту 15px.

Вы можете рассчитать размер пикселя на лету, визуализируя NSAttributedStringи получить его размер.

      extension UIFont {
    var pixelSize: CGFloat {
        let string = "AWZgjpq"
        let attributedString = NSMutableAttributedString(string: string)
        attributedString.setAttributes([.font: self], range: NSRange(location: 0, length: string.count))
        return attributedString.size().height
    }
}

Дальнейшая оптимизация может состоять в том, чтобы добавить словарь поиска и кэшировать результаты и/или сделать тестовую строку не переменной (но сам вызов очень быстрый). Кроме того, если в вашем шрифте есть очень неправильные глифы, вы также можете добавить их в тестовую строку.

Применение: let pixelSize = label.font.pixelSize

Другие вопросы по тегам