Czy CoreText obsługuje małe Caps?

Czy CoreText ma możliwość wyboru wariantu czcionki SmallCaps lub syntezy małych liter, jeśli czcionka nie ma tej funkcji? Nie mogę znaleźć w dokumentacji CoreText niczego, co mówi o małych literach, choć istnieją Ułatwienia do radzenia sobie z wariacjami/funkcjami czcionek. Czy ktoś zrobił coś podobnego?

Author: Peter Hosey, 2011-01-27

5 answers

Jest na ogół najłatwiejszy w użyciu CTFontDescriptorCreateCopyWithFeature. Jak wspomniałeś we własnej odpowiedzi, będzie to działać tylko w przypadku czcionek, które faktycznie implementują żądaną funkcję.

 6
Author: Ned Holbrook,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-27 00:26:14

Odpowiedź wydaje się być kwalifikowanym tak. Obsługuje czcionki, które mają funkcję małych liter, ale nie obsługuje syntezy małych liter w czcionkach, które nie mają tej funkcji. Tę funkcję można włączyć, tworząc atrybut CTFontDescriptor z atrybutem kCTFontFeatureSettingsAttribute, który mapuje do tablicy dictów funkcji. Klucz kCTFontFeatureTypeIdentifierKey musi być ustawiony na 3 dla liter, a kCTFontFeatureSelectorIdentifierKey musi być ustawiony na 3 dla małych liter. <ATS/SFNTLayoutTypes.h> zawiera stałe identyfikujące różne wartości, chociaż ten nagłówek nie jest dostępny w systemie iOS SDK.

Spośród czcionek dostępnych na iPadzie, następujące czcionki obsługują małe litery:

  • HoeflerText-Regular
  • HoeflerText-Italic
  • HoeflerText-Black
  • HoeflerText-BlackItalic
  • Didot

Uwaga, kursywa/pogrubienie czcionek z rodziny Didot nie obsługuje małych liter.

 10
Author: Kevin Ballard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-27 00:19:58

Postanowiłem odpowiedzieć tutaj, aby zapewnić bardziej kompletne rozwiązanie dla każdego, kto próbuje rozwiązać ten problem, ponieważ informacje tutaj są niekompletne.

To rozwiązanie wykorzystuje iOS 7 UIFontDescriptor, ponieważ teraz zrzucam wsparcie dla iOS 6.

Jak zauważył Anthony Mattox, wartości czcionek systemowych (które są wymienione jako 3 i 3, ale należy zauważyć, że w rzeczywistości są kLetterCaseType i kSmallCapsSelector, nie należy odwoływać się do enum po jego numerze), nie będą działać dla czcionek niestandardowych. Nie jestem pewien, czy tak jest w przypadku wszystkich niestandardowe czcionki lub tylko niektóre, ale okazało się, że tak jest w moim przypadku.

Podczas przeglądania deklaracji obu tych wartości enum można zauważyć, że i tak są one przestarzałe i prawdopodobnie działają tylko dla kilku czcionek systemowych, które obsługują małe litery. Po zalogowaniu dostępnych atrybutów dla mojej niestandardowej czcionki, jak opisał Anthony, znalazłem 2 poprawne atrybuty do użycia dla niestandardowych czcionek. Są to kLowerCaseType i kLowerCaseSmallCapsSelector. Uważam, że ta kombinacja jest jedyną inną opcją tak więc dla każdej czcionki, której spróbujesz użyć, będzie to jedna lub druga.

Napisałem kilka metod kategorii, aby enkapsulować tę funkcjonalność dla obu przypadków:

- (UIFont *) smallCapSystemFont
{
    UIFontDescriptor *descriptor = [self fontDescriptor];
    NSArray *array = @[@{UIFontFeatureTypeIdentifierKey : @(kLetterCaseType),
                         UIFontFeatureSelectorIdentifierKey : @(kSmallCapsSelector)}];
    descriptor = [descriptor fontDescriptorByAddingAttributes:@{UIFontDescriptorFeatureSettingsAttribute : array}];
    return [UIFont fontWithDescriptor:descriptor size:0];
}

