Slide 1

Slide 1 text

These are confidential sessions—please refrain from streaming, blogging, or taking pictures Features and techniques Session 226 Core Text and Fonts Ned Holbrook Typographic Engineer

Slide 2

Slide 2 text

What You Will Learn •New features in Mountain Lion and iOS 6 ■ Line bounds ■ Baseline alignment •Techniques ■ Vertical text ■ Font names, fallbacks, emoji ■ Avoiding common pitfalls

Slide 3

Slide 3 text

CoreText Overview •Fundamental framework for Unicode text layout and fonts •Available via: ■ AppKit (OS X) ■ Core Animation ■ UIKit (iOS) ■ WebKit

Slide 4

Slide 4 text

Availability CoreText Overview •Leopard and iOS 3.2 •Top-level framework on iOS and Mountain Lion

Slide 5

Slide 5 text

Deprecated OS X Frameworks CoreText Overview •ATSUI (text layout) •ATS (font management)

Slide 6

Slide 6 text

New Features

Slide 7

Slide 7 text

CTLineGetTypographicBounds(…) Line Bounds “Just the facts, ma’am.”

Slide 8

Slide 8 text

CTLineGetTypographicBounds(…) Line Bounds “Just the facts, ma’am.”

Slide 9

Slide 9 text

CTLineGetBoundsWithOptions(…, 0) Line Bounds “Just the facts, ma’am.”

Slide 10

Slide 10 text

CTLineGetBoundsWithOptions(…, kCTLineBoundsUseOpticalBounds) Line Bounds “Just the facts, ma’am.”

Slide 11

Slide 11 text

CTLineGetBoundsWithOptions(…, kCTLineBoundsUseHangingPunctuation) Line Bounds “Just the facts, ma’am.”

Slide 12

Slide 12 text

CTLineGetBoundsWithOptions(…, kCTLineBoundsUseHangingPunctuation | kCTLineBoundsUseOpticalBounds) Line Bounds “Just the facts, ma’am.”

Slide 13

Slide 13 text

CTLineGetBoundsWithOptions(…, kCTLineBoundsUseGlyphPathBounds) Line Bounds “Just the facts, ma’am.”

Slide 14

Slide 14 text

Line Bounds kCTParagraphStyleSpecifierLineBoundsOptions ■ Affects line edges during frame filling

Slide 15

Slide 15 text

•Better handling of mixed scripts Baseline Alignment Hello ੈք

Slide 16

Slide 16 text

•Better handling of mixed scripts Baseline Alignment Hello ੈք

Slide 17

Slide 17 text

•Better handling of mixed scripts Baseline Alignment World नम#$

Slide 18

Slide 18 text

•Better handling of mixed scripts Baseline Alignment World नम#$

Slide 19

Slide 19 text

•Typographic effects Baseline Alignment rop aps D C

Slide 20

Slide 20 text

•Typographic effects Baseline Alignment rop aps D C

Slide 21

Slide 21 text

Basics Baseline Alignment •Each font has multiple baselines •Each baseline is a vertical offset •Each glyph has a default baseline •Alignment uses the same baseline from two sets

Slide 22

Slide 22 text

Basics, cont. Baseline Alignment •Parameters determined by string attributes •Reference established with kCTBaselineReferenceInfoAttributeName •Baselines to be moved use kCTBaselineInfoAttributeName •Baseline being aligned is kCTBaselineClassAttributeName

Slide 23

Slide 23 text

Font Fallbacks Baseline Alignment CTFontRef font; NSMutableAttributedString *attrString; NSRange range; NSDictionary *referenceInfo = @{ (id)kCTBaselineReferenceFont : (id)font }; [attrString addAttribute:(id)kCTBaselineReferenceInfoAttributeName value:referenceInfo range:range];

Slide 24

Slide 24 text

Specifying a Baseline Baseline Alignment CTFontRef font, hangingFont; NSMutableAttributedString *attrString; NSRange range, wordRange; NSDictionary *referenceInfo = @{ (id)kCTBaselineReferenceFont : (id)font }; [attrString addAttribute:(id)kCTBaselineReferenceInfoAttributeName value:referenceInfo range:range]; NSRange hangingRange = NSMakeRange(wordRange.location, 1); [attrString addAttribute:(id)kCTBaselineClassAttributeName value:(id)kCTBaselineClassHanging range:hangingRange]; [attrString addAttribute:(id)kCTFontAttributeName, value:(id)hangingFont range:hangingRange];

Slide 25

Slide 25 text

Specifying an Offset Baseline Alignment CTFontRef font; NSMutableAttributedString *attrString; NSRange range; NSDictionary *referenceInfo = @{ (id)kCTBaselineReferenceFont : (id)font, (id)kCTBaselineClassHanging : @5.0 }; [attrString addAttribute:(id)kCTBaselineReferenceInfoAttributeName value:referenceInfo range:range];

Slide 26

Slide 26 text

CTFontCollection •Lion improvements ■ Mutable collections ■ Easier to access font family members ■ Toll-free bridged with NSFontCollection •Preferred way to enumerate fonts

Slide 27

Slide 27 text

AAT and OpenType Features •New AAT features correspond to common OT features ■ For example, to enable ‘pcap’ feature CTFontRef font; CTFontDescriptorRef descriptor = CTFontCopyFontDescriptor(font); CTFontDescriptorRef pcapDescriptor = CTFontDescriptorCreateCopyWithFeature(descriptor, (CFNumberRef)[NSNumber numberWithInt:kLowerCaseType], (CFNumberRef)[NSNumber numberWithInt: kLowerCasePetiteCapsSelector]); CTFontRef pcapFont = CTFontCreateWithFontDescriptor(pcapDescriptor, 0.0, NULL);

Slide 28

Slide 28 text

