Java Code Examples for java.awt.geom.AffineTransform#createTransformedShape()

The following examples show how to use java.awt.geom.AffineTransform#createTransformedShape() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SWTGraphics2D.java    From ccu-historian with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Returns <code>true</code> if the rectangle (in device space) intersects
 * with the shape (the interior, if <code>onStroke</code> is false, 
 * otherwise the stroked outline of the shape).
 * 
 * @param rect  a rectangle (in device space).
 * @param s the shape.
 * @param onStroke  test the stroked outline only?
 * 
 * @return A boolean. 
 */
@Override
public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
    AffineTransform transform = getTransform();
    Shape ts;
    if (onStroke) {
        Stroke stroke = getStroke();
        ts = transform.createTransformedShape(stroke.createStrokedShape(s));
    } else {
        ts = transform.createTransformedShape(s);
    }
    if (!rect.getBounds2D().intersects(ts.getBounds2D())) {
        return false;
    }
    Area a1 = new Area(rect);
    Area a2 = new Area(ts);
    a1.intersect(a2);
    return !a1.isEmpty();
}
 
Example 2
Source File: ZoomToLayerAction.java    From snap-desktop with GNU General Public License v3.0 6 votes vote down vote up
@Override
public void actionPerformed(ActionEvent e) {
    final ProductSceneView sceneView = SnapApp.getDefault().getSelectedProductSceneView();
    final Layer selectedLayer = sceneView.getSelectedLayer();
    Rectangle2D modelBounds = selectedLayer.getModelBounds();
    if (modelBounds != null) {
        final Viewport viewport = sceneView.getLayerCanvas().getViewport();
        final AffineTransform m2vTransform = viewport.getModelToViewTransform();
        final AffineTransform v2mTransform = viewport.getViewToModelTransform();
        final Rectangle2D viewBounds = m2vTransform.createTransformedShape(modelBounds).getBounds2D();
        viewBounds.setFrameFromDiagonal(viewBounds.getMinX() - 10, viewBounds.getMinY() - 10,
                                        viewBounds.getMaxX() + 10, viewBounds.getMaxY() + 10);
        final Shape transformedModelBounds = v2mTransform.createTransformedShape(viewBounds);
        sceneView.zoom(transformedModelBounds.getBounds2D());
    }
}
 
Example 3
Source File: ShapeTransform.java    From pentaho-reporting with GNU Lesser General Public License v2.1 6 votes vote down vote up
/**
 * Scales a given shape. The shape is first normalized, then scaled and finally brought back into its original
 * position.
 *
 * @param shape
 *          the shape to be scaled
 * @param scaleX
 *          the horizontal scaling factor
 * @param scaleY
 *          the vertical scaling factor
 * @return the scaled shape
 */
private static Shape performDefaultTransformation( final Shape shape, final double scaleX, final double scaleY ) {
  /**
   * Apply the normalisation shape transform ... bring the shape to pos (0,0)
   */
  final Rectangle2D bounds = shape.getBounds2D();
  final AffineTransform translateTransform =
      AffineTransform.getTranslateInstance( 0 - bounds.getX(), 0 - bounds.getY() );
  // apply normalisation translation ...
  final Shape translatedShape = translateTransform.createTransformedShape( shape );

  final AffineTransform scaleTransform = AffineTransform.getScaleInstance( scaleX, scaleY );
  // apply scaling ...
  final Shape scaledShape = scaleTransform.createTransformedShape( translatedShape );

  // now retranslate the shape to its original position ...
  final AffineTransform translateBackTransform = AffineTransform.getTranslateInstance( bounds.getX(), bounds.getY() );
  return translateBackTransform.createTransformedShape( scaledShape );
}
 
Example 4
Source File: SWTGraphics2D.java    From openstock with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Returns <code>true</code> if the rectangle (in device space) intersects
 * with the shape (the interior, if <code>onStroke</code> is false, 
 * otherwise the stroked outline of the shape).
 * 
 * @param rect  a rectangle (in device space).
 * @param s the shape.
 * @param onStroke  test the stroked outline only?
 * 
 * @return A boolean. 
 */
@Override
public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
    AffineTransform transform = getTransform();
    Shape ts;
    if (onStroke) {
        Stroke stroke = getStroke();
        ts = transform.createTransformedShape(stroke.createStrokedShape(s));
    } else {
        ts = transform.createTransformedShape(s);
    }
    if (!rect.getBounds2D().intersects(ts.getBounds2D())) {
        return false;
    }
    Area a1 = new Area(rect);
    Area a2 = new Area(ts);
    a1.intersect(a2);
    return !a1.isEmpty();
}
 
