is new.
java.lang.Objectjava.awt.font.TextLayout
public final class TextLayout
TextLayout is an immutable graphical representation of styled character data.
It provides the following capabilities:
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:
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):
Point2D click = ...;
TextHitInfo hit = layout.hitTestChar(
(float) (click.getX() - loc.getX()),
(float) (click.getY() - loc.getY()));
Responding to a right-arrow key press:
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.
| Nested Class Summary | |
|---|---|
| static class |
TextLayout.CaretPolicy
Defines a policy for determining the strong caret location. |
| Field Summary | |
|---|---|
| static TextLayout.CaretPolicy |
DEFAULT_CARET_POLICY
This CaretPolicy is used when a policy is not specified by the client. |
| Constructor Summary | |
|---|---|
|
TextLayout
(
AttributedCharacterIterator
text,
FontRenderContext
frc) Constructs a TextLayout from an iterator over styled text. |
|
|
TextLayout
(
String
string,
Font
font,
FontRenderContext
frc) Constructs a TextLayout from a String and a Font . |
|
|
TextLayout
(
String
string,
Map
<? extends
AttributedCharacterIterator.Attribute
,?> attributes,
FontRenderContext
frc) Constructs a TextLayout from a String and an attribute set. |
|
| Method Summary | |
|---|---|
| protected Object |
clone
() Creates a copy of this TextLayout. |
| void |
draw
(
Graphics2D
g2, float x, float y) Renders this TextLayout at the specified location in the specified Graphics2D context. |
| boolean |
equals
(
Object
obj) Returns true if the specified Object is a TextLayout object and if the specified Object equals this TextLayout. |
| boolean |
equals
(
TextLayout
rhs) Returns true if the two layouts are equal. |
| float |
getAdvance
() Returns the advance of this TextLayout. |
| float |
getAscent
() Returns the ascent of this TextLayout. |
| byte |
getBaseline
() Returns the baseline for this TextLayout. |
| float[] |
getBaselineOffsets
() Returns the offsets array for the baselines used for this TextLayout. |
| Shape |
getBlackBoxBounds
(int firstEndpoint, int secondEndpoint) Returns the black box bounds of the characters in the specified range. |
| Rectangle2D |
getBounds
() Returns the bounds of this TextLayout. |
| float[] |
getCaretInfo
(
TextHitInfo
hit) Returns information about the caret corresponding to hit. |
| float[] |
getCaretInfo
(
TextHitInfo
hit,
Rectangle2D
bounds) Returns information about the caret corresponding to hit. |
| Shape |
getCaretShape
(
TextHitInfo
hit) Returns a Shape representing the caret at the specified hit inside the natural bounds of this TextLayout. |
| Shape |
getCaretShape
(
TextHitInfo
hit,
Rectangle2D
bounds) Returns a Shape representing the caret at the specified hit inside the specified bounds. |
| Shape [] |
getCaretShapes
(int offset) Returns two paths corresponding to the strong and weak caret. |
| Shape [] |
getCaretShapes
(int offset,
Rectangle2D
bounds) Returns two paths corresponding to the strong and weak caret. |
| Shape [] |
getCaretShapes
(int offset,
Rectangle2D
bounds,
TextLayout.CaretPolicy
policy) Returns two paths corresponding to the strong and weak caret. |
| int |
getCharacterCount
() Returns the number of characters represented by this TextLayout. |
| byte |
getCharacterLevel
(int index) Returns the level of the character at index. |
| float |
getDescent
() Returns the descent of this TextLayout. |
| TextLayout |
getJustifiedLayout
(float justificationWidth) Creates a copy of this TextLayout justified to the specified width. |
| LayoutPath |
getLayoutPath
() Return the LayoutPath, or null if the layout path is the default path (x maps to advance, y maps to offset). |
| float |
getLeading
() Returns the leading of the TextLayout. |
| Shape |
getLogicalHighlightShape
(int firstEndpoint, int secondEndpoint) Returns a Shape enclosing the logical selection in the specified range, extended to the natural bounds of this TextLayout. |
| Shape |
getLogicalHighlightShape
(int firstEndpoint, int secondEndpoint,
Rectangle2D
bounds) Returns a Shape enclosing the logical selection in the specified range, extended to the specified bounds. |
| int[] |
getLogicalRangesForVisualSelection
(
TextHitInfo
firstEndpoint,
TextHitInfo
secondEndpoint) Returns the logical ranges of text corresponding to a visual selection. |
| TextHitInfo |
getNextLeftHit
(int offset) Returns the hit for the next caret to the left (top); if no such hit, returns null. |
| TextHitInfo |
getNextLeftHit
(int offset,
TextLayout.CaretPolicy
policy) Returns the hit for the next caret to the left (top); if no such hit, returns null. |
| TextHitInfo |
getNextLeftHit
(
TextHitInfo
hit) Returns the hit for the next caret to the left (top); if no such hit, returns null. |
| TextHitInfo |
getNextRightHit
(int offset) Returns the hit for the next caret to the right (bottom); if no such hit, returns null. |
| TextHitInfo |
getNextRightHit
(int offset,
TextLayout.CaretPolicy
policy) Returns the hit for the next caret to the right (bottom); if no such hit, returns null. |
| TextHitInfo |
getNextRightHit
(
TextHitInfo
hit) Returns the hit for the next caret to the right (bottom); if there is no such hit, returns null. |
| Shape |
getOutline
(
AffineTransform
tx) Returns a Shape representing the outline of this TextLayout. |
| Rectangle |
getPixelBounds
(
FontRenderContext
frc, float x, float y) Returns the pixel bounds of this TextLayout when rendered in a graphics with the given FontRenderContext at the given location. |
| float |
getVisibleAdvance
() Returns the advance of this TextLayout, minus trailing whitespace. |
| Shape |
getVisualHighlightShape
(
TextHitInfo
firstEndpoint,
TextHitInfo
secondEndpoint) Returns a Shape enclosing the visual selection in the specified range, extended to the bounds. |
| Shape |
getVisualHighlightShape
(
TextHitInfo
firstEndpoint,
TextHitInfo
secondEndpoint,
Rectangle2D
bounds) Returns a path enclosing the visual selection in the specified range, extended to bounds. |
| TextHitInfo |
getVisualOtherHit
(
TextHitInfo
hit) Returns the hit on the opposite side of the specified hit's caret. |
| protected void |
handleJustify
(float justificationWidth) Justify this layout. |
| int |
hashCode
() Returns the hash code of this TextLayout. |
| TextHitInfo |
hitTestChar
(float x, float y) Returns a TextHitInfo corresponding to the specified point. |
| TextHitInfo |
hitTestChar
(float x, float y,
Rectangle2D
bounds) Returns a TextHitInfo corresponding to the specified point. |
| void |
hitToPoint
(
TextHitInfo
hit,
Point2D
point) Convert a hit to a point in standard coordinates. |
| boolean |
isLeftToRight
() Returns true if this TextLayout has a left-to-right base direction or false if it has a right-to-left base direction. |
| boolean |
isVertical
() Returns true if this TextLayout is vertical. |
| String |
toString
() Returns debugging information for this TextLayout. |
| Methods inherited from class java.lang. Object |
|---|
| finalize , getClass , notify , notifyAll , wait , wait , wait |
| Field Detail |
|---|
public static final TextLayout.CaretPolicy DEFAULT_CARET_POLICY
| Constructor Detail |
|---|
public TextLayout(String string,
Font font,
FontRenderContext frc)
The String must specify a single paragraph of text, because an entire paragraph is required for the bidirectional algorithm.
public TextLayout(String string,
Map<? extends AttributedCharacterIterator.Attribute,?> attributes,
FontRenderContext frc)
All the text is styled using the provided attributes.
string must specify a single paragraph of text because an entire paragraph is required for the bidirectional algorithm.
public TextLayout(AttributedCharacterIterator text,
FontRenderContext frc)
The iterator must specify a single paragraph of text because an entire paragraph is required for the bidirectional algorithm.
| Method Detail |
|---|
protected Object clone()
public TextLayout getJustifiedLayout(float justificationWidth)
If this TextLayout has already been justified, an exception is thrown. If this TextLayout object's justification ratio is zero, a TextLayout identical to this TextLayout is returned.
protected void handleJustify(float justificationWidth)
Some code may rely on immutablity of layouts. Subclassers should not call this directly, but instead should call getJustifiedLayout, which will call this method on a clone of this layout, preserving the original.
public byte getBaseline()
public float[] getBaselineOffsets()
The array is indexed by one of the values defined in Font, which are roman, centered and hanging. The values are relative to this TextLayout object's baseline, so that getBaselineOffsets[getBaseline()] == 0. Offsets are added to the position of the TextLayout object's baseline to get the position for the new baseline.
public float getAdvance()
public float getVisibleAdvance()
public float getAscent()
public float getDescent()
public float getLeading()
The leading is computed from the leading, descent, and baseline of all glyphvectors in the TextLayout. The algorithm is roughly as follows:
maxD = 0;
maxDL = 0;
for (GlyphVector g in all glyphvectors) {
maxD = max(maxD, g.getDescent() + offsets[g.getBaseline()]);
maxDL = max(maxDL, g.getDescent() + g.getLeading() +
offsets[g.getBaseline()]);
}
return maxDL - maxD;
public Rectangle2D getBounds()
Due to rasterization effects, this bounds might not enclose all of the pixels rendered by the TextLayout.
It might not coincide exactly with the ascent, descent, origin or advance of the TextLayout.
public Rectangle getPixelBounds(FontRenderContext frc,
float x,
float y)
public boolean isLeftToRight()
public boolean isVertical()
public int getCharacterCount()
public float[] getCaretInfo(TextHitInfo hit,
Rectangle2D bounds)
This method is meant for informational use. To display carets, it is better to use getCaretShapes.
public float[] getCaretInfo(TextHitInfo hit)
public TextHitInfo getNextRightHit(TextHitInfo hit)
public TextHitInfo getNextRightHit(int offset,
TextLayout.CaretPolicy policy)
public TextHitInfo getNextRightHit(int offset)
public TextHitInfo getNextLeftHit(TextHitInfo hit)
public TextHitInfo getNextLeftHit(int offset,
TextLayout.CaretPolicy policy)
public TextHitInfo getNextLeftHit(int offset)
public TextHitInfo getVisualOtherHit(TextHitInfo hit)
public Shape getCaretShape(TextHitInfo hit,
Rectangle2D bounds)
public Shape getCaretShape(TextHitInfo hit)
public byte getCharacterLevel(int index)
public Shape[] getCaretShapes(int offset,
Rectangle2D bounds,
TextLayout.CaretPolicy policy)
public Shape[] getCaretShapes(int offset,
Rectangle2D bounds)
public Shape[] getCaretShapes(int offset)
public int[] getLogicalRangesForVisualSelection(TextHitInfo firstEndpoint,
TextHitInfo secondEndpoint)
public Shape getVisualHighlightShape(TextHitInfo firstEndpoint,
TextHitInfo secondEndpoint,
Rectangle2D bounds)
If the selection includes the leftmost (topmost) position, the selection is extended to the left (top) of bounds. If the selection includes the rightmost (bottommost) position, the selection is extended to the right (bottom) of the bounds. The height (width on vertical lines) of the selection is always extended to bounds.
Although the selection is always contiguous, the logically selected text can be discontiguous on lines with mixed-direction text. The logical ranges of text selected can be retrieved using getLogicalRangesForVisualSelection. For example, consider the text 'ABCdef' where capital letters indicate right-to-left text, rendered on a right-to-left line, with a visual selection from 0L (the leading edge of 'A') to 3T (the trailing edge of 'd'). The text appears as follows, with bold underlined areas representing the selection:
defCBA
The logical selection ranges are 0-3, 4-6 (ABC, ef) because the visually contiguous text is logically discontiguous. Also note that since the rightmost position on the layout (to the right of 'A') is selected, the selection is extended to the right of the bounds.
public Shape getVisualHighlightShape(TextHitInfo firstEndpoint,
TextHitInfo secondEndpoint)
public Shape getLogicalHighlightShape(int firstEndpoint,
int secondEndpoint,
Rectangle2D bounds)
If the selection range includes the first logical character, the selection is extended to the portion of bounds before the start of this TextLayout. If the range includes the last logical character, the selection is extended to the portion of bounds after the end of this TextLayout. The height (width on vertical lines) of the selection is always extended to bounds.
The selection can be discontiguous on lines with mixed-direction text. Only those characters in the logical range between start and limit appear selected. For example, consider the text 'ABCdef' where capital letters indicate right-to-left text, rendered on a right-to-left line, with a logical selection from 0 to 4 ('ABCd'). The text appears as follows, with bold standing in for the selection, and underlining for the extension:
defCBA
The selection is discontiguous because the selected characters are visually discontiguous. Also note that since the range includes the first logical character (A), the selection is extended to the portion of the bounds before the start of the layout, which in this case (a right-to-left line) is the right portion of the bounds.
public Shape getLogicalHighlightShape(int firstEndpoint,
int secondEndpoint)
public Shape getBlackBoxBounds(int firstEndpoint,
int secondEndpoint)
public TextHitInfo hitTestChar(float x,
float y,
Rectangle2D bounds)
public TextHitInfo hitTestChar(float x,
float y)
public int hashCode()
public boolean equals(Object obj)
public boolean equals(TextLayout rhs)
public String toString()
public void draw(Graphics2D g2,
float x,
float y)
x - the X coordinate of the origin of this TextLayout
y - the Y coordinate of the origin of this TextLayout
public Shape getOutline(AffineTransform tx)
public LayoutPath getLayoutPath()
public void hitToPoint(TextHitInfo hit,
Point2D point)