Text layout objects contain the stylistic information that influences the display and formatting of the text associated with the text layout object. In ATSUI, you can create a text layout object by calling the function ATSUCreateTextLayout with an ATSUTextLayout data structure as a parameter. Like style objects, text layout objects are opaque. You use ATSUI accessor functions to retrieve and manipulate the data associated with a text layout object.
Note: Beginning with Mac OS X version 10.2, ATSUI text layout objects are thread-safe; you can share them between threads.
Each text layout object contains the text layout attributes, soft line breaks, and style runs that have been set for a block of Unicode text. The text layout object keeps track of the following information:
A pointer to the Unicode text string associated with the text layout object, and the length of the text associated with the object (which could also include a subrange of the text). See “Text Information.”
The number of style runs in the text layout object, the length (in bytes) of each style run, and a list of references to the style objects that correspond to the text layout object’s style runs. See “Style Run Information.”
Attributes that control the layout of the text at the line and paragraph level. They influence the width of the text area from the left margin to the right margin, the alignment of the text, the justification of the text, the rotation of the text, the direction of the text, the locations of the various baselines for the text, and other layout controls. See “Line and Layout Attributes .”
When you create a text layout object, you need to provide a pointer to a Unicode text buffer along with information about the text. You must allocate and manage the memory for the text associated with the text layout object.
The following is a list of the text-related information you must supply to ATSUI for each text layout object you create:
address of the start of the text array in memory
ATSUI assumes that the block of text associated with a text layout object is found in memory as a contiguous block. To handle text that is broken up into discontinuous memory blocks, you must use one text layout object for each block.
offset to the beginning of the portion of text to be drawn
You must specify the portion of the text buffer to which ATSUI should apply style attributes. This allows you to draw only a portion of text—for example, the visible page and the areas immediately around it—and avoid the overhead of drawing the rest of the text. The starting position is represented as a double-byte character offset of type UniCharArrayOffset relative to the beginning of the text buffer.
ATSUI assumes that the memory between the beginning of the text and the beginning of the text that is to be drawn, contains text. ATSUI may need to examine the text prior to the starting offset to read Unicode control characters that are embedded in the Unicode text string.
length of the text to be drawn
The length of the text is measured in the number of double-byte Unicode characters of type UniCharCount.
total length (offset plus length of text to be drawn)
For best text-rendering performance, an ATSUI text layout object should contain at least a paragraph of text.
Typically the text associated with a text layout object spans a block of Unicode text—a sequence of characters terminated by Unicode block separator characters such as hard breaks or tabs. However, this does not have to be the case. The text associated with a text layout object may span multiple blocks of Unicode text or part of a block. Regardless of whether the text is shorter, longer, or equal to a block of text as defined by Unicode, ATSUI always behaves as if there are Unicode block separator characters preceding and terminating the text associated with the text layout object.
Figure 2-19 shows the text associated with a text object and calls out the portion of the text to be rendered by ATSUI. Even though ATSUI needs to draw only a portion of the text, ATSUI might scan the remainder of the text block for formatting controls or other information.
Although ASTUI requires Unicode text, you should not assume that the caret can move through the text one character at a time by moving at least two bytes at a time. The backing store position of each character in the text relative to the beginning of the text buffer is specified by a double-byte character offset of type UniCharArrayOffset, illustrated in Figure 2-20. The UniCharArrayOffset is a zero-based offset that represents the position between two Unicode characters in a text buffer. Because of the possible presence of surrogates, the double-byte UniCharArrayOffset edge offset does not necessarily represent a position between two logical Unicode characters.
Some ATSUI functions need more information than a text offset. They also need to know whether the offset comes after the preceding character or before the next character. This is important for bidirectional text, where some of the text has a left-to-right direction and some has a right-to-left direction, as shown in Figure 2-21.
The text associated with a text layout object is divided into one or more style runs. Each style run is specified by a style object that contains a collection of style attributes, font features, and font variations that influence the display and formatting of a style run in a text layout object.
Figure 2-22 shows text that’s divided into twelve style runs. Six of the style runs in the figure are marked with the style attribute unique to that run. The other six runs that aren’t marked have two attributes set—Palatino font and a point size of 18.0.
When you create a text layout object, you must provide the number of style runs in the text, the length of each style run, and the style object for each run. Style objects and style attributes are discussed in detail in “Style Objects.”
Line and layout attributes control how the lines of text associated with the text layout object are displayed and formatted. Similar to style attributes, ATSUI uses a triple to specify line and layout attributes: an attribute tag, the value of the attribute it sets, and the size (in bytes) of the attribute value. Attribute tags are constants supplied by ATSUI. Attribute values may be a scaler, a structure, or a pointer.
This section discusses most of the line and layout attributes for which ATSUI provides tags. It describes a line or layout attribute, the default setting for the attribute, and in many cases shows the effect of applying the attribute to a text layout. For the complete list of line and layout attributes that can be applied to a text layout object, see Inside Mac OS X: ATSUI Reference.
You can create a custom line or layout attribute for an attribute for which ATSUI does not provide a tag. For more information, see “Custom Attribute Tags.”
Alignment, or flushness, is the process of placing text in relation to one or both margins, which are the left and right sides (or top and bottom sides) of the text area. You can set and retrieve the alignment value using the following line and layout control attribute tag:
kATSULineFlushFactorTagFractkATSUStartAlignmentText can be aligned left (kATSUStartAlignment), right (kATSUEndAlignment), or center (kATSUCenterAlignment), as shown in Figure 1-16. You can also specify a fractional value to align text at any location between the margins. Note in Figure 1-16 how the words of the text are spaced normally. Unlike justification (see “Justification Attribute Tag”), alignment does not affect the spacing between words or individual glyphs.
The alignment attribute has an effect only with text whose width is shorter than the width specified by the width attribute (kATSULineWidthTag), as shown in Figure 2-23. You must specify a width if you want to have any alignment other than kATSUStartAlignment.
See “Justification Attribute Tag” for additional information on how the width, alignment, and justification attributes interact.
Baseline offsets specify the positions of different baseline types with respect to one another in a line of text. You can set and retrieve these values using the following line and layout control attribute tag:
kATSULineBaselineValuesTagBslnBaselineRecord0 for each entry in the recordIn general, a style run has a default baseline, the line to which all glyphs are visually aligned when the text is laid out. For example, in a run of Roman text, the default baseline is the Roman baseline, upon which glyphs sit (except for descenders, which extend below the baseline). In some other writing systems, glyphs hang from the baseline. When text in a line comprises runs using multiple baselines, the text layout object uses information in the baseline record to determine how to align the runs with each other.
The baseline structure contains an array of distances, in points, from a delta of 0 from the y-coordinate of the layout’s origin to the other baseline types the text layout object contains. Positive values indicate baselines above the default baseline and negative values indicate baselines below it. ATSUI can use these values to position text relative to the default baseline.
Figure 2-24 shows an example of text with multiple baselines aligned according to information in the baseline structure. Baseline types are described in detail in “Baselines.”
The font fallbacks attribute specifies a font fallback object to use with a text layout. You can set and retrieve the font fallback object for a text layout using the following line and layout control attribute tag:
Before you use this tag, you must associate a font fallback method with a font fallback object. Then you can call the function ATSUSetLayoutControls, passing as parameters the tag kATSULineFontFallbacksTag and the font fallback object you set up previously. For more information on using the font fallbacks attribute tag see “Using Font Fallback Objects.”
Justification is the process of typographically fitting a line of text to a given width (or height, in the case of vertical text). You can set and retrieve the justification value using the following line and layout control attribute tag:
kATSULineJustificationFactorTagFractkATSUNoJustificationIn ATSUI some of the information that controls justification behavior is contained in the text layout object, whereas other information is contained in the style objects associated with the text layout object. There are several different kinds of justification, including justification with white space, kashidas, glyph deformation, and ligature decomposition.
ATSUI justifies Roman text primarily by adjusting the white space between words and glyphs, as shown in Figure 2-25. Note that white space is added not only between words but also between glyphs. Also notice that ligatures such as “fi” and “ff” can be broken during justification.
When Arabic text is justified, ATSUI distributes the available white space on the line by automatically lengthening or shortening the kashidas, which are the extender bars stretching between some of the glyphs of a word, as shown in Figure 2-26.
The value of the justification attribute can have fractional values from 0 through 1. A value of 0.0 means no justification; a value of 1.0 means full justification using the width set by the width attribute tag kATSULineWidthTag. ATSUI interprets intermediate values, such as 0.5, to mean partial justification (also called ragged justification). Figure 2-27 shows a line with no justification followed by a partially justified line and a fully justified line.
Figure 2-28 shows how the justification and alignment line and layout attributes interact with values ranging from 0.0 to 1.0. Note that when the user chooses full justification—that is, when the line justification attribute equals 1.0—the value set by the alignment attribute tag (kATSULineFlushFactorTag) has no effect.
The width, justification, and alignment attributes interact, and may produce a text layout other than what you expect. Table 2-2 describe the text layout that results from the interaction of these three attributes set at various values.
Width | Justification | Alignment | Effect |
|---|---|---|---|
0 | 0 | 0 | Text is drawn flush left. |
0 | 0 | > 0 | Text is drawn proportionally around the origin. For example, if the value set by the attribute tag |
0 | > 0 | 0 | Text is drawn compressed, flush left. |
0 | > 0 | > 0 | Text is drawn compressed at the point specified by the attribute tag |
> 0 | 0 | 0 | Text is drawn flush left, unless the unjustified width is greater than the specified width. In this case, the text is drawn compressed into the specific width. |
> 0 | 0 | > 0 | Text is drawn at the point specified by the attribute tag |
> 0 | > 0 | 0 | Text is drawn in the specified width, flush left, unless the value set by the attribute tag |
> 0 | > 0 | > 0 | Text is drawn in the specified width at the point specified by the attribute tag |
The language attribute tag represents the regional language code for glyphs in a line or text layout. ATSUI uses the value associated with this tag to determine how to render region-dependent characteristics. You can set and retrieve the language region value using the following line and layout control attribute tag:
The layout operation attribute specifies a layout operation (such as morphing or kerning) that you want to handle instead of letting ATSUI perform it. You can set and retrieve the layout operation value using the following line and layout control attribute tag:
kATSULayoutOperationOverrideTagATSULayoutOperationOverrideSpecifierNULLFor information on how to use the layout operation override tag, see “Overriding ATSUI Layout Operations .”
The line ascent attribute tag represents the ascent associated with a line of text. You can obtain the line ascent value by using the following line and layout control attribute tag:
kATSULineAscentTagATSUTextMeasurementYou can retrieve the line ascent value when you need to calculate line height. See “Calculating Line Height.”
The line descent attribute tag represents the sum of the descent and leading associated with a line of text or a text layout object. You can obtain the line descent value by using the following line and layout control attribute tag:
kATSULineDescentTagATSUTextMeasurementYou can retrieve the line descent value when you need to calculate line height. See “Calculating Line Height.” Note the unlike the style descent value (see “Descent Attribute Tag”), the line descent value includes the leading value.
The line direction attribute specifies a left-to-right or right-to-left direction for the glyphs associated with a text layout object, regardless of their natural direction as specified in the font. You can set and retrieve the line direction value using the following line and layout control attribute tag:
kATSULineDirectionTagBooleanGetSysDirectionThe dominant direction of a line is the overall, controlling direction within which the individual glyph directions are set. If a Hebrew word is embedded in a line of Roman text, the dominant direction for that line is left to right, but the Hebrew word is still laid out right to left, as expected. Conversely, Roman text embedded in a line of Hebrew, in which the dominant direction is right to left, is still displayed left to right. For this reason, dominant direction has significance only in mixed-direction text.
The ATSUI text layout model accounts for dominant direction as well as glyph direction, automatically performing any reordering needed for correct display of simple mixed-direction lines of text.
Line layout options allow for fine control over the layout process. You can set and retrieve line layout options using the following attribute tag:
kATSULineLayoutOptionsTagATSLineLayoutOptionskATSUNoLayoutOptionsThe value for the line layout option attributes is specified by setting flags of type ATSLineLayoutOptions. These flags are described in Table 2-3. Note that some of the flags override style attributes set in the style objects associated with the text layout object.
The line truncation attribute specifies where truncation should occur and whether any negative justification should also be applied. You can set and retrieve the line truncation value using the following line and layout control attribute tag:
The Quartz context attribute specifies how ATSUI should render text. You can set and retrieve the Quartz context value using the following line and layout control attribute tag:
kATSUCGContextTagCGContextRefNULLYou can use this tag to set up ATSUI to draw using Quartz in an 8-bit, subpixel rendering mode. Using this method of rendering, glyph origins are positioned on fractional points, resulting in superior rendering compared to the default 4-bit pixel-aligned rendering. For information on how to use the Quartz context tag to set up a rendering mode, see “Drawing Text Using a Quartz Context.”
The rotation attribute specifies the angle (in degrees) by which the entire line should be rotated. You can set and retrieve the rotation value using the following line and layout control attribute tag:
In ATSUI, rotation is counterclockwise. To produce vertical text, set the rotation value to -90.0 degrees and the value accessed by the style attribute tag kATSUVerticalCharacterTag to the constant kATSUStronglyVertical, as described in “Glyph Orientation Attribute Tag .”
The line shown on the right side of Figure 2-29 is rotated -90.0 degrees, but the glyphs have not been rotated. This type of rotation can be used to label the axis of a scientific graph.
ATSUI uses text-locator information to determine where to break text and which options to apply to text breaks. The attribute value associated with this tag (TextBreakLocatorRef) contains the data needed by ATSUI to locate various kinds of text breaks. You can set and retrieve the text locator value using the following line and layout control attribute tag:
kATSULineTextLocatorTagTextBreakLocatorRef (an opaque structure defined in Unicode Utilities)NULLThe width attribute specifies the desired width of a line of text, in typographic points, of the line when drawn as justified or right-aligned text. ATSUI treats vertical text as if it were horizontal. You can set and retrieve the width value using the following line and layout control attribute tag:
kATSULineWidthTagATSUTextMeasurement0If a line is not justified or right-aligned, the value set by the width attribute tag kATSULineWidthTag is still used to apply negative justification (unless the kATSLineDisableNegativeJustification tag is set). Negative justification is the process of condensing text that exceeds the specified width so that the text fits the specified width. See “Justification Attribute Tag” for additional information on how the width, alignment, and justification attributes interact.
If the line contains glyphs with large negative side bearings, hanging punctuation, or optically aligned edges, the final width of the displayed text may be different from the value specified by the width attribute. See “Hanging Punctuation Attribute Tag ” and “Optical Alignment Attribute Tag ” for more information.
If you use the width of the image bounding rectangle and the typographic bounding rectangle as a measure of the overall line length, the measurements may be slightly different from each other. See “Text Measurements” for more information.
Last updated: 2007-07-10