src/macosx/classes/sun/lwawt/LWWindowPeer.java

Print this page

        

@@ -35,10 +35,11 @@
 
 import sun.awt.*;
 import sun.java2d.*;
 import sun.java2d.loops.Blit;
 import sun.java2d.loops.CompositeType;
+import sun.java2d.pipe.Region;
 import sun.util.logging.PlatformLogger;
 
 public class LWWindowPeer
     extends LWContainerPeer<Window, JComponent>
     implements WindowPeer, FramePeer, DialogPeer, FullScreenCapable

@@ -107,10 +108,12 @@
 
     private static LWWindowPeer grabbingWindow;
 
     private volatile boolean skipNextFocusChange;
 
+    private static final Color nonOpaqueBackground = new Color(0, 0, 0, 0);
+
     /**
      * Current modal blocker or null.
      *
      * Synchronization: peerTreeLock.
      */

@@ -167,20 +170,25 @@
         }
 
         setAlwaysOnTop(getTarget().isAlwaysOnTop());
         updateMinimumSize();
 
+        final Shape shape = getTarget().getShape();
+        if (shape != null) {
+            applyShape(Region.getInstance(shape, null));
+        }
+
         final float opacity = getTarget().getOpacity();
         if (opacity < 1.0f) {
             setOpacity(opacity);
         }
 
         setOpaque(getTarget().isOpaque());
 
         updateInsets(platformWindow.getInsets());
         if (getSurfaceData() == null) {
-            replaceSurfaceData();
+            replaceSurfaceData(false);
         }
     }
 
     // Just a helper method
     public PlatformWindow getPlatformWindow() {

@@ -278,11 +286,11 @@
             // unsupported, and 1 corresponds to a SingleBufferStrategy which
             // doesn't depend on the peer. Screen is considered as a separate
             // "buffer", that's why numBuffers - 1
             assert numBuffers > 1;
 
-            replaceSurfaceData(numBuffers - 1, caps);
+            replaceSurfaceData(numBuffers - 1, caps, false);
         } catch (InvalidPipeException z) {
             throw new AWTException(z.toString());
         }
     }
 

@@ -418,23 +426,34 @@
 
     @Override
     public final void setOpaque(final boolean isOpaque) {
         if (this.isOpaque != isOpaque) {
             this.isOpaque = isOpaque;
-            getPlatformWindow().setOpaque(isOpaque);
-            replaceSurfaceData();
-            repaintPeer();
+            updateOpaque();
         }
     }
 
-    public final boolean isOpaque() {
-        return isOpaque;
+    private void updateOpaque() {
+        getPlatformWindow().setOpaque(!isTranslucent());
+        replaceSurfaceData(false);
+        repaintPeer();
     }
 
     @Override
     public void updateWindow() {
-        flushOffscreenGraphics();
+    }
+
+    public final boolean isTranslucent() {
+        synchronized (getStateLock()) {
+            return !isOpaque || isShaped();
+        }
+    }
+
+    @Override
+    final void applyShapeImpl(final Region shape) {
+        super.applyShapeImpl(shape);
+        updateOpaque();
     }
 
     @Override
     public void repositionSecurityWarning() {
         throw new RuntimeException("not implemented");

@@ -585,11 +604,22 @@
     private void clearBackground(final int w, final int h) {
         final Graphics g = getOnscreenGraphics(getForeground(), getBackground(),
                                                getFont());
         if (g != null) {
             try {
-                g.clearRect(0, 0, w, h);
+                if (g instanceof Graphics2D) {
+                    ((Graphics2D) g).setComposite(AlphaComposite.Src);
+                }
+                if (isTranslucent()) {
+                    g.setColor(nonOpaqueBackground);
+                    g.fillRect(0, 0, w, h);
+                }
+                if (g instanceof SunGraphics2D) {
+                    SG2DConstraint((SunGraphics2D) g, getRegion());
+                }
+                g.setColor(getBackground());
+                g.fillRect(0, 0, w, h);
             } finally {
                 g.dispose();
             }
         }
     }

@@ -892,54 +922,30 @@
                 AWTAccessor.getComponentAccessor().setGraphicsConfiguration(getTarget(), newGC);
             }
         });
     }
 
