/*
* This file is modified by Ivan Maidanski <ivmai@ivmaisoft.com>
* Project name: JCGO-SUNAWT (http://www.ivmaisoft.com/jcgo/)
*/
/*
* @(#)Win32SurfaceData.java 1.44 03/01/23
*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package sun.awt.windows;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.GraphicsConfiguration;
import java.awt.color.ColorSpace;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.Raster;
import sun.awt.SunHints;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.java2d.pipe.Region;
import sun.java2d.pipe.PixelToShapeConverter;
import sun.java2d.loops.GraphicsPrimitive;
import sun.java2d.loops.SurfaceType;
import sun.java2d.loops.CompositeType;
import sun.java2d.loops.RenderLoops;
import sun.java2d.loops.XORComposite;
import sun.awt.Win32ColorModel24;
import sun.awt.Win32GraphicsConfig;
import sun.awt.Win32GraphicsDevice;
import sun.awt.image.PixelConverter;
public class Win32SurfaceData extends SurfaceData {
WComponentPeer peer;
private Win32GraphicsConfig graphicsConfig;
private RenderLoops solidloops;
// GDI onscreen surface type
public static final String
DESC_GDI = "GDI";
// DDraw offscreen surface type names
public static final String
DESC_INT_RGB_DD = "Integer RGB DirectDraw";
public static final String
DESC_INT_RGBx_DD = "Integer RGBx DirectDraw";
public static final String
DESC_USHORT_565_RGB_DD = "Short 565 RGB DirectDraw";
public static final String
DESC_USHORT_555_RGBx_DD = "Short 555 RGBx DirectDraw";
public static final String
DESC_USHORT_555_RGB_DD = "Short 555 RGB DirectDraw";
public static final String
DESC_BYTE_INDEXED_OPAQUE_DD
= "8-bit Indexed (Opaque) DirectDraw";
public static final String
DESC_BYTE_GRAY_DD = "Byte Gray DirectDraw";
public static final String
DESC_INDEX8_GRAY_DD = "Index8 Gray DirectDraw";
public static final String
DESC_3BYTE_BGR_DD = "3 Byte BGR DirectDraw";
// Surface types with 1-bit transparency
public static final String
DESC_INT_RGB_DD_BM = "Integer RGB DirectDraw with 1 bit transp";
public static final String
DESC_INT_RGBx_DD_BM = "Integer RGBx DirectDraw with 1 bit transp";
public static final String
DESC_USHORT_565_RGB_DD_BM
= "Short 565 RGB DirectDraw with 1 bit transp";
public static final String
DESC_USHORT_555_RGBx_DD_BM
= "Short 555 RGBx DirectDraw with 1 bit transp";
public static final String
DESC_USHORT_555_RGB_DD_BM
= "Short 555 RGB DirectDraw with 1 bit transp";
public static final String
DESC_3BYTE_BGR_DD_BM = "3 Byte BGR DirectDraw with 1 bit transp";
public static final String
DESC_BYTE_INDEXED_DD_BM = "8-bit Indexed DirectDraw with 1 bit transp";
public static final String
DESC_BYTE_GRAY_DD_BM = "Byte Gray DirectDraw with 1 bit transp";
public static final String
DESC_INDEX8_GRAY_DD_BM = "Index8 Gray DirectDraw with 1 bit transp";
// surface type for translucent offscreen image (texture)
public static final String
DESC_INT_ARGB_D3D = "Integer ARGB D3D with translucency";
public static final String
DESC_USHORT_4444_ARGB_D3D = "UShort 4444 ARGB D3D with translucency";
// Gdi (screen) surface types
// Generic GDI surface type - used for registering all loops
public static final SurfaceType AnyGdi =
SurfaceType.IntRgb.deriveSubType(DESC_GDI);
public static final SurfaceType IntRgbGdi =
SurfaceType.IntRgb.deriveSubType(DESC_GDI);
public static final SurfaceType Ushort565RgbGdi =
SurfaceType.Ushort565Rgb.deriveSubType(DESC_GDI);
public static final SurfaceType Ushort555RgbGdi =
SurfaceType.Ushort555Rgb.deriveSubType(DESC_GDI);
public static final SurfaceType ThreeByteBgrGdi =
SurfaceType.ThreeByteBgr.deriveSubType(DESC_GDI);
// DDraw offscreen surface types
public static final SurfaceType IntRgbDD =
SurfaceType.IntRgb.deriveSubType(DESC_INT_RGB_DD);
public static final SurfaceType IntRgbxDD =
SurfaceType.IntRgbx.deriveSubType(DESC_INT_RGBx_DD);
public static final SurfaceType Ushort565RgbDD =
SurfaceType.Ushort565Rgb.deriveSubType(DESC_USHORT_565_RGB_DD);
public static final SurfaceType Ushort555RgbxDD =
SurfaceType.Ushort555Rgbx.deriveSubType(DESC_USHORT_555_RGBx_DD);
public static final SurfaceType Ushort555RgbDD =
SurfaceType.Ushort555Rgb.deriveSubType(DESC_USHORT_555_RGB_DD);
public static final SurfaceType ByteIndexedOpaqueDD =
SurfaceType.ByteIndexedOpaque.deriveSubType(DESC_BYTE_INDEXED_OPAQUE_DD);
public static final SurfaceType ByteGrayDD =
SurfaceType.ByteGray.deriveSubType(DESC_BYTE_GRAY_DD);
public static final SurfaceType Index8GrayDD =
SurfaceType.Index8Gray.deriveSubType(DESC_INDEX8_GRAY_DD);
public static final SurfaceType ThreeByteBgrDD =
SurfaceType.ThreeByteBgr.deriveSubType(DESC_3BYTE_BGR_DD);
// DDraw onscreen surface types (derive from Gdi surfaces)
public static final SurfaceType IntRgbDDscreen =
IntRgbGdi.deriveSubType(DESC_INT_RGB_DD);
public static final SurfaceType Ushort565RgbDDscreen =
Ushort565RgbGdi.deriveSubType(DESC_USHORT_565_RGB_DD);
public static final SurfaceType Ushort555RgbDDscreen =
Ushort555RgbGdi.deriveSubType(DESC_USHORT_555_RGB_DD);
public static final SurfaceType ThreeByteBgrDDscreen =
ThreeByteBgrGdi.deriveSubType(DESC_3BYTE_BGR_DD);
// These screen types will not be handled as GDI surfaces
// (we can do dithering to 8-bit surfaces faster than
// GDI, so do not use GDI Blits to indexed surfaces.
// And Rgbx surfaces are documented to not work with
// GDI, so do not use GDI for that surface type either)
public static final SurfaceType IntRgbxDDscreen = IntRgbxDD;
public static final SurfaceType Ushort555RgbxDDscreen = Ushort555RgbxDD;
public static final SurfaceType ByteIndexedOpaqueDDscreen =
ByteIndexedOpaqueDD;
public static final SurfaceType ByteGrayDDscreen = ByteGrayDD;
public static final SurfaceType Index8GrayDDscreen = Index8GrayDD;
// Surface types with 1-bit transparency
public static final SurfaceType IntRgbDD_BM =
SurfaceType.Custom.deriveSubType(DESC_INT_RGB_DD_BM,
PixelConverter.Xrgb.instance);
public static final SurfaceType IntRgbxDD_BM =
SurfaceType.Custom.deriveSubType(DESC_INT_RGBx_DD_BM,
PixelConverter.Rgbx.instance);
public static final SurfaceType Ushort565RgbDD_BM =
SurfaceType.Custom.deriveSubType(DESC_USHORT_565_RGB_DD_BM,
PixelConverter.Ushort565Rgb.instance);
public static final SurfaceType Ushort555RgbxDD_BM =
SurfaceType.Custom.deriveSubType(DESC_USHORT_555_RGBx_DD_BM,
PixelConverter.Ushort555Rgbx.instance);
public static final SurfaceType Ushort555RgbDD_BM =
SurfaceType.Custom.deriveSubType(DESC_USHORT_555_RGB_DD_BM,
PixelConverter.Ushort555Rgb.instance);
public static final SurfaceType ByteIndexedDD_BM =
SurfaceType.Custom.deriveSubType(DESC_BYTE_INDEXED_DD_BM);
public static final SurfaceType ByteGrayDD_BM =
SurfaceType.Custom.deriveSubType(DESC_BYTE_GRAY_DD_BM);
public static final SurfaceType Index8GrayDD_BM =
SurfaceType.Custom.deriveSubType(DESC_INDEX8_GRAY_DD_BM);
public static final SurfaceType ThreeByteBgrDD_BM =
SurfaceType.Custom.deriveSubType(DESC_3BYTE_BGR_DD_BM,
PixelConverter.Xrgb.instance);
public static final SurfaceType IntArgbD3D =
SurfaceType.IntArgb.deriveSubType(DESC_INT_ARGB_D3D);
public static final SurfaceType Ushort4444ArgbD3D =
SurfaceType.Ushort4444Argb.deriveSubType(DESC_USHORT_4444_ARGB_D3D);
private static native void initDDraw(boolean useDDLockFlag,
boolean useDDLock);
private static native void initIDs(Class xorComp);
/**
* Description of command-line flags:
* noddraw: usage: "-Dsun.java2d.noddraw=true"
* turns off all usage of ddraw, including surface -> surface
* Blts (including onscreen->onscreen copyarea), offscreen
* surface creation, and surface locking via DDraw.
* gdiblit: usage: "-Dsun.java2d.gdiblit=false"
* turns off Blit loops that use GDI for copying to
* the screen from certain image types. Copies will,
* instead, happen via ddraw locking or temporary GDI DIB
* creation/copying (depending on OS and other flags)
* ddlock: usage: "-Dsun.java2d.ddlock=[true|false]"
* forces on|off usage of DirectDraw for locking the
* screen. This feature is usually enabled by default
* for pre-Win2k OS's and disabled by default for
* Win2k and future OS's (as of jdk1.4.1).
*/
static {
initIDs(XORComposite.class);
String noddraw = (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("sun.java2d.noddraw"));
String gdiBlitProp = (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("sun.java2d.gdiblit"));
String ddLockProp = (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("sun.java2d.ddlock"));
boolean useDDLock = false, useDDLockFlag = false;
if (ddLockProp != null) {
if (ddLockProp.equals("false") || ddLockProp.equals("f")) {
useDDLock = false;
useDDLockFlag = true;
} else if (ddLockProp.equals("true") || ddLockProp.equals("t")) {
useDDLock = true;
useDDLockFlag = true;
}
}
Win32OffScreenSurfaceData.initD3D();
if (noddraw == null) {
String magPresent = (String)java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("javax.accessibility.screen_magnifier_present"));
if (magPresent == null || !magPresent.equals("true")) {
if ("false".equals(magPresent) || getOsMajorVer() < 6)
initDDraw(useDDLockFlag, useDDLock);
}
}
boolean gdiBlitDisable = (gdiBlitProp != null &&
(gdiBlitProp.equals("false") ||
gdiBlitProp.equals("f")));
if (!gdiBlitDisable) {
// Register our gdi Blit loops
Win32GdiBlitLoops.register();
}
}
private static int getOsMajorVer() {
try {
String ver = System.getProperty("os.version");
int pos;
if (ver != null && (pos = ver.indexOf('.')) > 0)
return Integer.parseInt(ver.substring(0, pos));
}
catch (SecurityException e) {
}
catch (NumberFormatException e) {
}
return -1;
}
public static SurfaceType getSurfaceType(ColorModel cm) {
// REMIND: If ddraw not available, set sType to non-ddraw surface type
switch (cm.getPixelSize()) {
case 32:
case 24:
if (cm instanceof DirectColorModel) {
if (((DirectColorModel)cm).getRedMask() == 0xff0000) {
return IntRgbDDscreen;
} else {
return IntRgbxDDscreen;
}
} else {
return ThreeByteBgrDDscreen;
}
case 15:
return Ushort555RgbDDscreen;
case 16:
if ((cm instanceof DirectColorModel) &&
(((DirectColorModel)cm).getBlueMask() == 0x3e))
{
return Ushort555RgbxDDscreen;
} else {
return Ushort565RgbDDscreen;
}
case 8:
if (cm.getColorSpace().getType() == ColorSpace.TYPE_GRAY &&
cm instanceof ComponentColorModel) {
return ByteGrayDDscreen;
} else if (cm instanceof IndexColorModel &&
isOpaqueGray((IndexColorModel)cm)) {
return Index8GrayDDscreen;
} else {
return ByteIndexedOpaqueDDscreen;
}
default:
throw new sun.java2d.InvalidPipeException("Unsupported bit " +
"depth: " +
cm.getPixelSize());
}
}
public static Win32SurfaceData createData(WComponentPeer peer,
int numBuffers)
{
SurfaceType sType = getSurfaceType(peer.getDeviceColorModel());
return new Win32SurfaceData(peer, sType, numBuffers);
}
public Raster getRaster(int x, int y, int w, int h) {
throw new InternalError("not implemented yet");
}
protected static Win32Renderer gdiPipe;
protected static PixelToShapeConverter gdiTxPipe;
static {
gdiPipe = new Win32Renderer();
if (GraphicsPrimitive.tracingEnabled()) {
gdiPipe = gdiPipe.traceWrap();
}
gdiTxPipe = new PixelToShapeConverter(gdiPipe);
}
public void validatePipe(SunGraphics2D sg2d) {
if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON &&
sg2d.paintState == sg2d.PAINT_SOLIDCOLOR &&
(sg2d.compositeState == sg2d.COMP_ISCOPY ||
sg2d.compositeState == sg2d.COMP_XOR) &&
sg2d.clipState != sg2d.CLIP_SHAPE)
{
sg2d.imagepipe = imagepipe;
if (sg2d.transformState > sg2d.TRANSFORM_TRANSLATEONLY) {
sg2d.drawpipe = gdiTxPipe;
sg2d.fillpipe = gdiTxPipe;
} else if (sg2d.strokeState != sg2d.STROKE_THIN){
sg2d.drawpipe = gdiTxPipe;
sg2d.fillpipe = gdiPipe;
} else {
sg2d.drawpipe = gdiPipe;
sg2d.fillpipe = gdiPipe;
}
sg2d.shapepipe = gdiPipe;
// REMIND: There is no alternate text pipe for now...
if (sg2d.textAntialiasHint != SunHints.INTVAL_TEXT_ANTIALIAS_ON) {
sg2d.textpipe = solidTextRenderer;
} else {
sg2d.textpipe = aaTextRenderer;
}
// This is needed for AA text.
// Note that even a SolidTextRenderer can dispatch AA text
// if a GlyphVector overrides the AA setting.
// We use getRenderLoops() rather than setting solidloops
// directly so that we get the appropriate loops in XOR mode.
sg2d.loops = getRenderLoops(sg2d);
} else {
super.validatePipe(sg2d);
}
}
public void lock() {
// REMIND: Need to DirectDraw lock here...
}
public void unlock() {
// REMIND: Need to DirectDraw lock here...
}
public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
if (sg2d.paintState == sg2d.PAINT_SOLIDCOLOR &&
sg2d.compositeState == sg2d.COMP_ISCOPY)
{
return solidloops;
}
return super.getRenderLoops(sg2d);
}
public GraphicsConfiguration getDeviceConfiguration() {
return graphicsConfig;
}
/**
* Initializes the native Ops pointer.
*/
private native void initOps(WComponentPeer peer, int depth, int redMask,
int greenMask, int blueMask, int numBuffers,
int screen);
public Win32SurfaceData(WComponentPeer peer, SurfaceType sType,
int numBuffers) {
super(sType, peer.getDeviceColorModel());
ColorModel cm = peer.getDeviceColorModel();
this.peer = peer;
int rMask = 0, gMask = 0, bMask = 0;
int depth;
switch (cm.getPixelSize()) {
case 32:
case 24:
if (cm instanceof DirectColorModel) {
depth = 32;
} else {
depth = 24;
}
break;
default:
depth = cm.getPixelSize();
}
if (cm instanceof DirectColorModel) {
DirectColorModel dcm = (DirectColorModel)cm;
rMask = dcm.getRedMask();
gMask = dcm.getGreenMask();
bMask = dcm.getBlueMask();
}
this.graphicsConfig =
(Win32GraphicsConfig) peer.getGraphicsConfiguration();
this.solidloops = graphicsConfig.getSolidLoops(sType);
if (peer instanceof WFileDialogPeer ||
peer instanceof WPrintDialogPeer )
{
// REMIND: Awful hack. The right fix for this problem
// would be for these type of Peers to not even use a
// Win32SurfaceData object since they never do any
// rendering. Or they could actually implement the
// functionality needed in initOps. But this seems
// to work for now. See bug 4391928 for more info.
return;
}
Win32GraphicsDevice gd =
(Win32GraphicsDevice)graphicsConfig.getDevice();
initOps(peer, depth, rMask, gMask, bMask, numBuffers, gd.getScreen());
}
public SurfaceData getReplacement() {
return peer.getSurfaceData();
}
public Rectangle getBounds() {
Rectangle r = peer.getBounds();
r.x = r.y = 0;
return r;
}
public boolean copyArea(SunGraphics2D sg2d,
int x, int y, int w, int h, int dx, int dy)
{
CompositeType comptype = sg2d.imageComp;
if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE &&
sg2d.clipState != sg2d.CLIP_SHAPE &&
(CompositeType.SrcOverNoEa.equals(comptype) ||
CompositeType.SrcNoEa.equals(comptype)))
{
x += sg2d.transX;
y += sg2d.transY;
int dstx1 = x + dx;
int dsty1 = y + dy;
int dstx2 = dstx1 + w;
int dsty2 = dsty1 + h;
Region clip = sg2d.getCompClip();
if (dstx1 < clip.getLoX()) dstx1 = clip.getLoX();
if (dsty1 < clip.getLoY()) dsty1 = clip.getLoY();
if (dstx2 > clip.getHiX()) dstx2 = clip.getHiX();
if (dsty2 > clip.getHiY()) dsty2 = clip.getHiY();
if (dstx1 < dstx2 && dsty1 < dsty2) {
gdiPipe.devCopyArea(this, dstx1 - dx, dsty1 - dy,
dx, dy,
dstx2 - dstx1, dsty2 - dsty1);
}
return true;
}
return false;
}
private native void invalidateSD();
public void invalidate() {
if (isValid()) {
invalidateSD();
super.invalidate();
//peer.invalidateBackBuffer();
}
}
// This gets called when restoring the back buffer
public native void restoreSurface();
public native void flip(SurfaceData data);
}