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