- (UIFont *) smallCapCustomFont
{
    UIFontDescriptor *descriptor = [self fontDescriptor];
    NSArray *array = @[@{UIFontFeatureTypeIdentifierKey : @(kLowerCaseType),
                         UIFontFeatureSelectorIdentifierKey : @(kLowerCaseSmallCapsSelector)}];
    descriptor = [descriptor fontDescriptorByAddingAttributes:@{UIFontDescriptorFeatureSettingsAttribute : array}];
    return [UIFont fontWithDescriptor:descriptor size:0];
}

Używasz ich, tworząc czcionkę o prawidłowej nazwie i rozmiarze, a następnie wywołując na niej jedną z tych metod, która zwróci małą wersję tej czcionki. Musisz dowiedzieć się, jaka jest prawidłowa metoda użycia dla każdej czcionki z małymi literami, której zdecydujesz się użyć.

Jest prawdopodobnie sprytny sposób, aby dowiedzieć się, który jeden do wykorzystania programowo w czasie wykonywania, sprawdzając dostępne typy (nawet po prostu analizując wyniki tej tablicy właściwości czcionki), ale nie zadałem sobie tego trudu, ponieważ używam tylko kilku różnych czcionek i ręczne sprawdzanie jest dla mnie odpowiednie.

Edit:

Jedną rzeczą, którą zauważyłem jest to, że liczby są obsługiwane oddzielnie. Jeśli chcesz, aby Liczby również były małe (co w rzeczywistości wydaje się być nazywane "liczbami w starym stylu" w przypadku większości czcionek, które je obsługują), będziesz potrzebował tego jawnie jako atrybutu.

Wygląda na to, że jest taki sam zarówno dla czcionek systemowych, jak i czcionek niestandardowych, w przeciwieństwie do liter.

Wystarczy dodać ten słownik do każdej z powyższych tablic:

@{UIFontFeatureTypeIdentifierKey : @(kNumberCaseType),
                         UIFontFeatureSelectorIdentifierKey : @(kLowerCaseNumbersSelector)}

Jeszcze raz, aby to zadziałało, czcionka sama w sobie musi obsługiwać ten atrybut.

 5
Author: Dima,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-15 20:24:33

Aby rozszerzyć odpowiedź Kevina Ballarda. Wartości ' 3 ' i '3' działają dla czcionek systemowych, ale nie wydają się być uniwersalne. Używam zewnętrznej czcionki i te wartości nie działają.

Możesz wylogować wszystkie dostępne właściwości za pomocą czegoś takiego:

UIFont *font = [UIFont fontWithName: fontName size: fontSize];
CFArrayRef  fontProperties  =  CTFontCopyFeatures ( ( __bridge CTFontRef ) font ) ;
NSLog(@"properties = %@", fontProperties);
CFRelease(fontProperties);

I określ, jakiej funkcji czcionki i selektora potrzebujesz, aby włączyć małe litery lub inne funkcje czcionki.

 2
Author: Anthony Mattox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-04 19:24:26

Ponieważ nikt tutaj nie podał próbki Swift 4 , dołączę tylko kod placu zabaw, aby wyświetlić tekst z małymi literami w UILabel:

//: Playground - noun: a place where people can play    
import UIKit
import CoreGraphics

let pointSize : CGFloat = 24
let fontDescriptor = UIFont(name: "HoeflerText-Regular", size: pointSize)!.fontDescriptor



let fractionFontDesc = fontDescriptor.addingAttributes(
    [
        UIFontDescriptor.AttributeName.featureSettings: [
            [
                UIFontDescriptor.FeatureKey.featureIdentifier: kLetterCaseType,
                UIFontDescriptor.FeatureKey.typeIdentifier: kSmallCapsSelector
            ]
        ]
    ] )

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 500, height: 100))

label.font = UIFont(descriptor: fractionFontDesc, size:pointSize)
label.text = "Montpelier, Vermont" 
 0
Author: Glenn Howes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-10 03:26:32