135 * @param dashLen length of the given dash array |
135 * @param dashLen length of the given dash array |
136 * @param phase a <code>double</code> containing the dash phase |
136 * @param phase a <code>double</code> containing the dash phase |
137 * @param recycleDashes true to indicate to recycle the given dash array |
137 * @param recycleDashes true to indicate to recycle the given dash array |
138 * @return this instance |
138 * @return this instance |
139 */ |
139 */ |
140 DDasher init(final DPathConsumer2D out, double[] dash, int dashLen, |
140 DDasher init(final DPathConsumer2D out, final double[] dash, final int dashLen, |
141 double phase, boolean recycleDashes) |
141 double phase, final boolean recycleDashes) |
142 { |
142 { |
143 this.out = out; |
143 this.out = out; |
144 |
144 |
145 // Normalize so 0 <= phase < dash[0] |
145 // Normalize so 0 <= phase < dash[0] |
146 int sidx = 0; |
146 int sidx = 0; |
147 dashOn = true; |
147 dashOn = true; |
148 |
148 |
|
149 // note: BasicStroke constructor checks dash elements and sum > 0 |
149 double sum = 0.0d; |
150 double sum = 0.0d; |
150 for (double d : dash) { |
151 for (int i = 0; i < dashLen; i++) { |
151 sum += d; |
152 sum += dash[i]; |
152 } |
153 } |
153 this.cycleLen = sum; |
154 this.cycleLen = sum; |
154 |
155 |
155 double cycles = phase / sum; |
156 double cycles = phase / sum; |
156 if (phase < 0.0d) { |
157 if (phase < 0.0d) { |
157 if (-cycles >= MAX_CYCLES) { |
158 if (-cycles >= MAX_CYCLES) { |
158 phase = 0.0d; |
159 phase = 0.0d; |
159 } else { |
160 } else { |
160 int fullcycles = FloatMath.floor_int(-cycles); |
161 int fullcycles = FloatMath.floor_int(-cycles); |
161 if ((fullcycles & dash.length & 1) != 0) { |
162 if ((fullcycles & dashLen & 1) != 0) { |
162 dashOn = !dashOn; |
163 dashOn = !dashOn; |
163 } |
164 } |
164 phase += fullcycles * sum; |
165 phase += fullcycles * sum; |
165 while (phase < 0.0d) { |
166 while (phase < 0.0d) { |
166 if (--sidx < 0) { |
167 if (--sidx < 0) { |
167 sidx = dash.length - 1; |
168 sidx = dashLen - 1; |
168 } |
169 } |
169 phase += dash[sidx]; |
170 phase += dash[sidx]; |
170 dashOn = !dashOn; |
171 dashOn = !dashOn; |
171 } |
172 } |
172 } |
173 } |
173 } else if (phase > 0.0d) { |
174 } else if (phase > 0.0d) { |
174 if (cycles >= MAX_CYCLES) { |
175 if (cycles >= MAX_CYCLES) { |
175 phase = 0.0d; |
176 phase = 0.0d; |
176 } else { |
177 } else { |
177 int fullcycles = FloatMath.floor_int(cycles); |
178 int fullcycles = FloatMath.floor_int(cycles); |
178 if ((fullcycles & dash.length & 1) != 0) { |
179 if ((fullcycles & dashLen & 1) != 0) { |
179 dashOn = !dashOn; |
180 dashOn = !dashOn; |
180 } |
181 } |
181 phase -= fullcycles * sum; |
182 phase -= fullcycles * sum; |
182 double d; |
183 double d; |
183 while (phase >= (d = dash[sidx])) { |
184 while (phase >= (d = dash[sidx])) { |
184 phase -= d; |
185 phase -= d; |
185 sidx = (sidx + 1) % dash.length; |
186 sidx = (sidx + 1) % dashLen; |
186 dashOn = !dashOn; |
187 dashOn = !dashOn; |
187 } |
188 } |
188 } |
189 } |
189 } |
190 } |
190 |
191 |