1 /* 2 * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.java2d.windows; 27 28 import java.awt.Rectangle; 29 import java.awt.GraphicsConfiguration; 30 import java.awt.color.ColorSpace; 31 import java.awt.image.ColorModel; 32 import java.awt.image.ComponentColorModel; 33 import java.awt.image.DirectColorModel; 34 import java.awt.image.IndexColorModel; 35 import java.awt.image.Raster; 36 37 import sun.awt.SunHints; 38 import sun.awt.Win32GraphicsConfig; 39 import sun.awt.Win32GraphicsDevice; 40 import sun.awt.windows.WComponentPeer; 41 import sun.java2d.ScreenUpdateManager; 42 import sun.java2d.SunGraphics2D; 43 import sun.java2d.SurfaceData; 44 import sun.java2d.SurfaceDataProxy; 45 import sun.java2d.pipe.Region; 46 import sun.java2d.pipe.PixelToShapeConverter; 47 import sun.java2d.loops.GraphicsPrimitive; 48 import sun.java2d.loops.SurfaceType; 49 import sun.java2d.loops.CompositeType; 50 import sun.java2d.loops.RenderLoops; 51 import sun.java2d.loops.XORComposite; 52 53 public class GDIWindowSurfaceData extends SurfaceData { 54 private WComponentPeer peer; 55 private Win32GraphicsConfig graphicsConfig; 56 private RenderLoops solidloops; 57 58 // GDI onscreen surface type 59 public static final String 60 DESC_GDI = "GDI"; 61 62 // Generic GDI surface type - used for registering all loops 63 public static final SurfaceType AnyGdi = 64 SurfaceType.IntRgb.deriveSubType(DESC_GDI); 65 66 public static final SurfaceType IntRgbGdi = 67 SurfaceType.IntRgb.deriveSubType(DESC_GDI); 68 69 public static final SurfaceType Ushort565RgbGdi = 70 SurfaceType.Ushort565Rgb.deriveSubType(DESC_GDI); 71 72 public static final SurfaceType Ushort555RgbGdi = 73 SurfaceType.Ushort555Rgb.deriveSubType(DESC_GDI); 74 75 public static final SurfaceType ThreeByteBgrGdi = 76 SurfaceType.ThreeByteBgr.deriveSubType(DESC_GDI); 77 initIDs(Class xorComp)78 private static native void initIDs(Class xorComp); 79 80 static { 81 initIDs(XORComposite.class); 82 if (WindowsFlags.isGdiBlitEnabled()) { 83 // Register our gdi Blit loops GDIBlitLoops.register()84 GDIBlitLoops.register(); 85 } 86 } 87 getSurfaceType(ColorModel cm)88 public static SurfaceType getSurfaceType(ColorModel cm) { 89 switch (cm.getPixelSize()) { 90 case 32: 91 case 24: 92 if (cm instanceof DirectColorModel) { 93 if (((DirectColorModel)cm).getRedMask() == 0xff0000) { 94 return IntRgbGdi; 95 } else { 96 return SurfaceType.IntRgbx; 97 } 98 } else { 99 return ThreeByteBgrGdi; 100 } 101 case 15: 102 return Ushort555RgbGdi; 103 case 16: 104 if ((cm instanceof DirectColorModel) && 105 (((DirectColorModel)cm).getBlueMask() == 0x3e)) 106 { 107 return SurfaceType.Ushort555Rgbx; 108 } else { 109 return Ushort565RgbGdi; 110 } 111 case 8: 112 if (cm.getColorSpace().getType() == ColorSpace.TYPE_GRAY && 113 cm instanceof ComponentColorModel) { 114 return SurfaceType.ByteGray; 115 } else if (cm instanceof IndexColorModel && 116 isOpaqueGray((IndexColorModel)cm)) { 117 return SurfaceType.Index8Gray; 118 } else { 119 return SurfaceType.ByteIndexedOpaque; 120 } 121 default: 122 throw new sun.java2d.InvalidPipeException("Unsupported bit " + 123 "depth: " + 124 cm.getPixelSize()); 125 } 126 } 127 createData(WComponentPeer peer)128 public static GDIWindowSurfaceData createData(WComponentPeer peer) { 129 SurfaceType sType = getSurfaceType(peer.getDeviceColorModel()); 130 return new GDIWindowSurfaceData(peer, sType); 131 } 132 133 @Override makeProxyFor(SurfaceData srcData)134 public SurfaceDataProxy makeProxyFor(SurfaceData srcData) { 135 return SurfaceDataProxy.UNCACHED; 136 } 137 getRaster(int x, int y, int w, int h)138 public Raster getRaster(int x, int y, int w, int h) { 139 throw new InternalError("not implemented yet"); 140 } 141 142 protected static GDIRenderer gdiPipe; 143 protected static PixelToShapeConverter gdiTxPipe; 144 145 static { 146 gdiPipe = new GDIRenderer(); 147 if (GraphicsPrimitive.tracingEnabled()) { 148 gdiPipe = gdiPipe.traceWrap(); 149 } 150 gdiTxPipe = new PixelToShapeConverter(gdiPipe); 151 152 } 153 validatePipe(SunGraphics2D sg2d)154 public void validatePipe(SunGraphics2D sg2d) { 155 if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON && 156 sg2d.paintState <= sg2d.PAINT_ALPHACOLOR && 157 (sg2d.compositeState <= sg2d.COMP_ISCOPY || 158 sg2d.compositeState == sg2d.COMP_XOR)) 159 { 160 if (sg2d.clipState == sg2d.CLIP_SHAPE) { 161 // Do this to init textpipe correctly; we will override the 162 // other non-text pipes below 163 // REMIND: we should clean this up eventually instead of 164 // having this work duplicated. 165 super.validatePipe(sg2d); 166 } else { 167 switch (sg2d.textAntialiasHint) { 168 169 case SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT: 170 /* equate DEFAULT to OFF which it is for us */ 171 case SunHints.INTVAL_TEXT_ANTIALIAS_OFF: 172 sg2d.textpipe = solidTextRenderer; 173 break; 174 175 case SunHints.INTVAL_TEXT_ANTIALIAS_ON: 176 sg2d.textpipe = aaTextRenderer; 177 break; 178 179 default: 180 switch (sg2d.getFontInfo().aaHint) { 181 182 case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB: 183 case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB: 184 sg2d.textpipe = lcdTextRenderer; 185 break; 186 187 case SunHints.INTVAL_TEXT_ANTIALIAS_ON: 188 sg2d.textpipe = aaTextRenderer; 189 break; 190 191 default: 192 sg2d.textpipe = solidTextRenderer; 193 } 194 } 195 } 196 sg2d.imagepipe = imagepipe; 197 if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) { 198 sg2d.drawpipe = gdiTxPipe; 199 sg2d.fillpipe = gdiTxPipe; 200 } else if (sg2d.strokeState != sg2d.STROKE_THIN){ 201 sg2d.drawpipe = gdiTxPipe; 202 sg2d.fillpipe = gdiPipe; 203 } else { 204 sg2d.drawpipe = gdiPipe; 205 sg2d.fillpipe = gdiPipe; 206 } 207 sg2d.shapepipe = gdiPipe; 208 // This is needed for AA text. 209 // Note that even a SolidTextRenderer can dispatch AA text 210 // if a GlyphVector overrides the AA setting. 211 // We use getRenderLoops() rather than setting solidloops 212 // directly so that we get the appropriate loops in XOR mode. 213 if (sg2d.loops == null) { 214 // assert(some pipe will always be a LoopBasedPipe) 215 sg2d.loops = getRenderLoops(sg2d); 216 } 217 } else { 218 super.validatePipe(sg2d); 219 } 220 } 221 getRenderLoops(SunGraphics2D sg2d)222 public RenderLoops getRenderLoops(SunGraphics2D sg2d) { 223 if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR && 224 sg2d.compositeState <= sg2d.COMP_ISCOPY) 225 { 226 return solidloops; 227 } 228 return super.getRenderLoops(sg2d); 229 } 230 getDeviceConfiguration()231 public GraphicsConfiguration getDeviceConfiguration() { 232 return graphicsConfig; 233 } 234 235 /** 236 * Initializes the native Ops pointer. 237 */ initOps(WComponentPeer peer, int depth, int redMask, int greenMask, int blueMask, int screen)238 private native void initOps(WComponentPeer peer, int depth, int redMask, 239 int greenMask, int blueMask, int screen); 240 GDIWindowSurfaceData(WComponentPeer peer, SurfaceType sType)241 private GDIWindowSurfaceData(WComponentPeer peer, SurfaceType sType) { 242 super(sType, peer.getDeviceColorModel()); 243 ColorModel cm = peer.getDeviceColorModel(); 244 this.peer = peer; 245 int rMask = 0, gMask = 0, bMask = 0; 246 int depth; 247 switch (cm.getPixelSize()) { 248 case 32: 249 case 24: 250 if (cm instanceof DirectColorModel) { 251 depth = 32; 252 } else { 253 depth = 24; 254 } 255 break; 256 default: 257 depth = cm.getPixelSize(); 258 } 259 if (cm instanceof DirectColorModel) { 260 DirectColorModel dcm = (DirectColorModel)cm; 261 rMask = dcm.getRedMask(); 262 gMask = dcm.getGreenMask(); 263 bMask = dcm.getBlueMask(); 264 } 265 this.graphicsConfig = 266 (Win32GraphicsConfig) peer.getGraphicsConfiguration(); 267 this.solidloops = graphicsConfig.getSolidLoops(sType); 268 269 Win32GraphicsDevice gd = 270 (Win32GraphicsDevice)graphicsConfig.getDevice(); 271 initOps(peer, depth, rMask, gMask, bMask, gd.getScreen()); 272 setBlitProxyKey(graphicsConfig.getProxyKey()); 273 } 274 275 /** 276 * {@inheritDoc} 277 * 278 * Overridden to use ScreenUpdateManager to obtain the replacement surface. 279 * 280 * @see sun.java2d.ScreenUpdateManager#getReplacementScreenSurface 281 */ 282 @Override getReplacement()283 public SurfaceData getReplacement() { 284 ScreenUpdateManager mgr = ScreenUpdateManager.getInstance(); 285 return mgr.getReplacementScreenSurface(peer, this); 286 } 287 getBounds()288 public Rectangle getBounds() { 289 Rectangle r = peer.getBounds(); 290 r.x = r.y = 0; 291 return r; 292 } 293 copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy)294 public boolean copyArea(SunGraphics2D sg2d, 295 int x, int y, int w, int h, int dx, int dy) 296 { 297 CompositeType comptype = sg2d.imageComp; 298 if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE && 299 sg2d.clipState != sg2d.CLIP_SHAPE && 300 (CompositeType.SrcOverNoEa.equals(comptype) || 301 CompositeType.SrcNoEa.equals(comptype))) 302 { 303 x += sg2d.transX; 304 y += sg2d.transY; 305 int dstx1 = x + dx; 306 int dsty1 = y + dy; 307 int dstx2 = dstx1 + w; 308 int dsty2 = dsty1 + h; 309 Region clip = sg2d.getCompClip(); 310 if (dstx1 < clip.getLoX()) dstx1 = clip.getLoX(); 311 if (dsty1 < clip.getLoY()) dsty1 = clip.getLoY(); 312 if (dstx2 > clip.getHiX()) dstx2 = clip.getHiX(); 313 if (dsty2 > clip.getHiY()) dsty2 = clip.getHiY(); 314 if (dstx1 < dstx2 && dsty1 < dsty2) { 315 gdiPipe.devCopyArea(this, dstx1 - dx, dsty1 - dy, 316 dx, dy, 317 dstx2 - dstx1, dsty2 - dsty1); 318 } 319 return true; 320 } 321 return false; 322 } 323 invalidateSD()324 private native void invalidateSD(); 325 @Override invalidate()326 public void invalidate() { 327 if (isValid()) { 328 invalidateSD(); 329 super.invalidate(); 330 //peer.invalidateBackBuffer(); 331 } 332 } 333 334 /** 335 * Returns destination Component associated with this SurfaceData. 336 */ 337 @Override getDestination()338 public Object getDestination() { 339 return peer.getTarget(); 340 } 341 getPeer()342 public WComponentPeer getPeer() { 343 return peer; 344 } 345 } 346