-    /**
-     * This method returns a back buffer Graphics to render all the
-     * peers to. After the peer is painted, the back buffer contents
-     * should be flushed to the screen. All the target painting
-     * (Component.paint() method) should be done directly to the screen.
-     */
-    protected final Graphics getOffscreenGraphics(Color fg, Color bg, Font f) {
-        final Image bb = getBackBuffer();
-        if (bb == null) {
-            return null;
-        }
-        if (fg == null) {
-            fg = SystemColor.windowText;
-        }
-        if (bg == null) {
-            bg = SystemColor.window;
-        }
-        if (f == null) {
-            f = DEFAULT_FONT;
-        }
-        final Graphics2D g = (Graphics2D) bb.getGraphics();
-        if (g != null) {
-            g.setColor(fg);
-            g.setBackground(bg);
-            g.setFont(f);
-        }
-        return g;
-    }
-
     /*
      * May be called by delegate to provide SD to Java2D code.
      */
     public SurfaceData getSurfaceData() {
         synchronized (surfaceDataLock) {
             return surfaceData;
         }
     }
 
     private void replaceSurfaceData() {
-        replaceSurfaceData(backBufferCount, backBufferCaps);
+        replaceSurfaceData(true);
+    }
+
+    private void replaceSurfaceData(boolean blit) {
+        replaceSurfaceData(backBufferCount, backBufferCaps, blit);
     }
 
     private void replaceSurfaceData(int newBackBufferCount,
-                                                 BufferCapabilities newBackBufferCaps) {
+                                    BufferCapabilities newBackBufferCaps,
+                                    boolean blit) {
         synchronized (surfaceDataLock) {
             final SurfaceData oldData = getSurfaceData();
             surfaceData = platformWindow.replaceSurfaceData();
             // TODO: volatile image
     //        VolatileImage oldBB = backBuffer;

@@ -948,11 +954,14 @@
             backBufferCaps = newBackBufferCaps;
             final Rectangle size = getSize();
             if (getSurfaceData() != null && oldData != getSurfaceData()) {
                 clearBackground(size.width, size.height);
             }
+
+            if (blit) {
             blitSurfaceData(oldData, getSurfaceData());
+            }
 
             if (oldData != null && oldData != getSurfaceData()) {
                 // TODO: drop oldData for D3D/WGL pipelines
                 // This can only happen when this peer is being created
                 oldData.flush();

@@ -963,14 +972,19 @@
             backBuffer = (BufferedImage) platformWindow.createBackBuffer();
             if (backBuffer != null) {
                 Graphics g = backBuffer.getGraphics();
                 try {
                     Rectangle r = getBounds();
-                    g.setColor(getBackground());
                     if (g instanceof Graphics2D) {
                         ((Graphics2D) g).setComposite(AlphaComposite.Src);
                     }
+                    g.setColor(nonOpaqueBackground);
+                    g.fillRect(0, 0, r.width, r.height);
+                    if (g instanceof SunGraphics2D) {
+                        SG2DConstraint((SunGraphics2D) g, getRegion());
+                    }
+                    g.setColor(getBackground());
                     g.fillRect(0, 0, r.width, r.height);
                     if (oldBB != null) {
                         // Draw the old back buffer to the new one
                         g.drawImage(oldBB, 0, 0, null);
                         oldBB.flush();

@@ -991,11 +1005,11 @@
             final Rectangle size = getSize();
             final Blit blit = Blit.locate(src.getSurfaceType(),
                                           CompositeType.Src,
                                           dst.getSurfaceType());
             if (blit != null) {
-                blit.Blit(src, dst, ((Graphics2D) getGraphics()).getComposite(),
+                blit.Blit(src, dst, AlphaComposite.Src,
                           getRegion(), 0, 0, 0, 0, size.width, size.height);
             }
         }
     }