< prev index next >

modules/javafx.graphics/src/main/java/com/sun/prism/impl/shape/MarlinPrismUtils.java

Print this page

        

@@ -49,21 +49,21 @@
      * Private constructor to prevent instantiation.
      */
     private MarlinPrismUtils() {
     }
 
-    private static PathConsumer2D initRenderer(
+    private static boolean nearZero(final double num) {
+        return Math.abs(num) < 2.0d * Math.ulp(num);
+    }
+
+    private static PathConsumer2D initPipeline(
             final RendererContext rdrCtx,
             final BasicStroke stroke,
+            final float lineWidth,
             final BaseTransform tx,
-            final Rectangle clip,
-            final int pirule,
-            final MarlinRenderer renderer)
+            final PathConsumer2D out)
     {
-        final int oprule = (stroke == null && pirule == PathIterator.WIND_EVEN_ODD) ?
-            MarlinRenderer.WIND_EVEN_ODD : MarlinRenderer.WIND_NON_ZERO;
-
         // We use strokerat so that in Stroker and Dasher we can work only
         // with the pre-transformation coordinates. This will repeat a lot of
         // computations done in the path iterator, but the alternative is to
         // work with transformed paths and compute untransformed coordinates
         // as needed. This would be faster but I do not think the complexity

@@ -77,20 +77,20 @@
         // transformation before the path processing.
         BaseTransform strokerTx = null;
 
         int dashLen = -1;
         boolean recycleDashes = false;
-
+        float scale = 1.0f;
         float width = 0.0f, dashphase = 0.0f;
         float[] dashes = null;
 
         if (stroke != null) {
-            width = stroke.getLineWidth();
+            width = lineWidth;
             dashes = stroke.getDashArray();
             dashphase = stroke.getDashPhase();
 
-            if (tx != null && !tx.isIdentity()) {
+            if ((tx != null) && !tx.isIdentity()) {
                 final double a = tx.getMxx();
                 final double b = tx.getMxy();
                 final double c = tx.getMyx();
                 final double d = tx.getMyy();
 

@@ -99,11 +99,11 @@
                 // need to transform input paths to stroker and tell stroker
                 // the scaled width. This condition is satisfied if
                 // a*b == -c*d && a*a+c*c == b*b+d*d. In the actual check below, we
                 // leave a bit of room for error.
                 if (nearZero(a*b + c*d) && nearZero(a*a + c*c - (b*b + d*d))) {
-                    final float scale = (float) Math.sqrt(a*a + c*c);
+                    scale = (float) Math.sqrt(a*a + c*c);
 
                     if (dashes != null) {
                         recycleDashes = true;
                         dashLen = dashes.length;
                         dashes = rdrCtx.dasher.copyDashArray(dashes);

@@ -134,35 +134,36 @@
                     // to stroker's output.
                 }
             }
         }
 
-        PathConsumer2D pc = renderer.init(clip.x, clip.y, clip.width, clip.height, oprule);
+        // Prepare the pipeline:
+        PathConsumer2D pc = out;
 
         if (MarlinConst.USE_SIMPLIFIER) {
             // Use simplifier after stroker before Renderer
             // to remove collinear segments (notably due to cap square)
             pc = rdrCtx.simplifier.init(pc);
         }
 
         final TransformingPathConsumer2D transformerPC2D = rdrCtx.transformerPC2D;
-        pc = transformerPC2D.deltaTransformConsumer(pc, strokerTx);
 
         if (stroke != null) {
+            pc = transformerPC2D.deltaTransformConsumer(pc, strokerTx);
+
             pc = rdrCtx.stroker.init(pc, width, stroke.getEndCap(),
                     stroke.getLineJoin(), stroke.getMiterLimit());
 
             if (dashes != null) {
                 if (!recycleDashes) {
                     dashLen = dashes.length;
                 }
                 pc = rdrCtx.dasher.init(pc, dashes, dashLen, dashphase, recycleDashes);
             }
+            pc = transformerPC2D.inverseDeltaTransformConsumer(pc, strokerTx);
         }
 
-        pc = transformerPC2D.inverseDeltaTransformConsumer(pc, strokerTx);
-
         /*
          * Pipeline seems to be:
          * shape.getPathIterator(tx)
          * -> (inverseDeltaTransformConsumer)
          * -> (Dasher)

@@ -174,56 +175,72 @@
          * -> pc2d = Renderer (bounding box)
          */
         return pc;
     }
 
-    private static boolean nearZero(final double num) {
-        return Math.abs(num) < 2.0d * Math.ulp(num);
-    }
-
-    public static MarlinRenderer setupRenderer(
+    private static PathConsumer2D initRenderer(
             final RendererContext rdrCtx,
-            final Shape shape,
             final BasicStroke stroke,
-            final BaseTransform xform,
-            final Rectangle rclip,
-            final boolean antialiasedShape)
+            final BaseTransform tx,
+            final Rectangle clip,
+            final int piRule,
+            final MarlinRenderer renderer)
     {
-        // Test if transform is identity:
-        final BaseTransform tf = (xform != null && !xform.isIdentity()) ? xform : null;
+        final int oprule = ((stroke == null) && (piRule == PathIterator.WIND_EVEN_ODD)) ?
+            MarlinRenderer.WIND_EVEN_ODD : MarlinRenderer.WIND_NON_ZERO;
 
-        final PathIterator pi = shape.getPathIterator(tf);
+        renderer.init(clip.x, clip.y, clip.width, clip.height, oprule);
 
-        final MarlinRenderer r =  (!FORCE_NO_AA && antialiasedShape) ?
-                rdrCtx.renderer : rdrCtx.getRendererNoAA();
-
-        final PathConsumer2D pc2d = initRenderer(rdrCtx, stroke, tf, rclip, pi.getWindingRule(), r);
+        float lw = 0.0f;
 
-        feedConsumer(rdrCtx, pi, pc2d);
+        if (stroke != null) {
+            lw = stroke.getLineWidth();
+        }
 
-        return r;
+        return initPipeline(rdrCtx, stroke, lw, tx, renderer);
     }
 
     public static MarlinRenderer setupRenderer(
             final RendererContext rdrCtx,
-            final Path2D p2d,
+            final Shape shape,
             final BasicStroke stroke,
             final BaseTransform xform,
             final Rectangle rclip,
             final boolean antialiasedShape)
     {
         // Test if transform is identity:
-        final BaseTransform tf = (xform != null && !xform.isIdentity()) ? xform : null;
+        final BaseTransform tf = ((xform != null) && !xform.isIdentity()) ? xform : null;
 
         final MarlinRenderer r =  (!FORCE_NO_AA && antialiasedShape) ?
                 rdrCtx.renderer : rdrCtx.getRendererNoAA();
 
-        final PathConsumer2D pc2d = initRenderer(rdrCtx, stroke, tf, rclip, p2d.getWindingRule(), r);
+        if (shape instanceof Path2D) {
+            final Path2D p2d = (Path2D)shape;
+            final PathConsumer2D pc2d = initRenderer(rdrCtx, stroke, tf, rclip, p2d.getWindingRule(), r);
+            feedConsumer(rdrCtx, p2d, tf, pc2d);
+        } else {
+            final PathIterator pi = shape.getPathIterator(tf);
+            final PathConsumer2D pc2d = initRenderer(rdrCtx, stroke, tf, rclip, pi.getWindingRule(), r);
+            feedConsumer(rdrCtx, pi, pc2d);
+        }
+        return r;
+    }
 
-        feedConsumer(rdrCtx, p2d, tf, pc2d);
+    public static void strokeTo(
+            final RendererContext rdrCtx,
+            final Shape shape,
+            final BasicStroke stroke,
+            final float lineWidth,
+            final PathConsumer2D out)
+    {
+        final PathConsumer2D pc2d = initPipeline(rdrCtx, stroke, lineWidth, null, out);
 
-        return r;
+        if (shape instanceof Path2D) {
+            feedConsumer(rdrCtx, (Path2D)shape, null, pc2d);
+        } else {
+            feedConsumer(rdrCtx, shape.getPathIterator(null), pc2d);
+        }
     }
 
     private static void feedConsumer(final RendererContext rdrCtx, final PathIterator pi,
                                      final PathConsumer2D pc2d)
     {

@@ -356,12 +373,12 @@
         // ported from DuctusRenderingEngine.feedConsumer() but simplified:
         // - removed skip flag = !subpathStarted
         // - removed pathClosed (ie subpathStarted not set to false)
         boolean subpathStarted = false;
 
-        final float pCoords[] = p2d.getFloatCoordsNoClone();
-        final byte pTypes[] = p2d.getCommandsNoClone();
+        final float[] pCoords = p2d.getFloatCoordsNoClone();
+        final byte[] pTypes = p2d.getCommandsNoClone();
         final int nsegs = p2d.getNumCommands();
 
         for (int i = 0, coff = 0; i < nsegs; i++) {
             switch (pTypes[i]) {
             case PathIterator.SEG_MOVETO:
< prev index next >