src/share/classes/sun/java2d/SunGraphics2D.java

Print this page

        

@@ -93,10 +93,11 @@
 import java.util.Iterator;
 import sun.misc.PerformanceLogger;
 
 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;
 import static java.awt.geom.AffineTransform.TYPE_TRANSLATION;
 import sun.awt.image.MultiResolutionToolkitImage;

@@ -2106,11 +2107,11 @@
         }
         SurfaceData theData = surfaceData;
         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...)
 

@@ -2127,12 +2128,29 @@
             }
             lastCAblit = Blit.locate(dsttype, comptype, dsttype);
             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) {
                 int partW = Math.min(w, dx);

@@ -3071,10 +3089,15 @@
         }
     }
 // 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);
     }
 

@@ -3189,10 +3212,39 @@
         }
 
         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.
      */
     public boolean drawImage(Image img, int x, int y, int width, int height,

@@ -3466,11 +3518,14 @@
                           int y)  {
 
         if (bImg == null) {
             return;
         }
-
+        if (isHiDPIImage(bImg)) {
+            drawHiDPIImage(bImg, op, x, y);
+            return;
+        }
         try {
             imagepipe.transformImage(this, bImg, op, x, y);
         } catch (InvalidPipeException e) {
             try {
                 revalidateAll();