< prev index next >

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

Print this page




  63             MarlinRenderer.WIND_EVEN_ODD : MarlinRenderer.WIND_NON_ZERO;
  64 
  65         // We use strokerat so that in Stroker and Dasher we can work only
  66         // with the pre-transformation coordinates. This will repeat a lot of
  67         // computations done in the path iterator, but the alternative is to
  68         // work with transformed paths and compute untransformed coordinates
  69         // as needed. This would be faster but I do not think the complexity
  70         // of working with both untransformed and transformed coordinates in
  71         // the same code is worth it.
  72         // However, if a path's width is constant after a transformation,
  73         // we can skip all this untransforming.
  74 
  75         // As pathTo() will check transformed coordinates for invalid values
  76         // (NaN / Infinity) to ignore such points, it is necessary to apply the
  77         // transformation before the path processing.
  78         BaseTransform strokerTx = null;
  79 
  80         int dashLen = -1;
  81         boolean recycleDashes = false;
  82 
  83         float width = 0f, dashphase = 0f;
  84         float[] dashes = null;
  85 
  86         if (stroke != null) {
  87             width = stroke.getLineWidth();
  88             dashes = stroke.getDashArray();
  89             dashphase = stroke.getDashPhase();
  90 
  91             if (tx != null && !tx.isIdentity()) {
  92                 final double a = tx.getMxx();
  93                 final double b = tx.getMxy();
  94                 final double c = tx.getMyx();
  95                 final double d = tx.getMyy();
  96 
  97                 // If the transform is a constant multiple of an orthogonal transformation
  98                 // then every length is just multiplied by a constant, so we just
  99                 // need to transform input paths to stroker and tell stroker
 100                 // the scaled width. This condition is satisfied if
 101                 // a*b == -c*d && a*a+c*c == b*b+d*d. In the actual check below, we
 102                 // leave a bit of room for error.
 103                 if (nearZero(a*b + c*d) && nearZero(a*a + c*c - (b*b + d*d))) {


 160         }
 161 
 162         pc = transformerPC2D.inverseDeltaTransformConsumer(pc, strokerTx);
 163 
 164         /*
 165          * Pipeline seems to be:
 166          * shape.getPathIterator(tx)
 167          * -> (inverseDeltaTransformConsumer)
 168          * -> (Dasher)
 169          * -> Stroker
 170          * -> (deltaTransformConsumer)
 171          *
 172          * -> (CollinearSimplifier) to remove redundant segments
 173          *
 174          * -> pc2d = Renderer (bounding box)
 175          */
 176         return pc;
 177     }
 178 
 179     private static boolean nearZero(final double num) {
 180         return Math.abs(num) < 2.0 * Math.ulp(num);
 181     }
 182 
 183     public static MarlinRenderer setupRenderer(
 184             final RendererContext rdrCtx,
 185             final Shape shape,
 186             final BasicStroke stroke,
 187             final BaseTransform xform,
 188             final Rectangle rclip,
 189             final boolean antialiasedShape)
 190     {
 191         // Test if transform is identity:
 192         final BaseTransform tf = (xform != null && !xform.isIdentity()) ? xform : null;
 193 
 194         final PathIterator pi = shape.getPathIterator(tf);
 195 
 196         final MarlinRenderer r =  (!FORCE_NO_AA && antialiasedShape) ?
 197                 rdrCtx.renderer : rdrCtx.getRendererNoAA();
 198 
 199         final PathConsumer2D pc2d = initRenderer(rdrCtx, stroke, tf, rclip, pi.getWindingRule(), r);
 200 




  63             MarlinRenderer.WIND_EVEN_ODD : MarlinRenderer.WIND_NON_ZERO;
  64 
  65         // We use strokerat so that in Stroker and Dasher we can work only
  66         // with the pre-transformation coordinates. This will repeat a lot of
  67         // computations done in the path iterator, but the alternative is to
  68         // work with transformed paths and compute untransformed coordinates
  69         // as needed. This would be faster but I do not think the complexity
  70         // of working with both untransformed and transformed coordinates in
  71         // the same code is worth it.
  72         // However, if a path's width is constant after a transformation,
  73         // we can skip all this untransforming.
  74 
  75         // As pathTo() will check transformed coordinates for invalid values
  76         // (NaN / Infinity) to ignore such points, it is necessary to apply the
  77         // transformation before the path processing.
  78         BaseTransform strokerTx = null;
  79 
  80         int dashLen = -1;
  81         boolean recycleDashes = false;
  82 
  83         float width = 0.0f, dashphase = 0.0f;
  84         float[] dashes = null;
  85 
  86         if (stroke != null) {
  87             width = stroke.getLineWidth();
  88             dashes = stroke.getDashArray();
  89             dashphase = stroke.getDashPhase();
  90 
  91             if (tx != null && !tx.isIdentity()) {
  92                 final double a = tx.getMxx();
  93                 final double b = tx.getMxy();
  94                 final double c = tx.getMyx();
  95                 final double d = tx.getMyy();
  96 
  97                 // If the transform is a constant multiple of an orthogonal transformation
  98                 // then every length is just multiplied by a constant, so we just
  99                 // need to transform input paths to stroker and tell stroker
 100                 // the scaled width. This condition is satisfied if
 101                 // a*b == -c*d && a*a+c*c == b*b+d*d. In the actual check below, we
 102                 // leave a bit of room for error.
 103                 if (nearZero(a*b + c*d) && nearZero(a*a + c*c - (b*b + d*d))) {


 160         }
 161 
 162         pc = transformerPC2D.inverseDeltaTransformConsumer(pc, strokerTx);
 163 
 164         /*
 165          * Pipeline seems to be:
 166          * shape.getPathIterator(tx)
 167          * -> (inverseDeltaTransformConsumer)
 168          * -> (Dasher)
 169          * -> Stroker
 170          * -> (deltaTransformConsumer)
 171          *
 172          * -> (CollinearSimplifier) to remove redundant segments
 173          *
 174          * -> pc2d = Renderer (bounding box)
 175          */
 176         return pc;
 177     }
 178 
 179     private static boolean nearZero(final double num) {
 180         return Math.abs(num) < 2.0d * Math.ulp(num);
 181     }
 182 
 183     public static MarlinRenderer setupRenderer(
 184             final RendererContext rdrCtx,
 185             final Shape shape,
 186             final BasicStroke stroke,
 187             final BaseTransform xform,
 188             final Rectangle rclip,
 189             final boolean antialiasedShape)
 190     {
 191         // Test if transform is identity:
 192         final BaseTransform tf = (xform != null && !xform.isIdentity()) ? xform : null;
 193 
 194         final PathIterator pi = shape.getPathIterator(tf);
 195 
 196         final MarlinRenderer r =  (!FORCE_NO_AA && antialiasedShape) ?
 197                 rdrCtx.renderer : rdrCtx.getRendererNoAA();
 198 
 199         final PathConsumer2D pc2d = initRenderer(rdrCtx, stroke, tf, rclip, pi.getWindingRule(), r);
 200 


< prev index next >