--- old/src/java.desktop/share/classes/java/awt/Robot.java 2017-02-08 13:46:52.049859000 +0530
+++ new/src/java.desktop/share/classes/java/awt/Robot.java 2017-02-08 13:46:51.813859000 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,9 @@
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BaseMultiResolutionImage;
+import java.awt.image.MultiResolutionImage;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.image.DirectColorModel;
@@ -390,6 +393,11 @@
* @return Color of the pixel
*/
public synchronized Color getPixelColor(int x, int y) {
+ AffineTransform tx = GraphicsEnvironment.
+ getLocalGraphicsEnvironment().getDefaultScreenDevice().
+ getDefaultConfiguration().getDefaultTransform();
+ x = (int) (x * tx.getScaleX());
+ y = (int) (y * tx.getScaleY());
Color color = new Color(peer.getRGBPixel(x, y));
return color;
}
@@ -405,13 +413,56 @@
* @see AWTPermission
*/
public synchronized BufferedImage createScreenCapture(Rectangle screenRect) {
+ return createCompatibleImage(screenRect, false)[0];
+ }
+
+ /**
+ * Creates an image containing pixels read from the screen.
+ * This image does not include the mouse cursor.
+ * This method should be used in case where there is a scaling transform
+ * from user space to screen (device) space.
+ * Typically this means that the display is a high resolution screen,
+ * although strictly it means any case in which there is such a transform.
+ * Returns a {@link java.awt.image.MultiResolutionImage}.
+ *
+ * For a non-scaled display, the {@code MultiResolutionImage}
+ * will have one image variant:
+ *
+ * - Base Image with user specified size.
+ *
+ *
+ * For a high resolution display where there is scaling transform,
+ * the {@code MultiResolutionImage} will have two image variants:
+ *
+ * - Base Image with user specified size. This is scaled from the screen.
+ *
- Native device resolution image with device size pixels.
+ *
+ * @param screenRect Rect to capture in screen coordinates
+ * @return The captured image
+ * @throws IllegalArgumentException if {@code screenRect} width and height are not greater than zero
+ * @throws SecurityException if {@code readDisplayPixels} permission is not granted
+ * @see SecurityManager#checkPermission
+ * @see AWTPermission
+ */
+ public synchronized MultiResolutionImage
+ createMultiResolutionScreenCapture(Rectangle screenRect) {
+
+ return new BaseMultiResolutionImage(
+ createCompatibleImage(screenRect, true));
+ }
+
+ private synchronized BufferedImage[]
+ createCompatibleImage(Rectangle screenRect, boolean isHiDPI) {
+
checkScreenCaptureAllowed();
checkValidRect(screenRect);
- BufferedImage image;
+ BufferedImage lowResolutionImage;
+ BufferedImage highResolutionImage;
DataBufferInt buffer;
WritableRaster raster;
+ BufferedImage[] imageArray;
if (screenCapCM == null) {
/*
@@ -421,31 +472,92 @@
*/
screenCapCM = new DirectColorModel(24,
- /* red mask */ 0x00FF0000,
- /* green mask */ 0x0000FF00,
- /* blue mask */ 0x000000FF);
+ /* red mask */ 0x00FF0000,
+ /* green mask */ 0x0000FF00,
+ /* blue mask */ 0x000000FF);
}
+ int[] bandmasks = new int[3];
+ bandmasks[0] = screenCapCM.getRedMask();
+ bandmasks[1] = screenCapCM.getGreenMask();
+ bandmasks[2] = screenCapCM.getBlueMask();
+
// need to sync the toolkit prior to grabbing the pixels since in some
// cases rendering to the screen may be delayed
Toolkit.getDefaultToolkit().sync();
-
+ AffineTransform tx = GraphicsEnvironment.
+ getLocalGraphicsEnvironment().getDefaultScreenDevice().
+ getDefaultConfiguration().getDefaultTransform();
+ double uiScaleX = tx.getScaleX();
+ double uiScaleY = tx.getScaleY();
int pixels[];
- int[] bandmasks = new int[3];
- pixels = peer.getRGBPixels(screenRect);
- buffer = new DataBufferInt(pixels, pixels.length);
+ if (uiScaleX == 1 && uiScaleY == 1) {
- bandmasks[0] = screenCapCM.getRedMask();
- bandmasks[1] = screenCapCM.getGreenMask();
- bandmasks[2] = screenCapCM.getBlueMask();
+ pixels = peer.getRGBPixels(screenRect);
+ buffer = new DataBufferInt(pixels, pixels.length);
- raster = Raster.createPackedRaster(buffer, screenRect.width, screenRect.height, screenRect.width, bandmasks, null);
- SunWritableRaster.makeTrackable(buffer);
+ bandmasks[0] = screenCapCM.getRedMask();
+ bandmasks[1] = screenCapCM.getGreenMask();
+ bandmasks[2] = screenCapCM.getBlueMask();
+
+ raster = Raster.createPackedRaster(buffer, screenRect.width,
+ screenRect.height, screenRect.width, bandmasks, null);
+ SunWritableRaster.makeTrackable(buffer);
+
+ highResolutionImage = new BufferedImage(screenCapCM, raster,
+ false, null);
+ imageArray = new BufferedImage[1];
+ imageArray[0] = highResolutionImage;
+
+ } else {
+
+ int sX = (int) Math.floor(screenRect.x * uiScaleX);
+ int sY = (int) Math.floor(screenRect.y * uiScaleY);
+ int sWidth = (int) Math.ceil(screenRect.width * uiScaleX);
+ int sHeight = (int) Math.ceil(screenRect.height * uiScaleY);
+ int temppixels[];
+ Rectangle scaledRect = new Rectangle(sX, sY, sWidth, sHeight);
+ temppixels = peer.getRGBPixels(scaledRect);
+
+ // HighResolutionImage
+ pixels = temppixels;
+ buffer = new DataBufferInt(pixels, pixels.length);
+ raster = Raster.createPackedRaster(buffer, scaledRect.width,
+ scaledRect.height, scaledRect.width, bandmasks, null);
+ SunWritableRaster.makeTrackable(buffer);
+
+ highResolutionImage = new BufferedImage(screenCapCM, raster,
+ false, null);
+
+
+ // LowResolutionImage
+ lowResolutionImage = new BufferedImage(screenRect.width,
+ screenRect.height, highResolutionImage.getType());
+ Graphics2D g = lowResolutionImage.createGraphics();
+ g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+ RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+ g.setRenderingHint(RenderingHints.KEY_RENDERING,
+ RenderingHints.VALUE_RENDER_QUALITY);
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g.drawImage(highResolutionImage, 0, 0,
+ screenRect.width, screenRect.height,
+ 0, 0, scaledRect.width, scaledRect.height, null);
+ g.dispose();
+
+ if(!isHiDPI) {
+ imageArray = new BufferedImage[1];
+ imageArray[0] = lowResolutionImage;
+ } else {
+ imageArray = new BufferedImage[2];
+ imageArray[0] = lowResolutionImage;
+ imageArray[1] = highResolutionImage;
+ }
- image = new BufferedImage(screenCapCM, raster, false, null);
+ }
- return image;
+ return imageArray;
}
private static void checkValidRect(Rectangle rect) {