📄 textutilities.java
字号:
drawRotatedString(text, g2, x + textAdj[0], y + textAdj[1],
angle, x + textAdj[0] + rotateAdj[0],
y + textAdj[1] + rotateAdj[1]);
}
/**
* Returns a shape that represents the bounds of the string after the
* specified rotation has been applied.
*
* @param text the text (<code>null</code> permitted).
* @param g2 the graphics device.
* @param x the x coordinate for the anchor point.
* @param y the y coordinate for the anchor point.
* @param textAnchor the text anchor.
* @param angle the angle.
* @param rotationAnchor the rotation anchor.
*
* @return The bounds (possibly <code>null</code>).
*/
public static Shape calculateRotatedStringBounds(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 null;
}
final float[] textAdj = deriveTextBoundsAnchorOffsets(g2, text,
textAnchor);
if (logger.isDebugEnabled()) {
logger.debug("TextBoundsAnchorOffsets = " + textAdj[0] + ", "
+ textAdj[1]);
}
final float[] rotateAdj = deriveRotationAnchorOffsets(g2, text,
rotationAnchor);
if (logger.isDebugEnabled()) {
logger.debug("RotationAnchorOffsets = " + rotateAdj[0] + ", "
+ rotateAdj[1]);
}
final Shape result = calculateRotatedStringBounds(text, g2,
x + textAdj[0], y + textAdj[1], angle,
x + textAdj[0] + rotateAdj[0], y + textAdj[1] + rotateAdj[1]);
return result;
}
/**
* 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.
*
* @return The offsets.
*/
private static float[] deriveTextBoundsAnchorOffsets(final Graphics2D g2,
final String text, final TextAnchor anchor) {
final float[] result = new float[2];
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();
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();
}
result[0] = xAdj;
result[1] = yAdj;
return result;
}
/**
* A utility method that calculates the rotation anchor offsets for a
* string. These offsets are relative to the text starting coordinate
* (BASELINE_LEFT).
*
* @param g2 the graphics device.
* @param text the text.
* @param anchor the anchor point.
*
* @return The offsets.
*/
private static float[] deriveRotationAnchorOffsets(final Graphics2D g2,
final String text, final TextAnchor anchor) {
final float[] result = new float[2];
final FontRenderContext frc = g2.getFontRenderContext();
final LineMetrics metrics = g2.getFont().getLineMetrics(text, frc);
final FontMetrics fm = g2.getFontMetrics();
final Rectangle2D bounds = TextUtilities.getTextBounds(text, g2, fm);
final float ascent = metrics.getAscent();
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_LEFT
|| anchor == TextAnchor.CENTER_LEFT
|| anchor == TextAnchor.BOTTOM_LEFT
|| anchor == TextAnchor.BASELINE_LEFT
|| anchor == TextAnchor.HALF_ASCENT_LEFT) {
xAdj = 0.0f;
}
else 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.CENTER_LEFT
|| anchor == TextAnchor.CENTER
|| anchor == TextAnchor.CENTER_RIGHT) {
yAdj = descent + leading - (float) (bounds.getHeight() / 2.0);
}
else if (anchor == TextAnchor.HALF_ASCENT_LEFT
|| anchor == TextAnchor.HALF_ASCENT_CENTER
|| anchor == TextAnchor.HALF_ASCENT_RIGHT) {
yAdj = -halfAscent;
}
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();
}
result[0] = xAdj;
result[1] = yAdj;
return result;
}
/**
* Returns a shape that represents the bounds of the string after the
* specified rotation has been applied.
*
* @param text the text (<code>null</code> permitted).
* @param g2 the graphics device.
* @param textX the x coordinate for the text.
* @param textY the y coordinate for the text.
* @param angle the angle.
* @param rotateX the x coordinate for the rotation point.
* @param rotateY the y coordinate for the rotation point.
*
* @return The bounds (<code>null</code> if <code>text</code> is
* </code>null</code> or has zero length).
*/
public static Shape calculateRotatedStringBounds(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 null;
}
final FontMetrics fm = g2.getFontMetrics();
final Rectangle2D bounds = TextUtilities.getTextBounds(text, g2, fm);
final AffineTransform translate = AffineTransform.getTranslateInstance(
textX, textY);
final Shape translatedBounds = translate.createTransformedShape(bounds);
final AffineTransform rotate = AffineTransform.getRotateInstance(
angle, rotateX, rotateY);
final Shape result = rotate.createTransformedShape(translatedBounds);
return result;
}
/**
* Returns the flag that controls whether the FontMetrics.getStringBounds()
* method is used or not. If you are having trouble with label alignment
* or positioning, try changing the value of this flag.
*
* @return A boolean.
*/
public static boolean getUseFontMetricsGetStringBounds() {
return useFontMetricsGetStringBounds;
}
/**
* Sets the flag that controls whether the FontMetrics.getStringBounds()
* method is used or not. If you are having trouble with label alignment
* or positioning, try changing the value of this flag.
*
* @param use the flag.
*/
public static void setUseFontMetricsGetStringBounds(final boolean use) {
useFontMetricsGetStringBounds = use;
}
/**
* Returns the flag that controls whether or not a workaround is used for
* drawing rotated strings.
*
* @return A boolean.
*/
public static boolean isUseDrawRotatedStringWorkaround() {
return useDrawRotatedStringWorkaround;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -