📄 textutilities.java
字号:
return end;
}
}
return end;
}
else {
end = iterator.previous();
return end;
}
}
// we found at least one word that fits ...
firstWord = false;
current = end;
}
return BreakIterator.DONE;
}
/**
* Returns the bounds for the specified text.
*
* @param text the text (<code>null</code> permitted).
* @param g2 the graphics context (not <code>null</code>).
* @param fm the font metrics (not <code>null</code>).
*
* @return The text bounds (<code>null</code> if the <code>text</code>
* argument is <code>null</code>).
*/
public static Rectangle2D getTextBounds(final String text,
final Graphics2D g2, final FontMetrics fm) {
final Rectangle2D bounds;
if (TextUtilities.useFontMetricsGetStringBounds) {
bounds = fm.getStringBounds(text, g2);
// getStringBounds() can return incorrect height for some Unicode
// characters...see bug parade 6183356, let's replace it with
// something correct
LineMetrics lm = fm.getFont().getLineMetrics(text,
g2.getFontRenderContext());
bounds.setRect(bounds.getX(), bounds.getY(), bounds.getWidth(),
lm.getHeight());
}
else {
final double width = fm.stringWidth(text);
final double height = fm.getHeight();
if (logger.isDebugEnabled()) {
logger.debug("Height = " + height);
}
bounds = new Rectangle2D.Double(0.0, -fm.getAscent(), width,
height);
}
return bounds;
}
/**
* Draws a string such that the specified anchor point is aligned to the
* given (x, y) location.
*
* @param text the text.
* @param g2 the graphics device.
* @param x the x coordinate (Java 2D).
* @param y the y coordinate (Java 2D).
* @param anchor the anchor location.
*
* @return The text bounds (adjusted for the text position).
*/
public static Rectangle2D drawAlignedString(final String text,
final Graphics2D g2, final float x, final float y,
final TextAnchor anchor) {
final Rectangle2D textBounds = new Rectangle2D.Double();
final float[] adjust = deriveTextBoundsAnchorOffsets(g2, text, anchor,
textBounds);
// adjust text bounds to match string position
textBounds.setRect(x + adjust[0], y + adjust[1] + adjust[2],
textBounds.getWidth(), textBounds.getHeight());
g2.drawString(text, x + adjust[0], y + adjust[1]);
return textBounds;
}
/**
* A utility method that calculates the anchor offsets for a string.
* Normally, the (x, y) coordinate for drawing text is a point on the
* baseline at the left of the text string. If you add these offsets to
* (x, y) and draw the string, then the anchor point should coincide with
* the (x, y) point.
*
* @param g2 the graphics device (not <code>null</code>).
* @param text the text.
* @param anchor the anchor point.
* @param textBounds the text bounds (if not <code>null</code>, this
* object will be updated by this method to match the
* string bounds).
*
* @return The offsets.
*/
private static float[] deriveTextBoundsAnchorOffsets(final Graphics2D g2,
final String text, final TextAnchor anchor,
final Rectangle2D textBounds) {
final float[] result = new float[3];
final FontRenderContext frc = g2.getFontRenderContext();
final Font f = g2.getFont();
final FontMetrics fm = g2.getFontMetrics(f);
final Rectangle2D bounds = TextUtilities.getTextBounds(text, g2, fm);
final LineMetrics metrics = f.getLineMetrics(text, frc);
final float ascent = metrics.getAscent();
result[2] = -ascent;
final float halfAscent = ascent / 2.0f;
final float descent = metrics.getDescent();
final float leading = metrics.getLeading();
float xAdj = 0.0f;
float yAdj = 0.0f;
if (anchor == TextAnchor.TOP_CENTER
|| anchor == TextAnchor.CENTER
|| anchor == TextAnchor.BOTTOM_CENTER
|| anchor == TextAnchor.BASELINE_CENTER
|| anchor == TextAnchor.HALF_ASCENT_CENTER) {
xAdj = (float) -bounds.getWidth() / 2.0f;
}
else if (anchor == TextAnchor.TOP_RIGHT
|| anchor == TextAnchor.CENTER_RIGHT
|| anchor == TextAnchor.BOTTOM_RIGHT
|| anchor == TextAnchor.BASELINE_RIGHT
|| anchor == TextAnchor.HALF_ASCENT_RIGHT) {
xAdj = (float) -bounds.getWidth();
}
if (anchor == TextAnchor.TOP_LEFT
|| anchor == TextAnchor.TOP_CENTER
|| anchor == TextAnchor.TOP_RIGHT) {
yAdj = -descent - leading + (float) bounds.getHeight();
}
else if (anchor == TextAnchor.HALF_ASCENT_LEFT
|| anchor == TextAnchor.HALF_ASCENT_CENTER
|| anchor == TextAnchor.HALF_ASCENT_RIGHT) {
yAdj = halfAscent;
}
else if (anchor == TextAnchor.CENTER_LEFT
|| anchor == TextAnchor.CENTER
|| anchor == TextAnchor.CENTER_RIGHT) {
yAdj = -descent - leading + (float) (bounds.getHeight() / 2.0);
}
else if (anchor == TextAnchor.BASELINE_LEFT
|| anchor == TextAnchor.BASELINE_CENTER
|| anchor == TextAnchor.BASELINE_RIGHT) {
yAdj = 0.0f;
}
else if (anchor == TextAnchor.BOTTOM_LEFT
|| anchor == TextAnchor.BOTTOM_CENTER
|| anchor == TextAnchor.BOTTOM_RIGHT) {
yAdj = -metrics.getDescent() - metrics.getLeading();
}
if (textBounds != null) {
textBounds.setRect(bounds);
}
result[0] = xAdj;
result[1] = yAdj;
return result;
}
/**
* Sets the flag that controls whether or not a workaround is used for
* drawing rotated strings. The related bug is on Sun's bug parade
* (id 4312117) and the workaround involves using a <code>TextLayout</code>
* instance to draw the text instead of calling the
* <code>drawString()</code> method in the <code>Graphics2D</code> class.
*
* @param use the new flag value.
*/
public static void setUseDrawRotatedStringWorkaround(final boolean use) {
useDrawRotatedStringWorkaround = use;
}
/**
* A utility method for drawing rotated text.
* <P>
* A common rotation is -Math.PI/2 which draws text 'vertically' (with the
* top of the characters on the left).
*
* @param text the text.
* @param g2 the graphics device.
* @param angle the angle of the (clockwise) rotation (in radians).
* @param x the x-coordinate.
* @param y the y-coordinate.
*/
public static void drawRotatedString(final String text, final Graphics2D g2,
final double angle, final float x, final float y) {
drawRotatedString(text, g2, x, y, angle, x, y);
}
/**
* A utility method for drawing rotated text.
* <P>
* A common rotation is -Math.PI/2 which draws text 'vertically' (with the
* top of the characters on the left).
*
* @param text the text.
* @param g2 the graphics device.
* @param textX the x-coordinate for the text (before rotation).
* @param textY the y-coordinate for the text (before rotation).
* @param angle the angle of the (clockwise) rotation (in radians).
* @param rotateX the point about which the text is rotated.
* @param rotateY the point about which the text is rotated.
*/
public static void drawRotatedString(final String text, final Graphics2D g2,
final float textX, final float textY, final double angle,
final float rotateX, final float rotateY) {
if ((text == null) || (text.equals(""))) {
return;
}
final AffineTransform saved = g2.getTransform();
// apply the rotation...
final AffineTransform rotate = AffineTransform.getRotateInstance(
angle, rotateX, rotateY);
g2.transform(rotate);
if (useDrawRotatedStringWorkaround) {
// workaround for JDC bug ID 4312117 and others...
final TextLayout tl = new TextLayout(text, g2.getFont(),
g2.getFontRenderContext());
tl.draw(g2, textX, textY);
}
else {
// replaces this code...
g2.drawString(text, textX, textY);
}
g2.setTransform(saved);
}
/**
* Draws a string that is aligned by one anchor point and rotated about
* another anchor point.
*
* @param text the text.
* @param g2 the graphics device.
* @param x the x-coordinate for positioning the text.
* @param y the y-coordinate for positioning the text.
* @param textAnchor the text anchor.
* @param angle the rotation angle.
* @param rotationX the x-coordinate for the rotation anchor point.
* @param rotationY the y-coordinate for the rotation anchor point.
*/
public static void drawRotatedString(final String text,
final Graphics2D g2, final float x, final float y,
final TextAnchor textAnchor, final double angle,
final float rotationX, final float rotationY) {
if (text == null || text.equals("")) {
return;
}
final float[] textAdj = deriveTextBoundsAnchorOffsets(g2, text,
textAnchor);
drawRotatedString(text, g2, x + textAdj[0], y + textAdj[1], angle,
rotationX, rotationY);
}
/**
* Draws a string that is aligned by one anchor point and rotated about
* another anchor point.
*
* @param text the text.
* @param g2 the graphics device.
* @param x the x-coordinate for positioning the text.
* @param y the y-coordinate for positioning the text.
* @param textAnchor the text anchor.
* @param angle the rotation angle (in radians).
* @param rotationAnchor the rotation anchor.
*/
public static void drawRotatedString(final String text, final Graphics2D g2,
final float x, final float y, final TextAnchor textAnchor,
final double angle, final TextAnchor rotationAnchor) {
if (text == null || text.equals("")) {
return;
}
final float[] textAdj = deriveTextBoundsAnchorOffsets(g2, text,
textAnchor);
final float[] rotateAdj = deriveRotationAnchorOffsets(g2, text,
rotationAnchor);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -