下面列出了java.awt.Graphics2D#getFontRenderContext ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Estimates the maximum width of the tick labels, assuming the specified
* tick unit is used.
* <P>
* Rather than computing the string bounds of every tick on the axis, we
* just look at two values: the lower bound and the upper bound for the
* axis. These two values will usually be representative.
*
* @param g2 the graphics device.
* @param unit the tick unit to use for calculation.
*
* @return The estimated maximum width of the tick labels.
*/
private double estimateMaximumTickLabelWidth(Graphics2D g2,
DateTickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();
Font tickLabelFont = getTickLabelFont();
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = tickLabelFont.getLineMetrics("ABCxyz", frc);
if (isVerticalTickLabels()) {
// all tick labels have the same width (equal to the height of
// the font)...
result += lm.getHeight();
}
else {
// look at lower and upper bounds...
DateRange range = (DateRange) getRange();
Date lower = range.getLowerDate();
Date upper = range.getUpperDate();
String lowerStr, upperStr;
DateFormat formatter = getDateFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
}
else {
lowerStr = unit.dateToString(lower);
upperStr = unit.dateToString(upper);
}
FontMetrics fm = g2.getFontMetrics(tickLabelFont);
double w1 = fm.stringWidth(lowerStr);
double w2 = fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
protected double calculateLengthOfStringPlot(Graphics2D g2d, String label) {
TextLayout mLayout
= new TextLayout(
label, g2d.getFont(), g2d.getFontRenderContext());
Rectangle2D bounds = mLayout.getBounds();
return bounds.getWidth();
}
/**
* Estimates the maximum width of the tick labels, assuming the specified
* tick unit is used.
* <P>
* Rather than computing the string bounds of every tick on the axis, we
* just look at two values: the lower bound and the upper bound for the
* axis. These two values will usually be representative.
*
* @param g2 the graphics device.
* @param unit the tick unit to use for calculation.
*
* @return The estimated maximum width of the tick labels.
*/
protected double estimateMaximumTickLabelWidth(Graphics2D g2,
TickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();
if (isVerticalTickLabels()) {
// all tick labels have the same width (equal to the height of the
// font)...
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = getTickLabelFont().getLineMetrics("0", frc);
result += lm.getHeight();
}
else {
// look at lower and upper bounds...
FontMetrics fm = g2.getFontMetrics(getTickLabelFont());
Range range = getRange();
double lower = range.getLowerBound();
double upper = range.getUpperBound();
String lowerStr = "";
String upperStr = "";
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
}
else {
lowerStr = unit.valueToString(lower);
upperStr = unit.valueToString(upper);
}
double w1 = fm.stringWidth(lowerStr);
double w2 = fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
/**
* Estimates the maximum width of the tick labels, assuming the specified
* tick unit is used.
* <P>
* Rather than computing the string bounds of every tick on the axis, we
* just look at two values: the lower bound and the upper bound for the
* axis. These two values will usually be representative.
*
* @param g2 the graphics device.
* @param unit the tick unit to use for calculation.
*
* @return The estimated maximum width of the tick labels.
*/
private double estimateMaximumTickLabelWidth(Graphics2D g2,
DateTickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();
Font tickLabelFont = getTickLabelFont();
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = tickLabelFont.getLineMetrics("ABCxyz", frc);
if (isVerticalTickLabels()) {
// all tick labels have the same width (equal to the height of
// the font)...
result += lm.getHeight();
}
else {
// look at lower and upper bounds...
DateRange range = (DateRange) getRange();
Date lower = range.getLowerDate();
Date upper = range.getUpperDate();
String lowerStr, upperStr;
DateFormat formatter = getDateFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
}
else {
lowerStr = unit.dateToString(lower);
upperStr = unit.dateToString(upper);
}
FontMetrics fm = g2.getFontMetrics(tickLabelFont);
double w1 = fm.stringWidth(lowerStr);
double w2 = fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
/**
* Estimates the maximum width of the tick labels, assuming the specified
* tick unit is used.
* <P>
* Rather than computing the string bounds of every tick on the axis, we
* just look at two values: the lower bound and the upper bound for the
* axis. These two values will usually be representative.
*
* @param g2 the graphics device.
* @param unit the tick unit to use for calculation.
*
* @return The estimated maximum width of the tick labels.
*/
private double estimateMaximumTickLabelHeight(Graphics2D g2,
DateTickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getTop() + tickLabelInsets.getBottom();
Font tickLabelFont = getTickLabelFont();
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = tickLabelFont.getLineMetrics("ABCxyz", frc);
if (!isVerticalTickLabels()) {
// all tick labels have the same width (equal to the height of
// the font)...
result += lm.getHeight();
}
else {
// look at lower and upper bounds...
DateRange range = (DateRange) getRange();
Date lower = range.getLowerDate();
Date upper = range.getUpperDate();
String lowerStr = null;
String upperStr = null;
DateFormat formatter = getDateFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
}
else {
lowerStr = unit.dateToString(lower);
upperStr = unit.dateToString(upper);
}
FontMetrics fm = g2.getFontMetrics(tickLabelFont);
double w1 = fm.stringWidth(lowerStr);
double w2 = fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
/**
* Returns a rectangle that encloses the axis label. This is typically
* used for layout purposes (it gives the maximum dimensions of the label).
*
* @param g2 the graphics device.
* @param edge the edge of the plot area along which the axis is measuring.
*
* @return The enclosing rectangle.
*/
protected Rectangle2D getLabelEnclosure(Graphics2D g2, RectangleEdge edge) {
Rectangle2D result = new Rectangle2D.Double();
Rectangle2D bounds = null;
if (this.attributedLabel != null) {
TextLayout layout = new TextLayout(
this.attributedLabel.getIterator(),
g2.getFontRenderContext());
bounds = layout.getBounds();
} else {
String axisLabel = getLabel();
if (axisLabel != null && !axisLabel.equals("")) {
FontMetrics fm = g2.getFontMetrics(getLabelFont());
bounds = TextUtilities.getTextBounds(axisLabel, g2, fm);
}
}
if (bounds != null) {
RectangleInsets insets = getLabelInsets();
bounds = insets.createOutsetRectangle(bounds);
double angle = getLabelAngle();
if (edge == RectangleEdge.LEFT || edge == RectangleEdge.RIGHT) {
angle = angle - Math.PI / 2.0;
}
double x = bounds.getCenterX();
double y = bounds.getCenterY();
AffineTransform transformer
= AffineTransform.getRotateInstance(angle, x, y);
Shape labelBounds = transformer.createTransformedShape(bounds);
result = labelBounds.getBounds2D();
}
return result;
}
/**
* Estimates the maximum width of the tick labels, assuming the specified
* tick unit is used.
* <P>
* Rather than computing the string bounds of every tick on the axis, we
* just look at two values: the lower bound and the upper bound for the
* axis. These two values will usually be representative.
*
* @param g2 the graphics device.
* @param unit the tick unit to use for calculation.
*
* @return The estimated maximum width of the tick labels.
*/
private double estimateMaximumTickLabelWidth(Graphics2D g2,
DateTickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();
Font tickLabelFont = getTickLabelFont();
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = tickLabelFont.getLineMetrics("ABCxyz", frc);
if (isVerticalTickLabels()) {
// all tick labels have the same width (equal to the height of
// the font)...
result += lm.getHeight();
}
else {
// look at lower and upper bounds...
DateRange range = (DateRange) getRange();
Date lower = range.getLowerDate();
Date upper = range.getUpperDate();
String lowerStr, upperStr;
DateFormat formatter = getDateFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
}
else {
lowerStr = unit.dateToString(lower);
upperStr = unit.dateToString(upper);
}
FontMetrics fm = g2.getFontMetrics(tickLabelFont);
double w1 = fm.stringWidth(lowerStr);
double w2 = fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
/**
* Estimates the maximum width of the tick labels, assuming the specified
* tick unit is used.
* <P>
* Rather than computing the string bounds of every tick on the axis, we
* just look at two values: the lower bound and the upper bound for the
* axis. These two values will usually be representative.
*
* @param g2 the graphics device.
* @param unit the tick unit to use for calculation.
*
* @return The estimated maximum width of the tick labels.
*/
private double estimateMaximumTickLabelHeight(Graphics2D g2,
DateTickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getTop() + tickLabelInsets.getBottom();
Font tickLabelFont = getTickLabelFont();
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = tickLabelFont.getLineMetrics("ABCxyz", frc);
if (!isVerticalTickLabels()) {
// all tick labels have the same width (equal to the height of
// the font)...
result += lm.getHeight();
}
else {
// look at lower and upper bounds...
DateRange range = (DateRange) getRange();
Date lower = range.getLowerDate();
Date upper = range.getUpperDate();
String lowerStr, upperStr;
DateFormat formatter = getDateFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
}
else {
lowerStr = unit.dateToString(lower);
upperStr = unit.dateToString(upper);
}
FontMetrics fm = g2.getFontMetrics(tickLabelFont);
double w1 = fm.stringWidth(lowerStr);
double w2 = fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
protected void paintText(Graphics2D g, GeneralPath bodyOutline) {
Font font = getFont();
String text = getText();
g.setFont(font);
FontRenderContext frc = g.getFontRenderContext();
Rectangle2D r = font.getStringBounds(text, frc);
LineMetrics lineMetrics = font.getLineMetrics(text, frc);
Rectangle2D shapeBounds = ShapeBounds.getBounds(bodyOutline);
float shapeCenterX = (float) shapeBounds.getCenterX();
float shapeCenterY = (float) shapeBounds.getCenterY();
float textX = (float) (shapeCenterX - r.getWidth() / 2f);
float textY = (float) (shapeCenterY + lineMetrics.getAscent() / 2f - lineMetrics
.getDescent() / 3f);
if (isTextShadowActive()) {
Paint paint = this.getTextPaint();
boolean isTextDark = true;
if (paint instanceof Color) {
Color color = (Color) paint;
isTextDark = (color.getRed() + color.getGreen() + color
.getBlue()) / 3 < 120;
}
g.setColor(isTextDark ? new Color(255, 255, 255, 40) : new Color(0,
0, 0, 40));
g.translate(0, 1);
g.drawString(text, textX, textY);
g.translate(0, 1);
g.drawString(text, textX, textY);
g.translate(0, -2);
}
g.setPaint(getTextPaint());
g.drawString(text, textX, textY);
}
/**
* 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(Graphics2D g2,
AttributedString text, TextAnchor anchor) {
float[] result = new float[2];
TextLayout layout = new TextLayout(text.getIterator(),
g2.getFontRenderContext());
Rectangle2D bounds = layout.getBounds();
float ascent = layout.getAscent();
float halfAscent = ascent / 2.0f;
float descent = layout.getDescent();
float leading = layout.getLeading();
float xAdj = 0.0f;
float yAdj = 0.0f;
if (isHorizontalLeft(anchor)) {
xAdj = 0.0f;
}
else if (isHorizontalCenter(anchor)) {
xAdj = (float) bounds.getWidth() / 2.0f;
}
else if (isHorizontalRight(anchor)) {
xAdj = (float) bounds.getWidth();
}
if (isTop(anchor)) {
yAdj = descent + leading - (float) bounds.getHeight();
}
else if (isHalfHeight(anchor)) {
yAdj = descent + leading - (float) (bounds.getHeight() / 2.0);
}
else if (isHalfAscent(anchor)) {
yAdj = -halfAscent;
}
else if (isBaseline(anchor)) {
yAdj = 0.0f;
}
else if (isBottom(anchor)) {
yAdj = descent + leading;
}
result[0] = xAdj;
result[1] = yAdj;
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(Graphics2D g2,
String text, TextAnchor anchor) {
float[] result = new float[2];
FontRenderContext frc = g2.getFontRenderContext();
Font f = g2.getFont();
FontMetrics fm = g2.getFontMetrics(f);
Rectangle2D bounds = TextUtilities.getTextBounds(text, g2, fm);
LineMetrics metrics = f.getLineMetrics(text, frc);
float ascent = metrics.getAscent();
float halfAscent = ascent / 2.0f;
float descent = metrics.getDescent();
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;
}
/**
*
* @param g2d
* @param myConcordiaLine
* @param concordiaLabelFont
* @param concordiaLabelFontSize
* @param concordiaTicShape
* @param concordiaTicHalfWeight
* @param concordiaLineWeight
*/
public void plotConcordiaTicMarks(//
Graphics2D g2d,//
ConcordiaLine myConcordiaLine,
String concordiaLabelFont,
String concordiaLabelFontSize,
String concordiaTicShape,
float concordiaTicHalfWeight,
float concordiaLineWeight) {
// plot the Concordia tic marks on the concordia
g2d.setFont(new Font(
concordiaLabelFont,
Font.BOLD,
Integer.parseInt(concordiaLabelFontSize)));
setMin_T(myConcordiaLine.getStartSeg().getMinT());
setMax_T(myConcordiaLine.getEndSeg().getMaxT());
// all rebuild with tic generator nov 2011
BigDecimal[] tics = TicGeneratorForAxes.generateTics(min_T / 1e6, max_T / 1e6, 12); //minCtic, maxCtic, 20 );
// trap for bad plot
if (tics.length <= 1) {
tics = new BigDecimal[0];
}
int indexOfFirstMajorTic = TicGeneratorForAxes.indexOfFirstMajorTic;
int concordiaTicLabelFrequency = getcTicLabelFrequency();
// System.out.println(">> index " + indexOfFirstMajorTic);
for (int i = 0; i < tics.length; i++) {
double t = tics[i].movePointRight(6).doubleValue();
double xValue = 0.0;
double yValue = 0.0;
if (isTerraWasserbergGraph()) {
xValue = TeraWasserburgLineSegment.theX(t);
yValue = TeraWasserburgLineSegment.theY(t);
} else {
xValue = ConcordiaLineSegment.theX(t);
yValue = ConcordiaLineSegment.theY(t);
}
// June 2010 test for out of bounds
if (getXaxisSetup().valueInVisibleRange(xValue)//
&&//
getYaxisSetup().valueInVisibleRange(yValue)) {
if ((i - indexOfFirstMajorTic) % concordiaTicLabelFrequency == 0) {
// major tic
drawConcordiaTic(g2d, t, concordiaTicShape, concordiaTicHalfWeight);
// build the box to fit the value string
TextLayout ticLabelLayout = //
new TextLayout(
tics[i].toPlainString(), g2d.getFont(), g2d.getFontRenderContext());
Rectangle2D bounds = ticLabelLayout.getBounds();
float textX = (float) mapX(xValue) //
- (float) bounds.getWidth() - concordiaTicHalfWeight - 8f;
float textY = (float) mapY(yValue) //
+ (float) bounds.getHeight() * 0.4f;
// test for label out of bounds to left
if (mappedPointInVisiblePlot(textX, textY)) {
g2d.setPaint(Color.black);
g2d.drawString(tics[i].toPlainString(), textX, textY);
}
} else {
// minor tic
drawConcordiaTic(g2d, t, concordiaTicShape, concordiaTicHalfWeight / 2);
}
}
}
}
private void modeSpecificDrawLine( Graphics2D g2, String line,
int baseX, int baseY ) {
/// ABP - keep track of old tform, restore it later
AffineTransform oldTx = null;
oldTx = g2.getTransform();
g2.translate( baseX, baseY );
g2.transform( getAffineTransform( g2Transform ) );
switch ( drawMethod ) {
case DRAW_STRING:
g2.drawString( line, 0, 0 );
break;
case DRAW_CHARS:
g2.drawChars( line.toCharArray(), 0, line.length(), 0, 0 );
break;
case DRAW_BYTES:
try {
byte lineBytes[] = line.getBytes( "ISO-8859-1" );
g2.drawBytes( lineBytes, 0, lineBytes.length, 0, 0 );
}
catch ( Exception e ) {
e.printStackTrace();
}
break;
case DRAW_GLYPHV:
GlyphVector gv =
testFont.createGlyphVector( g2.getFontRenderContext(), line );
g2.drawGlyphVector( gv, (float) 0, (float) 0 );
break;
case TL_DRAW:
TextLayout tl = new TextLayout( line, testFont,
g2.getFontRenderContext() );
tl.draw( g2, (float) 0, (float) 0 );
break;
case GV_OUTLINE:
GlyphVector gvo =
testFont.createGlyphVector( g2.getFontRenderContext(), line );
g2.draw( gvo.getOutline( (float) 0, (float) 0 ));
break;
case TL_OUTLINE:
TextLayout tlo =
new TextLayout( line, testFont,
g2.getFontRenderContext() );
AffineTransform at = new AffineTransform();
g2.draw( tlo.getOutline( at ));
}
/// ABP - restore old tform
g2.setTransform ( oldTx );
}
/**
* 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(Graphics2D g2,
AttributedString text, TextAnchor anchor) {
float[] result = new float[2];
TextLayout layout = new TextLayout(text.getIterator(),
g2.getFontRenderContext());
Rectangle2D bounds = layout.getBounds();
float ascent = layout.getAscent();
float halfAscent = ascent / 2.0f;
float descent = layout.getDescent();
float leading = layout.getLeading();
float xAdj = 0.0f;
float yAdj = 0.0f;
if (isHorizontalLeft(anchor)) {
xAdj = 0.0f;
}
else if (isHorizontalCenter(anchor)) {
xAdj = (float) bounds.getWidth() / 2.0f;
}
else if (isHorizontalRight(anchor)) {
xAdj = (float) bounds.getWidth();
}
if (isTop(anchor)) {
yAdj = descent + leading - (float) bounds.getHeight();
}
else if (isHalfHeight(anchor)) {
yAdj = descent + leading - (float) (bounds.getHeight() / 2.0);
}
else if (isHalfAscent(anchor)) {
yAdj = -halfAscent;
}
else if (isBaseline(anchor)) {
yAdj = 0.0f;
}
else if (isBottom(anchor)) {
yAdj = descent + leading;
}
result[0] = xAdj;
result[1] = yAdj;
return result;
}
public void modeSpecificDrawChar( Graphics2D g2, int charCode,
int baseX, int baseY ) {
GlyphVector gv;
int oneGlyph[] = { charCode };
char charArray[] = Character.toChars( charCode );
FontRenderContext frc = g2.getFontRenderContext();
AffineTransform oldTX = g2.getTransform();
/// Create GlyphVector to measure the exact visual advance
/// Using that number, adjust the position of the character drawn
if ( textToUse == ALL_GLYPHS )
gv = testFont.createGlyphVector( frc, oneGlyph );
else
gv = testFont.createGlyphVector( frc, charArray );
Rectangle2D r2d2 = gv.getPixelBounds(frc, 0, 0);
int shiftedX = baseX;
// getPixelBounds returns a result in device space.
// we need to convert back to user space to be able to
// calculate the shift as baseX is in user space.
try {
double pt[] = new double[4];
pt[0] = r2d2.getX();
pt[1] = r2d2.getY();
pt[2] = r2d2.getX()+r2d2.getWidth();
pt[3] = r2d2.getY()+r2d2.getHeight();
oldTX.inverseTransform(pt,0,pt,0,2);
shiftedX = baseX - (int) ( pt[2] / 2 + pt[0] );
} catch (NoninvertibleTransformException e) {
}
/// ABP - keep track of old tform, restore it later
g2.translate( shiftedX, baseY );
g2.transform( getAffineTransform( g2Transform ) );
if ( textToUse == ALL_GLYPHS )
g2.drawGlyphVector( gv, 0f, 0f );
else {
if ( testFont.canDisplay( charCode ))
g2.setColor( Color.black );
else {
g2.setColor( Color.lightGray );
}
switch ( drawMethod ) {
case DRAW_STRING:
g2.drawString( new String( charArray ), 0, 0 );
break;
case DRAW_CHARS:
g2.drawChars( charArray, 0, 1, 0, 0 );
break;
case DRAW_BYTES:
if ( charCode > 0xff )
throw new CannotDrawException( DRAW_BYTES_ERROR );
byte oneByte[] = { (byte) charCode };
g2.drawBytes( oneByte, 0, 1, 0, 0 );
break;
case DRAW_GLYPHV:
g2.drawGlyphVector( gv, 0f, 0f );
break;
case TL_DRAW:
TextLayout tl = new TextLayout( new String( charArray ), testFont, frc );
tl.draw( g2, 0f, 0f );
break;
case GV_OUTLINE:
r2d2 = gv.getVisualBounds();
shiftedX = baseX - (int) ( r2d2.getWidth() / 2 + r2d2.getX() );
g2.draw( gv.getOutline( 0f, 0f ));
break;
case TL_OUTLINE:
r2d2 = gv.getVisualBounds();
shiftedX = baseX - (int) ( r2d2.getWidth() / 2 + r2d2.getX() );
TextLayout tlo =
new TextLayout( new String( charArray ), testFont,
g2.getFontRenderContext() );
g2.draw( tlo.getOutline( null ));
}
}
/// ABP - restore old tform
g2.setTransform ( oldTX );
}
/**
* 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(Graphics2D g2,
String text, TextAnchor anchor) {
float[] result = new float[2];
FontRenderContext frc = g2.getFontRenderContext();
Font f = g2.getFont();
FontMetrics fm = g2.getFontMetrics(f);
Rectangle2D bounds = TextUtilities.getTextBounds(text, g2, fm);
LineMetrics metrics = f.getLineMetrics(text, frc);
float ascent = metrics.getAscent();
float halfAscent = ascent / 2.0f;
float descent = metrics.getDescent();
float leading = metrics.getLeading();
float xAdj = 0.0f;
float yAdj = 0.0f;
if (anchor.isHorizontalCenter()) {
xAdj = (float) -bounds.getWidth() / 2.0f;
}
else if (anchor.isRight()) {
xAdj = (float) -bounds.getWidth();
}
if (anchor.isTop()) {
yAdj = -descent - leading + (float) bounds.getHeight();
}
else if (anchor.isHalfAscent()) {
yAdj = halfAscent;
}
else if (anchor.isVerticalCenter()) {
yAdj = -descent - leading + (float) (bounds.getHeight() / 2.0);
}
else if (anchor.isBaseline()) {
yAdj = 0.0f;
}
else if (anchor.isBottom()) {
yAdj = -metrics.getDescent() - metrics.getLeading();
}
result[0] = xAdj;
result[1] = yAdj;
return result;
}
private static float[] deriveTextBoundsAnchorOffsets(Graphics2D g2,
AttributedString text, TextAnchor anchor, Rectangle2D textBounds) {
TextLayout layout = new TextLayout(text.getIterator(), g2.getFontRenderContext());
Rectangle2D bounds = layout.getBounds();
float[] result = new float[3];
float ascent = layout.getAscent();
result[2] = -ascent;
float halfAscent = ascent / 2.0f;
float descent = layout.getDescent();
float leading = layout.getLeading();
float xAdj = 0.0f;
float yAdj = 0.0f;
if (isHorizontalCenter(anchor)) {
xAdj = (float) -bounds.getWidth() / 2.0f;
}
else if (isHorizontalRight(anchor)) {
xAdj = (float) -bounds.getWidth();
}
if (isTop(anchor)) {
//yAdj = -descent - leading + (float) bounds.getHeight();
yAdj = (float) bounds.getHeight();
}
else if (isHalfAscent(anchor)) {
yAdj = halfAscent;
}
else if (isHalfHeight(anchor)) {
yAdj = -descent - leading + (float) (bounds.getHeight() / 2.0);
}
else if (isBaseline(anchor)) {
yAdj = 0.0f;
}
else if (isBottom(anchor)) {
yAdj = -descent - leading;
}
if (textBounds != null) {
textBounds.setRect(bounds);
}
result[0] = xAdj;
result[1] = yAdj;
return result;
}
public void init(TestEnvironment env, Result results){
super.init(env, results);
g2d = (Graphics2D)graphics;
frc = g2d.getFontRenderContext();
}
private void modeSpecificDrawLine( Graphics2D g2, String line,
int baseX, int baseY ) {
/// ABP - keep track of old tform, restore it later
AffineTransform oldTx = null;
oldTx = g2.getTransform();
g2.translate( baseX, baseY );
g2.transform( getAffineTransform( g2Transform ) );
switch ( drawMethod ) {
case DRAW_STRING:
g2.drawString( line, 0, 0 );
break;
case DRAW_CHARS:
g2.drawChars( line.toCharArray(), 0, line.length(), 0, 0 );
break;
case DRAW_BYTES:
try {
byte lineBytes[] = line.getBytes( "ISO-8859-1" );
g2.drawBytes( lineBytes, 0, lineBytes.length, 0, 0 );
}
catch ( Exception e ) {
e.printStackTrace();
}
break;
case DRAW_GLYPHV:
GlyphVector gv =
testFont.createGlyphVector( g2.getFontRenderContext(), line );
g2.drawGlyphVector( gv, (float) 0, (float) 0 );
break;
case TL_DRAW:
TextLayout tl = new TextLayout( line, testFont,
g2.getFontRenderContext() );
tl.draw( g2, (float) 0, (float) 0 );
break;
case GV_OUTLINE:
GlyphVector gvo =
testFont.createGlyphVector( g2.getFontRenderContext(), line );
g2.draw( gvo.getOutline( (float) 0, (float) 0 ));
break;
case TL_OUTLINE:
TextLayout tlo =
new TextLayout( line, testFont,
g2.getFontRenderContext() );
AffineTransform at = new AffineTransform();
g2.draw( tlo.getOutline( at ));
}
/// ABP - restore old tform
g2.setTransform ( oldTx );
}
private void modeSpecificDrawLine( Graphics2D g2, String line,
int baseX, int baseY ) {
/// ABP - keep track of old tform, restore it later
AffineTransform oldTx = null;
oldTx = g2.getTransform();
g2.translate( baseX, baseY );
g2.transform( getAffineTransform( g2Transform ) );
switch ( drawMethod ) {
case DRAW_STRING:
g2.drawString( line, 0, 0 );
break;
case DRAW_CHARS:
g2.drawChars( line.toCharArray(), 0, line.length(), 0, 0 );
break;
case DRAW_BYTES:
try {
byte lineBytes[] = line.getBytes( "ISO-8859-1" );
g2.drawBytes( lineBytes, 0, lineBytes.length, 0, 0 );
}
catch ( Exception e ) {
e.printStackTrace();
}
break;
case DRAW_GLYPHV:
GlyphVector gv =
testFont.createGlyphVector( g2.getFontRenderContext(), line );
g2.drawGlyphVector( gv, (float) 0, (float) 0 );
break;
case TL_DRAW:
TextLayout tl = new TextLayout( line, testFont,
g2.getFontRenderContext() );
tl.draw( g2, (float) 0, (float) 0 );
break;
case GV_OUTLINE:
GlyphVector gvo =
testFont.createGlyphVector( g2.getFontRenderContext(), line );
g2.draw( gvo.getOutline( (float) 0, (float) 0 ));
break;
case TL_OUTLINE:
TextLayout tlo =
new TextLayout( line, testFont,
g2.getFontRenderContext() );
AffineTransform at = new AffineTransform();
g2.draw( tlo.getOutline( at ));
}
/// ABP - restore old tform
g2.setTransform ( oldTx );
}