[CoreText]
Core Text is designed for development of higher-level
text-handling frameworks. General app developers should
use Text Kit in iOS
(see Text Programming Guide for iOS). Core
Text mediates
between text layout and font support
provided by higher level
frameworks and the low-level capabilities Quartz
provides to all text and font frameworks. Quartz is the only way to
get glyphs drawn at a fundamental level.
The Core Text layout engine often works with attributed strings
(CFAttributedStringRef
) and graphics
paths (CGPathRef
). The
graphics path defines the shape of a frame of text. With an attributed string and a
graphics path as input, a framesetter generates one or more frames of text
(CTFrameRef
). Each CTFrame object represents a
paragraph.
To generate frames, the framesetter calls a typesetter object
(CTTypesetterRef
). As it lays text out in a frame, the framesetter
applies paragraph styles to it, including such attributes as
alignment, tab stops, line spacing, indentation, and line-breaking mode. The
typesetter converts the
characters in the attributed string to
glyphs and fits
those glyphs into the lines that fill a text frame.
Each CTFrame object contains the paragraph’s line (CTLine) objects. Each line object represents a line of text. A CTFrame object may contain just a single long CTLine object or it might contain a set of lines. Line objects are created by the typesetter during a framesetting operation and, like frames, can draw themselves directly into a graphics context.
Each CTLine object contains an array of glyph run (CTRun) objects. A glyph run is a set of consecutive glyphs that share the same attributes and direction. The typesetter creates glyph runs as it produces lines from character strings, attributes, and font objects. This means that a line is constructed of one or more glyphs runs. Glyph runs can draw themselves into a graphic context, if desired, although most clients have no need to interact directly with glyph runs.
[Font Objects]
You can think of font descriptors as queries into the font
system. You can create a font descriptor with an incomplete specification, that
is, with one or just a few values in the attribute dictionary, and the system
will choose the most appropriate font from those available. For example, if you
make a query using a descriptor for the name of family with the standard faces
(normal, bold, italic, bold italic), not specifying any traits would match all
faces in the family, but if you specify a traits dictionary with
akCTFontTraitsAttribute
of kCTFontTraitBold
,
the results are further narrowed from the whole family to its members satisfying
the bold trait. The system can give you a complete list of font descriptors
matching your query via CTFontDescriptorCreateMatchingFontDescriptors
.
Create a font collection of all the fonts available in the system by
calling CTFontCollectionCreateFromAvailableFonts
, and
you can use the collection to obtain an array of all of the member font
descriptors.
[Layout Opeartion]
One of the most common operations in typesetting is laying out a multiline paragraph within an arbitrarily sized rectangular area. To lay out the paragraph, you need a graphics context to draw into, a rectangular path to provide the area where the text is laid out, and an attributed string.
1 // Initialize a graphics context in iOS. 2 CGContextRef context = UIGraphicsGetCurrentContext(); 3 4 // Flip the context coordinates, in iOS only. 5 CGContextTranslateCTM(context, 0, self.bounds.size.height); 6 CGContextScaleCTM(context, 1.0, -1.0); 7 8 // Initializing a graphic context in OS X is different: 9 // CGContextRef context = 10 // (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; 11 12 // Set the text matrix. 13 CGContextSetTextMatrix(context, CGAffineTransformIdentity); 14 15 // Create a path which bounds the area where you will be drawing text. 16 // The path need not be rectangular. 17 CGMutablePathRef path = CGPathCreateMutable(); 18 19 // In this simple example, initialize a rectangular path. 20 CGRect bounds = CGRectMake(10.0, 10.0, 200.0, 200.0); 21 CGPathAddRect(path, NULL, bounds ); 22 23 // Initialize a string. 24 CFStringRef textString = CFSTR("Hello, World! I know nothing in the world that has as much power as a word. Sometimes I write one, and I look at it, until it begins to shine."); 25 26 // Create a mutable attributed string with a max length of 0. 27 // The max length is a hint as to how much internal storage to reserve. 28 // 0 means no hint. 29 CFMutableAttributedStringRef attrString = 30 CFAttributedStringCreateMutable(kCFAllocatorDefault, 0); 31 32 // Copy the textString into the newly created attrString 33 CFAttributedStringReplaceString (attrString, CFRangeMake(0, 0), 34 textString); 35 36 // Create a color that will be added as an attribute to the attrString. 37 CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 38 CGFloat components[] = { 1.0, 0.0, 0.0, 0.8 }; 39 CGColorRef red = CGColorCreate(rgbColorSpace, components); 40 CGColorSpaceRelease(rgbColorSpace); 41 42 // Set the color of the first 12 chars to red. 43 CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 12), 44 kCTForegroundColorAttributeName, red); 45 46 // Create the framesetter with the attributed string. 47 CTFramesetterRef framesetter = 48 CTFramesetterCreateWithAttributedString(attrString); 49 CFRelease(attrString); 50 51 // Create a frame. 52 CTFrameRef frame = CTFramesetterCreateFrame(framesetter, 53 CFRangeMake(0, 0), path, NULL); 54 55 // Draw the specified frame in the given context. 56 CTFrameDraw(frame, context); 57 58 // Release the objects we used. 59 CFRelease(frame); 60 CFRelease(path); 61 CFRelease(framesetter);
A nother common typesetting operation is drawing a single line of text to use as a label for a user-interface element. In Core Text this requires only two lines of code: one to create the line object with a CFAttributedString and another to draw the line into a graphic context.
1 CFStringRef string; CTFontRef font; CGContextRef context; 2 // Initialize the string, font, and context 3 4 CFStringRef keys[] = { kCTFontAttributeName }; 5 CFTypeRef values[] = { font }; 6 7 CFDictionaryRef attributes = 8 CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys, 9 (const void**)&values, sizeof(keys) / sizeof(keys[0]), 10 &kCFTypeDictionaryKeyCallBacks, 11 &kCFTypeDictionaryValueCallBacks); 12 13 CFAttributedStringRef attrString = 14 CFAttributedStringCreate(kCFAllocatorDefault, string, attributes); 15 CFRelease(string); 16 CFRelease(attributes); 17 18 CTLineRef line = CTLineCreateWithAttributedString(attrString); 19 20 // Set text position and draw the line into the graphics context 21 CGContextSetTextPosition(context, 10.0, 10.0); 22 CTLineDraw(line, context); 23 CFRelease(line);
[总结]
App应用开发如非必要, 尽量避免使用Core Text, 优先使用 Text Kit。
原文:http://www.cnblogs.com/tekkaman/p/3571331.html