Example 5
Source File: AbstractVisualVertexRenderer.java    From ghidra with Apache License 2.0 6 votes vote down vote up
protected void paintDropShadow(RenderContext<V, E> rc, GraphicsDecorator g, Shape shape) {

		if (!isScaledPastVertexInteractionThreshold(rc)) {
			return;
		}

		g.setColor(Color.GRAY);
		int grayOffset = 15;
		int blackOffset = 5;

		AffineTransform xform = AffineTransform.getTranslateInstance(grayOffset, grayOffset);
		Shape xShape = xform.createTransformedShape(shape);
		g.fill(xShape);
		g.setColor(Color.BLACK);
		AffineTransform xform2 = AffineTransform.getTranslateInstance(blackOffset, blackOffset);
		Shape xShape2 = xform2.createTransformedShape(shape);
		g.fill(xShape2);
	}
 
Example 6
Source File: SunGraphics2D.java    From jdk8u_jdk with GNU General Public License v2.0 5 votes vote down vote up
protected static Shape transformShape(AffineTransform tx, Shape clip) {
    if (clip == null) {
        return null;
    }

    if (clip instanceof Rectangle2D &&
        (tx.getType() & NON_RECTILINEAR_TRANSFORM_MASK) == 0)
    {
        Rectangle2D rect = (Rectangle2D) clip;
        double matrix[] = new double[4];
        matrix[0] = rect.getX();
        matrix[1] = rect.getY();
        matrix[2] = matrix[0] + rect.getWidth();
        matrix[3] = matrix[1] + rect.getHeight();
        tx.transform(matrix, 0, matrix, 0, 2);
        fixRectangleOrientation(matrix, rect);
        return new Rectangle2D.Double(matrix[0], matrix[1],
                                      matrix[2] - matrix[0],
                                      matrix[3] - matrix[1]);
    }

    if (tx.isIdentity()) {
        return cloneShape(clip);
    }

    return tx.createTransformedShape(clip);
}
 
Example 7
Source File: Chart_11_ShapeUtilities_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Creates and returns a translated shape.
 *
 * @param shape  the shape (<code>null</code> not permitted).
 * @param transX  the x translation (in Java2D space).
 * @param transY  the y translation (in Java2D space).
 *
 * @return The translated shape.
 */
public static Shape createTranslatedShape(Shape shape,
                                          double transX,
                                          double transY) {
    if (shape == null) {
        throw new IllegalArgumentException("Null 'shape' argument.");
    }
    AffineTransform transform = AffineTransform.getTranslateInstance(
            transX, transY);
    return transform.createTransformedShape(shape);
}
 
Example 8
Source File: AbstractShapeTransition2D.java    From pumpernickel with MIT License 5 votes vote down vote up
@Override
public Transition2DInstruction[] getInstructions(float progress,
		Dimension size) {
	Number multiplier = multipliers.get(size);
	if (multiplier == null) {
		multiplier = new Float(calculateMultiplier(size));
		multipliers.put(size, multiplier);
	}

	if (type == IN) {
		progress = 1 - progress;
	}

	Shape clipping = getShape();
	Rectangle2D r = ShapeBounds.getBounds(clipping);

	AffineTransform transform = new AffineTransform();

	transform.setToIdentity();

	transform.translate(size.width / 2, size.height / 2);
	transform.scale(progress * multiplier.floatValue(), progress
			* multiplier.floatValue());
	transform.translate(-size.width / 2, -size.height / 2);

	transform.translate(-r.getCenterX() + size.width / 2f, -r.getCenterY()
			+ size.height / 2f);

	clipping = transform.createTransformedShape(clipping);

	return new Transition2DInstruction[] {
			new ImageInstruction(type == OUT),
			new ImageInstruction(type != OUT, null, clipping) };
}
 
Example 9
Source File: Axis.java    From ECG-Viewer with GNU General Public License v2.0 5 votes vote down vote up
/**
 * 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;
}
 
Example 10
Source File: Axis.java    From ccu-historian with GNU General Public License v3.0 5 votes vote down vote up
/**
 * 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;
}
 
Example 11
Source File: PeekGraphics.java    From hottub with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Add the rectangle 'rect' to the area representing
 * the part of the page which is drawn into.
 */
