--- old/src/share/classes/sun/java2d/SunGraphics2D.java 2014-05-13 21:17:48.000000000 +0400 +++ new/src/share/classes/sun/java2d/SunGraphics2D.java 2014-05-13 21:17:48.000000000 +0400 @@ -95,6 +95,7 @@ import java.lang.annotation.Native; import sun.awt.image.MultiResolutionImage; +import sun.awt.image.OffScreenImage; import static java.awt.geom.AffineTransform.TYPE_FLIP; import static java.awt.geom.AffineTransform.TYPE_MASK_SCALE; @@ -2108,12 +2109,12 @@ if (theData.copyArea(this, x, y, w, h, dx, dy)) { return; } - if (transformState >= TRANSFORM_TRANSLATESCALE) { + if (transformState > TRANSFORM_TRANSLATESCALE) { throw new InternalError("transformed copyArea not implemented yet"); } // REMIND: This method does not deal with missing data from the // source object (i.e. it does not send exposure events...) - + Region clip = getCompClip(); Composite comp = composite; @@ -2129,9 +2130,26 @@ lastCAcomp = comp; } - x += transX; - y += transY; + double[] coords = {x, y, x + w, y + h, x + dx, y + dy}; + transform.transform(coords, 0, coords, 0, 3); + x = (int)Math.ceil(coords[0] - 0.5); + y = (int)Math.ceil(coords[1] - 0.5); + w = ((int)Math.ceil(coords[2] - 0.5)) - x; + h = ((int)Math.ceil(coords[3] - 0.5)) - y; + dx = ((int)Math.ceil(coords[4] - 0.5)) - x; + dy = ((int)Math.ceil(coords[5] - 0.5)) - y; + + // In case of negative scale transform, reflect the rect coords. + if (w < 0) { + w *= -1; + x -= w; + } + if (h < 0) { + h *= -1; + y -= h; + } + Blit ob = lastCAblit; if (dy == 0 && dx > 0 && dx < w) { while (w > 0) { @@ -3073,6 +3091,11 @@ // end of text rendering methods private boolean isHiDPIImage(final Image img) { + if (img instanceof OffScreenImage && + !((OffScreenImage)img).isReturnLayoutSize()) + { + return false; + } return (SurfaceManager.getImageScale(img) != 1) || (resolutionVariantHint != SunHints.INTVAL_RESOLUTION_VARIANT_OFF && img instanceof MultiResolutionImage); @@ -3191,6 +3214,35 @@ return resolutionVariant; } + private boolean drawHiDPIImage(BufferedImage img, BufferedImageOp op, + int x, int y) + { + final int scale = SurfaceManager.getImageScale(img); + if (op != null) { + if (op instanceof AffineTransformOp) { + AffineTransformOp atop = (AffineTransformOp)op; + AffineTransform at = atop.getTransform(); + try { + // The "atop" transform may move the bounding rect of the image, + // so the scale transform should be applied before. + at.concatenate(AffineTransform.getScaleInstance(scale, scale).createInverse()); + } catch (Exception e) { + // the inverse is always possible + } + atop = new AffineTransformOp(at, atop.getInterpolationType()); + imagepipe.transformImage(this, img, atop, x, y); + return true; + } + img = op.filter(img, null); + } + int w = img.getWidth(); + int h = img.getHeight(); + return drawHiDPIImage(img, + x, y, x + w, y + h, + 0, 0, w, h, + backgroundColor, null); + } + /** * Draws an image scaled to x,y,w,h in nonblocking mode with a * callback object. @@ -3468,7 +3520,10 @@ if (bImg == null) { return; } - + if (isHiDPIImage(bImg)) { + drawHiDPIImage(bImg, op, x, y); + return; + } try { imagepipe.transformImage(this, bImg, op, x, y); } catch (InvalidPipeException e) {