Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Working with Core Text by Roman Ilchyshyn

Working with Core Text by Roman Ilchyshyn

Working with Core Text by Roman Ilchyshyn

GDG Ternopil

November 19, 2015
Tweet

More Decks by GDG Ternopil

Other Decks in Programming

Transcript

  1. Do not to use it. Use Text Kit in iOS

    or the Cocoa text system in OS X. Core Text is the technology underlying those text systems, so they share in its speed and efficiency. When to use Core Text?
  2. 2 cases when you really need Core Text When building

    your own custom layout manager (e. g. buiding rich text editor) When drawing directly from Core Graphics and need to draw text
  3. We want to draw “Hello world!” on CALayer OK, but

    not so quick! A few words about typography first. “Hello world!” - is only the set of characters. It is not drawable
  4. Why? A character is the smallest unit of written language

    that carries meaning. Characters can correspond to a particular sound in the spoken form of the language. In every case, however, a character is an abstract concept. Computers store characters as numbers mapped by encoding tables to their corresponding characters. But this is not about drawing. “A” “a” “b” “B” … and other friends in encoding table.
  5. So what we need to draw? Although characters must be

    represented in a display area by a recognizable shape. A character can be drawn in various forms and remain the same character. Any one of these various concrete forms of a character is called a glyph. The glyphs used to depict characters are selected by layout manager during composition and layout processing.
  6. So what we need to draw? To draw some set

    of characters we need to apply a font to it. A font is a series of glyphs depicting the characters in a consistent size, typeface, and typestyle. To bind font to text as always we use NSAttributedString.
  7. Core Text is a C-baced API CFStringRef keys[] = {

    kCTFontAttributeName }; CFTypeRef values[] = { font }; CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys, (const void**)&values, sizeof(keys) / sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
  8. Core Text is a C-baced API CFStringRef keys[] = {

    kCTFontAttributeName }; CFTypeRef values[] = { font }; CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys, (const void**)&values, sizeof(keys) / sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
  9. Core Text is a C-based API The NSDictionary class is

    “toll-free bridged” with its Core Foundation counterpart, CFDictionaryRef. CFDictionaryRef attributes = (__bridge CFDictionaryRef) @{ NSFontAttributeName : [NSFont systemFontOfSize:13] };
  10. In Core Text we use For text layout: CTTypesetter CTFrame

    CTFramesetter CTLine CTRun For font setup: CTFont CTFontCollection CTFontDescriptor
  11. CTFramesetter - Describes an opaque type that generates text frames.

    CTFrame - Describes a multiline text frame.
  12. NSDictionary *stringAttributes = @{ NSFontAttributeName : [NSFont systemFontOfSize:12], NSForegroundColorAttributeName :

    (id)[NSColor redColor].CGColor}; CFAttributedStringRef stringToDraw = CFAttributedStringCreate(NULL, (__bridge CFStringRef)str, (__bridge CFDictionaryRef)stringAttributes); CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(stringToDraw); CTFrameRef frame = CTFramesetterCreateFrame (framesetter, CFRangeMake(0, str.length), path, NULL); CTFrameDraw(frame, ctx);
  13. CTLine - Describes a line of text. It is possible

    get lines of CTFrame NSArray *lines = ( id)CTFrameGetLines(frame); for (NSUInteger i = 0; i < lines.count; i++) { CGContextSetTextPosition(ctx, 5*i, 10*i); CTLineDraw((__bridge CTLineRef)[lines objectAtIndex:i], ctx); }
  14. CTLine … or create brand new CFAttributedStringRef ctLineAttrStr = CFAttributedStringCreate

    (NULL, (__bridge CFStringRef)@"CTLine text" , (__bridge CFDictionaryRef )stringAttributes); CTLineRef line = CTLineCreateWithAttributedString (ctLineAttrStr); CGContextSetTextPosition (ctx, 50, 50); CTLineDraw(line, ctx); // Do not forget to release! CFRelease(line); CFRelease(ctLineAttrStr);
  15. CTRun - Describes a set of consecutive glyphs sharing the

    same attributes and direction. СTRun is like subline of CTLine. Glyph runs can draw themselves into a graphic context, if desired, although most users have no need to interact directly with glyph runs.
  16. Use CGContext to customize layout // ... CGContextRotateCTM(ctx, 15 *

    M_PI/180); // Code drawing frame // ... CGContextSetTextMatrix(ctx, CGAffineTransformMakeRotation(25)); // Code drawing line