Source Code Cross Referenced for ExtendedGeneralPath.java in  » Graphic-Library » batik » org » apache » batik » ext » awt » geom » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Graphic Library » batik » org.apache.batik.ext.awt.geom 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Licensed to the Apache Software Foundation (ASF) under one or more
004:           contributor license agreements.  See the NOTICE file distributed with
005:           this work for additional information regarding copyright ownership.
006:           The ASF licenses this file to You under the Apache License, Version 2.0
007:           (the "License"); you may not use this file except in compliance with
008:           the License.  You may obtain a copy of the License at
009:
010:               http://www.apache.org/licenses/LICENSE-2.0
011:
012:           Unless required by applicable law or agreed to in writing, software
013:           distributed under the License is distributed on an "AS IS" BASIS,
014:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015:           See the License for the specific language governing permissions and
016:           limitations under the License.
017:
018:         */
019:        package org.apache.batik.ext.awt.geom;
020:
021:        import java.awt.Shape;
022:        import java.awt.Rectangle;
023:        import java.awt.geom.AffineTransform;
024:        import java.awt.geom.Arc2D;
025:        import java.awt.geom.GeneralPath;
026:        import java.awt.geom.PathIterator;
027:        import java.awt.geom.Point2D;
028:        import java.awt.geom.Rectangle2D;
029:        import java.util.Arrays;
030:
031:        /**
032:         * The <code>ExtendedGeneralPath</code> class represents a geometric
033:         * path constructed from straight lines, quadratic and cubic (Bezier)
034:         * curves and elliptical arc. This class delegates lines and curves to
035:         * an enclosed <code>GeneralPath</code>. Elliptical arc is implemented
036:         * using an <code>Arc2D</code> in float precision.
037:         *
038:         * <p><b>Warning</b> : An elliptical arc may be composed of several
039:         * path segments. For futher details, see the SVG Appendix&nbsp;F.6
040:         *
041:         * @author <a href="mailto:Thierry.Kormann@sophia.inria.fr">Thierry Kormann</a>
042:         * @version $Id: ExtendedGeneralPath.java 511565 2007-02-25 18:04:46Z dvholten $
043:         */
044:        public class ExtendedGeneralPath implements  ExtendedShape, Cloneable {
045:
046:            /** The enclosed general path. */
047:            protected GeneralPath path;
048:
049:            int numVals = 0;
050:            int numSeg = 0;
051:            float[] values = null;
052:            int[] types = null;
053:
054:            float mx, my, cx, cy;
055:
056:            /**
057:             * Constructs a new <code>ExtendedGeneralPath</code>.
058:             */
059:            public ExtendedGeneralPath() {
060:                path = new GeneralPath();
061:            }
062:
063:            /**
064:             * Constructs a new <code>ExtendedGeneralPath</code> with the
065:             * specified winding rule to control operations that require the
066:             * interior of the path to be defined.
067:             */
068:            public ExtendedGeneralPath(int rule) {
069:                path = new GeneralPath(rule);
070:            }
071:
072:            /**
073:             * Constructs a new <code>ExtendedGeneralPath</code> object with
074:             * the specified winding rule and the specified initial capacity
075:             * to store path coordinates.
076:             */
077:            public ExtendedGeneralPath(int rule, int initialCapacity) {
078:                path = new GeneralPath(rule, initialCapacity);
079:            }
080:
081:            /**
082:             * Constructs a new <code>ExtendedGeneralPath</code> object from
083:             * an arbitrary <code>Shape</code> object.
084:             */
085:            public ExtendedGeneralPath(Shape s) {
086:                this ();
087:                append(s, false);
088:            }
089:
090:            /**
091:             * Adds an elliptical arc, defined by two radii, an angle from the
092:             * x-axis, a flag to choose the large arc or not, a flag to
093:             * indicate if we increase or decrease the angles and the final
094:             * point of the arc.
095:             *
096:             * @param rx the x radius of the ellipse
097:             * @param ry the y radius of the ellipse
098:             *
099:             * @param angle the angle from the x-axis of the current
100:             * coordinate system to the x-axis of the ellipse in degrees.
101:             *
102:             * @param largeArcFlag the large arc flag. If true the arc
103:             * spanning less than or equal to 180 degrees is chosen, otherwise
104:             * the arc spanning greater than 180 degrees is chosen
105:             *
106:             * @param sweepFlag the sweep flag. If true the line joining
107:             * center to arc sweeps through decreasing angles otherwise it
108:             * sweeps through increasing angles
109:             *
110:             * @param x the absolute x coordinate of the final point of the arc.
111:             * @param y the absolute y coordinate of the final point of the arc.
112:             */
113:            public synchronized void arcTo(float rx, float ry, float angle,
114:                    boolean largeArcFlag, boolean sweepFlag, float x, float y) {
115:
116:                // Ensure radii are valid
117:                if (rx == 0 || ry == 0) {
118:                    lineTo((float) x, (float) y);
119:                    return;
120:                }
121:
122:                checkMoveTo(); // check if prev command was moveto
123:
124:                // Get the current (x, y) coordinates of the path
125:                double x0 = cx;
126:                double y0 = cy;
127:                if (x0 == x && y0 == y) {
128:                    // If the endpoints (x, y) and (x0, y0) are identical, then this
129:                    // is equivalent to omitting the elliptical arc segment entirely.
130:                    return;
131:                }
132:
133:                Arc2D arc = computeArc(x0, y0, rx, ry, angle, largeArcFlag,
134:                        sweepFlag, x, y);
135:                if (arc == null)
136:                    return;
137:
138:                AffineTransform t = AffineTransform.getRotateInstance(Math
139:                        .toRadians(angle), arc.getCenterX(), arc.getCenterY());
140:                Shape s = t.createTransformedShape(arc);
141:                path.append(s, true);
142:
143:                makeRoom(7);
144:                types[numSeg++] = ExtendedPathIterator.SEG_ARCTO;
145:                values[numVals++] = rx;
146:                values[numVals++] = ry;
147:                values[numVals++] = angle;
148:                values[numVals++] = largeArcFlag ? 1 : 0;
149:                values[numVals++] = sweepFlag ? 1 : 0;
150:                cx = values[numVals++] = x;
151:                cy = values[numVals++] = y;
152:            }
153:
154:            /**
155:             * This constructs an unrotated Arc2D from the SVG specification of an
156:             * Elliptical arc.  To get the final arc you need to apply a rotation
157:             * transform such as:
158:             *
159:             * AffineTransform.getRotateInstance
160:             *     (angle, arc.getX()+arc.getWidth()/2, arc.getY()+arc.getHeight()/2);
161:             */
162:            public static Arc2D computeArc(double x0, double y0, double rx,
163:                    double ry, double angle, boolean largeArcFlag,
164:                    boolean sweepFlag, double x, double y) {
165:                //
166:                // Elliptical arc implementation based on the SVG specification notes
167:                //
168:
169:                // Compute the half distance between the current and the final point
170:                double dx2 = (x0 - x) / 2.0;
171:                double dy2 = (y0 - y) / 2.0;
172:                // Convert angle from degrees to radians
173:                angle = Math.toRadians(angle % 360.0);
174:                double cosAngle = Math.cos(angle);
175:                double sinAngle = Math.sin(angle);
176:
177:                //
178:                // Step 1 : Compute (x1, y1)
179:                //
180:                double x1 = (cosAngle * dx2 + sinAngle * dy2);
181:                double y1 = (-sinAngle * dx2 + cosAngle * dy2);
182:                // Ensure radii are large enough
183:                rx = Math.abs(rx);
184:                ry = Math.abs(ry);
185:                double Prx = rx * rx;
186:                double Pry = ry * ry;
187:                double Px1 = x1 * x1;
188:                double Py1 = y1 * y1;
189:                // check that radii are large enough
190:                double radiiCheck = Px1 / Prx + Py1 / Pry;
191:                if (radiiCheck > 1) {
192:                    rx = Math.sqrt(radiiCheck) * rx;
193:                    ry = Math.sqrt(radiiCheck) * ry;
194:                    Prx = rx * rx;
195:                    Pry = ry * ry;
196:                }
197:
198:                //
199:                // Step 2 : Compute (cx1, cy1)
200:                //
201:                double sign = (largeArcFlag == sweepFlag) ? -1 : 1;
202:                double sq = ((Prx * Pry) - (Prx * Py1) - (Pry * Px1))
203:                        / ((Prx * Py1) + (Pry * Px1));
204:                sq = (sq < 0) ? 0 : sq;
205:                double coef = (sign * Math.sqrt(sq));
206:                double cx1 = coef * ((rx * y1) / ry);
207:                double cy1 = coef * -((ry * x1) / rx);
208:
209:                //
210:                // Step 3 : Compute (cx, cy) from (cx1, cy1)
211:                //
212:                double sx2 = (x0 + x) / 2.0;
213:                double sy2 = (y0 + y) / 2.0;
214:                double cx = sx2 + (cosAngle * cx1 - sinAngle * cy1);
215:                double cy = sy2 + (sinAngle * cx1 + cosAngle * cy1);
216:
217:                //
218:                // Step 4 : Compute the angleStart (angle1) and the angleExtent (dangle)
219:                //
220:                double ux = (x1 - cx1) / rx;
221:                double uy = (y1 - cy1) / ry;
222:                double vx = (-x1 - cx1) / rx;
223:                double vy = (-y1 - cy1) / ry;
224:                double p, n;
225:                // Compute the angle start
226:                n = Math.sqrt((ux * ux) + (uy * uy));
227:                p = ux; // (1 * ux) + (0 * uy)
228:                sign = (uy < 0) ? -1.0 : 1.0;
229:                double angleStart = Math.toDegrees(sign * Math.acos(p / n));
230:
231:                // Compute the angle extent
232:                n = Math.sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy));
233:                p = ux * vx + uy * vy;
234:                sign = (ux * vy - uy * vx < 0) ? -1.0 : 1.0;
235:                double angleExtent = Math.toDegrees(sign * Math.acos(p / n));
236:                if (!sweepFlag && angleExtent > 0) {
237:                    angleExtent -= 360f;
238:                } else if (sweepFlag && angleExtent < 0) {
239:                    angleExtent += 360f;
240:                }
241:                angleExtent %= 360f;
242:                angleStart %= 360f;
243:
244:                //
245:                // We can now build the resulting Arc2D in double precision
246:                //
247:                Arc2D.Double arc = new Arc2D.Double();
248:                arc.x = cx - rx;
249:                arc.y = cy - ry;
250:                arc.width = rx * 2.0;
251:                arc.height = ry * 2.0;
252:                arc.start = -angleStart;
253:                arc.extent = -angleExtent;
254:
255:                return arc;
256:            }
257:
258:            /**
259:             * Delegates to the enclosed <code>GeneralPath</code>.
260:             */
261:            public synchronized void moveTo(float x, float y) {
262:                // Don't add moveto to general path unless there is a reason.
263:                makeRoom(2);
264:                types[numSeg++] = PathIterator.SEG_MOVETO;
265:                cx = mx = values[numVals++] = x;
266:                cy = my = values[numVals++] = y;
267:
268:            }
269:
270:            /**
271:             * Delegates to the enclosed <code>GeneralPath</code>.
272:             */
273:            public synchronized void lineTo(float x, float y) {
274:                checkMoveTo(); // check if prev command was moveto
275:                path.lineTo(x, y);
276:
277:                makeRoom(2);
278:                types[numSeg++] = PathIterator.SEG_LINETO;
279:                cx = values[numVals++] = x;
280:                cy = values[numVals++] = y;
281:            }
282:
283:            /**
284:             * Delegates to the enclosed <code>GeneralPath</code>.
285:             */
286:            public synchronized void quadTo(float x1, float y1, float x2,
287:                    float y2) {
288:                checkMoveTo(); // check if prev command was moveto
289:                path.quadTo(x1, y1, x2, y2);
290:
291:                makeRoom(4);
292:                types[numSeg++] = PathIterator.SEG_QUADTO;
293:                values[numVals++] = x1;
294:                values[numVals++] = y1;
295:                cx = values[numVals++] = x2;
296:                cy = values[numVals++] = y2;
297:            }
298:
299:            /**
300:             * Delegates to the enclosed <code>GeneralPath</code>.
301:             */
302:            public synchronized void curveTo(float x1, float y1, float x2,
303:                    float y2, float x3, float y3) {
304:                checkMoveTo(); // check if prev command was moveto
305:                path.curveTo(x1, y1, x2, y2, x3, y3);
306:
307:                makeRoom(6);
308:                types[numSeg++] = PathIterator.SEG_CUBICTO;
309:                values[numVals++] = x1;
310:                values[numVals++] = y1;
311:                values[numVals++] = x2;
312:                values[numVals++] = y2;
313:                cx = values[numVals++] = x3;
314:                cy = values[numVals++] = y3;
315:            }
316:
317:            /**
318:             * Delegates to the enclosed <code>GeneralPath</code>.
319:             */
320:            public synchronized void closePath() {
321:                // Don't double close path.
322:                if ((numSeg != 0)
323:                        && (types[numSeg - 1] == PathIterator.SEG_CLOSE))
324:                    return;
325:
326:                // Only close path if the previous command wasn't a moveto
327:                if ((numSeg != 0)
328:                        && (types[numSeg - 1] != PathIterator.SEG_MOVETO))
329:                    path.closePath();
330:
331:                makeRoom(0);
332:                types[numSeg++] = PathIterator.SEG_CLOSE;
333:                cx = mx;
334:                cy = my;
335:            }
336:
337:            /**
338:             * Checks if previous command was a moveto command,
339:             * skipping a close command (if present).
340:             */
341:            protected void checkMoveTo() {
342:                if (numSeg == 0)
343:                    return;
344:
345:                switch (types[numSeg - 1]) {
346:
347:                case PathIterator.SEG_MOVETO:
348:                    path.moveTo(values[numVals - 2], values[numVals - 1]);
349:                    break;
350:
351:                case PathIterator.SEG_CLOSE:
352:                    if (numSeg == 1)
353:                        return;
354:                    if (types[numSeg - 2] == PathIterator.SEG_MOVETO)
355:                        path.moveTo(values[numVals - 2], values[numVals - 1]);
356:                    break;
357:
358:                default:
359:                    break;
360:                }
361:            }
362:
363:            /**
364:             * Delegates to the enclosed <code>GeneralPath</code>.
365:             */
366:            public void append(Shape s, boolean connect) {
367:                append(s.getPathIterator(new AffineTransform()), connect);
368:            }
369:
370:            /**
371:             * Delegates to the enclosed <code>GeneralPath</code>.
372:             */
373:            public void append(PathIterator pi, boolean connect) {
374:                double[] vals = new double[6];
375:
376:                while (!pi.isDone()) {
377:                    Arrays.fill(vals, 0);
378:                    int type = pi.currentSegment(vals);
379:                    pi.next();
380:                    if (connect && (numVals != 0)) {
381:                        if (type == PathIterator.SEG_MOVETO) {
382:                            double x = vals[0];
383:                            double y = vals[1];
384:                            if ((x != cx) || (y != cy)) {
385:                                // Change MOVETO to LINETO.
386:                                type = PathIterator.SEG_LINETO;
387:                            } else {
388:                                // Redundent segment (move to current loc) drop it...
389:                                if (pi.isDone())
390:                                    break; // Nothing interesting
391:                                type = pi.currentSegment(vals);
392:                                pi.next();
393:                            }
394:                        }
395:                        connect = false;
396:                    }
397:
398:                    switch (type) {
399:                    case PathIterator.SEG_CLOSE:
400:                        closePath();
401:                        break;
402:                    case PathIterator.SEG_MOVETO:
403:                        moveTo((float) vals[0], (float) vals[1]);
404:                        break;
405:                    case PathIterator.SEG_LINETO:
406:                        lineTo((float) vals[0], (float) vals[1]);
407:                        break;
408:                    case PathIterator.SEG_QUADTO:
409:                        quadTo((float) vals[0], (float) vals[1],
410:                                (float) vals[2], (float) vals[3]);
411:                        break;
412:                    case PathIterator.SEG_CUBICTO:
413:                        curveTo((float) vals[0], (float) vals[1],
414:                                (float) vals[2], (float) vals[3],
415:                                (float) vals[4], (float) vals[5]);
416:                        break;
417:                    }
418:                }
419:            }
420:
421:            /**
422:             * Delegates to the enclosed <code>GeneralPath</code>.
423:             */
424:            public void append(ExtendedPathIterator epi, boolean connect) {
425:                float[] vals = new float[7];
426:                while (!epi.isDone()) {
427:                    Arrays.fill(vals, 0);
428:                    int type = epi.currentSegment(vals);
429:                    epi.next();
430:                    if (connect && (numVals != 0)) {
431:                        if (type == PathIterator.SEG_MOVETO) {
432:                            float x = vals[0];
433:                            float y = vals[1];
434:                            if ((x != cx) || (y != cy)) {
435:                                // Change MOVETO to LINETO.
436:                                type = PathIterator.SEG_LINETO;
437:                            } else {
438:                                // Redundant segment (move to current loc) drop it...
439:                                if (epi.isDone())
440:                                    break; // Nothing interesting
441:                                type = epi.currentSegment(vals);
442:                                epi.next();
443:                            }
444:                        }
445:                        connect = false;
446:                    }
447:
448:                    switch (type) {
449:                    case PathIterator.SEG_CLOSE:
450:                        closePath();
451:                        break;
452:                    case PathIterator.SEG_MOVETO:
453:                        moveTo((float) vals[0], (float) vals[1]);
454:                        break;
455:                    case PathIterator.SEG_LINETO:
456:                        lineTo((float) vals[0], (float) vals[1]);
457:                        break;
458:                    case PathIterator.SEG_QUADTO:
459:                        quadTo((float) vals[0], (float) vals[1],
460:                                (float) vals[2], (float) vals[3]);
461:                        break;
462:                    case PathIterator.SEG_CUBICTO:
463:                        curveTo((float) vals[0], (float) vals[1],
464:                                (float) vals[2], (float) vals[3],
465:                                (float) vals[4], (float) vals[5]);
466:                        break;
467:                    case ExtendedPathIterator.SEG_ARCTO:
468:                        arcTo(vals[0], vals[1], vals[2], (vals[3] != 0),
469:                                (vals[4] != 0), vals[5], vals[6]);
470:                        break;
471:                    }
472:                }
473:            }
474:
475:            /**
476:             * Delegates to the enclosed <code>GeneralPath</code>.
477:             */
478:            public synchronized int getWindingRule() {
479:                return path.getWindingRule();
480:            }
481:
482:            /**
483:             * Delegates to the enclosed <code>GeneralPath</code>.
484:             */
485:            public void setWindingRule(int rule) {
486:                path.setWindingRule(rule);
487:            }
488:
489:            /**
490:             * get the current position or <code>null</code>.
491:             */
492:            public synchronized Point2D getCurrentPoint() {
493:                if (numVals == 0)
494:                    return null;
495:                return new Point2D.Double(cx, cy);
496:            }
497:
498:            /**
499:             * Delegates to the enclosed <code>GeneralPath</code>.
500:             */
501:            public synchronized void reset() {
502:                path.reset();
503:
504:                numSeg = 0;
505:                numVals = 0;
506:                values = null;
507:                types = null;
508:            }
509:
510:            /**
511:             * Delegates to the enclosed <code>GeneralPath</code>.
512:             */
513:            public void transform(AffineTransform at) {
514:                if (at.getType() != AffineTransform.TYPE_IDENTITY)
515:                    throw new IllegalArgumentException(
516:                            "ExtendedGeneralPaths can not be transformed");
517:            }
518:
519:            /**
520:             * Delegates to the enclosed <code>GeneralPath</code>.
521:             */
522:            public synchronized Shape createTransformedShape(AffineTransform at) {
523:                return path.createTransformedShape(at);
524:            }
525:
526:            /**
527:             * Delegates to the enclosed <code>GeneralPath</code>.
528:             */
529:            public synchronized Rectangle getBounds() {
530:                return path.getBounds();
531:            }
532:
533:            /**
534:             * Delegates to the enclosed <code>GeneralPath</code>.
535:             */
536:            public synchronized Rectangle2D getBounds2D() {
537:                return path.getBounds2D();
538:            }
539:
540:            /**
541:             * Delegates to the enclosed <code>GeneralPath</code>.
542:             */
543:            public boolean contains(double x, double y) {
544:                return path.contains(x, y);
545:            }
546:
547:            /**
548:             * Delegates to the enclosed <code>GeneralPath</code>.
549:             */
550:            public boolean contains(Point2D p) {
551:                return path.contains(p);
552:            }
553:
554:            /**
555:             * Delegates to the enclosed <code>GeneralPath</code>.
556:             */
557:            public boolean contains(double x, double y, double w, double h) {
558:                return path.contains(x, y, w, h);
559:            }
560:
561:            /**
562:             * Delegates to the enclosed <code>GeneralPath</code>.
563:             */
564:            public boolean contains(Rectangle2D r) {
565:                return path.contains(r);
566:            }
567:
568:            /**
569:             * Delegates to the enclosed <code>GeneralPath</code>.
570:             */
571:            public boolean intersects(double x, double y, double w, double h) {
572:                return path.intersects(x, y, w, h);
573:            }
574:
575:            /**
576:             * Delegates to the enclosed <code>GeneralPath</code>.
577:             */
578:            public boolean intersects(Rectangle2D r) {
579:                return path.intersects(r);
580:            }
581:
582:            /**
583:             * Delegates to the enclosed <code>GeneralPath</code>.
584:             */
585:            public PathIterator getPathIterator(AffineTransform at) {
586:                return path.getPathIterator(at);
587:            }
588:
589:            /**
590:             * Delegates to the enclosed <code>GeneralPath</code>.
591:             */
592:            public PathIterator getPathIterator(AffineTransform at,
593:                    double flatness) {
594:                return path.getPathIterator(at, flatness);
595:            }
596:
597:            /**
598:             * Delegates to the enclosed <code>GeneralPath</code>.
599:             */
600:            public ExtendedPathIterator getExtendedPathIterator() {
601:                return new EPI();
602:            }
603:
604:            class EPI implements  ExtendedPathIterator {
605:                int segNum = 0;
606:                int valsIdx = 0;
607:
608:                public int currentSegment() {
609:                    return types[segNum];
610:                }
611:
612:                public int currentSegment(double[] coords) {
613:                    int ret = types[segNum];
614:                    switch (ret) {
615:                    case SEG_CLOSE:
616:                        break;
617:                    case SEG_MOVETO:
618:                    case SEG_LINETO:
619:                        coords[0] = values[valsIdx];
620:                        coords[1] = values[valsIdx + 1];
621:                        break;
622:                    case SEG_QUADTO:
623:                        coords[0] = values[valsIdx];
624:                        coords[1] = values[valsIdx + 1];
625:                        coords[2] = values[valsIdx + 2];
626:                        coords[3] = values[valsIdx + 3];
627:                        break;
628:                    case SEG_CUBICTO:
629:                        coords[0] = values[valsIdx];
630:                        coords[1] = values[valsIdx + 1];
631:                        coords[2] = values[valsIdx + 2];
632:                        coords[3] = values[valsIdx + 3];
633:                        coords[4] = values[valsIdx + 4];
634:                        coords[5] = values[valsIdx + 5];
635:                        break;
636:                    case SEG_ARCTO:
637:                        coords[0] = values[valsIdx];
638:                        coords[1] = values[valsIdx + 1];
639:                        coords[2] = values[valsIdx + 2];
640:                        coords[3] = values[valsIdx + 3];
641:                        coords[4] = values[valsIdx + 4];
642:                        coords[5] = values[valsIdx + 5];
643:                        coords[6] = values[valsIdx + 6];
644:                        break;
645:                    }
646:                    // System.out.println("Seg: [" + segNum + "] type: " + ret +
647:                    //                    " vals: [" + coords[0] + ", " + coords[1] +
648:                    //                    "]");
649:                    return ret;
650:                }
651:
652:                public int currentSegment(float[] coords) {
653:                    int ret = types[segNum];
654:                    switch (ret) {
655:                    case SEG_CLOSE:
656:                        break;
657:                    case SEG_MOVETO:
658:                    case SEG_LINETO:
659:                        coords[0] = values[valsIdx];
660:                        coords[1] = values[valsIdx + 1];
661:                        break;
662:                    case SEG_QUADTO:
663:                        // coords[0] = values[valsIdx];
664:                        // coords[1] = values[valsIdx+1];
665:                        // coords[2] = values[valsIdx+2];
666:                        // coords[3] = values[valsIdx+3];
667:                        System.arraycopy(values, 0, coords, 0, 4);
668:                        break;
669:                    case SEG_CUBICTO:
670:                        // coords[0] = values[valsIdx];
671:                        // coords[1] = values[valsIdx+1];
672:                        // coords[2] = values[valsIdx+2];
673:                        // coords[3] = values[valsIdx+3];
674:                        // coords[4] = values[valsIdx+4];
675:                        // coords[5] = values[valsIdx+5];
676:                        System.arraycopy(values, 0, coords, 0, 6);
677:                        break;
678:                    case SEG_ARCTO:
679:                        // coords[0] = values[valsIdx];
680:                        // coords[1] = values[valsIdx+1];
681:                        // coords[2] = values[valsIdx+2];
682:                        // coords[3] = values[valsIdx+3];
683:                        // coords[4] = values[valsIdx+4];
684:                        // coords[5] = values[valsIdx+5];
685:                        // coords[6] = values[valsIdx+6];
686:                        System.arraycopy(values, 0, coords, 0, 7);
687:                        break;
688:                    }
689:                    return ret;
690:                }
691:
692:                public int getWindingRule() {
693:                    return path.getWindingRule();
694:                }
695:
696:                public boolean isDone() {
697:                    return segNum == numSeg;
698:                }
699:
700:                public void next() {
701:                    int type = types[segNum++];
702:                    switch (type) {
703:                    case SEG_CLOSE:
704:                        break;
705:                    case SEG_MOVETO: // fallthrough is intended
706:                    case SEG_LINETO:
707:                        valsIdx += 2;
708:                        break;
709:                    case SEG_QUADTO:
710:                        valsIdx += 4;
711:                        break;
712:                    case SEG_CUBICTO:
713:                        valsIdx += 6;
714:                        break;
715:                    case SEG_ARCTO:
716:                        valsIdx += 7;
717:                        break;
718:                    }
719:                }
720:            }
721:
722:            /**
723:             * Delegates to the enclosed <code>GeneralPath</code>.
724:             */
725:            public Object clone() {
726:                try {
727:                    ExtendedGeneralPath result = (ExtendedGeneralPath) super 
728:                            .clone();
729:                    result.path = (GeneralPath) path.clone();
730:
731:                    if (values != null) {
732:                        result.values = new float[values.length];
733:                        System.arraycopy(values, 0, result.values, 0,
734:                                values.length);
735:                    }
736:                    result.numVals = numVals;
737:
738:                    if (types != null) {
739:                        result.types = new int[types.length];
740:                        System.arraycopy(types, 0, result.types, 0,
741:                                types.length);
742:                    }
743:                    result.numSeg = numSeg;
744:
745:                    return result;
746:                } catch (CloneNotSupportedException ex) {
747:                }
748:                return null;
749:            }
750:
751:            /**
752:             * Make sure, that the requested number of slots in vales[] are available.
753:             * Must be called even for numValues = 0, because it is also
754:             * used for initialization of those arrays.
755:             *
756:             * @param numValues number of requested coordinates
757:             */
758:            private void makeRoom(int numValues) {
759:                if (values == null) {
760:                    values = new float[2 * numValues];
761:                    types = new int[2];
762:                    numVals = 0;
763:                    numSeg = 0;
764:                    return;
765:                }
766:
767:                int newSize = numVals + numValues;
768:                if (newSize > values.length) {
769:                    int nlen = values.length * 2;
770:                    if (nlen < newSize)
771:                        nlen = newSize;
772:
773:                    float[] nvals = new float[nlen];
774:                    System.arraycopy(values, 0, nvals, 0, numVals);
775:                    values = nvals;
776:                }
777:
778:                if (numSeg == types.length) {
779:                    int[] ntypes = new int[types.length * 2];
780:                    System.arraycopy(types, 0, ntypes, 0, types.length);
781:                    types = ntypes;
782:                }
783:            }
784:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.