2011-01-26 16 views
12

CoreText ha qualche possibilità per selezionare una variante SmallCaps di un font o per sintetizzare maiuscole se il carattere non ha quella caratteristica? Non riesco a trovare nulla nella documentazione di CoreText che parla di maiuscoletto, sebbene ci siano delle possibilità per gestire le variazioni/caratteristiche dei caratteri. Qualcuno ha fatto qualcosa di simile a questo?CoreText supporta Small Caps?

risposta

6

In genere è più semplice utilizzare CTFontDescriptorCreateCopyWithFeature. Come hai detto nella tua risposta, questo funzionerà solo con i font che implementano effettivamente la funzione che stai richiedendo.

+0

Nel mio caso, devo anche opzionalmente supportare il corsivo/grassetto, quindi ho bisogno di usare la versione degli attributi più generica. Ma hai ragione, per una semplice attivazione/disattivazione di maiuscoletto, 'CTFontDescriptorCreateCopyWithFeature' è leggermente più facile da usare. –

10

La risposta sembra essere un Sì qualificato. Supporta i caratteri che hanno una funzionalità Small Caps, ma non supporta la sintesi di maiuscoletto nei tipi di carattere che non hanno la funzione. Questa funzione può essere abilitata creando un CTFontDescriptor con l'attributo kCTFontFeatureSettingsAttribute, che esegue il mapping su un array di diciture di funzioni. La chiave kCTFontFeatureTypeIdentifierKey deve essere impostata su 3 per Letter Case e lo kCTFontFeatureSelectorIdentifierKey deve essere impostato su 3 per Maiuscole. <ATS/SFNTLayoutTypes.h> contiene costanti che identificano i vari valori, sebbene questa intestazione non sia disponibile nell'SDK di iOS.

dei caratteri disponibili su iPad, il seguente supporto maiuscoletto:

  • hoefler text-Regular
  • hoefler text-italica
  • hoefler text-Black
  • hoefler text-BlackItalic
  • Didot

Nota, il corsivo/grassetto per i membri della famiglia Didot non supportano le maiuscoletto.

+0

Penso che questa intestazione è ora disponibile in l'SDK iOS 5 –

2

Per prolungare la risposta di Kevin Ballard. I valori "3" e "3" funzionano per i caratteri di sistema, ma non sembrano universali. Sto usando un font esterno e questi valori non hanno funzionato.

È possibile accedere tutte le proprietà disponibili con qualcosa di simile:

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

e determinare quali funzionalità di carattere e di selezione è necessario abilitare le small cap o altre caratteristiche dei font.

5

Ho deciso di rispondere qui per fornire una soluzione più completa a chiunque cerchi di risolvere questo problema, poiché le informazioni qui sono incomplete.

Questa soluzione utilizza l'IOS 7 UIFontDescriptor come ora sto rimozione del supporto per iOS 6.

Come Anthony Mattox sottolineato, i valori dei caratteri del sistema (che sono elencati come 3 e 3 ma va notato essere effettivamente kLetterCaseType e kSmallCapsSelector, non si dovrebbe fare riferimento a un enum per il suo numero), non funzionerà per i caratteri personalizzati. Non sono sicuro se questo è il caso per tutti i caratteri personalizzati o solo alcuni, ma ho trovato che questo è il mio caso.

Quando si scava nella dichiarazione di entrambi questi valori di enumerazione, si può effettivamente vedere che sono comunque deprecati e presumibilmente funzionano solo per i pochi caratteri di sistema che supportano le maiuscoletto. Dopo aver registrato gli attributi disponibili per il mio carattere personalizzato come descritto da Anthony, ho trovato i 2 attributi corretti da usare per i caratteri personalizzati. Sono kLowerCaseType e kLowerCaseSmallCapsSelector. Credo che questa combinazione sia l'unica altra opzione, quindi per qualsiasi font che si tenta di usare, sarà l'uno o l'altro.

ho scritto alcuni metodi di categoria per incapsulare questa funzionalità per entrambi i casi:

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

Si utilizza questi con la creazione di un tipo di carattere con il nome e le dimensioni corrette e quindi chiamando uno di questi metodi su di esso, che restituirà un versione small cap di quel font. Dovrai trovare il metodo corretto da utilizzare per qualsiasi carattere di maiuscoletto che decidi di usare.

Probabilmente c'è un modo intelligente per capire quale utilizzare a livello di programmazione in fase di esecuzione controllando i tipi disponibili (anche solo analizzando i risultati di tale array di proprietà dei font), ma non mi sono preso la briga di farlo come sono solo utilizzando alcuni tipi di carattere diversi e un controllo manuale è adatto a me.

Edit:

Una cosa che ho notato è che i numeri vengono gestiti separatamente. Se vuoi che i numeri siano anche limitati (che in realtà sembrano essere chiamati "numeri vecchio stile" nel caso di molti font che lo supportano), ne avrai bisogno esplicitamente come attributo.

Sembra che sia lo stesso per entrambi i tipi di carattere di sistema di supporto e caratteri personalizzati, a differenza delle lettere.

si sarebbe solo aggiungere questo dizionario per ciascuna delle matrici di cui sopra:

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

Ancora una volta, per far funzionare il tipo di carattere in sé in realtà ha la necessità di sostenere questo attributo.

+0

Questo metodo non funziona con il font di sistema iOS 7 (Helvetica Neue). – Legoless

+0

@Legoless Per chiarire, non funzionerà con Helvetica Neue perché quel font non ha una modalità small cap. Questo funzionerà solo con i font che hanno inserito in essi. C'è una lista di questi caratteri in un'altra risposta a questa domanda. Un esempio di carattere di sistema con cui questo funzionerà è "Didot". Prova 'smallCapsSystemFont' con quello e lo vedrai in azione. – Dima

+0

Se si desidera avere maiuscoletto con Helvetica Neue, sarà necessario trovare una versione del font che qualcun altro ha realizzato in cui è incorporata, o fingere disegnando caratteri maiuscoli di dimensioni minori. – Dima

0

Come nessuno qui ha fornito un campione di Swift , sto solo andando a includere il codice parco giochi per visualizzare qualche piccolo testo di tappi in un 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" 
Problemi correlati