modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGCanvas.java

Print this page

        

@@ -51,10 +51,11 @@
 import com.sun.prism.BasicStroke;
 import com.sun.prism.CompositeMode;
 import com.sun.prism.Graphics;
 import com.sun.prism.GraphicsPipeline;
 import com.sun.prism.Image;
+import com.sun.prism.MaskTextureGraphics;
 import com.sun.prism.PrinterGraphics;
 import com.sun.prism.RTTexture;
 import com.sun.prism.ResourceFactory;
 import com.sun.prism.Texture;
 import com.sun.prism.Texture.WrapMode;

@@ -671,13 +672,19 @@
                 }
                 if (clipRect != null) {
                     renderClip(new RoundRectangle2D(clipRect.x, clipRect.y,
                                                     clipRect.width, clipRect.height,
                                                     0, 0));
-                    clipRect = null;
                 }
             }
+            shapebounds(clippath, TEMP_RECTBOUNDS, BaseTransform.IDENTITY_TRANSFORM);
+            TEMP_RECT.setBounds(TEMP_RECTBOUNDS);
+            if (clipRect == null) {
+                clipRect = new Rectangle(TEMP_RECT);
+            } else {
+                clipRect.intersectWith(TEMP_RECT);
+            }
             renderClip(clippath);
         }
         if (clipValidated && clipIsRect) {
             clip.tex.unlock();
         }

@@ -1016,16 +1023,15 @@
                     if (clipvalidated) {
                         temp.validate(cv.g, tw, th);
                         tempvalidated = true;
                         dest = temp;
                     } else if (blendmode != Blend.Mode.SRC_OVER) {
-                        clipvalidated = false;
                         temp.validate(cv.g, tw, th);
                         tempvalidated = true;
                         dest = temp;
                     } else {
-                        clipvalidated = tempvalidated = false;
+                        tempvalidated = false;
                         dest = cv;
                     }
                     if (effect != null) {
                         buf.save();
                         handleRenderOp(token, buf, null, TEMP_RECTBOUNDS);

@@ -1074,13 +1080,29 @@
                             // mode here so that the erased (or reduced) pixels
                             // actually get reduced to their new alpha.
                             // assert: dest == temp;
                             compmode = CompositeMode.SRC;
                         }
+                        if (clipRect != null) {
+                            TEMP_RECTBOUNDS.intersectWith(clipRect);
+                        }
+                        if (!TEMP_RECTBOUNDS.isEmpty()) {
+                            if (dest == cv && cv.g instanceof MaskTextureGraphics) {
+                                MaskTextureGraphics mtg = (MaskTextureGraphics) cv.g;
+                                int dx = (int) Math.floor(TEMP_RECTBOUNDS.getMinX());
+                                int dy = (int) Math.floor(TEMP_RECTBOUNDS.getMinY());
+                                int dw = (int) Math.ceil(TEMP_RECTBOUNDS.getMaxX()) - dx;
+                                int dh = (int) Math.ceil(TEMP_RECTBOUNDS.getMaxY()) - dy;
+                                mtg.drawPixelsMasked(temp.tex, clip.tex,
+                                                     dx, dy, dw, dh,
+                                                     dx, dy, dx, dy);
+                            } else {
                         blendAthruBintoC(temp, Mode.SRC_IN, clip,
                                          TEMP_RECTBOUNDS, compmode, dest);
                     }
+                        }
+                    }
                     if (blendmode != Blend.Mode.SRC_OVER) {
                         // We always use SRC mode here because the results of
                         // the blend operation are final and must replace
                         // the associated pixel in the canvas with no further
                         // blending math.