in batik-gvt/src/main/java/org/apache/batik/gvt/font/AWTGVTGlyphVector.java [834:966]
public void draw(Graphics2D graphics2D,
AttributedCharacterIterator aci) {
int numGlyphs = getNumGlyphs();
aci.first();
TextPaintInfo tpi = (TextPaintInfo)aci.getAttribute
(GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO);
if (tpi == null) return;
if (!tpi.visible) return;
Paint fillPaint = tpi.fillPaint;
Stroke stroke = tpi.strokeStroke;
Paint strokePaint = tpi.strokePaint;
if ((fillPaint == null) && ((strokePaint == null) ||
(stroke == null)))
return;
boolean useHinting = drawGlyphVectorWorks;
if (useHinting && (stroke != null) && (strokePaint != null))
// Can't stroke with drawGlyphVector.
useHinting = false;
if (useHinting &&
(fillPaint != null) && !(fillPaint instanceof Color))
// The coordinate system is different for drawGlyphVector.
// So complex paints aren't positioned properly.
useHinting = false;
if (useHinting) {
Object v1 = graphics2D.getRenderingHint
(RenderingHints.KEY_TEXT_ANTIALIASING);
Object v2 = graphics2D.getRenderingHint
(RenderingHints.KEY_STROKE_CONTROL);
// text-rendering = geometricPrecision so fill shapes.
if ((v1 == RenderingHints.VALUE_TEXT_ANTIALIAS_ON) &&
(v2 == RenderingHints.VALUE_STROKE_PURE))
useHinting = false;
}
final int typeGRot = AffineTransform.TYPE_GENERAL_ROTATION;
final int typeGTrans = AffineTransform.TYPE_GENERAL_TRANSFORM;
if (useHinting) {
// Check if usr->dev transform has general rotation,
// or shear..
AffineTransform at = graphics2D.getTransform();
int type = at.getType();
if (((type & typeGTrans) != 0) || ((type & typeGRot) != 0))
useHinting = false;
}
if (useHinting) {
for (int i=0; i<numGlyphs; i++) {
if (!glyphVisible[i]) {
useHinting = false;
break;
}
AffineTransform at = glyphTransforms[i];
if (at != null) {
int type = at.getType();
if ((type & ~AffineTransform.TYPE_TRANSLATION) == 0) {
// Just translation
} else if (glyphVectorTransformWorks &&
((type & typeGTrans) == 0) &&
((type & typeGRot) == 0)) {
// It's a simple 90Deg rotate, and we can put
// it into the GlyphVector.
} else {
// we can't (or it doesn't make sense
// to use the GlyphVector.
useHinting = false;
break;
}
}
}
}
if (useHinting) {
double sf = scaleFactor;
double [] mat = new double[6];
for (int i=0; i< numGlyphs; i++) {
Point2D pos = glyphPositions[i];
double x = pos.getX();
double y = pos.getY();
AffineTransform at = glyphTransforms[i];
if (at != null) {
// Scale the translate portion of matrix,
// and add it into the position.
at.getMatrix(mat);
x += mat[4];
y += mat[5];
if ((mat[0] != 1) || (mat[1] != 0) ||
(mat[2] != 0) || (mat[3] != 1)) {
// More than just translation.
mat[4] = 0; mat[5] = 0;
at = new AffineTransform(mat);
} else {
at = null;
}
}
pos = new Point2D.Double(x/sf, y/sf);
awtGlyphVector.setGlyphPosition(i, pos);
awtGlyphVector.setGlyphTransform(i, at);
}
graphics2D.scale(sf, sf);
graphics2D.setPaint(fillPaint);
graphics2D.drawGlyphVector(awtGlyphVector, 0.0f, 0.0f);
graphics2D.scale(1.0/sf, 1.0/sf);
for (int i=0; i< numGlyphs; i++) {
Point2D pos = defaultGlyphPositions[i];
awtGlyphVector.setGlyphPosition(i, pos);
awtGlyphVector.setGlyphTransform(i, null);
}
} else {
Shape outline = getOutline();
// check if we need to fill this glyph
if (fillPaint != null) {
graphics2D.setPaint(fillPaint);
graphics2D.fill(outline);
}
// check if we need to draw the outline of this glyph
if (stroke != null && strokePaint != null) {
graphics2D.setStroke(stroke);
graphics2D.setPaint(strokePaint);
graphics2D.draw(outline);
}
}
}