private void addDrawingRect(Rectangle2D rect) {

    /*  For testing purposes the following line can be uncommented.
        When uncommented it causes the entire page to be rasterized
        thus eliminating errors caused by a faulty bounding box
        calculation.
    */
    //mDrawingArea.addInfinite();



    AffineTransform matrix = getTransform();

    Shape transShape = matrix.createTransformedShape(rect);

    Rectangle2D transRect = transShape.getBounds2D();

    mDrawingArea.add((float) transRect.getMinY(),
                     (float) transRect.getMaxY());


}
 
Example 12
Source File: IncorrectClipXorModeSW2Surface.java    From openjdk-jdk9 with GNU General Public License v2.0 4 votes vote down vote up
public static void main(final String[] args) throws IOException {
    GraphicsEnvironment ge = GraphicsEnvironment
            .getLocalGraphicsEnvironment();
    GraphicsConfiguration gc = ge.getDefaultScreenDevice()
                                 .getDefaultConfiguration();
    AffineTransform at;
    for (int size : SIZES) {
        at = AffineTransform.getScaleInstance(size, size);
        for (Shape clip : SHAPES) {
            clip = at.createTransformedShape(clip);
            for (Shape to : SHAPES) {
                to = at.createTransformedShape(to);
                // Prepare test images
                BufferedImage snapshot;
                BufferedImage bi = getBufferedImage(size);
                VolatileImage vi = getVolatileImage(gc, size);
                while (true) {
                    vi.validate(gc);
                    Graphics2D g2d = vi.createGraphics();
                    g2d.setColor(Color.GREEN);
                    g2d.fillRect(0, 0, size, size);
                    g2d.dispose();
                    if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
                        continue;
                    }
                    draw(clip, to, bi, vi);
                    snapshot = vi.getSnapshot();
                    if (vi.contentsLost()) {
                        continue;
                    }
                    break;
                }
                // Prepare gold images
                BufferedImage goldvi = getCompatibleImage(gc, size);
                BufferedImage goldbi = getBufferedImage(size);
                draw(clip, to, goldbi, goldvi);
                validate(snapshot, goldvi);
                vi.flush();
            }
        }
    }
}
 
Example 13
Source File: IncorrectClipXorModeSW2Surface.java    From openjdk-jdk8u with GNU General Public License v2.0 4 votes vote down vote up
public static void main(final String[] args) throws IOException {
    GraphicsEnvironment ge = GraphicsEnvironment
            .getLocalGraphicsEnvironment();
    GraphicsConfiguration gc = ge.getDefaultScreenDevice()
                                 .getDefaultConfiguration();
    AffineTransform at;
    for (int size : SIZES) {
        at = AffineTransform.getScaleInstance(size, size);
        for (Shape clip : SHAPES) {
            clip = at.createTransformedShape(clip);
            for (Shape to : SHAPES) {
                to = at.createTransformedShape(to);
                // Prepare test images
                BufferedImage snapshot;
                BufferedImage bi = getBufferedImage(size);
                VolatileImage vi = getVolatileImage(gc, size);
                while (true) {
                    vi.validate(gc);
                    Graphics2D g2d = vi.createGraphics();
                    g2d.setColor(Color.GREEN);
                    g2d.fillRect(0, 0, size, size);
                    g2d.dispose();
                    if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
                        continue;
                    }
                    draw(clip, to, bi, vi);
                    snapshot = vi.getSnapshot();
                    if (vi.contentsLost()) {
                        continue;
                    }
                    break;
                }
                // Prepare gold images
                BufferedImage goldvi = getCompatibleImage(gc, size);
                BufferedImage goldbi = getBufferedImage(size);
                draw(clip, to, goldbi, goldvi);
                validate(snapshot, goldvi);
                vi.flush();
            }
        }
    }
}
 
Example 14
Source File: IncorrectClipXorModeSW2Surface.java    From TencentKona-8 with GNU General Public License v2.0 4 votes vote down vote up
public static void main(final String[] args) throws IOException {
    GraphicsEnvironment ge = GraphicsEnvironment
            .getLocalGraphicsEnvironment();
    GraphicsConfiguration gc = ge.getDefaultScreenDevice()
                                 .getDefaultConfiguration();
    AffineTransform at;
    for (int size : SIZES) {
        at = AffineTransform.getScaleInstance(size, size);
        for (Shape clip : SHAPES) {
            clip = at.createTransformedShape(clip);
            for (Shape to : SHAPES) {
                to = at.createTransformedShape(to);
                // Prepare test images
                BufferedImage snapshot;
                BufferedImage bi = getBufferedImage(size);
                VolatileImage vi = getVolatileImage(gc, size);
                while (true) {
                    vi.validate(gc);
                    Graphics2D g2d = vi.createGraphics();
                    g2d.setColor(Color.GREEN);
                    g2d.fillRect(0, 0, size, size);
                    g2d.dispose();
                    if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
                        continue;
                    }
                    draw(clip, to, bi, vi);
                    snapshot = vi.getSnapshot();
                    if (vi.contentsLost()) {
                        continue;
                    }
                    break;
                }
                // Prepare gold images
                BufferedImage goldvi = getCompatibleImage(gc, size);
                BufferedImage goldbi = getBufferedImage(size);
                draw(clip, to, goldbi, goldvi);
                validate(snapshot, goldvi);
                vi.flush();
            }
        }
    }
}
 
