mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-01 03:30:34 +00:00
8073320: Windows HiDPI Graphics support
Reviewed-by: flar, serb
This commit is contained in:
parent
7b6f3bbed8
commit
a00e011325
@ -37,7 +37,7 @@
|
||||
<!-- Indicate JDK is high-dpi aware. -->
|
||||
<asmv3:application>
|
||||
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
|
||||
<dpiAware>true</dpiAware>
|
||||
<dpiAware>true/PM</dpiAware>
|
||||
</asmv3:windowsSettings>
|
||||
</asmv3:application>
|
||||
|
||||
|
||||
@ -166,7 +166,12 @@ public abstract class CGLSurfaceData extends OGLSurfaceData {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultScale() {
|
||||
public double getDefaultScaleX() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDefaultScaleY() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
|
||||
@ -1156,7 +1156,9 @@ public class LWWindowPeer
|
||||
&& !(dst instanceof NullSurfaceData)
|
||||
&& !(src instanceof NullSurfaceData)
|
||||
&& src.getSurfaceType().equals(dst.getSurfaceType())
|
||||
&& src.getDefaultScale() == dst.getDefaultScale()) {
|
||||
&& src.getDefaultScaleX() == dst.getDefaultScaleX()
|
||||
&& src.getDefaultScaleY() == dst.getDefaultScaleY())
|
||||
{
|
||||
final Rectangle size = src.getBounds();
|
||||
final Blit blit = Blit.locate(src.getSurfaceType(),
|
||||
CompositeType.Src,
|
||||
|
||||
@ -50,6 +50,8 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
BufferedImage bufImg;
|
||||
private BufferedImageGraphicsConfig graphicsConfig;
|
||||
RenderLoops solidloops;
|
||||
private final double scaleX;
|
||||
private final double scaleY;
|
||||
|
||||
private static native void initIDs(Class<?> ICM, Class<?> ICMColorData);
|
||||
|
||||
@ -73,6 +75,12 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
}
|
||||
|
||||
public static SurfaceData createData(BufferedImage bufImg) {
|
||||
return createData(bufImg, 1, 1);
|
||||
}
|
||||
|
||||
public static SurfaceData createData(BufferedImage bufImg,
|
||||
double scaleX, double scaleY)
|
||||
{
|
||||
if (bufImg == null) {
|
||||
throw new NullPointerException("BufferedImage cannot be null");
|
||||
}
|
||||
@ -82,31 +90,36 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
// REMIND: Check the image type and pick an appropriate subclass
|
||||
switch (type) {
|
||||
case BufferedImage.TYPE_INT_BGR:
|
||||
sData = createDataIC(bufImg, SurfaceType.IntBgr);
|
||||
sData = createDataIC(bufImg, SurfaceType.IntBgr, scaleX, scaleY);
|
||||
break;
|
||||
case BufferedImage.TYPE_INT_RGB:
|
||||
sData = createDataIC(bufImg, SurfaceType.IntRgb);
|
||||
sData = createDataIC(bufImg, SurfaceType.IntRgb, scaleX, scaleY);
|
||||
break;
|
||||
case BufferedImage.TYPE_INT_ARGB:
|
||||
sData = createDataIC(bufImg, SurfaceType.IntArgb);
|
||||
sData = createDataIC(bufImg, SurfaceType.IntArgb, scaleX, scaleY);
|
||||
break;
|
||||
case BufferedImage.TYPE_INT_ARGB_PRE:
|
||||
sData = createDataIC(bufImg, SurfaceType.IntArgbPre);
|
||||
sData = createDataIC(bufImg, SurfaceType.IntArgbPre, scaleX, scaleY);
|
||||
break;
|
||||
case BufferedImage.TYPE_3BYTE_BGR:
|
||||
sData = createDataBC(bufImg, SurfaceType.ThreeByteBgr, 2);
|
||||
sData = createDataBC(bufImg, SurfaceType.ThreeByteBgr, 2,
|
||||
scaleX, scaleY);
|
||||
break;
|
||||
case BufferedImage.TYPE_4BYTE_ABGR:
|
||||
sData = createDataBC(bufImg, SurfaceType.FourByteAbgr, 3);
|
||||
sData = createDataBC(bufImg, SurfaceType.FourByteAbgr, 3,
|
||||
scaleX, scaleY);
|
||||
break;
|
||||
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
|
||||
sData = createDataBC(bufImg, SurfaceType.FourByteAbgrPre, 3);
|
||||
sData = createDataBC(bufImg, SurfaceType.FourByteAbgrPre, 3,
|
||||
scaleX, scaleY);
|
||||
break;
|
||||
case BufferedImage.TYPE_USHORT_565_RGB:
|
||||
sData = createDataSC(bufImg, SurfaceType.Ushort565Rgb, null);
|
||||
sData = createDataSC(bufImg, SurfaceType.Ushort565Rgb, null,
|
||||
scaleX, scaleY);
|
||||
break;
|
||||
case BufferedImage.TYPE_USHORT_555_RGB:
|
||||
sData = createDataSC(bufImg, SurfaceType.Ushort555Rgb, null);
|
||||
sData = createDataSC(bufImg, SurfaceType.Ushort555Rgb, null,
|
||||
scaleX, scaleY);
|
||||
break;
|
||||
case BufferedImage.TYPE_BYTE_INDEXED:
|
||||
{
|
||||
@ -128,14 +141,16 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
default:
|
||||
throw new InternalError("Unrecognized transparency");
|
||||
}
|
||||
sData = createDataBC(bufImg, sType, 0);
|
||||
sData = createDataBC(bufImg, sType, 0, scaleX, scaleY);
|
||||
}
|
||||
break;
|
||||
case BufferedImage.TYPE_BYTE_GRAY:
|
||||
sData = createDataBC(bufImg, SurfaceType.ByteGray, 0);
|
||||
sData = createDataBC(bufImg, SurfaceType.ByteGray, 0,
|
||||
scaleX, scaleY);
|
||||
break;
|
||||
case BufferedImage.TYPE_USHORT_GRAY:
|
||||
sData = createDataSC(bufImg, SurfaceType.UshortGray, null);
|
||||
sData = createDataSC(bufImg, SurfaceType.UshortGray, null,
|
||||
scaleX, scaleY);
|
||||
break;
|
||||
case BufferedImage.TYPE_BYTE_BINARY:
|
||||
{
|
||||
@ -154,7 +169,7 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
default:
|
||||
throw new InternalError("Unrecognized pixel size");
|
||||
}
|
||||
sData = createDataBP(bufImg, sType);
|
||||
sData = createDataBP(bufImg, sType, scaleX, scaleY);
|
||||
}
|
||||
break;
|
||||
case BufferedImage.TYPE_CUSTOM:
|
||||
@ -191,7 +206,7 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
sType = SurfaceType.AnyDcm;
|
||||
}
|
||||
}
|
||||
sData = createDataIC(bufImg, sType);
|
||||
sData = createDataIC(bufImg, sType, scaleX, scaleY);
|
||||
break;
|
||||
} else if (raster instanceof ShortComponentRaster &&
|
||||
raster.getNumDataElements() == 1 &&
|
||||
@ -233,11 +248,12 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
icm = null;
|
||||
}
|
||||
}
|
||||
sData = createDataSC(bufImg, sType, icm);
|
||||
sData = createDataSC(bufImg, sType, icm, scaleX, scaleY);
|
||||
break;
|
||||
}
|
||||
sData = new BufImgSurfaceData(raster.getDataBuffer(),
|
||||
bufImg, SurfaceType.Custom);
|
||||
sData = new BufImgSurfaceData(raster.getDataBuffer(), bufImg,
|
||||
SurfaceType.Custom,
|
||||
scaleX, scaleY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -250,11 +266,15 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
}
|
||||
|
||||
public static SurfaceData createDataIC(BufferedImage bImg,
|
||||
SurfaceType sType) {
|
||||
SurfaceType sType,
|
||||
double scaleX,
|
||||
double scaleY)
|
||||
{
|
||||
IntegerComponentRaster icRaster =
|
||||
(IntegerComponentRaster)bImg.getRaster();
|
||||
BufImgSurfaceData bisd =
|
||||
new BufImgSurfaceData(icRaster.getDataBuffer(), bImg, sType);
|
||||
new BufImgSurfaceData(icRaster.getDataBuffer(), bImg, sType,
|
||||
scaleX, scaleY);
|
||||
bisd.initRaster(icRaster.getDataStorage(),
|
||||
icRaster.getDataOffset(0) * 4, 0,
|
||||
icRaster.getWidth(),
|
||||
@ -267,11 +287,14 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
|
||||
public static SurfaceData createDataSC(BufferedImage bImg,
|
||||
SurfaceType sType,
|
||||
IndexColorModel icm) {
|
||||
IndexColorModel icm,
|
||||
double scaleX, double scaleY)
|
||||
{
|
||||
ShortComponentRaster scRaster =
|
||||
(ShortComponentRaster)bImg.getRaster();
|
||||
BufImgSurfaceData bisd =
|
||||
new BufImgSurfaceData(scRaster.getDataBuffer(), bImg, sType);
|
||||
new BufImgSurfaceData(scRaster.getDataBuffer(), bImg, sType,
|
||||
scaleX, scaleY);
|
||||
bisd.initRaster(scRaster.getDataStorage(),
|
||||
scRaster.getDataOffset(0) * 2, 0,
|
||||
scRaster.getWidth(),
|
||||
@ -284,11 +307,14 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
|
||||
public static SurfaceData createDataBC(BufferedImage bImg,
|
||||
SurfaceType sType,
|
||||
int primaryBank) {
|
||||
int primaryBank,
|
||||
double scaleX, double scaleY)
|
||||
{
|
||||
ByteComponentRaster bcRaster =
|
||||
(ByteComponentRaster)bImg.getRaster();
|
||||
BufImgSurfaceData bisd =
|
||||
new BufImgSurfaceData(bcRaster.getDataBuffer(), bImg, sType);
|
||||
new BufImgSurfaceData(bcRaster.getDataBuffer(), bImg, sType,
|
||||
scaleX, scaleY);
|
||||
ColorModel cm = bImg.getColorModel();
|
||||
IndexColorModel icm = ((cm instanceof IndexColorModel)
|
||||
? (IndexColorModel) cm
|
||||
@ -304,11 +330,14 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
}
|
||||
|
||||
public static SurfaceData createDataBP(BufferedImage bImg,
|
||||
SurfaceType sType) {
|
||||
SurfaceType sType,
|
||||
double scaleX, double scaleY)
|
||||
{
|
||||
BytePackedRaster bpRaster =
|
||||
(BytePackedRaster)bImg.getRaster();
|
||||
BufImgSurfaceData bisd =
|
||||
new BufImgSurfaceData(bpRaster.getDataBuffer(), bImg, sType);
|
||||
new BufImgSurfaceData(bpRaster.getDataBuffer(), bImg, sType,
|
||||
scaleX, scaleY);
|
||||
ColorModel cm = bImg.getColorModel();
|
||||
IndexColorModel icm = ((cm instanceof IndexColorModel)
|
||||
? (IndexColorModel) cm
|
||||
@ -350,15 +379,22 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
IndexColorModel icm);
|
||||
|
||||
public BufImgSurfaceData(DataBuffer db,
|
||||
BufferedImage bufImg, SurfaceType sType)
|
||||
BufferedImage bufImg,
|
||||
SurfaceType sType,
|
||||
double scaleX,
|
||||
double scaleY)
|
||||
{
|
||||
super(SunWritableRaster.stealTrackable(db),
|
||||
sType, bufImg.getColorModel());
|
||||
this.bufImg = bufImg;
|
||||
this.scaleX = scaleX;
|
||||
this.scaleY = scaleY;
|
||||
}
|
||||
|
||||
protected BufImgSurfaceData(SurfaceType surfaceType, ColorModel cm) {
|
||||
super(surfaceType, cm);
|
||||
this.scaleX = 1;
|
||||
this.scaleY = 1;
|
||||
}
|
||||
|
||||
public void initSolidLoops() {
|
||||
@ -395,7 +431,8 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
|
||||
public synchronized GraphicsConfiguration getDeviceConfiguration() {
|
||||
if (graphicsConfig == null) {
|
||||
graphicsConfig = BufferedImageGraphicsConfig.getConfig(bufImg);
|
||||
graphicsConfig = BufferedImageGraphicsConfig
|
||||
.getConfig(bufImg, scaleX, scaleY);
|
||||
}
|
||||
return graphicsConfig;
|
||||
}
|
||||
@ -418,6 +455,16 @@ public class BufImgSurfaceData extends SurfaceData {
|
||||
return bufImg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDefaultScaleX() {
|
||||
return scaleX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDefaultScaleY() {
|
||||
return scaleY;
|
||||
}
|
||||
|
||||
public static final class ICMColorData {
|
||||
private long pData = 0L;
|
||||
|
||||
|
||||
@ -45,19 +45,32 @@ public class BufferedImageGraphicsConfig
|
||||
extends GraphicsConfiguration
|
||||
{
|
||||
private static final int numconfigs = BufferedImage.TYPE_BYTE_BINARY;
|
||||
private static BufferedImageGraphicsConfig configs[] =
|
||||
private static BufferedImageGraphicsConfig standardConfigs[] =
|
||||
new BufferedImageGraphicsConfig[numconfigs];
|
||||
private static BufferedImageGraphicsConfig scaledConfigs[] =
|
||||
new BufferedImageGraphicsConfig[numconfigs];
|
||||
|
||||
public static BufferedImageGraphicsConfig getConfig(BufferedImage bImg) {
|
||||
return getConfig(bImg, 1, 1);
|
||||
}
|
||||
|
||||
public static BufferedImageGraphicsConfig getConfig(BufferedImage bImg,
|
||||
double scaleX,
|
||||
double scaleY)
|
||||
{
|
||||
BufferedImageGraphicsConfig ret;
|
||||
int type = bImg.getType();
|
||||
|
||||
BufferedImageGraphicsConfig[] configs = (scaleX == 1 && scaleY == 1)
|
||||
? standardConfigs : scaledConfigs;
|
||||
|
||||
if (type > 0 && type < numconfigs) {
|
||||
ret = configs[type];
|
||||
if (ret != null) {
|
||||
if (ret != null && ret.scaleX == scaleX && ret.scaleY == scaleY) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = new BufferedImageGraphicsConfig(bImg, null);
|
||||
ret = new BufferedImageGraphicsConfig(bImg, null, scaleX, scaleY);
|
||||
if (type > 0 && type < numconfigs) {
|
||||
configs[type] = ret;
|
||||
}
|
||||
@ -67,8 +80,16 @@ public class BufferedImageGraphicsConfig
|
||||
GraphicsDevice gd;
|
||||
ColorModel model;
|
||||
Raster raster;
|
||||
private final double scaleX;
|
||||
private final double scaleY;
|
||||
|
||||
public BufferedImageGraphicsConfig(BufferedImage bufImg, Component comp) {
|
||||
this(bufImg, comp, 1, 1);
|
||||
}
|
||||
|
||||
public BufferedImageGraphicsConfig(BufferedImage bufImg, Component comp,
|
||||
double scaleX, double scaleY)
|
||||
{
|
||||
if (comp == null) {
|
||||
this.gd = new BufferedImageDevice(this);
|
||||
} else {
|
||||
@ -77,6 +98,8 @@ public class BufferedImageGraphicsConfig
|
||||
}
|
||||
this.model = bufImg.getColorModel();
|
||||
this.raster = bufImg.getRaster().createCompatibleWritableRaster(1, 1);
|
||||
this.scaleX = scaleX;
|
||||
this.scaleY = scaleY;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,7 +161,7 @@ public class BufferedImageGraphicsConfig
|
||||
* For image buffers, this Transform will be the Identity transform.
|
||||
*/
|
||||
public AffineTransform getDefaultTransform() {
|
||||
return new AffineTransform();
|
||||
return AffineTransform.getScaleInstance(scaleX, scaleY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -233,8 +233,17 @@ public class SunVolatileImage extends VolatileImage
|
||||
* or a backup surface.
|
||||
*/
|
||||
public BufferedImage getBackupImage() {
|
||||
return graphicsConfig.createCompatibleImage(getWidth(), getHeight(),
|
||||
getTransparency());
|
||||
return getBackupImage(1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates a BufferedImage intended for use as a "snapshot"
|
||||
* or a backup surface with the given horizontal and vertical scale factors.
|
||||
*/
|
||||
public BufferedImage getBackupImage(double scaleX, double scaleY) {
|
||||
int w = (int) Math.ceil(getWidth() * scaleX);
|
||||
int h = (int) Math.ceil(getHeight() * scaleY);
|
||||
return graphicsConfig.createCompatibleImage(w, h, getTransparency());
|
||||
}
|
||||
|
||||
public BufferedImage getSnapshot() {
|
||||
|
||||
@ -290,16 +290,30 @@ public abstract class SurfaceManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a scale factor of the image. This is utility method, which
|
||||
* fetches information from the SurfaceData of the image.
|
||||
* Returns a horizontal scale factor of the image. This is utility method,
|
||||
* which fetches information from the SurfaceData of the image.
|
||||
*
|
||||
* @see SurfaceData#getDefaultScale
|
||||
* @see SurfaceData#getDefaultScaleX
|
||||
*/
|
||||
public static int getImageScale(final Image img) {
|
||||
public static double getImageScaleX(final Image img) {
|
||||
if (!(img instanceof VolatileImage)) {
|
||||
return 1;
|
||||
}
|
||||
final SurfaceManager sm = getManager(img);
|
||||
return sm.getPrimarySurfaceData().getDefaultScale();
|
||||
return sm.getPrimarySurfaceData().getDefaultScaleX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a vertical scale factor of the image. This is utility method,
|
||||
* which fetches information from the SurfaceData of the image.
|
||||
*
|
||||
* @see SurfaceData#getDefaultScaleY
|
||||
*/
|
||||
public static double getImageScaleY(final Image img) {
|
||||
if (!(img instanceof VolatileImage)) {
|
||||
return 1;
|
||||
}
|
||||
final SurfaceManager sm = getManager(img);
|
||||
return sm.getPrimarySurfaceData().getDefaultScaleY();
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,18 +25,16 @@
|
||||
|
||||
package sun.awt.image;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.ImageCapabilities;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.VolatileImage;
|
||||
import sun.awt.DisplayChangedListener;
|
||||
import sun.awt.image.SunVolatileImage;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.loops.CompositeType;
|
||||
import static sun.java2d.pipe.hw.AccelSurface.*;
|
||||
|
||||
/**
|
||||
@ -260,12 +258,16 @@ public abstract class VolatileSurfaceManager
|
||||
*/
|
||||
protected SurfaceData getBackupSurface() {
|
||||
if (sdBackup == null) {
|
||||
BufferedImage bImg = vImg.getBackupImage();
|
||||
GraphicsConfiguration gc = vImg.getGraphicsConfig();
|
||||
AffineTransform tx = gc.getDefaultTransform();
|
||||
double scaleX = tx.getScaleX();
|
||||
double scaleY = tx.getScaleY();
|
||||
BufferedImage bImg = vImg.getBackupImage(scaleX, scaleY);
|
||||
// Sabotage the acceleration capabilities of the BufImg surface
|
||||
SunWritableRaster.stealTrackable(bImg
|
||||
.getRaster()
|
||||
.getDataBuffer()).setUntrackable();
|
||||
sdBackup = BufImgSurfaceData.createData(bImg);
|
||||
sdBackup = BufImgSurfaceData.createData(bImg, scaleX, scaleY);
|
||||
}
|
||||
return sdBackup;
|
||||
}
|
||||
|
||||
@ -61,7 +61,6 @@ import java.awt.FontMetrics;
|
||||
import java.awt.Rectangle;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.awt.Font;
|
||||
import java.awt.Point;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.font.GlyphVector;
|
||||
@ -99,6 +98,7 @@ import java.awt.image.MultiResolutionImage;
|
||||
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 java.awt.image.VolatileImage;
|
||||
import sun.awt.image.MultiResolutionToolkitImage;
|
||||
import sun.awt.image.ToolkitImage;
|
||||
|
||||
@ -3086,30 +3086,50 @@ public final class SunGraphics2D
|
||||
}
|
||||
// end of text rendering methods
|
||||
|
||||
private boolean isHiDPIImage(final Image img) {
|
||||
return (SurfaceManager.getImageScale(img) != 1)
|
||||
|| img instanceof MultiResolutionImage;
|
||||
}
|
||||
private Boolean drawHiDPIImage(Image img,
|
||||
int dx1, int dy1, int dx2, int dy2,
|
||||
int sx1, int sy1, int sx2, int sy2,
|
||||
Color bgcolor, ImageObserver observer,
|
||||
AffineTransform xform) {
|
||||
|
||||
private boolean drawHiDPIImage(Image img, int dx1, int dy1, int dx2,
|
||||
int dy2, int sx1, int sy1, int sx2, int sy2,
|
||||
Color bgcolor, ImageObserver observer) {
|
||||
if (img instanceof VolatileImage) {
|
||||
final SurfaceData sd = SurfaceManager.getManager(img)
|
||||
.getPrimarySurfaceData();
|
||||
final double scaleX = sd.getDefaultScaleX();
|
||||
final double scaleY = sd.getDefaultScaleY();
|
||||
if (scaleX == 1 && scaleY == 1) {
|
||||
return null;
|
||||
}
|
||||
sx1 = Region.clipScale(sx1, scaleX);
|
||||
sx2 = Region.clipScale(sx2, scaleX);
|
||||
sy1 = Region.clipScale(sy1, scaleY);
|
||||
sy2 = Region.clipScale(sy2, scaleY);
|
||||
|
||||
if (SurfaceManager.getImageScale(img) != 1) { // Volatile Image
|
||||
final int scale = SurfaceManager.getImageScale(img);
|
||||
sx1 = Region.clipScale(sx1, scale);
|
||||
sx2 = Region.clipScale(sx2, scale);
|
||||
sy1 = Region.clipScale(sy1, scale);
|
||||
sy2 = Region.clipScale(sy2, scale);
|
||||
} else if (img instanceof MultiResolutionImage) {
|
||||
AffineTransform tx = null;
|
||||
if (xform != null) {
|
||||
tx = new AffineTransform(transform);
|
||||
transform(xform);
|
||||
}
|
||||
boolean result = scaleImage(img, dx1, dy1, dx2, dy2,
|
||||
sx1, sy1, sx2, sy2,
|
||||
bgcolor, observer);
|
||||
if (tx != null) {
|
||||
transform.setTransform(tx);
|
||||
invalidateTransform();
|
||||
}
|
||||
return result;
|
||||
} else if (resolutionVariantHint != SunHints.INTVAL_RESOLUTION_VARIANT_BASE
|
||||
&& (img instanceof MultiResolutionImage)) {
|
||||
// get scaled destination image size
|
||||
|
||||
int width = img.getWidth(observer);
|
||||
int height = img.getHeight(observer);
|
||||
|
||||
Image resolutionVariant = getResolutionVariant(
|
||||
(MultiResolutionImage) img, width, height,
|
||||
dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2);
|
||||
MultiResolutionImage mrImage = (MultiResolutionImage) img;
|
||||
Image resolutionVariant = getResolutionVariant(mrImage, width, height,
|
||||
dx1, dy1, dx2, dy2,
|
||||
sx1, sy1, sx2, sy2,
|
||||
xform);
|
||||
|
||||
if (resolutionVariant != img && resolutionVariant != null) {
|
||||
// recalculate source region for the resolution variant
|
||||
@ -3123,8 +3143,8 @@ public final class SunGraphics2D
|
||||
|
||||
if (0 < width && 0 < height && 0 < rvWidth && 0 < rvHeight) {
|
||||
|
||||
float widthScale = ((float) rvWidth) / width;
|
||||
float heightScale = ((float) rvHeight) / height;
|
||||
double widthScale = ((double) rvWidth) / width;
|
||||
double heightScale = ((double) rvHeight) / height;
|
||||
|
||||
sx1 = Region.clipScale(sx1, widthScale);
|
||||
sy1 = Region.clipScale(sy1, heightScale);
|
||||
@ -3133,10 +3153,29 @@ public final class SunGraphics2D
|
||||
|
||||
observer = rvObserver;
|
||||
img = resolutionVariant;
|
||||
|
||||
if (xform != null) {
|
||||
assert dx1 == 0 && dy1 == 0;
|
||||
assert dx2 == img.getWidth(observer);
|
||||
assert dy2 == img.getHeight(observer);
|
||||
AffineTransform renderTX = new AffineTransform(xform);
|
||||
renderTX.scale(1 / widthScale, 1 / heightScale);
|
||||
return transformImage(img, renderTX, observer);
|
||||
}
|
||||
|
||||
return scaleImage(img, dx1, dy1, dx2, dy2,
|
||||
sx1, sy1, sx2, sy2,
|
||||
bgcolor, observer);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean scaleImage(Image img, int dx1, int dy1, int dx2, int dy2,
|
||||
int sx1, int sy1, int sx2, int sy2,
|
||||
Color bgcolor, ImageObserver observer)
|
||||
{
|
||||
try {
|
||||
return imagepipe.scaleImage(this, img, dx1, dy1, dx2, dy2, sx1, sy1,
|
||||
sx2, sy2, bgcolor, observer);
|
||||
@ -3156,9 +3195,30 @@ public final class SunGraphics2D
|
||||
}
|
||||
}
|
||||
|
||||
private boolean transformImage(Image img,
|
||||
AffineTransform xform,
|
||||
ImageObserver observer)
|
||||
{
|
||||
try {
|
||||
return imagepipe.transformImage(this, img, xform, observer);
|
||||
} catch (InvalidPipeException e) {
|
||||
try {
|
||||
revalidateAll();
|
||||
return imagepipe.transformImage(this, img, xform, observer);
|
||||
} catch (InvalidPipeException e2) {
|
||||
// Still catching the exception; we are not yet ready to
|
||||
// validate the surfaceData correctly. Fail for now and
|
||||
// try again next time around.
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
surfaceData.markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
private Image getResolutionVariant(MultiResolutionImage img,
|
||||
int srcWidth, int srcHeight, int dx1, int dy1, int dx2, int dy2,
|
||||
int sx1, int sy1, int sx2, int sy2) {
|
||||
int sx1, int sy1, int sx2, int sy2, AffineTransform xform) {
|
||||
|
||||
if (srcWidth <= 0 || srcHeight <= 0) {
|
||||
return null;
|
||||
@ -3171,7 +3231,16 @@ public final class SunGraphics2D
|
||||
return null;
|
||||
}
|
||||
|
||||
int type = transform.getType();
|
||||
AffineTransform tx;
|
||||
|
||||
if (xform == null) {
|
||||
tx = transform;
|
||||
} else {
|
||||
tx = new AffineTransform(transform);
|
||||
tx.concatenate(xform);
|
||||
}
|
||||
|
||||
int type = tx.getType();
|
||||
int dw = dx2 - dx1;
|
||||
int dh = dy2 - dy1;
|
||||
|
||||
@ -3198,13 +3267,13 @@ public final class SunGraphics2D
|
||||
destRegionWidth = dw;
|
||||
destRegionHeight = dh;
|
||||
} else if ((type & ~(TYPE_TRANSLATION | TYPE_FLIP | TYPE_MASK_SCALE)) == 0) {
|
||||
destRegionWidth = dw * transform.getScaleX();
|
||||
destRegionHeight = dh * transform.getScaleY();
|
||||
destRegionWidth = dw * tx.getScaleX();
|
||||
destRegionHeight = dh * tx.getScaleY();
|
||||
} else {
|
||||
destRegionWidth = dw * Math.hypot(
|
||||
transform.getScaleX(), transform.getShearY());
|
||||
tx.getScaleX(), tx.getShearY());
|
||||
destRegionHeight = dh * Math.hypot(
|
||||
transform.getShearX(), transform.getScaleY());
|
||||
tx.getShearX(), tx.getScaleY());
|
||||
}
|
||||
destImageWidth = Math.abs(srcWidth * destRegionWidth / sw);
|
||||
destImageHeight = Math.abs(srcHeight * destRegionHeight / sh);
|
||||
@ -3277,9 +3346,11 @@ public final class SunGraphics2D
|
||||
|
||||
final int imgW = img.getWidth(null);
|
||||
final int imgH = img.getHeight(null);
|
||||
if (isHiDPIImage(img)) {
|
||||
return drawHiDPIImage(img, x, y, x + width, y + height, 0, 0, imgW,
|
||||
imgH, bg, observer);
|
||||
Boolean hidpiImageDrawn = drawHiDPIImage(img, x, y, x + width, y + height,
|
||||
0, 0, imgW, imgH, bg, observer,
|
||||
null);
|
||||
if (hidpiImageDrawn != null) {
|
||||
return hidpiImageDrawn;
|
||||
}
|
||||
|
||||
if (width == imgW && height == imgH) {
|
||||
@ -3323,11 +3394,13 @@ public final class SunGraphics2D
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isHiDPIImage(img)) {
|
||||
final int imgW = img.getWidth(null);
|
||||
final int imgH = img.getHeight(null);
|
||||
return drawHiDPIImage(img, x, y, x + imgW, y + imgH, 0, 0, imgW,
|
||||
imgH, bg, observer);
|
||||
final int imgW = img.getWidth(null);
|
||||
final int imgH = img.getHeight(null);
|
||||
Boolean hidpiImageDrawn = drawHiDPIImage(img, x, y, x + imgW, y + imgH,
|
||||
0, 0, imgW, imgH, bg, observer,
|
||||
null);
|
||||
if (hidpiImageDrawn != null) {
|
||||
return hidpiImageDrawn;
|
||||
}
|
||||
|
||||
try {
|
||||
@ -3378,9 +3451,12 @@ public final class SunGraphics2D
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isHiDPIImage(img)) {
|
||||
return drawHiDPIImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,
|
||||
bgcolor, observer);
|
||||
Boolean hidpiImageDrawn = drawHiDPIImage(img, dx1, dy1, dx2, dy2,
|
||||
sx1, sy1, sx2, sy2,
|
||||
bgcolor, observer, null);
|
||||
|
||||
if (hidpiImageDrawn != null) {
|
||||
return hidpiImageDrawn;
|
||||
}
|
||||
|
||||
if (((sx2 - sx1) == (dx2 - dx1)) &&
|
||||
@ -3461,33 +3537,16 @@ public final class SunGraphics2D
|
||||
return drawImage(img, 0, 0, null, observer);
|
||||
}
|
||||
|
||||
if (isHiDPIImage(img)) {
|
||||
final int w = img.getWidth(null);
|
||||
final int h = img.getHeight(null);
|
||||
final AffineTransform tx = new AffineTransform(transform);
|
||||
transform(xform);
|
||||
boolean result = drawHiDPIImage(img, 0, 0, w, h, 0, 0, w, h, null,
|
||||
observer);
|
||||
transform.setTransform(tx);
|
||||
invalidateTransform();
|
||||
return result;
|
||||
final int w = img.getWidth(null);
|
||||
final int h = img.getHeight(null);
|
||||
Boolean hidpiImageDrawn = drawHiDPIImage(img, 0, 0, w, h, 0, 0, w, h,
|
||||
null, observer, xform);
|
||||
|
||||
if (hidpiImageDrawn != null) {
|
||||
return hidpiImageDrawn;
|
||||
}
|
||||
|
||||
try {
|
||||
return imagepipe.transformImage(this, img, xform, observer);
|
||||
} catch (InvalidPipeException e) {
|
||||
try {
|
||||
revalidateAll();
|
||||
return imagepipe.transformImage(this, img, xform, observer);
|
||||
} catch (InvalidPipeException e2) {
|
||||
// Still catching the exception; we are not yet ready to
|
||||
// validate the surfaceData correctly. Fail for now and
|
||||
// try again next time around.
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
surfaceData.markDirty();
|
||||
}
|
||||
return transformImage(img, xform, observer);
|
||||
}
|
||||
|
||||
public void drawImage(BufferedImage bImg,
|
||||
|
||||
@ -66,6 +66,8 @@ import sun.font.FontManager;
|
||||
import sun.font.FontManagerFactory;
|
||||
import sun.font.FontManagerForSGE;
|
||||
import sun.font.NativeFont;
|
||||
import java.security.AccessController;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
* This is an implementation of a GraphicsEnvironment object for the
|
||||
@ -80,6 +82,15 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
|
||||
public static boolean isOpenSolaris;
|
||||
private static Font defaultFont;
|
||||
|
||||
private static final boolean uiScaleEnabled;
|
||||
private static final double debugScale;
|
||||
|
||||
static {
|
||||
uiScaleEnabled = "true".equals(AccessController.doPrivileged(
|
||||
new GetPropertyAction("sun.java2d.uiScale.enabled", "true")));
|
||||
debugScale = uiScaleEnabled ? getScaleFactor("sun.java2d.uiScale") : -1;
|
||||
}
|
||||
|
||||
public SunGraphicsEnvironment() {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Object>() {
|
||||
@ -341,4 +352,41 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
|
||||
public boolean isFlipStrategyPreferred(ComponentPeer peer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isUIScaleEnabled() {
|
||||
return uiScaleEnabled;
|
||||
}
|
||||
|
||||
public static double getDebugScale() {
|
||||
return debugScale;
|
||||
}
|
||||
|
||||
public static double getScaleFactor(String propertyName) {
|
||||
|
||||
String scaleFactor = AccessController.doPrivileged(
|
||||
new GetPropertyAction(propertyName, "-1"));
|
||||
|
||||
if (scaleFactor == null || scaleFactor.equals("-1")) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
try {
|
||||
double units = 1.0;
|
||||
|
||||
if (scaleFactor.endsWith("x")) {
|
||||
scaleFactor = scaleFactor.substring(0, scaleFactor.length() - 1);
|
||||
} else if (scaleFactor.endsWith("dpi")) {
|
||||
units = 96;
|
||||
scaleFactor = scaleFactor.substring(0, scaleFactor.length() - 3);
|
||||
} else if (scaleFactor.endsWith("%")) {
|
||||
units = 100;
|
||||
scaleFactor = scaleFactor.substring(0, scaleFactor.length() - 1);
|
||||
}
|
||||
|
||||
double scale = Double.parseDouble(scaleFactor);
|
||||
return scale <= 0 ? -1 : scale / units;
|
||||
} catch (NumberFormatException ignored) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1059,12 +1059,22 @@ public abstract class SurfaceData
|
||||
public abstract Object getDestination();
|
||||
|
||||
/**
|
||||
* Returns default scale factor of the destination surface. Scale factor
|
||||
* describes the mapping between virtual and physical coordinates of the
|
||||
* Returns default horizontal scale factor of the destination surface. Scale
|
||||
* factor describes the mapping between virtual and physical coordinates of the
|
||||
* SurfaceData. If the scale is 2 then virtual pixel coordinates need to be
|
||||
* doubled for physical pixels.
|
||||
*/
|
||||
public int getDefaultScale() {
|
||||
public double getDefaultScaleX() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns default vertical scale factor of the destination surface. Scale
|
||||
* factor describes the mapping between virtual and physical coordinates of the
|
||||
* SurfaceData. If the scale is 2 then virtual pixel coordinates need to be
|
||||
* doubled for physical pixels.
|
||||
*/
|
||||
public double getDefaultScaleY() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -736,9 +736,10 @@ public class DrawImage implements DrawImagePipe
|
||||
atfm.scale(m00, m11);
|
||||
atfm.translate(srcX-sx1, srcY-sy1);
|
||||
|
||||
final int scale = SurfaceManager.getImageScale(img);
|
||||
final int imgW = img.getWidth(null) * scale;
|
||||
final int imgH = img.getHeight(null) * scale;
|
||||
final double scaleX = SurfaceManager.getImageScaleX(img);
|
||||
final double scaleY = SurfaceManager.getImageScaleY(img);
|
||||
final int imgW = (int) Math.ceil(img.getWidth(null) * scaleX);
|
||||
final int imgH = (int) Math.ceil(img.getHeight(null) * scaleY);
|
||||
srcW += srcX;
|
||||
srcH += srcY;
|
||||
// Make sure we are not out of bounds
|
||||
|
||||
@ -106,7 +106,7 @@ public class Win32GraphicsConfig extends GraphicsConfiguration
|
||||
/**
|
||||
* Return the graphics device associated with this configuration.
|
||||
*/
|
||||
public GraphicsDevice getDevice() {
|
||||
public Win32GraphicsDevice getDevice() {
|
||||
return screen;
|
||||
}
|
||||
|
||||
@ -182,7 +182,9 @@ public class Win32GraphicsConfig extends GraphicsConfiguration
|
||||
* For image buffers, this Transform will be the Identity transform.
|
||||
*/
|
||||
public AffineTransform getDefaultTransform() {
|
||||
return new AffineTransform();
|
||||
double scaleX = screen.getDefaultScaleX();
|
||||
double scaleY = screen.getDefaultScaleY();
|
||||
return AffineTransform.getScaleInstance(scaleX, scaleY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -37,13 +37,19 @@ import java.awt.Window;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Vector;
|
||||
import java.awt.peer.WindowPeer;
|
||||
import java.security.AccessController;
|
||||
import sun.awt.windows.WWindowPeer;
|
||||
import sun.java2d.SunGraphicsEnvironment;
|
||||
import sun.java2d.opengl.WGLGraphicsConfig;
|
||||
import sun.java2d.windows.WindowsFlags;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import static sun.awt.Win32GraphicsEnvironment.debugScaleX;
|
||||
import static sun.awt.Win32GraphicsEnvironment.debugScaleY;
|
||||
|
||||
/**
|
||||
* This is an implementation of a GraphicsDevice object for a single
|
||||
@ -81,6 +87,9 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
// activation/deactivation listener for the full-screen window
|
||||
private WindowListener fsWindowListener;
|
||||
|
||||
private float scaleX;
|
||||
private float scaleY;
|
||||
|
||||
static {
|
||||
|
||||
// 4455041 - Even when ddraw is disabled, ddraw.dll is loaded when
|
||||
@ -97,6 +106,10 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
private static native void initIDs();
|
||||
|
||||
native void initDevice(int screen);
|
||||
native void initNativeScale(int screen);
|
||||
native void setNativeScale(int screen, float scaleX, float scaleY);
|
||||
native float getNativeScaleX(int screen);
|
||||
native float getNativeScaleY(int screen);
|
||||
|
||||
public Win32GraphicsDevice(int screennum) {
|
||||
this.screen = screennum;
|
||||
@ -109,6 +122,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
valid = true;
|
||||
|
||||
initDevice(screennum);
|
||||
initScaleFactors();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,6 +142,31 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
return screen;
|
||||
}
|
||||
|
||||
public float getDefaultScaleX() {
|
||||
return scaleX;
|
||||
}
|
||||
|
||||
public float getDefaultScaleY() {
|
||||
return scaleY;
|
||||
}
|
||||
|
||||
private void initScaleFactors() {
|
||||
if (SunGraphicsEnvironment.isUIScaleEnabled()) {
|
||||
if (debugScaleX > 0 && debugScaleY > 0) {
|
||||
scaleX = debugScaleX;
|
||||
scaleY = debugScaleY;
|
||||
setNativeScale(screen, scaleX, scaleY);
|
||||
} else {
|
||||
initNativeScale(screen);
|
||||
scaleX = getNativeScaleX(screen);
|
||||
scaleY = getNativeScaleY(screen);
|
||||
}
|
||||
} else {
|
||||
scaleX = 1;
|
||||
scaleY = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this is a valid devicie. Device can become
|
||||
* invalid as a result of device removal event.
|
||||
@ -486,6 +525,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements
|
||||
configs = null;
|
||||
// pass on to all top-level windows on this display
|
||||
topLevels.notifyListeners();
|
||||
initScaleFactors();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -51,6 +51,9 @@ import sun.java2d.windows.WindowsFlags;
|
||||
|
||||
public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
|
||||
static final float debugScaleX;
|
||||
static final float debugScaleY;
|
||||
|
||||
static {
|
||||
// Ensure awt is loaded already. Also, this forces static init
|
||||
// of WToolkit and Toolkit, which we depend upon
|
||||
@ -61,6 +64,21 @@ public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment {
|
||||
|
||||
// Install correct surface manager factory.
|
||||
SurfaceManagerFactory.setInstance(new WindowsSurfaceManagerFactory());
|
||||
|
||||
double sx = -1;
|
||||
double sy = -1;
|
||||
if (isUIScaleEnabled()) {
|
||||
sx = getScaleFactor("sun.java2d.win.uiScaleX");
|
||||
sy = getScaleFactor("sun.java2d.win.uiScaleY");
|
||||
if (sx <= 0 || sy <= 0) {
|
||||
double s = getDebugScale();
|
||||
sx = s;
|
||||
sy = s;
|
||||
}
|
||||
}
|
||||
|
||||
debugScaleX = (float) sx;
|
||||
debugScaleY = (float) sy;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -294,6 +294,12 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
|
||||
synchronized native void reshapeFrame(int x, int y, int width, int height);
|
||||
|
||||
native Dimension getNativeWindowSize();
|
||||
|
||||
public Dimension getScaledWindowSize() {
|
||||
return getNativeWindowSize();
|
||||
}
|
||||
|
||||
public boolean requestWindowFocus(CausedFocusEvent.Cause cause) {
|
||||
if (!focusAllowedFor()) {
|
||||
return false;
|
||||
@ -490,8 +496,7 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
|
||||
}
|
||||
|
||||
// get current GD
|
||||
Win32GraphicsDevice oldDev = (Win32GraphicsDevice)winGraphicsConfig
|
||||
.getDevice();
|
||||
Win32GraphicsDevice oldDev = winGraphicsConfig.getDevice();
|
||||
|
||||
Win32GraphicsDevice newDev;
|
||||
GraphicsDevice devs[] = GraphicsEnvironment
|
||||
|
||||
@ -63,9 +63,12 @@ import static sun.java2d.d3d.D3DContext.D3DContextCaps.*;
|
||||
import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.*;
|
||||
import sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType;
|
||||
import java.awt.BufferCapabilities.FlipContents;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Window;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.image.SunVolatileImage;
|
||||
import sun.awt.windows.WWindowPeer;
|
||||
import sun.java2d.ScreenUpdateManager;
|
||||
import sun.java2d.StateTracker;
|
||||
import sun.java2d.SurfaceDataProxy;
|
||||
@ -162,6 +165,8 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
|
||||
|
||||
private int type;
|
||||
private int width, height;
|
||||
private final double scaleX;
|
||||
private final double scaleY;
|
||||
// these fields are set from the native code when the surface is
|
||||
// initialized
|
||||
private int nativeWidth, nativeHeight;
|
||||
@ -218,16 +223,29 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
|
||||
{
|
||||
super(getCustomSurfaceType(type), cm);
|
||||
this.graphicsDevice = gc.getD3DDevice();
|
||||
this.scaleX = type == TEXTURE ? 1 : graphicsDevice.getDefaultScaleX();
|
||||
this.scaleY = type == TEXTURE ? 1 : graphicsDevice.getDefaultScaleY();
|
||||
this.peer = peer;
|
||||
this.type = type;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
if (scaleX == 1 && scaleY == 1) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
} else if (peer instanceof WWindowPeer) {
|
||||
Dimension scaledSize = ((WWindowPeer) peer).getScaledWindowSize();
|
||||
this.width = scaledSize.width;
|
||||
this.height = scaledSize.height;
|
||||
} else {
|
||||
this.width = (int) Math.ceil(width * scaleX);
|
||||
this.height = (int) Math.ceil(height * scaleY);
|
||||
}
|
||||
|
||||
this.offscreenImage = image;
|
||||
this.backBuffersNum = numBackBuffers;
|
||||
this.swapEffect = swapEffect;
|
||||
this.syncType = vSyncType;
|
||||
|
||||
initOps(graphicsDevice.getScreen(), width, height);
|
||||
initOps(graphicsDevice.getScreen(), this.width, this.height);
|
||||
if (type == WINDOW) {
|
||||
// we put the surface into the "lost"
|
||||
// state; it will be restored by the D3DScreenUpdateManager
|
||||
@ -240,6 +258,16 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
|
||||
setBlitProxyKey(gc.getProxyKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDefaultScaleX() {
|
||||
return scaleX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDefaultScaleY() {
|
||||
return scaleY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
|
||||
return D3DSurfaceDataProxy.
|
||||
@ -777,8 +805,12 @@ public class D3DSurfaceData extends SurfaceData implements AccelSurface {
|
||||
|
||||
public Rectangle getBounds() {
|
||||
if (type == FLIP_BACKBUFFER || type == WINDOW) {
|
||||
double scaleX = getDefaultScaleX();
|
||||
double scaleY = getDefaultScaleY();
|
||||
Rectangle r = peer.getBounds();
|
||||
r.x = r.y = 0;
|
||||
r.width = (int) Math.ceil(r.width * scaleX);
|
||||
r.height = (int) Math.ceil(r.height * scaleY);
|
||||
return r;
|
||||
} else {
|
||||
return new Rectangle(width, height);
|
||||
|
||||
@ -31,8 +31,10 @@ import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.ColorModel;
|
||||
import sun.awt.SunToolkit;
|
||||
import sun.awt.Win32GraphicsDevice;
|
||||
import sun.awt.windows.WComponentPeer;
|
||||
import sun.java2d.SurfaceData;
|
||||
|
||||
@ -40,6 +42,8 @@ public abstract class WGLSurfaceData extends OGLSurfaceData {
|
||||
|
||||
protected WComponentPeer peer;
|
||||
private WGLGraphicsConfig graphicsConfig;
|
||||
protected double scaleX = 1;
|
||||
protected double scaleY = 1;
|
||||
|
||||
private native void initOps(long pConfigInfo, WComponentPeer peer,
|
||||
long hwnd);
|
||||
@ -50,6 +54,9 @@ public abstract class WGLSurfaceData extends OGLSurfaceData {
|
||||
super(gc, cm, type);
|
||||
this.peer = peer;
|
||||
this.graphicsConfig = gc;
|
||||
Win32GraphicsDevice device = gc.getDevice();
|
||||
this.scaleX = type == TEXTURE ? 1 : device.getDefaultScaleX();
|
||||
this.scaleY = type == TEXTURE ? 1 : device.getDefaultScaleY();
|
||||
|
||||
long pConfigInfo = gc.getNativeConfigInfo();
|
||||
long hwnd = peer != null ? peer.getHWnd() : 0L;
|
||||
@ -57,6 +64,16 @@ public abstract class WGLSurfaceData extends OGLSurfaceData {
|
||||
initOps(pConfigInfo, peer, hwnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDefaultScaleX() {
|
||||
return scaleX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDefaultScaleY() {
|
||||
return scaleY;
|
||||
}
|
||||
|
||||
public GraphicsConfiguration getDeviceConfiguration() {
|
||||
return graphicsConfig;
|
||||
}
|
||||
@ -148,6 +165,8 @@ public abstract class WGLSurfaceData extends OGLSurfaceData {
|
||||
public Rectangle getBounds() {
|
||||
Rectangle r = peer.getBounds();
|
||||
r.x = r.y = 0;
|
||||
r.width = (int) Math.ceil(r.width * scaleX);
|
||||
r.height = (int) Math.ceil(r.height * scaleY);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -208,11 +227,11 @@ public abstract class WGLSurfaceData extends OGLSurfaceData {
|
||||
{
|
||||
super(peer, gc, cm, type);
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.width = (int) Math.ceil(width * scaleX);
|
||||
this.height = (int) Math.ceil(height * scaleY);
|
||||
offscreenImage = image;
|
||||
|
||||
initSurface(width, height);
|
||||
initSurface(this.width, this.height);
|
||||
}
|
||||
|
||||
public SurfaceData getReplacement() {
|
||||
@ -222,6 +241,8 @@ public abstract class WGLSurfaceData extends OGLSurfaceData {
|
||||
public Rectangle getBounds() {
|
||||
if (type == FLIP_BACKBUFFER) {
|
||||
Rectangle r = peer.getBounds();
|
||||
r.width = (int) Math.ceil(r.width * scaleX);
|
||||
r.height = (int) Math.ceil(r.height * scaleY);
|
||||
r.x = r.y = 0;
|
||||
return r;
|
||||
} else {
|
||||
|
||||
@ -28,6 +28,7 @@ package sun.java2d.windows;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.DirectColorModel;
|
||||
@ -77,6 +78,9 @@ public class GDIWindowSurfaceData extends SurfaceData {
|
||||
|
||||
private static native void initIDs(Class<?> xorComp);
|
||||
|
||||
private final double scaleX;
|
||||
private final double scaleY;
|
||||
|
||||
static {
|
||||
initIDs(XORComposite.class);
|
||||
if (WindowsFlags.isGdiBlitEnabled()) {
|
||||
@ -265,13 +269,23 @@ public class GDIWindowSurfaceData extends SurfaceData {
|
||||
this.graphicsConfig =
|
||||
(Win32GraphicsConfig) peer.getGraphicsConfiguration();
|
||||
this.solidloops = graphicsConfig.getSolidLoops(sType);
|
||||
|
||||
Win32GraphicsDevice gd =
|
||||
(Win32GraphicsDevice)graphicsConfig.getDevice();
|
||||
Win32GraphicsDevice gd = graphicsConfig.getDevice();
|
||||
scaleX = gd.getDefaultScaleX();
|
||||
scaleY = gd.getDefaultScaleY();
|
||||
initOps(peer, depth, rMask, gMask, bMask, gd.getScreen());
|
||||
setBlitProxyKey(graphicsConfig.getProxyKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDefaultScaleX() {
|
||||
return scaleX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDefaultScaleY() {
|
||||
return scaleY;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@ -288,6 +302,8 @@ public class GDIWindowSurfaceData extends SurfaceData {
|
||||
public Rectangle getBounds() {
|
||||
Rectangle r = peer.getBounds();
|
||||
r.x = r.y = 0;
|
||||
r.width = (int) Math.ceil(r.width * scaleX);
|
||||
r.height = (int) Math.ceil(r.height * scaleY);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@ -94,12 +94,21 @@ Java_sun_awt_DefaultMouseInfoPeer_fillPointWithCoords(JNIEnv *env, jclass cls, j
|
||||
pointClass = (jclass)env->NewGlobalRef(pointClassLocal);
|
||||
env->DeleteLocalRef(pointClassLocal);
|
||||
}
|
||||
|
||||
int screen = AwtWin32GraphicsDevice::GetDefaultDeviceIndex();
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
|
||||
xID = env->GetFieldID(pointClass, "x", "I");
|
||||
CHECK_NULL_RETURN(xID, (jint)0);
|
||||
yID = env->GetFieldID(pointClass, "y", "I");
|
||||
CHECK_NULL_RETURN(yID, (jint)0);
|
||||
env->SetIntField(point, xID, pt.x);
|
||||
env->SetIntField(point, yID, pt.y);
|
||||
|
||||
int x = (device == NULL) ? pt.x : device->ScaleDownX(pt.x);
|
||||
int y = (device == NULL) ? pt.y : device->ScaleDownY(pt.y);
|
||||
|
||||
env->SetIntField(point, xID, x);
|
||||
env->SetIntField(point, yID, y);
|
||||
|
||||
// Always return 0 on Windows: we assume there's always a
|
||||
// virtual screen device used.
|
||||
|
||||
@ -206,9 +206,10 @@ int AwtChoice::GetDropDownHeight()
|
||||
int itemHeight =(int)::SendMessage(GetHWnd(), CB_GETITEMHEIGHT, (UINT)0,0);
|
||||
int numItemsToShow = (int)::SendMessage(GetHWnd(), CB_GETCOUNT, 0,0);
|
||||
numItemsToShow = min(MINIMUM_NUMBER_OF_VISIBLE_ITEMS, numItemsToShow);
|
||||
|
||||
// drop-down height snaps to nearest line, so add a
|
||||
// fudge factor of 1/2 line to ensure last line shows
|
||||
return itemHeight*numItemsToShow + itemHeight/2;
|
||||
return ScaleDownY(itemHeight * numItemsToShow + itemHeight / 2);
|
||||
}
|
||||
|
||||
// get the height of the field portion of the combobox
|
||||
@ -221,7 +222,7 @@ int AwtChoice::GetFieldHeight()
|
||||
// Win 4.x (3d edge) vs 3.x (1 pixel line)
|
||||
borderHeight = ::GetSystemMetrics(SM_CYEDGE);
|
||||
fieldHeight += borderHeight*2;
|
||||
return fieldHeight;
|
||||
return ScaleDownY(fieldHeight);
|
||||
}
|
||||
|
||||
// gets the total height of the combobox, including drop down
|
||||
@ -325,8 +326,8 @@ void AwtChoice::Reshape(int x, int y, int w, int h)
|
||||
* Fix: Set the Choice to its actual size in the component.
|
||||
*/
|
||||
::GetClientRect(GetHWnd(), &rc);
|
||||
env->SetIntField(target, AwtComponent::widthID, (jint)rc.right);
|
||||
env->SetIntField(target, AwtComponent::heightID, (jint)rc.bottom);
|
||||
env->SetIntField(target, AwtComponent::widthID, ScaleDownX(rc.right));
|
||||
env->SetIntField(target, AwtComponent::heightID, ScaleDownY(rc.bottom));
|
||||
|
||||
env->DeleteLocalRef(target);
|
||||
env->DeleteLocalRef(parent);
|
||||
|
||||
@ -963,6 +963,12 @@ void AwtComponent::Reshape(int x, int y, int w, int h)
|
||||
::MapWindowPoints(HWND_DESKTOP, ::GetParent(GetHWnd()), (LPPOINT)&rc, 2);
|
||||
DTRACE_PRINTLN4("AwtComponent::Reshape from %d, %d, %d, %d", rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
|
||||
#endif
|
||||
|
||||
x = ScaleUpX(x);
|
||||
y = ScaleUpY(y);
|
||||
w = ScaleUpX(w);
|
||||
h = ScaleUpY(h);
|
||||
|
||||
AwtWindow* container = GetContainer();
|
||||
AwtComponent* parent = GetParent();
|
||||
if (container != NULL && container == parent) {
|
||||
@ -2212,8 +2218,11 @@ void AwtComponent::PaintUpdateRgn(const RECT *insets)
|
||||
}
|
||||
for(i = 0; i < 2; i++) {
|
||||
if (un[i] != 0) {
|
||||
DoCallback("handleExpose", "(IIII)V", un[i]->left, un[i]->top,
|
||||
un[i]->right-un[i]->left, un[i]->bottom-un[i]->top);
|
||||
DoCallback("handleExpose", "(IIII)V",
|
||||
ScaleDownX(un[i]->left),
|
||||
ScaleDownY(un[i]->top),
|
||||
ScaleDownX(un[i]->right - un[i]->left),
|
||||
ScaleDownY(un[i]->bottom - un[i]->top));
|
||||
}
|
||||
}
|
||||
delete [] buffer;
|
||||
@ -4608,6 +4617,34 @@ void AwtComponent::FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha)
|
||||
}
|
||||
}
|
||||
|
||||
int AwtComponent::ScaleUpX(int x) {
|
||||
int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? x : device->ScaleUpX(x);
|
||||
}
|
||||
|
||||
int AwtComponent::ScaleUpY(int y) {
|
||||
int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? y : device->ScaleUpY(y);
|
||||
}
|
||||
|
||||
int AwtComponent::ScaleDownX(int x) {
|
||||
int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? x : device->ScaleDownX(x);
|
||||
}
|
||||
|
||||
int AwtComponent::ScaleDownY(int y) {
|
||||
int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(GetHWnd());
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
|
||||
return device == NULL ? y : device->ScaleDownY(y);
|
||||
}
|
||||
|
||||
jintArray AwtComponent::CreatePrintedPixels(SIZE &loc, SIZE &size, int alpha) {
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
|
||||
@ -4901,8 +4938,9 @@ void AwtComponent::SendMouseEvent(jint id, jlong when, jint x, jint y,
|
||||
jobject mouseEvent = env->NewObject(mouseEventCls, mouseEventConst,
|
||||
target,
|
||||
id, when, modifiers,
|
||||
x+insets.left, y+insets.top,
|
||||
xAbs, yAbs,
|
||||
ScaleDownX(x + insets.left),
|
||||
ScaleDownY(y + insets.top),
|
||||
ScaleDownX(xAbs), ScaleDownY(yAbs),
|
||||
clickCount, popupTrigger, button);
|
||||
|
||||
if (safe_ExceptionOccurred(env)) {
|
||||
@ -4969,8 +5007,10 @@ AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
|
||||
mouseWheelEventConst,
|
||||
target,
|
||||
id, when, modifiers,
|
||||
x+insets.left, y+insets.top,
|
||||
xAbs, yAbs,
|
||||
ScaleDownX(x + insets.left),
|
||||
ScaleDownY(y + insets.top),
|
||||
ScaleDownX(xAbs),
|
||||
ScaleDownY(yAbs),
|
||||
clickCount, popupTrigger,
|
||||
scrollType, scrollAmount,
|
||||
roundedWheelRotation, preciseWheelRotation);
|
||||
@ -5476,7 +5516,8 @@ jobject AwtComponent::_GetLocationOnScreen(void *param)
|
||||
RECT rect;
|
||||
VERIFY(::GetWindowRect(p->GetHWnd(),&rect));
|
||||
result = JNU_NewObjectByName(env, "java/awt/Point", "(II)V",
|
||||
rect.left, rect.top);
|
||||
p->ScaleDownX(rect.left),
|
||||
p->ScaleDownY(rect.top));
|
||||
}
|
||||
ret:
|
||||
env->DeleteGlobalRef(self);
|
||||
@ -7064,6 +7105,11 @@ void AwtComponent::VerifyState()
|
||||
target = parent;
|
||||
}
|
||||
|
||||
x = ScaleUpX(x);
|
||||
y = ScaleUpY(y);
|
||||
width = ScaleUpX(width);
|
||||
height = ScaleUpY(height);
|
||||
|
||||
// Test whether component's bounds match the native window's
|
||||
RECT rect;
|
||||
VERIFY(::GetWindowRect(GetHWnd(), &rect));
|
||||
@ -7256,5 +7302,4 @@ void ReleaseDCList(HWND hwnd, DCList &list) {
|
||||
removedDCs = removedDCs->next;
|
||||
delete tmpDCList;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -746,6 +746,11 @@ protected:
|
||||
virtual void FillBackground(HDC hMemoryDC, SIZE &size);
|
||||
virtual void FillAlpha(void *bitmapBits, SIZE &size, BYTE alpha);
|
||||
|
||||
int ScaleUpX(int x);
|
||||
int ScaleUpY(int y);
|
||||
int ScaleDownX(int x);
|
||||
int ScaleDownY(int y);
|
||||
|
||||
private:
|
||||
/* A bitmask keeps the button's numbers as MK_LBUTTON, MK_MBUTTON, MK_RBUTTON
|
||||
* which are allowed to
|
||||
|
||||
@ -398,6 +398,38 @@ static void strip_tail(wchar_t* text, wchar_t* tail) { // strips tail and any po
|
||||
|
||||
}
|
||||
|
||||
static int ScaleUpX(float x) {
|
||||
int deviceIndex = AwtWin32GraphicsDevice::DeviceIndexForWindow(
|
||||
::GetDesktopWindow());
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(deviceIndex);
|
||||
return device == NULL ? x : device->ScaleUpX(x);
|
||||
}
|
||||
|
||||
static int ScaleUpY(int y) {
|
||||
int deviceIndex = AwtWin32GraphicsDevice::DeviceIndexForWindow(
|
||||
::GetDesktopWindow());
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(deviceIndex);
|
||||
return device == NULL ? y : device->ScaleUpY(y);
|
||||
}
|
||||
|
||||
static int ScaleDownX(int x) {
|
||||
int deviceIndex = AwtWin32GraphicsDevice::DeviceIndexForWindow(
|
||||
::GetDesktopWindow());
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(deviceIndex);
|
||||
return device == NULL ? x : device->ScaleDownX(x);
|
||||
}
|
||||
|
||||
static int ScaleDownY(int y) {
|
||||
int deviceIndex = AwtWin32GraphicsDevice::DeviceIndexForWindow(
|
||||
::GetDesktopWindow());
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(deviceIndex);
|
||||
return device == NULL ? y : device->ScaleDownY(y);
|
||||
}
|
||||
|
||||
static HFONT CreateHFont_sub(LPCWSTR name, int style, int height,
|
||||
int angle=0, float awScale=1.0f)
|
||||
{
|
||||
@ -424,7 +456,7 @@ static HFONT CreateHFont_sub(LPCWSTR name, int style, int height,
|
||||
logFont.lfUnderline = 0;//(style & java_awt_Font_UNDERLINE) != 0;
|
||||
|
||||
// Get point size
|
||||
logFont.lfHeight = -height;
|
||||
logFont.lfHeight = ScaleUpY(-height);
|
||||
|
||||
// Set font name
|
||||
WCHAR tmpname[80];
|
||||
@ -451,7 +483,7 @@ static HFONT CreateHFont_sub(LPCWSTR name, int style, int height,
|
||||
VERIFY(::DeleteObject(oldFont));
|
||||
}
|
||||
avgWidth = tm.tmAveCharWidth;
|
||||
logFont.lfWidth = (LONG)((fabs)(avgWidth*awScale));
|
||||
logFont.lfWidth = (LONG) ScaleUpX((fabs) (avgWidth * awScale));
|
||||
hFont = ::CreateFontIndirect(&logFont);
|
||||
DASSERT(hFont != NULL);
|
||||
VERIFY(::ReleaseDC(0, hDC));
|
||||
@ -535,19 +567,20 @@ void AwtFont::LoadMetrics(JNIEnv *env, jobject fontMetrics)
|
||||
int ascent = metrics.tmAscent;
|
||||
int descent = metrics.tmDescent;
|
||||
int leading = metrics.tmExternalLeading;
|
||||
env->SetIntField(fontMetrics, AwtFont::ascentID, ascent);
|
||||
env->SetIntField(fontMetrics, AwtFont::descentID, descent);
|
||||
env->SetIntField(fontMetrics, AwtFont::leadingID, leading);
|
||||
env->SetIntField(fontMetrics, AwtFont::heightID, metrics.tmAscent +
|
||||
metrics.tmDescent + leading);
|
||||
env->SetIntField(fontMetrics, AwtFont::maxAscentID, ascent);
|
||||
env->SetIntField(fontMetrics, AwtFont::maxDescentID, descent);
|
||||
|
||||
env->SetIntField(fontMetrics, AwtFont::ascentID, ScaleDownY(ascent));
|
||||
env->SetIntField(fontMetrics, AwtFont::descentID, ScaleDownY(descent));
|
||||
env->SetIntField(fontMetrics, AwtFont::leadingID, ScaleDownX(leading));
|
||||
env->SetIntField(fontMetrics, AwtFont::heightID,
|
||||
ScaleDownY(metrics.tmAscent + metrics.tmDescent + leading));
|
||||
env->SetIntField(fontMetrics, AwtFont::maxAscentID, ScaleDownY(ascent));
|
||||
env->SetIntField(fontMetrics, AwtFont::maxDescentID, ScaleDownY(descent));
|
||||
|
||||
int maxHeight = ascent + descent + leading;
|
||||
env->SetIntField(fontMetrics, AwtFont::maxHeightID, maxHeight);
|
||||
env->SetIntField(fontMetrics, AwtFont::maxHeightID, ScaleDownY(maxHeight));
|
||||
|
||||
int maxAdvance = metrics.tmMaxCharWidth;
|
||||
env->SetIntField(fontMetrics, AwtFont::maxAdvanceID, maxAdvance);
|
||||
env->SetIntField(fontMetrics, AwtFont::maxAdvanceID, ScaleDownX(maxAdvance));
|
||||
|
||||
awtFont->m_overhang = metrics.tmOverhang;
|
||||
|
||||
@ -818,6 +851,7 @@ Java_sun_awt_windows_WFontMetrics_stringWidth(JNIEnv *env, jobject self,
|
||||
jobject font = env->GetObjectField(self, AwtFont::fontID);
|
||||
|
||||
long ret = AwtFont::getMFStringWidth(hDC, font, str);
|
||||
ret = ScaleDownX(ret);
|
||||
VERIFY(::ReleaseDC(0, hDC));
|
||||
return ret;
|
||||
|
||||
@ -924,7 +958,7 @@ Java_sun_awt_windows_WFontMetrics_bytesWidth(JNIEnv *env, jobject self,
|
||||
}
|
||||
|
||||
env->ReleasePrimitiveArrayCritical(str, pStrBody, 0);
|
||||
return result;
|
||||
return ScaleDownX(result);
|
||||
|
||||
CATCH_BAD_ALLOC_RET(0);
|
||||
}
|
||||
|
||||
@ -80,6 +80,13 @@ void AwtRobot::MouseMove( jint x, jint y)
|
||||
(PVOID)newSpeed,
|
||||
SPIF_SENDCHANGE);
|
||||
|
||||
int primaryIndex = AwtWin32GraphicsDevice::GetDefaultDeviceIndex();
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(primaryIndex);
|
||||
|
||||
x = (device == NULL) ? x : device->ScaleUpX(x);
|
||||
y = (device == NULL) ? y : device->ScaleUpY(y);
|
||||
|
||||
POINT curPos;
|
||||
::GetCursorPos(&curPos);
|
||||
x -= curPos.x;
|
||||
@ -217,11 +224,24 @@ void AwtRobot::GetRGBPixels(jint x, jint y, jint width, jint height, jintArray p
|
||||
AwtWin32GraphicsDevice::SelectPalette(hdcMem, primaryIndex);
|
||||
AwtWin32GraphicsDevice::RealizePalette(hdcMem, primaryIndex);
|
||||
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(primaryIndex);
|
||||
int sWidth = (device == NULL) ? width : device->ScaleUpX(width);
|
||||
int sHeight = (device == NULL) ? height : device->ScaleUpY(height);
|
||||
|
||||
// copy screen image to offscreen bitmap
|
||||
// CAPTUREBLT flag is required to capture WS_EX_LAYERED windows' contents
|
||||
// correctly on Win2K/XP
|
||||
VERIFY(::BitBlt(hdcMem, 0, 0, width, height, hdcScreen, x, y,
|
||||
SRCCOPY|CAPTUREBLT) != 0);
|
||||
if (width == sWidth && height == sHeight) {
|
||||
VERIFY(::BitBlt(hdcMem, 0, 0, width, height, hdcScreen, x, y,
|
||||
SRCCOPY | CAPTUREBLT) != 0);
|
||||
} else {
|
||||
int sX = (device == NULL) ? x : device->ScaleUpX(x);
|
||||
int sY = (device == NULL) ? y : device->ScaleUpY(y);
|
||||
VERIFY(::StretchBlt(hdcMem, 0, 0, width, height,
|
||||
hdcScreen, sX, sY, sWidth, sHeight,
|
||||
SRCCOPY | CAPTUREBLT) != 0);
|
||||
}
|
||||
|
||||
static const int BITS_PER_PIXEL = 32;
|
||||
static const int BYTES_PER_PIXEL = BITS_PER_PIXEL/8;
|
||||
|
||||
@ -2355,8 +2355,13 @@ Java_sun_awt_windows_WToolkit_getScreenWidth(JNIEnv *env, jobject self)
|
||||
{
|
||||
TRY;
|
||||
|
||||
return ::GetSystemMetrics(SM_CXSCREEN);
|
||||
int width = ::GetSystemMetrics(SM_CXSCREEN);
|
||||
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(
|
||||
AwtWin32GraphicsDevice::GetDefaultDeviceIndex());
|
||||
|
||||
return (device == NULL) ? width : device->ScaleDownX(width);
|
||||
CATCH_BAD_ALLOC_RET(0);
|
||||
}
|
||||
|
||||
@ -2370,7 +2375,12 @@ Java_sun_awt_windows_WToolkit_getScreenHeight(JNIEnv *env, jobject self)
|
||||
{
|
||||
TRY;
|
||||
|
||||
return ::GetSystemMetrics(SM_CYSCREEN);
|
||||
int height = ::GetSystemMetrics(SM_CYSCREEN);
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(
|
||||
AwtWin32GraphicsDevice::GetDefaultDeviceIndex());
|
||||
|
||||
return (device == NULL) ? height : device->ScaleDownY(height);
|
||||
|
||||
CATCH_BAD_ALLOC_RET(0);
|
||||
}
|
||||
|
||||
@ -95,19 +95,31 @@ JNIEXPORT jobject JNICALL
|
||||
mid = env->GetMethodID(clazz, "<init>", "(IIII)V");
|
||||
if (mid != 0) {
|
||||
RECT rRW = {0, 0, 0, 0};
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
|
||||
if (TRUE == MonitorBounds(AwtWin32GraphicsDevice::GetMonitor(screen), &rRW)) {
|
||||
bounds = env->NewObject(clazz, mid,
|
||||
rRW.left, rRW.top,
|
||||
rRW.right - rRW.left,
|
||||
rRW.bottom - rRW.top);
|
||||
|
||||
int x = (device == NULL) ? rRW.left : device->ScaleDownX(rRW.left);
|
||||
int y = (device == NULL) ? rRW.top : device->ScaleDownY(rRW.top);
|
||||
int w = (device == NULL) ? rRW.right - rRW.left
|
||||
: device->ScaleDownX(rRW.right - rRW.left);
|
||||
int h = (device == NULL) ? rRW.bottom - rRW.top
|
||||
: device->ScaleDownY(rRW.bottom - rRW.top);
|
||||
|
||||
bounds = env->NewObject(clazz, mid, x, y, w, h);
|
||||
|
||||
}
|
||||
else {
|
||||
// 4910760 - don't return a null bounds, return the bounds of the
|
||||
// primary screen
|
||||
int w = ::GetSystemMetrics(SM_CXSCREEN);
|
||||
int h = ::GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
bounds = env->NewObject(clazz, mid,
|
||||
0, 0,
|
||||
::GetSystemMetrics(SM_CXSCREEN),
|
||||
::GetSystemMetrics(SM_CYSCREEN));
|
||||
device == NULL ? w : device->ScaleDownX(w),
|
||||
device == NULL ? h : device->ScaleDownY(h));
|
||||
}
|
||||
if (safe_ExceptionOccurred(env)) {
|
||||
return 0;
|
||||
|
||||
@ -49,6 +49,12 @@
|
||||
#include "dither.h"
|
||||
#include "img_util_md.h"
|
||||
#include "Devices.h"
|
||||
#include <d2d1.h>
|
||||
#pragma comment(lib, "d2d1")
|
||||
|
||||
#ifndef MDT_Effective_DPI
|
||||
#define MDT_Effective_DPI 0
|
||||
#endif
|
||||
|
||||
uns_ordered_dither_array img_oda_alpha;
|
||||
|
||||
@ -74,6 +80,8 @@ AwtWin32GraphicsDevice::AwtWin32GraphicsDevice(int screen,
|
||||
{
|
||||
this->screen = screen;
|
||||
this->devicesArray = arr;
|
||||
this->scaleX = 1;
|
||||
this->scaleY = 1;
|
||||
javaDevice = NULL;
|
||||
colorData = new ImgColorData;
|
||||
colorData->grayscale = GS_NOTGRAY;
|
||||
@ -616,6 +624,104 @@ void AwtWin32GraphicsDevice::SetJavaDevice(JNIEnv *env, jobject objPtr)
|
||||
javaDevice = env->NewWeakGlobalRef(objPtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets horizontal and vertical scale factors
|
||||
*/
|
||||
void AwtWin32GraphicsDevice::SetScale(float sx, float sy)
|
||||
{
|
||||
scaleX = sx;
|
||||
scaleY = sy;
|
||||
}
|
||||
|
||||
int AwtWin32GraphicsDevice::ScaleUpX(int x)
|
||||
{
|
||||
return (int)ceil(x * scaleX);
|
||||
}
|
||||
|
||||
int AwtWin32GraphicsDevice::ScaleUpY(int y)
|
||||
{
|
||||
return (int)ceil(y * scaleY);
|
||||
}
|
||||
|
||||
int AwtWin32GraphicsDevice::ScaleDownX(int x)
|
||||
{
|
||||
return (int)ceil(x / scaleX);
|
||||
}
|
||||
|
||||
int AwtWin32GraphicsDevice::ScaleDownY(int y)
|
||||
{
|
||||
return (int)ceil(y / scaleY);
|
||||
}
|
||||
|
||||
void AwtWin32GraphicsDevice::InitDesktopScales()
|
||||
{
|
||||
unsigned x = 0;
|
||||
unsigned y = 0;
|
||||
float dpiX = -1.0f;
|
||||
float dpiY = -1.0f;
|
||||
|
||||
// for debug purposes
|
||||
static float scale = -2.0f;
|
||||
if (scale == -2) {
|
||||
scale = -1;
|
||||
char *uiScale = getenv("J2D_UISCALE");
|
||||
if (uiScale != NULL) {
|
||||
scale = (float)strtod(uiScale, NULL);
|
||||
if (errno == ERANGE || scale <= 0) {
|
||||
scale = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scale > 0) {
|
||||
SetScale(scale, scale);
|
||||
return;
|
||||
}
|
||||
|
||||
typedef HRESULT(WINAPI GetDpiForMonitorFunc)(HMONITOR, int, UINT*, UINT*);
|
||||
static HMODULE hLibSHCoreDll = NULL;
|
||||
static GetDpiForMonitorFunc *lpGetDpiForMonitor = NULL;
|
||||
|
||||
if (hLibSHCoreDll == NULL) {
|
||||
hLibSHCoreDll = JDK_LoadSystemLibrary("shcore.dll");
|
||||
if (hLibSHCoreDll != NULL) {
|
||||
lpGetDpiForMonitor = (GetDpiForMonitorFunc*)GetProcAddress(
|
||||
hLibSHCoreDll, "GetDpiForMonitor");
|
||||
}
|
||||
}
|
||||
|
||||
if (lpGetDpiForMonitor != NULL) {
|
||||
HRESULT hResult = lpGetDpiForMonitor(GetMonitor(),
|
||||
MDT_Effective_DPI, &x, &y);
|
||||
if (hResult == S_OK) {
|
||||
dpiX = static_cast<float>(x);
|
||||
dpiY = static_cast<float>(y);
|
||||
}
|
||||
} else {
|
||||
ID2D1Factory* m_pDirect2dFactory;
|
||||
HRESULT res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||
&m_pDirect2dFactory);
|
||||
if (res == S_OK) {
|
||||
m_pDirect2dFactory->GetDesktopDpi(&dpiX, &dpiY);
|
||||
m_pDirect2dFactory->Release();
|
||||
}
|
||||
}
|
||||
|
||||
if (dpiX > 0 && dpiY > 0) {
|
||||
SetScale(dpiX / 96, dpiY / 96);
|
||||
}
|
||||
}
|
||||
|
||||
float AwtWin32GraphicsDevice::GetScaleX()
|
||||
{
|
||||
return scaleX;
|
||||
}
|
||||
|
||||
float AwtWin32GraphicsDevice::GetScaleY()
|
||||
{
|
||||
return scaleY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables offscreen acceleration for this device. This
|
||||
* sets a flag in the java object that is used to determine
|
||||
@ -1304,3 +1410,65 @@ JNIEXPORT void JNICALL
|
||||
Devices::InstanceAccess devices;
|
||||
devices->GetDevice(screen)->SetJavaDevice(env, thisPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_Win32GraphicsDevice
|
||||
* Method: setNativeScale
|
||||
* Signature: (I,F,F)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_awt_Win32GraphicsDevice_setNativeScale
|
||||
(JNIEnv *env, jobject thisPtr, jint screen, jfloat scaleX, jfloat scaleY)
|
||||
{
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
|
||||
if (device != NULL ) {
|
||||
device->SetScale(scaleX, scaleY);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_Win32GraphicsDevice
|
||||
* Method: getNativeScaleX
|
||||
* Signature: (I)F
|
||||
*/
|
||||
JNIEXPORT jfloat JNICALL
|
||||
Java_sun_awt_Win32GraphicsDevice_getNativeScaleX
|
||||
(JNIEnv *env, jobject thisPtr, jint screen)
|
||||
{
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
return (device == NULL) ? 1 : device->GetScaleX();
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_Win32GraphicsDevice
|
||||
* Method: getNativeScaleY
|
||||
* Signature: (I)F
|
||||
*/
|
||||
JNIEXPORT jfloat JNICALL
|
||||
Java_sun_awt_Win32GraphicsDevice_getNativeScaleY
|
||||
(JNIEnv *env, jobject thisPtr, jint screen)
|
||||
{
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
return (device == NULL) ? 1 : device->GetScaleY();
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_Win32GraphicsDevice
|
||||
* Method: initNativeScale
|
||||
* Signature: (I)V;
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_awt_Win32GraphicsDevice_initNativeScale
|
||||
(JNIEnv *env, jobject thisPtr, jint screen)
|
||||
{
|
||||
Devices::InstanceAccess devices;
|
||||
AwtWin32GraphicsDevice *device = devices->GetDevice(screen);
|
||||
|
||||
if (device != NULL) {
|
||||
device->InitDesktopScales();
|
||||
}
|
||||
}
|
||||
@ -66,6 +66,14 @@ public:
|
||||
void Release();
|
||||
void DisableOffscreenAcceleration();
|
||||
void Invalidate(JNIEnv *env);
|
||||
void InitDesktopScales();
|
||||
void SetScale(float scaleX, float scaleY);
|
||||
float GetScaleX();
|
||||
float GetScaleY();
|
||||
int ScaleUpX(int x);
|
||||
int ScaleUpY(int y);
|
||||
int ScaleDownX(int x);
|
||||
int ScaleDownY(int y);
|
||||
|
||||
static int DeviceIndexForWindow(HWND hWnd);
|
||||
static jobject GetColorModel(JNIEnv *env, jboolean dynamic,
|
||||
@ -107,6 +115,8 @@ private:
|
||||
LPMONITORINFO pMonitorInfo;
|
||||
jobject javaDevice;
|
||||
Devices *devicesArray;
|
||||
float scaleX;
|
||||
float scaleY;
|
||||
|
||||
static HDC MakeDCFromMonitor(HMONITOR);
|
||||
};
|
||||
|
||||
@ -1407,19 +1407,19 @@ BOOL AwtWindow::UpdateInsets(jobject insets)
|
||||
/* Get insets into our peer directly */
|
||||
jobject peerInsets = (env)->GetObjectField(peer, AwtPanel::insets_ID);
|
||||
DASSERT(!safe_ExceptionOccurred(env));
|
||||
|
||||
if (peerInsets != NULL) { // may have been called during creation
|
||||
(env)->SetIntField(peerInsets, AwtInsets::topID, m_insets.top);
|
||||
(env)->SetIntField(peerInsets, AwtInsets::bottomID,
|
||||
m_insets.bottom);
|
||||
(env)->SetIntField(peerInsets, AwtInsets::leftID, m_insets.left);
|
||||
(env)->SetIntField(peerInsets, AwtInsets::rightID, m_insets.right);
|
||||
(env)->SetIntField(peerInsets, AwtInsets::topID, ScaleDownY(m_insets.top));
|
||||
(env)->SetIntField(peerInsets, AwtInsets::bottomID, ScaleDownY(m_insets.bottom));
|
||||
(env)->SetIntField(peerInsets, AwtInsets::leftID, ScaleDownX(m_insets.left));
|
||||
(env)->SetIntField(peerInsets, AwtInsets::rightID, ScaleDownX(m_insets.right));
|
||||
}
|
||||
/* Get insets into the Inset object (if any) that was passed */
|
||||
if (insets != NULL) {
|
||||
(env)->SetIntField(insets, AwtInsets::topID, m_insets.top);
|
||||
(env)->SetIntField(insets, AwtInsets::bottomID, m_insets.bottom);
|
||||
(env)->SetIntField(insets, AwtInsets::leftID, m_insets.left);
|
||||
(env)->SetIntField(insets, AwtInsets::rightID, m_insets.right);
|
||||
(env)->SetIntField(insets, AwtInsets::topID, ScaleDownY(m_insets.top));
|
||||
(env)->SetIntField(insets, AwtInsets::bottomID, ScaleDownY(m_insets.bottom));
|
||||
(env)->SetIntField(insets, AwtInsets::leftID, ScaleDownX(m_insets.left));
|
||||
(env)->SetIntField(insets, AwtInsets::rightID, ScaleDownX(m_insets.right));
|
||||
}
|
||||
env->DeleteLocalRef(peerInsets);
|
||||
|
||||
@ -1735,10 +1735,10 @@ MsgRouting AwtWindow::WmMove(int x, int y)
|
||||
RECT rect;
|
||||
::GetWindowRect(GetHWnd(), &rect);
|
||||
|
||||
(env)->SetIntField(target, AwtComponent::xID, rect.left);
|
||||
(env)->SetIntField(target, AwtComponent::yID, rect.top);
|
||||
(env)->SetIntField(peer, AwtWindow::sysXID, rect.left);
|
||||
(env)->SetIntField(peer, AwtWindow::sysYID, rect.top);
|
||||
(env)->SetIntField(target, AwtComponent::xID, ScaleDownX(rect.left));
|
||||
(env)->SetIntField(target, AwtComponent::yID, ScaleDownY(rect.top));
|
||||
(env)->SetIntField(peer, AwtWindow::sysXID, ScaleDownX(rect.left));
|
||||
(env)->SetIntField(peer, AwtWindow::sysYID, ScaleDownY(rect.top));
|
||||
SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED);
|
||||
|
||||
env->DeleteLocalRef(target);
|
||||
@ -1803,12 +1803,12 @@ MsgRouting AwtWindow::WmSize(UINT type, int w, int h)
|
||||
int newWidth = w + m_insets.left + m_insets.right;
|
||||
int newHeight = h + m_insets.top + m_insets.bottom;
|
||||
|
||||
(env)->SetIntField(target, AwtComponent::widthID, newWidth);
|
||||
(env)->SetIntField(target, AwtComponent::heightID, newHeight);
|
||||
(env)->SetIntField(target, AwtComponent::widthID, ScaleDownX(newWidth));
|
||||
(env)->SetIntField(target, AwtComponent::heightID, ScaleDownY(newHeight));
|
||||
|
||||
jobject peer = GetPeer(env);
|
||||
(env)->SetIntField(peer, AwtWindow::sysWID, newWidth);
|
||||
(env)->SetIntField(peer, AwtWindow::sysHID, newHeight);
|
||||
(env)->SetIntField(peer, AwtWindow::sysWID, ScaleDownX(newWidth));
|
||||
(env)->SetIntField(peer, AwtWindow::sysHID, ScaleDownY(newHeight));
|
||||
|
||||
if (!AwtWindow::IsResizing()) {
|
||||
WindowResized();
|
||||
@ -3072,6 +3072,25 @@ void AwtWindow::_SetFullScreenExclusiveModeState(void *param)
|
||||
delete data;
|
||||
}
|
||||
|
||||
void AwtWindow::_GetNativeWindowSize(void* param) {
|
||||
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
|
||||
SizeStruct *ss = (SizeStruct *)param;
|
||||
jobject self = ss->window;
|
||||
AwtWindow *window = NULL;
|
||||
PDATA pData;
|
||||
JNI_CHECK_PEER_RETURN(self);
|
||||
window = (AwtWindow *)pData;
|
||||
|
||||
RECT rc;
|
||||
::GetWindowRect(window->GetHWnd(), &rc);
|
||||
ss->w = rc.right - rc.left;
|
||||
ss->h = rc.bottom - rc.top;
|
||||
|
||||
env->DeleteGlobalRef(self);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*
|
||||
@ -3301,6 +3320,46 @@ Java_sun_awt_windows_WWindowPeer_reshapeFrame(JNIEnv *env, jobject self,
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_windows_WWindowPeer
|
||||
* Method: getNativeWindowSize
|
||||
* Signature: ()Ljava/awt/Dimension;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_sun_awt_windows_WWindowPeer_getNativeWindowSize
|
||||
(JNIEnv *env, jobject self) {
|
||||
|
||||
jobject res = NULL;
|
||||
TRY;
|
||||
SizeStruct *ss = new SizeStruct;
|
||||
ss->window = env->NewGlobalRef(self);
|
||||
|
||||
AwtToolkit::GetInstance().SyncCall(AwtWindow::_GetNativeWindowSize, ss);
|
||||
|
||||
int w = ss->w;
|
||||
int h = ss->h;
|
||||
|
||||
delete ss;
|
||||
// global ref is deleted in _GetNativeWindowSize()
|
||||
|
||||
static jmethodID dimMID = NULL;
|
||||
static jclass dimClassID = NULL;
|
||||
if (dimClassID == NULL) {
|
||||
jclass dimClassIDLocal = env->FindClass("java/awt/Dimension");
|
||||
CHECK_NULL_RETURN(dimClassIDLocal, NULL);
|
||||
dimClassID = (jclass)env->NewGlobalRef(dimClassIDLocal);
|
||||
env->DeleteLocalRef(dimClassIDLocal);
|
||||
}
|
||||
|
||||
if (dimMID == NULL) {
|
||||
dimMID = env->GetMethodID(dimClassID, "<init>", "(II)V");
|
||||
CHECK_NULL_RETURN(dimMID, NULL);
|
||||
}
|
||||
|
||||
return env->NewObject(dimClassID, dimMID, w, h);
|
||||
|
||||
CATCH_BAD_ALLOC_RET(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: sun_awt_windows_WWindowPeer
|
||||
* Method: getSysMinWidth
|
||||
|
||||
@ -241,6 +241,7 @@ public:
|
||||
static void _UpdateWindow(void* param);
|
||||
static void _RepositionSecurityWarning(void* param);
|
||||
static void _SetFullScreenExclusiveModeState(void* param);
|
||||
static void _GetNativeWindowSize(void* param);
|
||||
|
||||
inline static BOOL IsResizing() {
|
||||
return sm_resizing;
|
||||
|
||||
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.Frame;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/* @test
|
||||
* @bug 8073320
|
||||
* @summary Windows HiDPI support
|
||||
* @author Alexander Scherbatiy
|
||||
* @requires (os.family == "windows")
|
||||
* @run main/othervm -Dsun.java2d.win.uiScale=2 HiDPIRobotMouseClick
|
||||
*/
|
||||
public class HiDPIRobotMouseClick {
|
||||
|
||||
private static volatile int mouseX;
|
||||
private static volatile int mouseY;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel(
|
||||
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
|
||||
} catch (Exception e) {
|
||||
return;
|
||||
}
|
||||
|
||||
Frame frame = new Frame();
|
||||
frame.setBounds(30, 20, 400, 300);
|
||||
frame.setUndecorated(true);
|
||||
|
||||
frame.addMouseListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
mouseX = e.getXOnScreen();
|
||||
mouseY = e.getYOnScreen();
|
||||
}
|
||||
});
|
||||
|
||||
frame.setVisible(true);
|
||||
|
||||
Robot robot = new Robot();
|
||||
robot.waitForIdle();
|
||||
Thread.sleep(200);
|
||||
|
||||
Rectangle rect = frame.getBounds();
|
||||
rect.setLocation(frame.getLocationOnScreen());
|
||||
|
||||
int x = (int) rect.getCenterX();
|
||||
int y = (int) rect.getCenterY();
|
||||
|
||||
robot.mouseMove(x, y);
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||
robot.waitForIdle();
|
||||
|
||||
if (x != mouseX || y != mouseY) {
|
||||
throw new RuntimeException("Wrong mouse click point!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Canvas;
|
||||
import java.awt.Color;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Panel;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/* @test
|
||||
* @bug 8073320
|
||||
* @summary Windows HiDPI support
|
||||
* @author Alexander Scherbatiy
|
||||
* @requires (os.family == "windows")
|
||||
* @run main/othervm -Dsun.java2d.win.uiScaleX=3 -Dsun.java2d.win.uiScaleY=2
|
||||
* HiDPIRobotScreenCaptureTest
|
||||
*/
|
||||
public class HiDPIRobotScreenCaptureTest {
|
||||
|
||||
private static final Color[] COLORS = {
|
||||
Color.GREEN, Color.BLUE, Color.ORANGE, Color.RED};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel(
|
||||
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
|
||||
} catch (Exception e) {
|
||||
return;
|
||||
}
|
||||
|
||||
Frame frame = new Frame();
|
||||
frame.setBounds(40, 30, 400, 300);
|
||||
frame.setUndecorated(true);
|
||||
|
||||
Panel panel = new Panel(new BorderLayout());
|
||||
Canvas canvas = new Canvas() {
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
int w = getWidth();
|
||||
int h = getHeight();
|
||||
g.setColor(COLORS[0]);
|
||||
g.fillRect(0, 0, w / 2, h / 2);
|
||||
g.setColor(COLORS[1]);
|
||||
g.fillRect(w / 2, 0, w / 2, h / 2);
|
||||
g.setColor(COLORS[2]);
|
||||
g.fillRect(0, h / 2, w / 2, h / 2);
|
||||
g.setColor(COLORS[3]);
|
||||
g.fillRect(w / 2, h / 2, w / 2, h / 2);
|
||||
}
|
||||
};
|
||||
|
||||
panel.add(canvas);
|
||||
frame.add(panel);
|
||||
frame.setVisible(true);
|
||||
Robot robot = new Robot();
|
||||
robot.waitForIdle();
|
||||
Thread.sleep(200);
|
||||
|
||||
Rectangle rect = canvas.getBounds();
|
||||
rect.setLocation(canvas.getLocationOnScreen());
|
||||
|
||||
BufferedImage image = robot.createScreenCapture(rect);
|
||||
frame.dispose();
|
||||
|
||||
int w = image.getWidth();
|
||||
int h = image.getHeight();
|
||||
|
||||
if (w != frame.getWidth() || h != frame.getHeight()) {
|
||||
throw new RuntimeException("Wrong image size!");
|
||||
}
|
||||
|
||||
if (image.getRGB(w / 4, h / 4) != COLORS[0].getRGB()) {
|
||||
throw new RuntimeException("Wrong image color!");
|
||||
}
|
||||
|
||||
if (image.getRGB(3 * w / 4, h / 4) != COLORS[1].getRGB()) {
|
||||
throw new RuntimeException("Wrong image color!");
|
||||
}
|
||||
|
||||
if (image.getRGB(w / 4, 3 * h / 4) != COLORS[2].getRGB()) {
|
||||
throw new RuntimeException("Wrong image color!");
|
||||
}
|
||||
|
||||
if (image.getRGB(3 * w / 4, 3 * h / 4) != COLORS[3].getRGB()) {
|
||||
throw new RuntimeException("Wrong image color!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/* @test
|
||||
* @bug 8073320
|
||||
* @summary Windows HiDPI support
|
||||
* @author Alexander Scherbatiy
|
||||
* @requires (os.family == "windows")
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=false
|
||||
* -Dsun.java2d.win.uiScaleX=3 -Dsun.java2d.win.uiScaleY=2
|
||||
* HiDPIPropertiesWindowsTest UISCALE_DISABLED
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=false
|
||||
* -Dsun.java2d.uiScale=3
|
||||
* HiDPIPropertiesWindowsTest UISCALE_DISABLED
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=false
|
||||
* -Dsun.java2d.uiScale=3
|
||||
* -Dsun.java2d.win.uiScaleX=5 -Dsun.java2d.win.uiScaleY=6
|
||||
* HiDPIPropertiesWindowsTest UISCALE_DISABLED
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=true
|
||||
* -Dsun.java2d.uiScale=3
|
||||
* HiDPIPropertiesWindowsTest UISCALE_3
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=true
|
||||
* -Dsun.java2d.uiScale=4
|
||||
* -Dsun.java2d.win.uiScaleX=2 -Dsun.java2d.win.uiScaleY=3
|
||||
* HiDPIPropertiesWindowsTest UISCALE_2X3
|
||||
* @run main/othervm -Dsun.java2d.uiScale.enabled=true
|
||||
* -Dsun.java2d.win.uiScaleX=3 -Dsun.java2d.win.uiScaleY=2
|
||||
* HiDPIPropertiesWindowsTest UISCALE_3X2
|
||||
* @run main/othervm -Dsun.java2d.uiScale=4
|
||||
* HiDPIPropertiesWindowsTest UISCALE_4
|
||||
* @run main/othervm -Dsun.java2d.uiScale=4
|
||||
* -Dsun.java2d.win.uiScaleX=2 -Dsun.java2d.win.uiScaleY=3
|
||||
* HiDPIPropertiesWindowsTest UISCALE_2X3
|
||||
* @run main/othervm -Dsun.java2d.win.uiScaleX=4 -Dsun.java2d.win.uiScaleY=5
|
||||
* HiDPIPropertiesWindowsTest UISCALE_4X5
|
||||
* @run main/othervm -Dsun.java2d.uiScale=3
|
||||
* -Dsun.java2d.win.uiScaleX=0 -Dsun.java2d.win.uiScaleY=0
|
||||
* HiDPIPropertiesWindowsTest UISCALE_3
|
||||
* @run main/othervm -Dsun.java2d.uiScale=4
|
||||
* -Dsun.java2d.win.uiScaleX=-7 -Dsun.java2d.win.uiScaleY=-8
|
||||
* HiDPIPropertiesWindowsTest UISCALE_4
|
||||
* @run main/othervm -Dsun.java2d.uiScale=4x
|
||||
* HiDPIPropertiesWindowsTest UISCALE_4
|
||||
* @run main/othervm -Dsun.java2d.win.uiScaleX=4x -Dsun.java2d.win.uiScaleY=5x
|
||||
* HiDPIPropertiesWindowsTest UISCALE_4X5
|
||||
* @run main/othervm -Dsun.java2d.uiScale=384dpi
|
||||
* HiDPIPropertiesWindowsTest UISCALE_4
|
||||
* @run main/othervm -Dsun.java2d.uiScale=300%
|
||||
* HiDPIPropertiesWindowsTest UISCALE_3
|
||||
* @run main/othervm -Dsun.java2d.win.uiScaleX=400% -Dsun.java2d.win.uiScaleY=500%
|
||||
* HiDPIPropertiesWindowsTest UISCALE_4X5
|
||||
* @run main/othervm -Dsun.java2d.win.uiScaleX=288dpi -Dsun.java2d.win.uiScaleY=192dpi
|
||||
* HiDPIPropertiesWindowsTest UISCALE_3X2
|
||||
* @run main/othervm -Dsun.java2d.win.uiScaleX=200% -Dsun.java2d.win.uiScaleY=288dpi
|
||||
* HiDPIPropertiesWindowsTest UISCALE_2X3
|
||||
*/
|
||||
public class HiDPIPropertiesWindowsTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel(
|
||||
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
|
||||
} catch (Exception e) {
|
||||
return;
|
||||
}
|
||||
|
||||
String testCase = args[0];
|
||||
switch (testCase) {
|
||||
case "UISCALE_DISABLED":
|
||||
testScale(1.0, 1.0);
|
||||
break;
|
||||
case "UISCALE_3":
|
||||
testScale(3.0, 3.0);
|
||||
break;
|
||||
case "UISCALE_4":
|
||||
testScale(4.0, 4.0);
|
||||
break;
|
||||
case "UISCALE_2X3":
|
||||
testScale(2.0, 3.0);
|
||||
break;
|
||||
case "UISCALE_3X2":
|
||||
testScale(3.0, 2.0);
|
||||
break;
|
||||
case "UISCALE_4X5":
|
||||
testScale(4.0, 5.0);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unknown test case: " + testCase);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testScale(double scaleX, double scaleY) {
|
||||
|
||||
Dialog dialog = new Dialog((Frame) null, true) {
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
AffineTransform tx = ((Graphics2D) g).getTransform();
|
||||
dispose();
|
||||
if (scaleX != tx.getScaleX() || scaleY != tx.getScaleY()) {
|
||||
throw new RuntimeException(String.format("Wrong scale:"
|
||||
+ "[%f, %f] instead of [%f, %f].",
|
||||
tx.getScaleX(), tx.getScaleY(), scaleX, scaleY));
|
||||
}
|
||||
}
|
||||
};
|
||||
dialog.setSize(200, 300);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.BaseMultiResolutionImage;
|
||||
import static java.awt.RenderingHints.KEY_RESOLUTION_VARIANT;
|
||||
import static java.awt.RenderingHints.VALUE_RESOLUTION_VARIANT_SIZE_FIT;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import sun.java2d.StateTrackable;
|
||||
import sun.java2d.SunGraphics2D;
|
||||
import sun.java2d.SurfaceData;
|
||||
import sun.java2d.loops.SurfaceType;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8073320
|
||||
* @author Alexander Scherbatiy
|
||||
* @summary Windows HiDPI support
|
||||
* @modules java.desktop/sun.java2d java.desktop/sun.java2d.loops
|
||||
* @run main MultiResolutionDrawImageWithTransformTest
|
||||
*/
|
||||
public class MultiResolutionDrawImageWithTransformTest {
|
||||
|
||||
private static final int SCREEN_SIZE = 400;
|
||||
private static final int IMAGE_SIZE = SCREEN_SIZE / 4;
|
||||
private static final Color BACKGROUND_COLOR = Color.PINK;
|
||||
private static final Color[] COLORS = {
|
||||
Color.CYAN, Color.GREEN, Color.BLUE, Color.ORANGE
|
||||
};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
int length = COLORS.length;
|
||||
BufferedImage[] resolutionVariants = new BufferedImage[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
resolutionVariants[i] = createRVImage(getSize(i), COLORS[i]);
|
||||
}
|
||||
|
||||
BaseMultiResolutionImage mrImage = new BaseMultiResolutionImage(
|
||||
resolutionVariants);
|
||||
|
||||
// scale 1, transform 1, resolution variant 1
|
||||
Color color = getImageColor(mrImage, 1, 1);
|
||||
if (!getColorForScale(1).equals(color)) {
|
||||
throw new RuntimeException("Wrong resolution variant!");
|
||||
}
|
||||
|
||||
// scale 1, transform 2, resolution variant 2
|
||||
color = getImageColor(mrImage, 1, 2);
|
||||
if (!getColorForScale(2).equals(color)) {
|
||||
throw new RuntimeException("Wrong resolution variant!");
|
||||
}
|
||||
|
||||
// scale 2, transform 1, resolution variant 2
|
||||
color = getImageColor(mrImage, 2, 1);
|
||||
if (!getColorForScale(2).equals(color)) {
|
||||
throw new RuntimeException("Wrong resolution variant!");
|
||||
}
|
||||
|
||||
// scale 2, transform 2, resolution variant 4
|
||||
color = getImageColor(mrImage, 2, 2);
|
||||
if (!getColorForScale(4).equals(color)) {
|
||||
throw new RuntimeException("Wrong resolution variant!");
|
||||
}
|
||||
}
|
||||
|
||||
private static Color getColorForScale(int scale) {
|
||||
return COLORS[scale - 1];
|
||||
}
|
||||
|
||||
private static Color getImageColor(Image image, double configScale,
|
||||
double transformScale) {
|
||||
|
||||
TestSurfaceData surface = new TestSurfaceData(SCREEN_SIZE, SCREEN_SIZE,
|
||||
configScale);
|
||||
SunGraphics2D g2d = new SunGraphics2D(surface,
|
||||
Color.BLACK, Color.BLACK, null);
|
||||
g2d.setRenderingHint(KEY_RESOLUTION_VARIANT,
|
||||
VALUE_RESOLUTION_VARIANT_SIZE_FIT);
|
||||
AffineTransform tx = AffineTransform.getScaleInstance(transformScale,
|
||||
transformScale);
|
||||
g2d.drawImage(image, tx, null);
|
||||
g2d.dispose();
|
||||
|
||||
int backgroundX = (int) (1.5 * image.getWidth(null) * transformScale);
|
||||
int backgroundY = (int) (1.5 * image.getHeight(null) * transformScale);
|
||||
Color backgroundColor = surface.getColor(backgroundX, backgroundY);
|
||||
//surface.show(String.format("Config: %f, transform: %f", configScale, transformScale));
|
||||
if (!BACKGROUND_COLOR.equals(backgroundColor)) {
|
||||
throw new RuntimeException("Wrong background color!");
|
||||
}
|
||||
return surface.getColor(IMAGE_SIZE / 4, IMAGE_SIZE / 4);
|
||||
}
|
||||
|
||||
private static int getSize(int i) {
|
||||
return (i + 1) * IMAGE_SIZE;
|
||||
}
|
||||
|
||||
private static BufferedImage createRVImage(int size, Color color) {
|
||||
BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics g = image.createGraphics();
|
||||
g.setColor(color);
|
||||
g.fillRect(0, 0, size, size);
|
||||
g.dispose();
|
||||
return image;
|
||||
}
|
||||
|
||||
static class TestGraphicsConfig extends GraphicsConfiguration {
|
||||
|
||||
private final double scale;
|
||||
|
||||
TestGraphicsConfig(double scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphicsDevice getDevice() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorModel getColorModel() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorModel getColorModel(int transparency) {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AffineTransform getDefaultTransform() {
|
||||
return AffineTransform.getScaleInstance(scale, scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AffineTransform getNormalizingTransform() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle getBounds() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
}
|
||||
|
||||
static class TestSurfaceData extends SurfaceData {
|
||||
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final GraphicsConfiguration gc;
|
||||
private final BufferedImage buffImage;
|
||||
private final double scale;
|
||||
|
||||
public TestSurfaceData(int width, int height, double scale) {
|
||||
super(StateTrackable.State.DYNAMIC, SurfaceType.Custom, ColorModel.getRGBdefault());
|
||||
this.scale = scale;
|
||||
gc = new TestGraphicsConfig(scale);
|
||||
this.width = (int) Math.ceil(scale * width);
|
||||
this.height = (int) Math.ceil(scale * height);
|
||||
buffImage = new BufferedImage(this.width, this.height,
|
||||
BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
Graphics imageGraphics = buffImage.createGraphics();
|
||||
imageGraphics.setColor(BACKGROUND_COLOR);
|
||||
imageGraphics.fillRect(0, 0, this.width, this.height);
|
||||
imageGraphics.dispose();
|
||||
}
|
||||
|
||||
Color getColor(int x, int y) {
|
||||
int sx = (int) Math.ceil(x * scale);
|
||||
int sy = (int) Math.ceil(y * scale);
|
||||
return new Color(buffImage.getRGB(sx, sy));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurfaceData getReplacement() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphicsConfiguration getDeviceConfiguration() {
|
||||
return gc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Raster getRaster(int x, int y, int w, int h) {
|
||||
return buffImage.getRaster();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle getBounds() {
|
||||
return new Rectangle(0, 0, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDestination() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
private void show(String title) {
|
||||
Frame frame = new Frame() {
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
g.drawImage(buffImage, 0, 0, this);
|
||||
g.setColor(Color.GRAY);
|
||||
g.drawRect(0, 0, width, height);
|
||||
g.drawRect(0, height / 2, width, height / 2);
|
||||
g.drawRect(width / 2, 0, width / 2, height);
|
||||
}
|
||||
};
|
||||
frame.setTitle(title);
|
||||
frame.setSize(width, height);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user