001: /*
002: * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.java2d.windows;
027:
028: import java.awt.Rectangle;
029: import java.awt.GraphicsConfiguration;
030: import java.awt.color.ColorSpace;
031: import java.awt.image.ColorModel;
032: import java.awt.image.ComponentColorModel;
033: import java.awt.image.DirectColorModel;
034: import java.awt.image.IndexColorModel;
035: import java.awt.image.Raster;
036:
037: import sun.awt.SunHints;
038: import sun.awt.Win32GraphicsConfig;
039: import sun.awt.Win32GraphicsDevice;
040: import sun.awt.image.PixelConverter;
041: import sun.awt.windows.WComponentPeer;
042: import sun.awt.windows.WFileDialogPeer;
043: import sun.awt.windows.WPrintDialogPeer;
044: import sun.java2d.SunGraphics2D;
045: import sun.java2d.SurfaceData;
046: import sun.java2d.SurfaceDataProxy;
047: import sun.java2d.pipe.Region;
048: import sun.java2d.pipe.PixelToShapeConverter;
049: import sun.java2d.loops.GraphicsPrimitive;
050: import sun.java2d.loops.SurfaceType;
051: import sun.java2d.loops.CompositeType;
052: import sun.java2d.loops.RenderLoops;
053: import sun.java2d.loops.XORComposite;
054:
055: public class Win32SurfaceData extends SurfaceData {
056: WComponentPeer peer;
057: private Win32GraphicsConfig graphicsConfig;
058: private RenderLoops solidloops;
059:
060: // GDI onscreen surface type
061: public static final String DESC_GDI = "GDI";
062:
063: // DDraw offscreen surface type names
064: public static final String DESC_INT_RGB_DD = "Integer RGB DirectDraw";
065:
066: public static final String DESC_INT_RGBx_DD = "Integer RGBx DirectDraw";
067:
068: public static final String DESC_USHORT_565_RGB_DD = "Short 565 RGB DirectDraw";
069:
070: public static final String DESC_USHORT_555_RGBx_DD = "Short 555 RGBx DirectDraw";
071:
072: public static final String DESC_USHORT_555_RGB_DD = "Short 555 RGB DirectDraw";
073:
074: public static final String DESC_BYTE_INDEXED_OPAQUE_DD = "8-bit Indexed (Opaque) DirectDraw";
075:
076: public static final String DESC_BYTE_GRAY_DD = "Byte Gray DirectDraw";
077:
078: public static final String DESC_INDEX8_GRAY_DD = "Index8 Gray DirectDraw";
079:
080: public static final String DESC_3BYTE_BGR_DD = "3 Byte BGR DirectDraw";
081:
082: // Surface types with 1-bit transparency
083: public static final String DESC_INT_RGB_DD_BM = "Integer RGB DirectDraw with 1 bit transp";
084:
085: public static final String DESC_INT_RGBx_DD_BM = "Integer RGBx DirectDraw with 1 bit transp";
086:
087: public static final String DESC_USHORT_565_RGB_DD_BM = "Short 565 RGB DirectDraw with 1 bit transp";
088:
089: public static final String DESC_USHORT_555_RGBx_DD_BM = "Short 555 RGBx DirectDraw with 1 bit transp";
090:
091: public static final String DESC_USHORT_555_RGB_DD_BM = "Short 555 RGB DirectDraw with 1 bit transp";
092:
093: public static final String DESC_3BYTE_BGR_DD_BM = "3 Byte BGR DirectDraw with 1 bit transp";
094:
095: public static final String DESC_BYTE_INDEXED_DD_BM = "8-bit Indexed DirectDraw with 1 bit transp";
096:
097: public static final String DESC_BYTE_GRAY_DD_BM = "Byte Gray DirectDraw with 1 bit transp";
098:
099: public static final String DESC_INDEX8_GRAY_DD_BM = "Index8 Gray DirectDraw with 1 bit transp";
100:
101: // Gdi (screen) surface types
102:
103: // Generic GDI surface type - used for registering all loops
104: public static final SurfaceType AnyGdi = SurfaceType.IntRgb
105: .deriveSubType(DESC_GDI);
106:
107: public static final SurfaceType IntRgbGdi = SurfaceType.IntRgb
108: .deriveSubType(DESC_GDI);
109:
110: public static final SurfaceType Ushort565RgbGdi = SurfaceType.Ushort565Rgb
111: .deriveSubType(DESC_GDI);
112:
113: public static final SurfaceType Ushort555RgbGdi = SurfaceType.Ushort555Rgb
114: .deriveSubType(DESC_GDI);
115:
116: public static final SurfaceType ThreeByteBgrGdi = SurfaceType.ThreeByteBgr
117: .deriveSubType(DESC_GDI);
118:
119: // DDraw offscreen surface types
120: public static final SurfaceType IntRgbDD = SurfaceType.IntRgb
121: .deriveSubType(DESC_INT_RGB_DD);
122:
123: public static final SurfaceType IntRgbxDD = SurfaceType.IntRgbx
124: .deriveSubType(DESC_INT_RGBx_DD);
125:
126: public static final SurfaceType Ushort565RgbDD = SurfaceType.Ushort565Rgb
127: .deriveSubType(DESC_USHORT_565_RGB_DD);
128:
129: public static final SurfaceType Ushort555RgbxDD = SurfaceType.Ushort555Rgbx
130: .deriveSubType(DESC_USHORT_555_RGBx_DD);
131:
132: public static final SurfaceType Ushort555RgbDD = SurfaceType.Ushort555Rgb
133: .deriveSubType(DESC_USHORT_555_RGB_DD);
134:
135: public static final SurfaceType ByteIndexedOpaqueDD = SurfaceType.ByteIndexedOpaque
136: .deriveSubType(DESC_BYTE_INDEXED_OPAQUE_DD);
137:
138: public static final SurfaceType ByteGrayDD = SurfaceType.ByteGray
139: .deriveSubType(DESC_BYTE_GRAY_DD);
140:
141: public static final SurfaceType Index8GrayDD = SurfaceType.Index8Gray
142: .deriveSubType(DESC_INDEX8_GRAY_DD);
143:
144: public static final SurfaceType ThreeByteBgrDD = SurfaceType.ThreeByteBgr
145: .deriveSubType(DESC_3BYTE_BGR_DD);
146:
147: // DDraw onscreen surface types (derive from Gdi surfaces)
148: public static final SurfaceType IntRgbDDscreen = IntRgbGdi
149: .deriveSubType(DESC_INT_RGB_DD);
150:
151: public static final SurfaceType Ushort565RgbDDscreen = Ushort565RgbGdi
152: .deriveSubType(DESC_USHORT_565_RGB_DD);
153:
154: public static final SurfaceType Ushort555RgbDDscreen = Ushort555RgbGdi
155: .deriveSubType(DESC_USHORT_555_RGB_DD);
156:
157: public static final SurfaceType ThreeByteBgrDDscreen = ThreeByteBgrGdi
158: .deriveSubType(DESC_3BYTE_BGR_DD);
159:
160: // These screen types will not be handled as GDI surfaces
161: // (we can do dithering to 8-bit surfaces faster than
162: // GDI, so do not use GDI Blits to indexed surfaces.
163: // And Rgbx surfaces are documented to not work with
164: // GDI, so do not use GDI for that surface type either)
165: public static final SurfaceType IntRgbxDDscreen = IntRgbxDD;
166:
167: public static final SurfaceType Ushort555RgbxDDscreen = Ushort555RgbxDD;
168:
169: public static final SurfaceType ByteIndexedOpaqueDDscreen = ByteIndexedOpaqueDD;
170:
171: public static final SurfaceType ByteGrayDDscreen = ByteGrayDD;
172:
173: public static final SurfaceType Index8GrayDDscreen = Index8GrayDD;
174:
175: // Surface types with 1-bit transparency
176: public static final SurfaceType IntRgbDD_BM = SurfaceType.Custom
177: .deriveSubType(DESC_INT_RGB_DD_BM,
178: PixelConverter.Xrgb.instance);
179:
180: public static final SurfaceType IntRgbxDD_BM = SurfaceType.Custom
181: .deriveSubType(DESC_INT_RGBx_DD_BM,
182: PixelConverter.Rgbx.instance);
183:
184: public static final SurfaceType Ushort565RgbDD_BM = SurfaceType.Custom
185: .deriveSubType(DESC_USHORT_565_RGB_DD_BM,
186: PixelConverter.Ushort565Rgb.instance);
187:
188: public static final SurfaceType Ushort555RgbxDD_BM = SurfaceType.Custom
189: .deriveSubType(DESC_USHORT_555_RGBx_DD_BM,
190: PixelConverter.Ushort555Rgbx.instance);
191:
192: public static final SurfaceType Ushort555RgbDD_BM = SurfaceType.Custom
193: .deriveSubType(DESC_USHORT_555_RGB_DD_BM,
194: PixelConverter.Ushort555Rgb.instance);
195:
196: public static final SurfaceType ByteIndexedDD_BM = SurfaceType.Custom
197: .deriveSubType(DESC_BYTE_INDEXED_DD_BM);
198:
199: public static final SurfaceType ByteGrayDD_BM = SurfaceType.Custom
200: .deriveSubType(DESC_BYTE_GRAY_DD_BM);
201:
202: public static final SurfaceType Index8GrayDD_BM = SurfaceType.Custom
203: .deriveSubType(DESC_INDEX8_GRAY_DD_BM);
204:
205: public static final SurfaceType ThreeByteBgrDD_BM = SurfaceType.Custom
206: .deriveSubType(DESC_3BYTE_BGR_DD_BM,
207: PixelConverter.Xrgb.instance);
208:
209: private static native void initIDs(Class xorComp);
210:
211: static {
212: initIDs(XORComposite.class);
213: if (WindowsFlags.isGdiBlitEnabled()) {
214: // Register our gdi Blit loops
215: GDIBlitLoops.register();
216: }
217: }
218:
219: public static SurfaceType getSurfaceType(ColorModel cm) {
220: // REMIND: If ddraw not available, set sType to non-ddraw surface type
221: switch (cm.getPixelSize()) {
222: case 32:
223: case 24:
224: if (cm instanceof DirectColorModel) {
225: if (((DirectColorModel) cm).getRedMask() == 0xff0000) {
226: return IntRgbDDscreen;
227: } else {
228: return IntRgbxDDscreen;
229: }
230: } else {
231: return ThreeByteBgrDDscreen;
232: }
233: case 15:
234: return Ushort555RgbDDscreen;
235: case 16:
236: if ((cm instanceof DirectColorModel)
237: && (((DirectColorModel) cm).getBlueMask() == 0x3e)) {
238: return Ushort555RgbxDDscreen;
239: } else {
240: return Ushort565RgbDDscreen;
241: }
242: case 8:
243: if (cm.getColorSpace().getType() == ColorSpace.TYPE_GRAY
244: && cm instanceof ComponentColorModel) {
245: return ByteGrayDDscreen;
246: } else if (cm instanceof IndexColorModel
247: && isOpaqueGray((IndexColorModel) cm)) {
248: return Index8GrayDDscreen;
249: } else {
250: return ByteIndexedOpaqueDDscreen;
251: }
252: default:
253: throw new sun.java2d.InvalidPipeException(
254: "Unsupported bit " + "depth: " + cm.getPixelSize());
255: }
256: }
257:
258: @Override
259: public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {
260: // If D3D is enabled then we might have D3D capabilities, but
261: // that pipeline is going away soon so we will not bother
262: // creating the D3DProxy needed to manage those. For now we
263: // will just use DDraw cached surfaces in all cases.
264: return Win32SurfaceDataProxy.createProxy(srcData,
265: graphicsConfig);
266: }
267:
268: public static Win32SurfaceData createData(WComponentPeer peer,
269: int numBuffers) {
270: SurfaceType sType = getSurfaceType(peer.getDeviceColorModel());
271: return new Win32SurfaceData(peer, sType, numBuffers);
272: }
273:
274: public Raster getRaster(int x, int y, int w, int h) {
275: throw new InternalError("not implemented yet");
276: }
277:
278: protected static GDIRenderer gdiPipe;
279: protected static PixelToShapeConverter gdiTxPipe;
280:
281: static {
282: gdiPipe = new GDIRenderer();
283: if (GraphicsPrimitive.tracingEnabled()) {
284: gdiPipe = gdiPipe.traceWrap();
285: }
286: gdiTxPipe = new PixelToShapeConverter(gdiPipe);
287: }
288:
289: public void validatePipe(SunGraphics2D sg2d) {
290: if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON
291: && sg2d.paintState <= sg2d.PAINT_ALPHACOLOR
292: && (sg2d.compositeState <= sg2d.COMP_ISCOPY || sg2d.compositeState == sg2d.COMP_XOR)) {
293: if (sg2d.clipState == sg2d.CLIP_SHAPE) {
294: // Do this to init textpipe correctly; we will override the
295: // other non-text pipes below
296: // REMIND: we should clean this up eventually instead of
297: // having this work duplicated.
298: super .validatePipe(sg2d);
299: } else {
300: switch (sg2d.textAntialiasHint) {
301:
302: case SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT:
303: /* equate DEFAULT to OFF which it is for us */
304: case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:
305: sg2d.textpipe = solidTextRenderer;
306: break;
307:
308: case SunHints.INTVAL_TEXT_ANTIALIAS_ON:
309: sg2d.textpipe = aaTextRenderer;
310: break;
311:
312: default:
313: switch (sg2d.getFontInfo().aaHint) {
314:
315: case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB:
316: case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB:
317: sg2d.textpipe = lcdTextRenderer;
318: break;
319:
320: case SunHints.INTVAL_TEXT_ANTIALIAS_ON:
321: sg2d.textpipe = aaTextRenderer;
322: break;
323:
324: default:
325: sg2d.textpipe = solidTextRenderer;
326: }
327: }
328: }
329: sg2d.imagepipe = imagepipe;
330: if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) {
331: sg2d.drawpipe = gdiTxPipe;
332: sg2d.fillpipe = gdiTxPipe;
333: } else if (sg2d.strokeState != sg2d.STROKE_THIN) {
334: sg2d.drawpipe = gdiTxPipe;
335: sg2d.fillpipe = gdiPipe;
336: } else {
337: sg2d.drawpipe = gdiPipe;
338: sg2d.fillpipe = gdiPipe;
339: }
340: sg2d.shapepipe = gdiPipe;
341: // This is needed for AA text.
342: // Note that even a SolidTextRenderer can dispatch AA text
343: // if a GlyphVector overrides the AA setting.
344: // We use getRenderLoops() rather than setting solidloops
345: // directly so that we get the appropriate loops in XOR mode.
346: sg2d.loops = getRenderLoops(sg2d);
347: } else {
348: super .validatePipe(sg2d);
349: }
350: }
351:
352: public RenderLoops getRenderLoops(SunGraphics2D sg2d) {
353: if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR
354: && sg2d.compositeState <= sg2d.COMP_ISCOPY) {
355: return solidloops;
356: }
357: return super .getRenderLoops(sg2d);
358: }
359:
360: public GraphicsConfiguration getDeviceConfiguration() {
361: return graphicsConfig;
362: }
363:
364: /**
365: * Initializes the native Ops pointer.
366: */
367: private native void initOps(WComponentPeer peer, int depth,
368: int redMask, int greenMask, int blueMask, int numBuffers,
369: int screen);
370:
371: public Win32SurfaceData(WComponentPeer peer, SurfaceType sType,
372: int numBuffers) {
373: super (sType, peer.getDeviceColorModel());
374: ColorModel cm = peer.getDeviceColorModel();
375: this .peer = peer;
376: int rMask = 0, gMask = 0, bMask = 0;
377: int depth;
378: switch (cm.getPixelSize()) {
379: case 32:
380: case 24:
381: if (cm instanceof DirectColorModel) {
382: depth = 32;
383: } else {
384: depth = 24;
385: }
386: break;
387: default:
388: depth = cm.getPixelSize();
389: }
390: if (cm instanceof DirectColorModel) {
391: DirectColorModel dcm = (DirectColorModel) cm;
392: rMask = dcm.getRedMask();
393: gMask = dcm.getGreenMask();
394: bMask = dcm.getBlueMask();
395: }
396: this .graphicsConfig = (Win32GraphicsConfig) peer
397: .getGraphicsConfiguration();
398: this .solidloops = graphicsConfig.getSolidLoops(sType);
399: if (peer instanceof WFileDialogPeer
400: || peer instanceof WPrintDialogPeer) {
401: // REMIND: Awful hack. The right fix for this problem
402: // would be for these type of Peers to not even use a
403: // Win32SurfaceData object since they never do any
404: // rendering. Or they could actually implement the
405: // functionality needed in initOps. But this seems
406: // to work for now. See bug 4391928 for more info.
407: return;
408: }
409: Win32GraphicsDevice gd = (Win32GraphicsDevice) graphicsConfig
410: .getDevice();
411: initOps(peer, depth, rMask, gMask, bMask, numBuffers, gd
412: .getScreen());
413: setBlitProxyKey(graphicsConfig.getProxyKey());
414: }
415:
416: public SurfaceData getReplacement() {
417: return peer.getSurfaceData();
418: }
419:
420: public Rectangle getBounds() {
421: Rectangle r = peer.getBounds();
422: r.x = r.y = 0;
423: return r;
424: }
425:
426: public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w,
427: int h, int dx, int dy) {
428: CompositeType comptype = sg2d.imageComp;
429: if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE
430: && sg2d.clipState != sg2d.CLIP_SHAPE
431: && (CompositeType.SrcOverNoEa.equals(comptype) || CompositeType.SrcNoEa
432: .equals(comptype))) {
433: x += sg2d.transX;
434: y += sg2d.transY;
435: int dstx1 = x + dx;
436: int dsty1 = y + dy;
437: int dstx2 = dstx1 + w;
438: int dsty2 = dsty1 + h;
439: Region clip = sg2d.getCompClip();
440: if (dstx1 < clip.getLoX())
441: dstx1 = clip.getLoX();
442: if (dsty1 < clip.getLoY())
443: dsty1 = clip.getLoY();
444: if (dstx2 > clip.getHiX())
445: dstx2 = clip.getHiX();
446: if (dsty2 > clip.getHiY())
447: dsty2 = clip.getHiY();
448: if (dstx1 < dstx2 && dsty1 < dsty2) {
449: gdiPipe.devCopyArea(this , dstx1 - dx, dsty1 - dy, dx,
450: dy, dstx2 - dstx1, dsty2 - dsty1);
451: }
452: return true;
453: }
454: return false;
455: }
456:
457: private native void invalidateSD();
458:
459: public void invalidate() {
460: if (isValid()) {
461: invalidateSD();
462: super .invalidate();
463: //peer.invalidateBackBuffer();
464: }
465: }
466:
467: // This gets called when restoring the back buffer
468: public native void restoreSurface();
469:
470: public native void flip(SurfaceData data);
471:
472: /**
473: * Returns destination Component associated with this SurfaceData.
474: */
475: public Object getDestination() {
476: return peer.getTarget();
477: }
478: }
|