Example 15
Source File: PageDrawer.java    From sambox with Apache License 2.0 4 votes vote down vote up
/**
 * Render the font using the Glyph2D interface.
 *
 * @param glyph2D the Glyph2D implementation provided a GeneralPath for each glyph
 * @param font the font
 * @param code character code
 * @param displacement the glyph's displacement (advance)
 * @param at the transformation
 * @throws IOException if something went wrong
 */
private void drawGlyph2D(Glyph2D glyph2D, PDFont font, int code, Vector displacement,
        AffineTransform at) throws IOException
{
    PDGraphicsState state = getGraphicsState();
    RenderingMode renderingMode = state.getTextState().getRenderingMode();

    GeneralPath path = glyph2D.getPathForCharacterCode(code);
    if (path != null)
    {
        // Stretch non-embedded glyph if it does not match the height/width contained in the PDF.
        // Vertical fonts have zero X displacement, so the following code scales to 0 if we don't skip it.
        // TODO: How should vertical fonts be handled?
        if (!font.isEmbedded() && !font.isVertical() && !font.isStandard14()
                && font.hasExplicitWidth(code))
        {
            float fontWidth = font.getWidthFromFont(code);
            if (fontWidth > 0 && // ignore spaces
                    Math.abs(fontWidth - displacement.getX() * 1000) > 0.0001)
            {
                float pdfWidth = displacement.getX() * 1000;
                at.scale(pdfWidth / fontWidth, 1);
            }
        }

        // render glyph
        Shape glyph = at.createTransformedShape(path);

        if (renderingMode.isFill())
        {
            graphics.setComposite(state.getNonStrokingJavaComposite());
            graphics.setPaint(getNonStrokingPaint());
            setClip();
            if (isContentRendered() && isTextContentRendered())
            {
                graphics.fill(glyph);
            }
        }

        if (renderingMode.isStroke())
        {
            graphics.setComposite(state.getStrokingJavaComposite());
            graphics.setPaint(getStrokingPaint());
            graphics.setStroke(getStroke());
            setClip();
            if (isContentRendered() && isTextContentRendered())
            {
                graphics.draw(glyph);
            }
        }

        if (renderingMode.isClip())
        {
            textClippings.add(glyph);
        }
    }
}
 
Example 16
Source File: TextClipErrorTest.java    From openjdk-jdk8u with GNU General Public License v2.0 4 votes vote down vote up
public static void main(String[] args) {
    Locale.setDefault(Locale.US);

    // initialize j.u.l Looger:
    final Logger log = Logger.getLogger("sun.java2d.marlin");
    log.addHandler(new Handler() {
        @Override
        public void publish(LogRecord record) {
            Throwable th = record.getThrown();
            // detect any Throwable:
            if (th != null) {
                System.out.println("Test failed:\n" + record.getMessage());
                th.printStackTrace(System.out);

                throw new RuntimeException("Test failed: ", th);
            }
        }

        @Override
        public void flush() {
        }

        @Override
        public void close() throws SecurityException {
        }
    });

    log.info("TextClipErrorTest: start");

    // enable Marlin logging & internal checks:
    System.setProperty("sun.java2d.renderer.log", "true");
    System.setProperty("sun.java2d.renderer.useLogger", "true");
    System.setProperty("sun.java2d.renderer.doChecks", "true");

    BufferedImage image = new BufferedImage(256, 256,
                                            BufferedImage.TYPE_INT_ARGB);

    Graphics2D g2d = image.createGraphics();
    g2d.setColor(Color.red);
    try {
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                             RenderingHints.VALUE_ANTIALIAS_ON);

        Font font = g2d.getFont();
        FontRenderContext frc = new FontRenderContext(
            new AffineTransform(), true, true);

        g2d.setStroke(new BasicStroke(4.0f,
                                      BasicStroke.CAP_ROUND,
                                      BasicStroke.JOIN_ROUND));

        final Shape badShape;
        if (SERIALIZE) {
            final GlyphVector gv1 = font.createGlyphVector(frc, "\u00d6");
            final Shape textShape = gv1.getOutline();

            final AffineTransform at1 = AffineTransform.getTranslateInstance(
                -2091202.554154681, 5548.601436981691);
            badShape = at1.createTransformedShape(textShape);
            serializeShape(badShape);
        } else {
            badShape = deserializeShape();
        }

        g2d.draw(badShape);

        // Draw anything within bounds and it fails:
        g2d.draw(new Line2D.Double(10, 20, 30, 40));

        if (SAVE_IMAGE) {
            final File file = new File("TextClipErrorTest.png");
            System.out.println("Writing file: " + file.getAbsolutePath());
            ImageIO.write(image, "PNG", file);
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    } finally {
        g2d.dispose();
        log.info("TextClipErrorTest: end");
    }
}
 
