6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.java2d.marlin;
27
28 final class Curve {
29
30 float ax, ay, bx, by, cx, cy, dx, dy;
31 float dax, day, dbx, dby;
32 // shared iterator instance
33 private final BreakPtrIterator iterator = new BreakPtrIterator();
34
35 Curve() {
36 }
37
38 void set(float[] points, int type) {
39 switch(type) {
40 case 8:
41 set(points[0], points[1],
42 points[2], points[3],
43 points[4], points[5],
44 points[6], points[7]);
45 return;
46 case 6:
47 set(points[0], points[1],
48 points[2], points[3],
49 points[4], points[5]);
50 return;
51 default:
52 throw new InternalError("Curves can only be cubic or quadratic");
53 }
219 }
220
221 private static boolean sameSign(float x, float y) {
222 // another way is to test if x*y > 0. This is bad for small x, y.
223 return (x < 0f && y < 0f) || (x > 0f && y > 0f);
224 }
225
226 // returns the radius of curvature squared at t of this curve
227 // see http://en.wikipedia.org/wiki/Radius_of_curvature_(applications)
228 private float ROCsq(final float t) {
229 // dx=xat(t) and dy=yat(t). These calls have been inlined for efficiency
230 final float dx = t * (t * dax + dbx) + cx;
231 final float dy = t * (t * day + dby) + cy;
232 final float ddx = 2f * dax * t + dbx;
233 final float ddy = 2f * day * t + dby;
234 final float dx2dy2 = dx*dx + dy*dy;
235 final float ddx2ddy2 = ddx*ddx + ddy*ddy;
236 final float ddxdxddydy = ddx*dx + ddy*dy;
237 return dx2dy2*((dx2dy2*dx2dy2) / (dx2dy2 * ddx2ddy2 - ddxdxddydy*ddxdxddydy));
238 }
239
240 // curve to be broken should be in pts
241 // this will change the contents of pts but not Ts
242 // TODO: There's no reason for Ts to be an array. All we need is a sequence
243 // of t values at which to subdivide. An array statisfies this condition,
244 // but is unnecessarily restrictive. Ts should be an Iterator<Float> instead.
245 // Doing this will also make dashing easier, since we could easily make
246 // LengthIterator an Iterator<Float> and feed it to this function to simplify
247 // the loop in Dasher.somethingTo.
248 BreakPtrIterator breakPtsAtTs(final float[] pts, final int type,
249 final float[] Ts, final int numTs)
250 {
251 assert pts.length >= 2*type && numTs <= Ts.length;
252
253 // initialize shared iterator:
254 iterator.init(pts, type, Ts, numTs);
255
256 return iterator;
257 }
258
259 static final class BreakPtrIterator {
260 private int nextCurveIdx;
261 private int curCurveOff;
262 private float prevT;
263 private float[] pts;
264 private int type;
265 private float[] ts;
266 private int numTs;
267
268 void init(final float[] pts, final int type,
269 final float[] ts, final int numTs) {
270 this.pts = pts;
271 this.type = type;
272 this.ts = ts;
273 this.numTs = numTs;
274
275 nextCurveIdx = 0;
276 curCurveOff = 0;
277 prevT = 0f;
278 }
279
280 public boolean hasNext() {
281 return nextCurveIdx <= numTs;
282 }
283
284 public int next() {
285 int ret;
286 if (nextCurveIdx < numTs) {
287 float curT = ts[nextCurveIdx];
288 float splitT = (curT - prevT) / (1f - prevT);
289 Helpers.subdivideAt(splitT,
290 pts, curCurveOff,
291 pts, 0,
292 pts, type, type);
293 prevT = curT;
294 ret = 0;
295 curCurveOff = type;
296 } else {
297 ret = curCurveOff;
298 }
299 nextCurveIdx++;
300 return ret;
301 }
302 }
303 }
304
|
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.marlin;
27
28 final class Curve {
29
30 float ax, ay, bx, by, cx, cy, dx, dy;
31 float dax, day, dbx, dby;
32
33 Curve() {
34 }
35
36 void set(float[] points, int type) {
37 switch(type) {
38 case 8:
39 set(points[0], points[1],
40 points[2], points[3],
41 points[4], points[5],
42 points[6], points[7]);
43 return;
44 case 6:
45 set(points[0], points[1],
46 points[2], points[3],
47 points[4], points[5]);
48 return;
49 default:
50 throw new InternalError("Curves can only be cubic or quadratic");
51 }
217 }
218
219 private static boolean sameSign(float x, float y) {
220 // another way is to test if x*y > 0. This is bad for small x, y.
221 return (x < 0f && y < 0f) || (x > 0f && y > 0f);
222 }
223
224 // returns the radius of curvature squared at t of this curve
225 // see http://en.wikipedia.org/wiki/Radius_of_curvature_(applications)
226 private float ROCsq(final float t) {
227 // dx=xat(t) and dy=yat(t). These calls have been inlined for efficiency
228 final float dx = t * (t * dax + dbx) + cx;
229 final float dy = t * (t * day + dby) + cy;
230 final float ddx = 2f * dax * t + dbx;
231 final float ddy = 2f * day * t + dby;
232 final float dx2dy2 = dx*dx + dy*dy;
233 final float ddx2ddy2 = ddx*ddx + ddy*ddy;
234 final float ddxdxddydy = ddx*dx + ddy*dy;
235 return dx2dy2*((dx2dy2*dx2dy2) / (dx2dy2 * ddx2ddy2 - ddxdxddydy*ddxdxddydy));
236 }
237 }
|