63 DMarlinRenderer.WIND_EVEN_ODD : DMarlinRenderer.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 double width = 0f, dashphase = 0f;
84 double[] dashesD = null;
85
86 if (stroke != null) {
87 width = stroke.getLineWidth();
88 final float[] dashes = stroke.getDashArray();
89 dashphase = stroke.getDashPhase();
90
91 // Ensure converting dashes to double precision:
92 if (dashes != null) {
93 recycleDashes = true;
94 dashLen = dashes.length;
95 dashesD = rdrCtx.dasher.copyDashArray(dashes);
96 }
97
98 if (tx != null && !tx.isIdentity()) {
99 final double a = tx.getMxx();
100 final double b = tx.getMxy();
101 final double c = tx.getMyx();
102 final double d = tx.getMyy();
103
161 }
162
163 pc = transformerPC2D.inverseDeltaTransformConsumer(pc, strokerTx);
164
165 /*
166 * Pipeline seems to be:
167 * shape.getPathIterator(tx)
168 * -> (inverseDeltaTransformConsumer)
169 * -> (Dasher)
170 * -> Stroker
171 * -> (deltaTransformConsumer)
172 *
173 * -> (CollinearSimplifier) to remove redundant segments
174 *
175 * -> pc2d = Renderer (bounding box)
176 */
177 return pc;
178 }
179
180 private static boolean nearZero(final double num) {
181 return Math.abs(num) < 2.0 * Math.ulp(num);
182 }
183
184 public static DMarlinRenderer setupRenderer(
185 final DRendererContext rdrCtx,
186 final Shape shape,
187 final BasicStroke stroke,
188 final BaseTransform xform,
189 final Rectangle rclip,
190 final boolean antialiasedShape)
191 {
192 // Test if transform is identity:
193 final BaseTransform tf = (xform != null && !xform.isIdentity()) ? xform : null;
194
195 final PathIterator pi = shape.getPathIterator(tf);
196
197 final DMarlinRenderer r = (!FORCE_NO_AA && antialiasedShape) ?
198 rdrCtx.renderer : rdrCtx.getRendererNoAA();
199
200 final DPathConsumer2D pc2d = initRenderer(rdrCtx, stroke, tf, rclip, pi.getWindingRule(), r);
201
|
63 DMarlinRenderer.WIND_EVEN_ODD : DMarlinRenderer.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 double width = 0.0f, dashphase = 0.0f;
84 double[] dashesD = null;
85
86 if (stroke != null) {
87 width = stroke.getLineWidth();
88 final float[] dashes = stroke.getDashArray();
89 dashphase = stroke.getDashPhase();
90
91 // Ensure converting dashes to double precision:
92 if (dashes != null) {
93 recycleDashes = true;
94 dashLen = dashes.length;
95 dashesD = rdrCtx.dasher.copyDashArray(dashes);
96 }
97
98 if (tx != null && !tx.isIdentity()) {
99 final double a = tx.getMxx();
100 final double b = tx.getMxy();
101 final double c = tx.getMyx();
102 final double d = tx.getMyy();
103
161 }
162
163 pc = transformerPC2D.inverseDeltaTransformConsumer(pc, strokerTx);
164
165 /*
166 * Pipeline seems to be:
167 * shape.getPathIterator(tx)
168 * -> (inverseDeltaTransformConsumer)
169 * -> (Dasher)
170 * -> Stroker
171 * -> (deltaTransformConsumer)
172 *
173 * -> (CollinearSimplifier) to remove redundant segments
174 *
175 * -> pc2d = Renderer (bounding box)
176 */
177 return pc;
178 }
179
180 private static boolean nearZero(final double num) {
181 return Math.abs(num) < 2.0d * Math.ulp(num);
182 }
183
184 public static DMarlinRenderer setupRenderer(
185 final DRendererContext rdrCtx,
186 final Shape shape,
187 final BasicStroke stroke,
188 final BaseTransform xform,
189 final Rectangle rclip,
190 final boolean antialiasedShape)
191 {
192 // Test if transform is identity:
193 final BaseTransform tf = (xform != null && !xform.isIdentity()) ? xform : null;
194
195 final PathIterator pi = shape.getPathIterator(tf);
196
197 final DMarlinRenderer r = (!FORCE_NO_AA && antialiasedShape) ?
198 rdrCtx.renderer : rdrCtx.getRendererNoAA();
199
200 final DPathConsumer2D pc2d = initRenderer(rdrCtx, stroke, tf, rclip, pi.getWindingRule(), r);
201
|