Bidirectional Text kCTWritingDirectionAttributeName ■ Embedding or override

Slide 29

Slide 29 text

“Advanced” Topics

Slide 30

Slide 30 text

Vertical Text αϯϑϥϯγεί

Slide 31

Slide 31 text

kCTVerticalFormsAttributeName = @YES Vertical Text αϯϑϥϯγεί

Slide 32

Slide 32 text

kCTVerticalFormsAttributeName = @YES Vertical Text α ϯ ϑ ϥ ϯ γ ε ί

Slide 33

Slide 33 text

α ϯ ϑ ϥ ϯ γ ε ί Vertical Text ■ Rotate context

Slide 34

Slide 34 text

α ϯ ϑ ϥ ϯ γ ε ί Vertical Text ■ Rotate context

Slide 35

Slide 35 text

Vertical Text •Use NSTextView or CTFramesetter if possible •Not using one of those? ■ Layout process is same as with horizontal text ■ Drawing is much, much different

Slide 36

Slide 36 text

Font Names •Fonts have many names ■ Example: PostScript TimesNewRomanPS-ItalicMT Family Times New Roman Full/Display Times New Roman Italic Style Italic

Slide 37

Slide 37 text

PostScript TimesNewRomanPS-ItalicMT Family Times New Roman Full/Display Times New Roman Italic Style Italic Font Names •Fonts have many names ■ Example:

Slide 38

Slide 38 text

PostScript TimesNewRomanPS-ItalicMT Family Times New Roman Full/Display Times New Roman Italic Style Italic Font Names •Fonts have many names ■ Example:

Slide 39

Slide 39 text

Performance Font Names CTFontCreateWithName() is currently too lenient ■ Will stop accepting non-PostScript names in future releases •iOS 6 adds logging to detect use of wrong name: June 13 08:50:59 YourDevice YourApp[237] : CoreText performance note: Client requested font with PostScript name "HelveticaNeue" using name "Helvetica Neue" instead. June 13 08:50:59 YourDevice YourApp[237] : CoreText performance note: Set a breakpoint on CTLogSuboptimalRequest to debug.

Slide 40

Slide 40 text

Specifying a non-PostScript name Font Names NSDictionary *attributes = @{ (id)kCTFontFamilyNameAttribute : @"Times New Roman" }; CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes( (CFDictionaryRef)attributes); NSArray *matches = (NSArray *)CTFontDescriptorCreateMatchingFontDescriptors( descriptor, NULL); if ([matches count] != 0) { // at least one match found, first one would have been returned by // CTFontDescriptorCreateMatchingFontDescriptor() }

Slide 41

Slide 41 text

Fallback Fonts •Layout relies on fallback fonts •Augment system cascade using kCTFontCascadeListAttribute •Terminate fallback processing with font covering all characters ■ “LastResort” •Composite (CFR) fonts on Mountain Lion ■ /System/Library/DTDs/SplicedFont.dtd

Slide 42

Slide 42 text

Embedding Fonts •Fonts need not live in distinct files to be usable •On Mountain Lion or iOS CGDataProviderRef provider = CGDataProviderCreateWithCFData(data); CGFontRef cgFont = CGFontCreateWithDataProvider(provider); CFErrorRef error = NULL; if (CTFontManagerRegisterGraphicsFont(cgFont, &error)) { // access font via font names CTFontManagerUnregisterGraphicsFont(cgFont, NULL); } •On Lion or higher ■ CTFontManagerCreateFontDescriptorFromData()

Slide 43

Slide 43 text

Emoji

Slide 44

Slide 44 text

Emoji

Slide 45

Slide 45 text

Emoji •Unification is a big problem I — Unicode I — Unicode ≠

Slide 46

Slide 46 text

Emoji •Unicode 6.1 solution—variation sequences ??? —

Slide 47

Slide 47 text

Drawing Color Glyphs •Automatic with CTFrameDraw(), CTLineDraw(), and CTRunDraw() •Or use CTFontDrawGlyphs() ■ Analogous to CGContextShowGlyphsAtPositions()

Slide 48

Slide 48 text

Identifying Color Glyphs CTFontRef font; CGGlyph glyph; CTFontSymbolicTraits symTraits = CTFontGetSymbolicTraits(font); if ((symTraits & kCTFontTraitColorGlyphs) != 0) { // font has color glyphs CGPathRef path = CTFontCreatePathForGlyph(font, glyph, NULL); if (path == NULL) { // this is a color glyph } else { // not a color glyph CFRelease(path); } }

Slide 49

Slide 49 text

CGContext Drawing Parameters •CoreText only sets what it needs to •Most string attributes correspond to a particular parameter •Exception to the rule—kCTForegroundColorAttributeName ■ Use kCTForegroundColorFromContextAttributeName

Slide 50

Slide 50 text

Synthesizing Styles •CoreText does not synthesize font styles (bold, italic) •Clients may choose to do something for compatibility reasons ■ Italic: Skewed font matrix ■ Bold: No best approach

Slide 51

Slide 51 text

More Information Jake Behrens UI Frameworks Evangelist [email protected] Documentation Mac OS X Human Interface Guidelines http://developer.apple.com/ue Apple Developer Forums http://devforums.apple.com

Slide 52

Slide 52 text

Related Sessions Introduction to Attributed Strings for iOS Mission Wednesday 3:15PM Advanced Attributed Strings for iOS Mission Thursday 10:15AM

Slide 53

Slide 53 text

Labs Core Text Framework Lab Essentials Lab B Thursday 11:30AM

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

The last 3 slides after the logo are intentionally left blank for all presentations.

Slide 56

Slide 56 text

The last 3 slides after the logo are intentionally left blank for all presentations.

Slide 57

Slide 57 text

The last 3 slides after the logo are intentionally left blank for all presentations.