TextLayout is an immutable graphical representation of styled
character data.
It provides the following capabilities:
implicit bidirectional analysis and reordering,
cursor positioning and movement, including split cursors for
mixed directional text,
highlighting, including both logical and visual highlighting
for mixed directional text,
multiple baselines (roman, hanging, and centered),
hit testing,
justification,
default font substitution,
metric information such as ascent, descent, and advance, and
rendering
A TextLayout object can be rendered using
its draw method.
TextLayout can be constructed either directly or through
the use of a LineBreakMeasurer . When constructed directly, the
source text represents a single paragraph. LineBreakMeasurer
allows styled text to be broken into lines that fit within a particular
width. See the LineBreakMeasurer documentation for more
information.
TextLayout construction logically proceeds as follows:
paragraph attributes are extracted and examined,
text is analyzed for bidirectional reordering, and reordering
information is computed if needed,
text is segmented into style runs
fonts are chosen for style runs, first by using a font if the
attribute FONT is present, otherwise by computing
a default font using the attributes that have been defined
if text is on multiple baselines, the runs or subruns are further
broken into subruns sharing a common baseline,
glyphvectors are generated for each run using the chosen font,
final bidirectional reordering is performed on the glyphvectors
All graphical information returned from a TextLayout
object's methods is relative to the origin of the
TextLayout, which is the intersection of the
TextLayout object's baseline with its left edge. Also,
coordinates passed into a TextLayout object's methods
are assumed to be relative to the TextLayout object's
origin. Clients usually need to translate between a
TextLayout object's coordinate system and the coordinate
system in another object (such as a
Graphics object).
TextLayout objects are constructed from styled text,
but they do not retain a reference to their source text. Thus,
changes in the text previously used to generate a TextLayout
do not affect the TextLayout.
Three methods on a TextLayout object
(getNextRightHit, getNextLeftHit, and
hitTestChar) return instances of TextHitInfo .
The offsets contained in these TextHitInfo objects
are relative to the start of the TextLayout, not
to the text used to create the TextLayout. Similarly,
TextLayout methods that accept TextHitInfo
instances as parameters expect the TextHitInfo object's
offsets to be relative to the TextLayout, not to any
underlying text storage model.
Examples:
Constructing and drawing a TextLayout and its bounding
rectangle:
Graphics2D g = ...;
Point2D loc = ...;
Font font = Font.getFont("Helvetica-bold-italic");
FontRenderContext frc = g.getFontRenderContext();
TextLayout layout = new TextLayout("This is a string", font, frc);
layout.draw(g, (float)loc.getX(), (float)loc.getY());
Rectangle2D bounds = layout.getBounds();
bounds.setRect(bounds.getX()+loc.getX(),
bounds.getY()+loc.getY(),
bounds.getWidth(),
bounds.getHeight());
g.draw(bounds);
Hit-testing a TextLayout (determining which character is at
a particular graphical location):
int insertionIndex = ...;
TextHitInfo next = layout.getNextRightHit(insertionIndex);
if (next != null) {
// translate graphics to origin of layout on screen
g.translate(loc.getX(), loc.getY());
Shape[] carets = layout.getCaretShapes(next.getInsertionIndex());
g.draw(carets[0]);
if (carets[1] != null) {
g.draw(carets[1]);
}
}
Drawing a selection range corresponding to a substring in the source text.
The selected area may not be visually contiguous:
// selStart, selLimit should be relative to the layout,
// not to the source text
int selStart = ..., selLimit = ...;
Color selectionColor = ...;
Shape selection = layout.getLogicalHighlightShape(selStart, selLimit);
// selection may consist of disjoint areas
// graphics is assumed to be tranlated to origin of layout
g.setColor(selectionColor);
g.fill(selection);
Drawing a visually contiguous selection range. The selection range may
correspond to more than one substring in the source text. The ranges of
the corresponding source text substrings can be obtained with
getLogicalRangesForVisualSelection():
TextHitInfo selStart = ..., selLimit = ...;
Shape selection = layout.getVisualHighlightShape(selStart, selLimit);
g.setColor(selectionColor);
g.fill(selection);
int[] ranges = getLogicalRangesForVisualSelection(selStart, selLimit);
// ranges[0], ranges[1] is the first selection range,
// ranges[2], ranges[3] is the second selection range, etc.
Note: Font rotations can cause text baselines to be rotated, and
multiple runs with different rotations can cause the baseline to
bend or zig-zag. In order to account for this (rare) possibility,
some APIs are specified to return metrics and take parameters 'in
baseline-relative coordinates' (e.g. ascent, advance), and others
are in 'in standard coordinates' (e.g. getBounds). Values in
baseline-relative coordinates map the 'x' coordinate to the
distance along the baseline, (positive x is forward along the
baseline), and the 'y' coordinate to a distance along the
perpendicular to the baseline at 'x' (postitive y is 90 degrees
clockwise from the baseline vector). Values in standard
coordinates are measured along the x and y axes, with 0,0 at the
origin of the TextLayout. Documentation for each relevant API
indicates what values are in what coordinate system. In general,
measurement-related APIs are in baseline-relative coordinates,
while display-related APIs are in standard coordinates.
TextLayoutis an immutable graphical representation of styled character data.It provides the following capabilities:
A
TextLayoutobject can be rendered using itsdrawmethod.TextLayoutcan be constructed either directly or through the use of a LineBreakMeasurer . When constructed directly, the source text represents a single paragraph.LineBreakMeasurerallows styled text to be broken into lines that fit within a particular width. See theLineBreakMeasurerdocumentation for more information.TextLayoutconstruction logically proceeds as follows:All graphical information returned from a
TextLayoutobject's methods is relative to the origin of theTextLayout, which is the intersection of theTextLayoutobject's baseline with its left edge. Also, coordinates passed into aTextLayoutobject's methods are assumed to be relative to theTextLayoutobject's origin. Clients usually need to translate between aTextLayoutobject's coordinate system and the coordinate system in another object (such as a Graphics object).TextLayoutobjects are constructed from styled text, but they do not retain a reference to their source text. Thus, changes in the text previously used to generate aTextLayoutdo not affect theTextLayout.Three methods on a
TextLayoutobject (getNextRightHit,getNextLeftHit, andhitTestChar) return instances of TextHitInfo . The offsets contained in theseTextHitInfoobjects are relative to the start of theTextLayout, not to the text used to create theTextLayout. Similarly,TextLayoutmethods that acceptTextHitInfoinstances as parameters expect theTextHitInfoobject's offsets to be relative to theTextLayout, not to any underlying text storage model.Examples:
Constructing and drawing a
TextLayoutand its bounding rectangle:Hit-testing a
TextLayout(determining which character is at a particular graphical location):Responding to a right-arrow key press:
Drawing a selection range corresponding to a substring in the source text. The selected area may not be visually contiguous:
Drawing a visually contiguous selection range. The selection range may correspond to more than one substring in the source text. The ranges of the corresponding source text substrings can be obtained with
getLogicalRangesForVisualSelection():Note: Font rotations can cause text baselines to be rotated, and multiple runs with different rotations can cause the baseline to bend or zig-zag. In order to account for this (rare) possibility, some APIs are specified to return metrics and take parameters 'in baseline-relative coordinates' (e.g. ascent, advance), and others are in 'in standard coordinates' (e.g. getBounds). Values in baseline-relative coordinates map the 'x' coordinate to the distance along the baseline, (positive x is forward along the baseline), and the 'y' coordinate to a distance along the perpendicular to the baseline at 'x' (postitive y is 90 degrees clockwise from the baseline vector). Values in standard coordinates are measured along the x and y axes, with 0,0 at the origin of the TextLayout. Documentation for each relevant API indicates what values are in what coordinate system. In general, measurement-related APIs are in baseline-relative coordinates, while display-related APIs are in standard coordinates.