Example 17
Source File: PeekGraphics.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Add the rectangle 'rect' to the area representing
 * the part of the page which is drawn into.
 */
private void addDrawingRect(Rectangle2D rect) {

    /*  For testing purposes the following line can be uncommented.
        When uncommented it causes the entire page to be rasterized
        thus eliminating errors caused by a faulty bounding box
        calculation.
    */
    //mDrawingArea.addInfinite();



    AffineTransform matrix = getTransform();

    Shape transShape = matrix.createTransformedShape(rect);

    Rectangle2D transRect = transShape.getBounds2D();

    mDrawingArea.add((float) transRect.getMinY(),
                     (float) transRect.getMaxY());


}
 
Example 18
Source File: Chart_11_ShapeUtilities_t.java    From coming with MIT License 3 votes vote down vote up
/**
 * Rotates a shape about the specified coordinates.
 *
 * @param base  the shape (<code>null</code> permitted, returns
 *              <code>null</code>).
 * @param angle  the angle (in radians).
 * @param x  the x coordinate for the rotation point (in Java2D space).
 * @param y  the y coordinate for the rotation point (in Java2D space).
 *
 * @return the rotated shape.
 */
public static Shape rotateShape(Shape base, double angle,
                                float x, float y) {
    if (base == null) {
        return null;
    }
    AffineTransform rotate = AffineTransform.getRotateInstance(angle, x, y);
    Shape result = rotate.createTransformedShape(base);
    return result;
}
 
Example 19
Source File: ShapeGraphicAttribute.java    From Java8CN with Apache License 2.0 2 votes vote down vote up
/**
 * Return a {@link java.awt.Shape} that represents the region that
 * this <code>ShapeGraphicAttribute</code> renders.  This is used when a
 * {@link TextLayout} is requested to return the outline of the text.
 * The (untransformed) shape must not extend outside the rectangular
 * bounds returned by <code>getBounds</code>.
 * @param tx an optional {@link AffineTransform} to apply to the
 *   this <code>ShapeGraphicAttribute</code>. This can be null.
 * @return the <code>Shape</code> representing this graphic attribute,
 *   suitable for stroking or filling.
 * @since 1.6
 */
public Shape getOutline(AffineTransform tx) {
    return tx == null ? fShape : tx.createTransformedShape(fShape);
}
 
Example 20
Source File: GlyphVector.java    From JDKSourceCode1.8 with MIT License 2 votes vote down vote up
/**
 * Returns a <code>Shape</code> whose interior corresponds to the
 * visual representation of the specified glyph
 * within this <code>GlyphVector</code>, offset to x,&nbsp;y.
 * The outline returned by this method is positioned around the
 * origin of each individual glyph.
 * @param glyphIndex the index into this <code>GlyphVector</code>
 * @param x the X coordinate of the location of this {@code GlyphVector}
 * @param y the Y coordinate of the location of this {@code GlyphVector}
 * @return a <code>Shape</code> that is the outline of the glyph
 *   at the specified <code>glyphIndex</code> of this
 *   <code>GlyphVector</code> when rendered at the specified
 *   coordinates.
 * @throws IndexOutOfBoundsException if <code>glyphIndex</code>
 *   is less than 0 or greater than or equal to the number
 *   of glyphs in this <code>GlyphVector</code>
 * @since 1.4
 */
public Shape getGlyphOutline(int glyphIndex, float x, float y) {
    Shape s = getGlyphOutline(glyphIndex);
    AffineTransform at = AffineTransform.getTranslateInstance(x,y);
    return at.createTransformedShape(s);
    }