124 rdrCtx.stats.stat_array_str_polystack_curves, 125 rdrCtx.stats.stat_array_str_polystack_types) 126 : new PolyStack(rdrCtx); 127 128 this.curve = rdrCtx.curve; 129 this.curveSplitter = rdrCtx.curveClipSplitter; 130 } 131 132 /** 133 * Inits the <code>Stroker</code>. 134 * 135 * @param pc2d an output <code>PathConsumer2D</code>. 136 * @param lineWidth the desired line width in pixels 137 * @param capStyle the desired end cap style, one of 138 * <code>CAP_BUTT</code>, <code>CAP_ROUND</code> or 139 * <code>CAP_SQUARE</code>. 140 * @param joinStyle the desired line join style, one of 141 * <code>JOIN_MITER</code>, <code>JOIN_ROUND</code> or 142 * <code>JOIN_BEVEL</code>. 143 * @param miterLimit the desired miter limit 144 * @param scale scaling factor applied to clip boundaries 145 * @param rdrOffX renderer's coordinate offset on X axis 146 * @param rdrOffY renderer's coordinate offset on Y axis 147 * @param subdivideCurves true to indicate to subdivide curves, false if dasher does 148 * @return this instance 149 */ 150 public Stroker init(final PathConsumer2D pc2d, 151 final float lineWidth, 152 final int capStyle, 153 final int joinStyle, 154 final float miterLimit, 155 final float scale, 156 double rdrOffX, 157 double rdrOffY, 158 final boolean subdivideCurves) 159 { 160 this.out = pc2d; 161 162 this.lineWidth2 = lineWidth / 2.0f; 163 this.invHalfLineWidth2Sq = 1.0f / (2.0f * lineWidth2 * lineWidth2); 164 this.monotonize = subdivideCurves; 165 166 this.capStyle = capStyle; 167 this.joinStyle = joinStyle; 168 169 final float limit = miterLimit * lineWidth2; 170 this.miterLimitSq = limit * limit; 171 172 this.prev = CLOSE; 173 174 rdrCtx.stroking = 1; 175 176 if (rdrCtx.doClip) { 177 // Adjust the clipping rectangle with the stroker margin (miter limit, width) 178 float margin = lineWidth2; 179 180 if (capStyle == CAP_SQUARE) { 181 margin *= SQRT_2; 182 } 183 if ((joinStyle == JOIN_MITER) && (margin < limit)) { 184 margin = limit; 185 } 186 if (scale != 1.0f) { 187 margin *= scale; 188 rdrOffX *= scale; 189 rdrOffY *= scale; 190 } 191 // add a small rounding error: 192 margin += 1e-3f; 193 194 // bounds as half-open intervals: minX <= x < maxX and minY <= y < maxY 195 // adjust clip rectangle (ymin, ymax, xmin, xmax): 196 final float[] _clipRect = rdrCtx.clipRect; 197 _clipRect[0] -= margin - rdrOffY; 198 _clipRect[1] += margin + rdrOffY; 199 _clipRect[2] -= margin - rdrOffX; 200 _clipRect[3] += margin + rdrOffX; 201 this.clipRect = _clipRect; 202 203 // initialize curve splitter here for stroker & dasher: 204 if (DO_CLIP_SUBDIVIDER) { 205 subdivide = subdivideCurves; 206 // adjust padded clip rectangle: 207 curveSplitter.init(); 208 } else { 209 subdivide = false; 210 } 211 } else { 212 this.clipRect = null; 213 this.cOutCode = 0; 214 this.sOutCode = 0; 215 } 216 return this; // fluent API 217 } 218 219 public void disableClipping() { 220 this.clipRect = null; 221 this.cOutCode = 0; 222 this.sOutCode = 0; | 124 rdrCtx.stats.stat_array_str_polystack_curves, 125 rdrCtx.stats.stat_array_str_polystack_types) 126 : new PolyStack(rdrCtx); 127 128 this.curve = rdrCtx.curve; 129 this.curveSplitter = rdrCtx.curveClipSplitter; 130 } 131 132 /** 133 * Inits the <code>Stroker</code>. 134 * 135 * @param pc2d an output <code>PathConsumer2D</code>. 136 * @param lineWidth the desired line width in pixels 137 * @param capStyle the desired end cap style, one of 138 * <code>CAP_BUTT</code>, <code>CAP_ROUND</code> or 139 * <code>CAP_SQUARE</code>. 140 * @param joinStyle the desired line join style, one of 141 * <code>JOIN_MITER</code>, <code>JOIN_ROUND</code> or 142 * <code>JOIN_BEVEL</code>. 143 * @param miterLimit the desired miter limit 144 * @param subdivideCurves true to indicate to subdivide curves, false if dasher does 145 * @return this instance 146 */ 147 public Stroker init(final PathConsumer2D pc2d, 148 final float lineWidth, 149 final int capStyle, 150 final int joinStyle, 151 final float miterLimit, 152 final boolean subdivideCurves) 153 { 154 this.out = pc2d; 155 156 this.lineWidth2 = lineWidth / 2.0f; 157 this.invHalfLineWidth2Sq = 1.0f / (2.0f * lineWidth2 * lineWidth2); 158 this.monotonize = subdivideCurves; 159 160 this.capStyle = capStyle; 161 this.joinStyle = joinStyle; 162 163 final float limit = miterLimit * lineWidth2; 164 this.miterLimitSq = limit * limit; 165 166 this.prev = CLOSE; 167 168 rdrCtx.stroking = 1; 169 170 if (rdrCtx.doClip) { 171 // Adjust the clipping rectangle with the stroker margin (miter limit, width) 172 float margin = lineWidth2; 173 174 if (capStyle == CAP_SQUARE) { 175 margin *= SQRT_2; 176 } 177 if ((joinStyle == JOIN_MITER) && (margin < limit)) { 178 margin = limit; 179 } 180 181 // bounds as half-open intervals: minX <= x < maxX and minY <= y < maxY 182 // adjust clip rectangle (ymin, ymax, xmin, xmax): 183 final float[] _clipRect = rdrCtx.clipRect; 184 _clipRect[0] -= margin; 185 _clipRect[1] += margin; 186 _clipRect[2] -= margin; 187 _clipRect[3] += margin; 188 this.clipRect = _clipRect; 189 190 if (MarlinConst.DO_LOG_CLIP) { 191 MarlinUtils.logInfo("clipRect (stroker): " 192 + Arrays.toString(rdrCtx.clipRect)); 193 } 194 195 // initialize curve splitter here for stroker & dasher: 196 if (DO_CLIP_SUBDIVIDER) { 197 subdivide = subdivideCurves; 198 // adjust padded clip rectangle: 199 curveSplitter.init(); 200 } else { 201 subdivide = false; 202 } 203 } else { 204 this.clipRect = null; 205 this.cOutCode = 0; 206 this.sOutCode = 0; 207 } 208 return this; // fluent API 209 } 210 211 public void disableClipping() { 212 this.clipRect = null; 213 this.cOutCode = 0; 214 this.sOutCode = 0; |