Java Code Examples for java.awt.geom.AffineTransform#transform()
The following examples show how to use
java.awt.geom.AffineTransform#transform() .
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: Treeline.java From TrakEM2 with GNU General Public License v3.0 | 6 votes |
/** A list of calibrated radii, one per node in the path.*/ @Override protected List<Float> calibratedData() { final ArrayList<Float> data = new ArrayList<Float>(); final AffineTransform aff = new AffineTransform(Treeline.this.at); final Calibration cal = layer_set.getCalibration(); aff.preConcatenate(new AffineTransform(cal.pixelWidth, 0, 0, cal.pixelHeight, 0, 0)); final float[] fp = new float[4]; for (final Node<Float> nd : super.path) { final Float r = nd.getData(); if (null == r) data.add(null); fp[0] = nd.x; fp[1] = nd.y; fp[2] = nd.x + r.floatValue(); fp[3] = nd.y; aff.transform(fp, 0, fp, 0, 2); data.add((float)Math.sqrt(Math.pow(fp[2] - fp[0], 2) + Math.pow(fp[3] - fp[1], 2))); } return data; }
Example 2
Source File: GraphicsTests.java From hottub with GNU General Public License v2.0 | 6 votes |
public static Dimension scaleForTransform(AffineTransform at, Dimension dim) { int w = dim.width; int h = dim.height; Point2D.Double ptd = new Point2D.Double(0, 0); at.transform(ptd, ptd); double ox = ptd.getX(); double oy = ptd.getY(); if (ox < 0 || ox > w || oy < 0 || oy > h) { throw new InternalError("origin outside destination"); } double scalex = scaleForPoint(at, ox, oy, w, h, w, h); double scaley = scalex; scalex = Math.min(scaleForPoint(at, ox, oy, w, 0, w, h), scalex); scaley = Math.min(scaleForPoint(at, ox, oy, 0, h, w, h), scaley); if (scalex < 0 || scaley < 0) { throw new InternalError("could not fit dims to transform"); } return new Dimension((int) Math.floor(w * scalex), (int) Math.floor(h * scaley)); }
Example 3
Source File: GraphicsTests.java From jdk8u-jdk with GNU General Public License v2.0 | 6 votes |
public static Dimension scaleForTransform(AffineTransform at, Dimension dim) { int w = dim.width; int h = dim.height; Point2D.Double ptd = new Point2D.Double(0, 0); at.transform(ptd, ptd); double ox = ptd.getX(); double oy = ptd.getY(); if (ox < 0 || ox > w || oy < 0 || oy > h) { throw new InternalError("origin outside destination"); } double scalex = scaleForPoint(at, ox, oy, w, h, w, h); double scaley = scalex; scalex = Math.min(scaleForPoint(at, ox, oy, w, 0, w, h), scalex); scaley = Math.min(scaleForPoint(at, ox, oy, 0, h, w, h), scaley); if (scalex < 0 || scaley < 0) { throw new InternalError("could not fit dims to transform"); } return new Dimension((int) Math.floor(w * scalex), (int) Math.floor(h * scaley)); }
Example 4
Source File: StandardGlyphVector.java From hottub with GNU General Public License v2.0 | 6 votes |
/** * !!! not used currently, but might be by getPixelbounds? */ public void pixellate(FontRenderContext renderFRC, Point2D loc, Point pxResult) { if (renderFRC == null) { renderFRC = frc; } // it is a total pain that you have to copy the transform. AffineTransform at = renderFRC.getTransform(); at.transform(loc, loc); pxResult.x = (int)loc.getX(); // but must not behave oddly around zero pxResult.y = (int)loc.getY(); loc.setLocation(pxResult.x, pxResult.y); try { at.inverseTransform(loc, loc); } catch (NoninvertibleTransformException e) { throw new IllegalArgumentException("must be able to invert frc transform"); } }
Example 5
Source File: GraphicsTests.java From hottub with GNU General Public License v2.0 | 6 votes |
public static double scaleForPoint(AffineTransform at, double xorig, double yorig, double x, double y, int w, int h) { Point2D.Double ptd = new Point2D.Double(x, y); at.transform(ptd, ptd); x = ptd.getX(); y = ptd.getY(); double scale = 1.0; if (x < 0) { scale = Math.min(scale, xorig / (xorig - x)); } else if (x > w) { scale = Math.min(scale, (w - xorig) / (x - xorig)); } if (y < 0) { scale = Math.min(scale, yorig / (yorig - y)); } else if (y > h) { scale = Math.min(scale, (h - yorig) / (y - yorig)); } return scale; }
Example 6
Source File: EllipticGradientPaint.java From mars-sim with GNU General Public License v3.0 | 5 votes |
@Override public java.awt.PaintContext createContext(final ColorModel COLOR_MODEL, final Rectangle DEVICE_BOUNDS, final Rectangle2D USER_BOUNDS, final AffineTransform TRANSFORM, final RenderingHints RENDERING_HINTS) { final Point2D TRANSFORMED_CENTER = TRANSFORM.transform(CENTER, null); final Point2D TRANSFORMED_RADIUS_XY = TRANSFORM.deltaTransform(RADIUS_X_Y, null); return new OvalGradientContext(TRANSFORMED_CENTER, TRANSFORMED_RADIUS_XY, FRACTIONS, COLORS); }
Example 7
Source File: SwingXUtil.java From darklaf with MIT License | 5 votes |
public static <T extends JComponent> Point convertPointToParent(final Component source, final JXLayer<T> layer, final Point p) { if (layer != null && layer.getUI() instanceof TransformUI) { TransformUI ui = (TransformUI) layer.getUI(); Point pos = SwingUtilities.convertPoint(source, p, layer); AffineTransform transform = ui.getPreferredTransform(layer.getSize(), layer); transform.transform(pos, pos); return pos; } return SwingUtilities.convertPoint(source, p, source.getParent()); }
Example 8
Source File: SunGraphics2D.java From openjdk-jdk8u with GNU General Public License v2.0 | 5 votes |
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 9
Source File: SunGraphics2D.java From jdk8u-jdk with GNU General Public License v2.0 | 5 votes |
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 10
Source File: DrawImage.java From Bytecoder with Apache License 2.0 | 5 votes |
protected void transformImage(SunGraphics2D sg, Image img, AffineTransform tx, int interpType, int sx1, int sy1, int sx2, int sy2, Color bgColor) { // Transform 3 source corners by tx and analyze them // for simplified operations (Copy or Scale). Using // 3 points lets us analyze any kind of transform, // even transforms that involve very tiny amounts of // rotation or skew to see if they degenerate to a // simple scale or copy operation within the allowable // error bounds. // Note that we use (0,0,w,h) instead of (sx1,sy1,sx2,sy2) // because the transform is already translated such that // the origin is where sx1, sy1 should go. double[] coords = new double[6]; /* index: 0 1 2 3 4 5 */ /* coord: (0, 0), (w, h), (0, h) */ coords[2] = sx2 - sx1; coords[3] = coords[5] = sy2 - sy1; tx.transform(coords, 0, coords, 0, 3); // First test if the X coords of the transformed UL // and LL points match and that the Y coords of the // transformed LR and LL points also match. // If they do then it is a "rectilinear" transform and // tryCopyOrScale will make sure it is upright and // integer-based. if (Math.abs(coords[0] - coords[4]) < MAX_TX_ERROR && Math.abs(coords[3] - coords[5]) < MAX_TX_ERROR && tryCopyOrScale(sg, img, sx1, sy1, sx2, sy2, bgColor, interpType, coords)) { return; } renderImageXform(sg, img, tx, interpType, sx1, sy1, sx2, sy2, bgColor); }
Example 11
Source File: StandardGlyphVector.java From openjdk-8-source with GNU General Public License v2.0 | 5 votes |
/** * Ensure that the positions array exists and holds position data. * If the array is null, this allocates it and sets default positions. */ private void initPositions() { if (positions == null) { setFRCTX(); positions = new float[glyphs.length * 2 + 2]; Point2D.Float trackPt = null; float track = getTracking(font); if (track != 0) { track *= font.getSize2D(); trackPt = new Point2D.Float(track, 0); // advance delta } Point2D.Float pt = new Point2D.Float(0, 0); if (font.isTransformed()) { AffineTransform at = font.getTransform(); at.transform(pt, pt); positions[0] = pt.x; positions[1] = pt.y; if (trackPt != null) { at.deltaTransform(trackPt, trackPt); } } for (int i = 0, n = 2; i < glyphs.length; ++i, n += 2) { getGlyphStrike(i).addDefaultGlyphAdvance(glyphs[i], pt); if (trackPt != null) { pt.x += trackPt.x; pt.y += trackPt.y; } positions[n] = pt.x; positions[n+1] = pt.y; } } }
Example 12
Source File: WPathGraphics.java From openjdk-jdk9 with GNU General Public License v2.0 | 5 votes |
@Override protected void deviceFillRect(int x, int y, int width, int height, Color color) { /* * Transform to device coordinates */ AffineTransform deviceTransform = getTransform(); /* check if rotated or sheared */ int transformType = deviceTransform.getType(); boolean usePath = ((transformType & (AffineTransform.TYPE_GENERAL_ROTATION | AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0); if (usePath) { fill(new Rectangle2D.Float(x, y, width, height)); return; } Point2D.Float tlc_pos = new Point2D.Float(x, y); deviceTransform.transform(tlc_pos, tlc_pos); Point2D.Float brc_pos = new Point2D.Float(x+width, y+height); deviceTransform.transform(brc_pos, brc_pos); float deviceWidth = (float) (brc_pos.getX() - tlc_pos.getX()); float deviceHeight = (float)(brc_pos.getY() - tlc_pos.getY()); WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob(); wPrinterJob.fillRect((float)tlc_pos.getX(), (float)tlc_pos.getY(), deviceWidth, deviceHeight, color); }
Example 13
Source File: FruchtermanReingoldLayout.java From netbeans with Apache License 2.0 | 5 votes |
private void relayoutNonFixed(NodeWidget w) { Point masterPoint = new Point(); masterPoint.setLocation(w.locX, w.locY); double r; double theta; double thetaStep = Math.PI / 5; r = 30; theta = 0; w.setFixed(false); while (true) { AffineTransform tr = AffineTransform.getRotateInstance(theta); Point2D d2point = tr.transform(new Point2D.Double(0, r), null); Point point = new Point((int)d2point.getX() + masterPoint.x, (int)d2point.getY() + masterPoint.y); w.locX = point.getX(); w.locY = point.getY(); if (isThereFreeSpaceNonFixedSpace(w)) { w.setFixed(true); return; } theta = theta + thetaStep; if (theta > (Math.PI * 2 - Math.PI / 10)) { r = r + 30; theta = theta - Math.PI * 2; thetaStep = thetaStep * 3 / 4; } } }
Example 14
Source File: ImageUtils.java From Pdf2Dom with GNU Lesser General Public License v3.0 | 5 votes |
public static BufferedImage rotateImage(BufferedImage image, double theta) { int degrees = (int) Math.abs(Math.toDegrees(theta)); double xCenter = image.getWidth() / 2; double yCenter = image.getHeight() / 2; AffineTransform rotateTransform = AffineTransform.getRotateInstance(-theta, xCenter, yCenter); // Translation adjustments so image still centered after rotate width/height changes if (image.getHeight() != image.getWidth() && degrees != 180 && degrees != 0) { Point2D origin = new Point2D.Double(0.0, 0.0); origin = rotateTransform.transform(origin, null); double yTranslate = origin.getY(); Point2D yMax = new Point2D.Double(0, image.getHeight()); yMax = rotateTransform.transform(yMax, null); double xTranslate = yMax.getX(); AffineTransform translationAdjustment = AffineTransform.getTranslateInstance(-xTranslate, -yTranslate); rotateTransform.preConcatenate(translationAdjustment); } AffineTransformOp op = new AffineTransformOp(rotateTransform, AffineTransformOp.TYPE_BILINEAR); // Have to recopy image because of JDK bug #4723021, AffineTransformationOp throwing exception sometimes image = copyImage(image, BufferedImage.TYPE_INT_ARGB); // Need to create filter dest image ourselves since AffineTransformOp's own dest image creation // throws exceptions in some cases. Rectangle bounds = op.getBounds2D(image).getBounds(); BufferedImage finalImage = new BufferedImage((int) bounds.getWidth(), (int) bounds.getHeight(), BufferedImage.TYPE_INT_ARGB); return op.filter(image, finalImage); }
Example 15
Source File: WPathGraphics.java From jdk8u-dev-jdk with GNU General Public License v2.0 | 4 votes |
/** * Draw the bounding rectangle using transformed coordinates. */ @Override protected void deviceFrameRect(int x, int y, int width, int height, Color color) { AffineTransform deviceTransform = getTransform(); /* check if rotated or sheared */ int transformType = deviceTransform.getType(); boolean usePath = ((transformType & (AffineTransform.TYPE_GENERAL_ROTATION | AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0); if (usePath) { draw(new Rectangle2D.Float(x, y, width, height)); return; } Stroke stroke = getStroke(); if (stroke instanceof BasicStroke) { BasicStroke lineStroke = (BasicStroke) stroke; int endCap = lineStroke.getEndCap(); int lineJoin = lineStroke.getLineJoin(); /* check for default style and try to optimize it by * calling the frameRect native function instead of using paths. */ if ((endCap == BasicStroke.CAP_SQUARE) && (lineJoin == BasicStroke.JOIN_MITER) && (lineStroke.getMiterLimit() ==10.0f)) { float lineWidth = lineStroke.getLineWidth(); Point2D.Float penSize = new Point2D.Float(lineWidth, lineWidth); deviceTransform.deltaTransform(penSize, penSize); float deviceLineWidth = Math.min(Math.abs(penSize.x), Math.abs(penSize.y)); /* transform upper left coordinate */ Point2D.Float ul_pos = new Point2D.Float(x, y); deviceTransform.transform(ul_pos, ul_pos); /* transform lower right coordinate */ Point2D.Float lr_pos = new Point2D.Float(x + width, y + height); deviceTransform.transform(lr_pos, lr_pos); float w = (float) (lr_pos.getX() - ul_pos.getX()); float h = (float)(lr_pos.getY() - ul_pos.getY()); WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob(); /* use selectStylePen, if supported */ if (wPrinterJob.selectStylePen(endCap, lineJoin, deviceLineWidth, color) == true) { wPrinterJob.frameRect((float)ul_pos.getX(), (float)ul_pos.getY(), w, h); } /* not supported, must be a Win 9x */ else { double lowerRes = Math.min(wPrinterJob.getXRes(), wPrinterJob.getYRes()); if ((deviceLineWidth/lowerRes) < MAX_THINLINE_INCHES) { /* use the default pen styles for thin pens. */ wPrinterJob.selectPen(deviceLineWidth, color); wPrinterJob.frameRect((float)ul_pos.getX(), (float)ul_pos.getY(), w, h); } else { draw(new Rectangle2D.Float(x, y, width, height)); } } } else { draw(new Rectangle2D.Float(x, y, width, height)); } } }
Example 16
Source File: WPathGraphics.java From openjdk-jdk8u-backup with GNU General Public License v2.0 | 4 votes |
/** * Draw a line using a pen created using the specified color * and current stroke properties. */ @Override protected void deviceDrawLine(int xBegin, int yBegin, int xEnd, int yEnd, Color color) { Stroke stroke = getStroke(); if (stroke instanceof BasicStroke) { BasicStroke lineStroke = (BasicStroke) stroke; if (lineStroke.getDashArray() != null) { draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd)); return; } float lineWidth = lineStroke.getLineWidth(); Point2D.Float penSize = new Point2D.Float(lineWidth, lineWidth); AffineTransform deviceTransform = getTransform(); deviceTransform.deltaTransform(penSize, penSize); float deviceLineWidth = Math.min(Math.abs(penSize.x), Math.abs(penSize.y)); Point2D.Float begin_pos = new Point2D.Float(xBegin, yBegin); deviceTransform.transform(begin_pos, begin_pos); Point2D.Float end_pos = new Point2D.Float(xEnd, yEnd); deviceTransform.transform(end_pos, end_pos); int endCap = lineStroke.getEndCap(); int lineJoin = lineStroke.getLineJoin(); /* check if it's a one-pixel line */ if ((end_pos.getX() == begin_pos.getX()) && (end_pos.getY() == begin_pos.getY())) { /* endCap other than Round will not print! * due to Windows GDI limitation, force it to CAP_ROUND */ endCap = BasicStroke.CAP_ROUND; } WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob(); /* call native function that creates pen with style */ if (wPrinterJob.selectStylePen(endCap, lineJoin, deviceLineWidth, color)) { wPrinterJob.moveTo((float)begin_pos.getX(), (float)begin_pos.getY()); wPrinterJob.lineTo((float)end_pos.getX(), (float)end_pos.getY()); } /* selectStylePen is not supported, must be Win 9X */ else { /* let's see if we can use a a default pen * if it's round end (Windows' default style) * or it's vertical/horizontal * or stroke is too thin. */ double lowerRes = Math.min(wPrinterJob.getXRes(), wPrinterJob.getYRes()); if ((endCap == BasicStroke.CAP_ROUND) || (((xBegin == xEnd) || (yBegin == yEnd)) && (deviceLineWidth/lowerRes < MAX_THINLINE_INCHES))) { wPrinterJob.selectPen(deviceLineWidth, color); wPrinterJob.moveTo((float)begin_pos.getX(), (float)begin_pos.getY()); wPrinterJob.lineTo((float)end_pos.getX(), (float)end_pos.getY()); } else { draw(new Line2D.Float(xBegin, yBegin, xEnd, yEnd)); } } } }
Example 17
Source File: StandardGlyphVector.java From dragonwell8_jdk with GNU General Public License v2.0 | 4 votes |
/** * The strike cache works like this. * * -Each glyph is thought of as having a transform, usually identity. * -Each request for a strike is based on a device transform, either the * one in the frc or the rendering transform. * -For general info, strikes are held with soft references. * -When rendering, strikes must be held with hard references for the * duration of the rendering call. GlyphList will have to hold this * info along with the image and position info, but toss the strike info * when done. * -Build the strike cache as needed. If the dev transform we want to use * has changed from the last time it is built, the cache is flushed by * the caller before these methods are called. * * Use a tx that doesn't include translation components of dst tx. */ Object setupGlyphImages(long[] images, float[] positions, AffineTransform tx) { int len = sgv.glyphs.length; GlyphStrike[] sl = getAllStrikes(); for (int i = 0; i < len; ++i) { GlyphStrike gs = sl[indices[i]]; int glyphID = sgv.glyphs[i]; images[i] = gs.strike.getGlyphImagePtr(glyphID); gs.getGlyphPosition(glyphID, i*2, sgv.positions, positions); } tx.transform(positions, 0, positions, 0, len); return sl; }
Example 18
Source File: WPathGraphics.java From openjdk-jdk9 with GNU General Public License v2.0 | 4 votes |
/** * Draw the bounding rectangle using transformed coordinates. */ @Override protected void deviceFrameRect(int x, int y, int width, int height, Color color) { AffineTransform deviceTransform = getTransform(); /* check if rotated or sheared */ int transformType = deviceTransform.getType(); boolean usePath = ((transformType & (AffineTransform.TYPE_GENERAL_ROTATION | AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0); if (usePath) { draw(new Rectangle2D.Float(x, y, width, height)); return; } Stroke stroke = getStroke(); if (stroke instanceof BasicStroke) { BasicStroke lineStroke = (BasicStroke) stroke; int endCap = lineStroke.getEndCap(); int lineJoin = lineStroke.getLineJoin(); /* check for default style and try to optimize it by * calling the frameRect native function instead of using paths. */ if ((endCap == BasicStroke.CAP_SQUARE) && (lineJoin == BasicStroke.JOIN_MITER) && (lineStroke.getMiterLimit() ==10.0f)) { float lineWidth = lineStroke.getLineWidth(); Point2D.Float penSize = new Point2D.Float(lineWidth, lineWidth); deviceTransform.deltaTransform(penSize, penSize); float deviceLineWidth = Math.min(Math.abs(penSize.x), Math.abs(penSize.y)); /* transform upper left coordinate */ Point2D.Float ul_pos = new Point2D.Float(x, y); deviceTransform.transform(ul_pos, ul_pos); /* transform lower right coordinate */ Point2D.Float lr_pos = new Point2D.Float(x + width, y + height); deviceTransform.transform(lr_pos, lr_pos); float w = (float) (lr_pos.getX() - ul_pos.getX()); float h = (float)(lr_pos.getY() - ul_pos.getY()); WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob(); /* use selectStylePen, if supported */ if (wPrinterJob.selectStylePen(endCap, lineJoin, deviceLineWidth, color) == true) { wPrinterJob.frameRect((float)ul_pos.getX(), (float)ul_pos.getY(), w, h); } /* not supported, must be a Win 9x */ else { double lowerRes = Math.min(wPrinterJob.getXRes(), wPrinterJob.getYRes()); if ((deviceLineWidth/lowerRes) < MAX_THINLINE_INCHES) { /* use the default pen styles for thin pens. */ wPrinterJob.selectPen(deviceLineWidth, color); wPrinterJob.frameRect((float)ul_pos.getX(), (float)ul_pos.getY(), w, h); } else { draw(new Rectangle2D.Float(x, y, width, height)); } } } else { draw(new Rectangle2D.Float(x, y, width, height)); } } }
Example 19
Source File: GlyphLayout.java From openjdk-8-source with GNU General Public License v2.0 | 4 votes |
public void adjustPositions(AffineTransform invdtx) { invdtx.transform(_positions, 0, _positions, 0, _count); }
Example 20
Source File: BufferedPaints.java From jdk8u-jdk with GNU General Public License v2.0 | 4 votes |
/** * This method calculates six m** values and a focusX value that * are used by the native fragment shader. These techniques are * based on a whitepaper by Daniel Rice on radial gradient performance * (attached to the bug report for 6521533). One can refer to that * document for the complete set of formulas and calculations, but * the basic goal is to compose a transform that will convert an * (x,y) position in device space into a "u" value that represents * the relative distance to the gradient focus point. The resulting * value can be used to look up the appropriate color by linearly * interpolating between the two nearest colors in the gradient. */ private static void setRadialGradientPaint(RenderQueue rq, SunGraphics2D sg2d, RadialGradientPaint paint, boolean useMask) { boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB); int cycleMethod = paint.getCycleMethod().ordinal(); float[] fractions = paint.getFractions(); Color[] colors = paint.getColors(); int numStops = colors.length; int[] pixels = convertToIntArgbPrePixels(colors, linear); Point2D center = paint.getCenterPoint(); Point2D focus = paint.getFocusPoint(); float radius = paint.getRadius(); // save original (untransformed) center and focus points double cx = center.getX(); double cy = center.getY(); double fx = focus.getX(); double fy = focus.getY(); // transform from gradient coords to device coords AffineTransform at = paint.getTransform(); at.preConcatenate(sg2d.transform); focus = at.transform(focus, focus); // transform unit circle to gradient coords; we start with the // unit circle (center=(0,0), focus on positive x-axis, radius=1) // and then transform into gradient space at.translate(cx, cy); at.rotate(fx - cx, fy - cy); at.scale(radius, radius); // invert to get mapping from device coords to unit circle try { at.invert(); } catch (Exception e) { at.setToScale(0.0, 0.0); } focus = at.transform(focus, focus); // clamp the focus point so that it does not rest on, or outside // of, the circumference of the gradient circle fx = Math.min(focus.getX(), 0.99); // assert rq.lock.isHeldByCurrentThread(); rq.ensureCapacity(20 + 28 + (numStops*4*2)); RenderBuffer buf = rq.getBuffer(); buf.putInt(SET_RADIAL_GRADIENT_PAINT); buf.putInt(useMask ? 1 : 0); buf.putInt(linear ? 1 : 0); buf.putInt(numStops); buf.putInt(cycleMethod); buf.putFloat((float)at.getScaleX()); buf.putFloat((float)at.getShearX()); buf.putFloat((float)at.getTranslateX()); buf.putFloat((float)at.getShearY()); buf.putFloat((float)at.getScaleY()); buf.putFloat((float)at.getTranslateY()); buf.putFloat((float)fx); buf.put(fractions); buf.put(pixels); }