Source Code Cross Referenced for PathSupport.java in  » 6.0-JDK-Modules » j2me » com » sun » perseus » j2d » 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 » 6.0 JDK Modules » j2me » com.sun.perseus.j2d 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *
003:         *
004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006:         * 
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License version
009:         * 2 only, as published by the Free Software Foundation.
010:         * 
011:         * This program is distributed in the hope that it will be useful, but
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014:         * General Public License version 2 for more details (a copy is
015:         * included at /legal/license.txt).
016:         * 
017:         * You should have received a copy of the GNU General Public License
018:         * version 2 along with this work; if not, write to the Free Software
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA
021:         * 
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023:         * Clara, CA 95054 or visit www.sun.com if you need additional
024:         * information or have any questions.
025:         */
026:        package com.sun.perseus.j2d;
027:
028:        import org.w3c.dom.svg.SVGPath;
029:
030:        import com.sun.pisces.Dasher;
031:        import com.sun.pisces.Flattener;
032:        import com.sun.pisces.PathSink;
033:        import com.sun.pisces.PathStore;
034:        import com.sun.pisces.Stroker;
035:        import com.sun.pisces.Transformer;
036:        import com.sun.pisces.Transform4;
037:        import com.sun.pisces.Transform6;
038:
039:        /**
040:         * @version $Id: PathSupport.java,v 1.12 2006/04/21 06:35:29 st125089 Exp $
041:         */
042:        public class PathSupport {
043:            /**
044:             *  Identity Transform4
045:             */
046:            private static final Transform4 identity = new Transform4();
047:
048:            /**
049:             *  Identity Transform6
050:             */
051:            private static final Transform6 identity6 = new Transform6();
052:
053:            /**
054:             * A transform used in the implementation of computeStrokedPathTile
055:             */
056:            private static final Transform6 txf = new Transform6();
057:
058:            /**
059:             * Used to compute a stroked path's outline.
060:             */
061:            private static TileSink tileSink = new TileSink();
062:
063:            /**
064:             * Used to transform the coordinates of stroked path.
065:             */
066:            private static Transformer transformerSink = new Transformer(
067:                    tileSink, identity6);
068:
069:            private static int toFixed(float f) {
070:                return (int) (f * 65536.0f);
071:            }
072:
073:            private static void emitPath(Path path, PathSink output) {
074:                int numSegments = path.getNumberOfSegments();
075:                byte[] pathCommands = path.getCommands();
076:                float[] pathData = path.getData();
077:
078:                int x1 = -1, y1 = -1, x2, y2, x3, y3;
079:                float[] pt = null;
080:
081:                int offset = 0;
082:
083:                for (int seg = 0; seg < numSegments; seg++) {
084:                    if (pathCommands[seg] != Path.CLOSE_IMPL) {
085:                        x1 = toFixed(pathData[offset]);
086:                        y1 = toFixed(pathData[offset + 1]);
087:                    }
088:
089:                    switch (pathCommands[seg]) {
090:                    case Path.MOVE_TO_IMPL:
091:                        output.moveTo(x1, y1);
092:                        offset += 2;
093:                        break;
094:                    case Path.LINE_TO_IMPL:
095:                        output.lineTo(x1, y1);
096:                        offset += 2;
097:                        break;
098:                    case Path.QUAD_TO_IMPL:
099:                        x2 = toFixed(pathData[offset + 2]);
100:                        y2 = toFixed(pathData[offset + 3]);
101:                        output.quadTo(x1, y1, x2, y2);
102:                        offset += 4;
103:                        break;
104:                    case Path.CURVE_TO_IMPL:
105:                        x2 = toFixed(pathData[offset + 2]);
106:                        y2 = toFixed(pathData[offset + 3]);
107:                        x3 = toFixed(pathData[offset + 4]);
108:                        y3 = toFixed(pathData[offset + 5]);
109:                        output.cubicTo(x1, y1, x2, y2, x3, y3);
110:                        offset += 6;
111:                        break;
112:                    case Path.CLOSE_IMPL:
113:                        output.close();
114:                        break;
115:                    }
116:                }
117:
118:                output.end();
119:            }
120:
121:            /**
122:             * Returns true if the shape is hit by the given point.
123:             *
124:             * @param path the shape on which we do hit testing. Should not be null.
125:             * @param windingRule the winding rule fo the path.
126:             * @param hx the hit point x-axis coordinate.
127:             * @param hy the hit point y-axis coordinate.
128:             *
129:             * @return true if the input shape is hit. false otherwise.
130:             */
131:            public static boolean isHit(final Path path, final int windingRule,
132:                    final float hx, final float hy) {
133:                HitTester hitTester = new HitTester(windingRule, toFixed(hx),
134:                        toFixed(hy));
135:                emitPath(path, hitTester);
136:                boolean hit = hitTester.containsPoint();
137:                return hit;
138:            }
139:
140:            /**
141:             * Returns true if the input object is hit by the given point.
142:             *
143:             * @param strokedPath the shape on which we do hit testing.
144:             *        Should not be null.
145:             * @param windingRule the winding rule fo the path.
146:             * @param hx the hit point x-axis coordinate.
147:             * @param hy the hit point y-axis coordinate.
148:             *
149:             * @return true if the input shape is hit. false otherwise.
150:             */
151:            public static boolean isStrokedPathHit(final Object strokedPath,
152:                    final int windingRule, final float hx, final float hy) {
153:                HitTester hitTester = new HitTester(Path.WIND_NON_ZERO,
154:                        toFixed(hx), toFixed(hy));
155:                PathStore path = (PathStore) strokedPath;
156:                path.produce(hitTester);
157:                boolean hit = hitTester.containsPoint();
158:                return hit;
159:            }
160:
161:            /**
162:             * @param strokedPath the object returned from a previous getStrokedPath 
163:             *        call. Should not be null.
164:             * @param t the transform from the strokedPath space to the requested
165:             *        tile space. 
166:             * @param tile the bounds of the given stroked outline.
167:             */
168:            public static void computeStrokedPathTile(final Tile tile,
169:                    final Object strokedPath, final Transform t) {
170:                // Reuse the same TileSink over and over again.
171:                PathStore sp = (PathStore) strokedPath;
172:
173:                // We use out own TileSink, chained with a Transformer to compute the 
174:                // stroked shape bounds.
175:
176:                // Start from initial values
177:                tileSink.reset();
178:
179:                // Transfer the input Transform value to the working transform txf.
180:                RenderGraphics.setTransform(t, txf);
181:
182:                // Compute now. This call starts pulling data.
183:                transformerSink.setTransform(txf);
184:                sp.produce(transformerSink);
185:
186:                // Compute the tile from the data that was just computed.
187:                tileSink.setTile(tile);
188:            }
189:
190:            /**
191:             * Returns a PathSink that will accept path commands and feed them
192:             * into a stroking pipeline based on the stroke parameters of a
193:             * given GraphicsProperties.  The stroked output will be fed into the
194:             * given output PathSink.
195:             *
196:             * @param output a PathSink that will receive the stroked outline
197:             * @param gp a GraphicsProperties containing stroking parameters
198:             * @return a new PathSink that can accept the path to be stroked
199:             */
200:            private static PathSink createStroker(PathSink output,
201:                    final GraphicsProperties gp) {
202:                Stroker stroker = new Stroker();
203:                stroker.setParameters((int) (gp.getStrokeWidth() * 65536), gp
204:                        .getStrokeLineCap(), gp.getStrokeLineJoin(), (int) (gp
205:                        .getStrokeMiterLimit() * 65536), identity);
206:                stroker.setOutput(output);
207:                Flattener flattener = new Flattener();
208:                flattener.setFlatness(1 << 16);
209:
210:                float[] strokeDashArray = gp.getStrokeDashArray();
211:                if (strokeDashArray != null) {
212:                    int[] intStrokeDashArray = new int[strokeDashArray.length];
213:                    for (int i = 0; i < strokeDashArray.length; i++) {
214:                        intStrokeDashArray[i] = (int) (strokeDashArray[i] * 65536);
215:                    }
216:
217:                    // flattener -> dasher -> stroker -> output
218:                    Dasher dasher = new Dasher();
219:                    dasher.setParameters(intStrokeDashArray,
220:                            computeStrokeDashOffset(gp.getStrokeDashOffset(),
221:                                    gp.getStrokeDashArray()), identity);
222:                    dasher.setOutput(stroker);
223:                    flattener.setOutput(dasher);
224:                } else {
225:                    // flattener -> stroker -> output
226:                    flattener.setOutput(stroker);
227:                }
228:
229:                return flattener;
230:            }
231:
232:            /**
233:             * Implemnetation: Handles negative strokeDashOffset
234:             *
235:             * @param strokeDashOffset the possibly negative dash offset value.
236:             * @param strokeDashArray the applicable dash array.
237:             * @return a positive strokeDashOffset.
238:             */
239:            static int computeStrokeDashOffset(final float strokeDashOffset,
240:                    final float[] strokeDashArray) {
241:                if (strokeDashArray == null) {
242:                    // The stroke dash offset does not matter, simply return 0
243:                    return 0;
244:                }
245:
246:                if (strokeDashOffset >= 0) {
247:                    return (int) (strokeDashOffset * 65536);
248:                }
249:
250:                int length = 0;
251:                for (int i = 0; i < strokeDashArray.length; i++) {
252:                    length += strokeDashArray[i];
253:                }
254:
255:                if (length <= 0) {
256:                    return 0;
257:                }
258:
259:                float sdo = strokeDashOffset;
260:                while (sdo < 0) {
261:                    sdo += length;
262:                }
263:
264:                return (int) (sdo * 65536);
265:            }
266:
267:            /**
268:             * @param path the Path to stroke.
269:             * @param gp the GraphicsProperties defining the rendering conditions.
270:             *
271:             * @return the stroked outline.
272:             */
273:            public static Object getStrokedPath(final Path path,
274:                    final GraphicsProperties gp) {
275:                PathStore strokedPath = new PathStore();
276:                PathSink stroker = createStroker(strokedPath, gp);
277:
278:                emitPath(path, stroker);
279:
280:                return strokedPath;
281:            }
282:
283:            /**
284:             * @param x the rectangle's x-axis origin
285:             * @param y the rectangle's y-axis origin
286:             * @param w the rectangle's length along the x-axis
287:             * @param h the rectangle's length along the y-axis
288:             * @param gp the GraphicsProperties defining rendering conditions.
289:             *
290:             * @return the stroked outline.
291:             */
292:            public static Object getStrokedRect(final float x, final float y,
293:                    final float w, final float h, final GraphicsProperties gp) {
294:                PathStore strokedPath = new PathStore();
295:                PathSink stroker = createStroker(strokedPath, gp);
296:
297:                stroker.moveTo(toFixed(x), toFixed(y));
298:                stroker.lineTo(toFixed(x + w), toFixed(y));
299:                stroker.lineTo(toFixed(x + w), toFixed(y + h));
300:                stroker.lineTo(toFixed(x), toFixed(y + h));
301:                stroker.close();
302:                stroker.end();
303:
304:                return strokedPath;
305:            }
306:
307:            private static long acv = (long) (65536.0 * 0.22385762508460333);
308:
309:            /**
310:             * @param fx the rectangle's x-axis origin
311:             * @param fy the rectangle's y-axis origin
312:             * @param fw the rectangle's length along the x-axis
313:             * @param fh the rectangle's length along the y-axis
314:             * @param rx the rectangle's rounded corner diameter along the x-axis
315:             * @param ry the rectangle's rounded corner diameter along the y-axis.
316:             * @param gp the GraphicsProperties defining rendering conditions.
317:             *
318:             * @return the stroked outline.
319:             */
320:            public static Object getStrokedRect(final float fx, final float fy,
321:                    final float fw, final float fh, final float rx,
322:                    final float ry, final GraphicsProperties gp) {
323:                int x = toFixed(fx);
324:                int y = toFixed(fy);
325:                int w = toFixed(fw);
326:                int h = toFixed(fh);
327:                int aw = toFixed(rx);
328:                int ah = toFixed(ry);
329:
330:                int xw = x + w;
331:                int yh = y + h;
332:                int aw2 = aw >> 1;
333:                int ah2 = ah >> 1;
334:                int acvaw = (int) (acv * aw >> 16);
335:                int acvah = (int) (acv * ah >> 16);
336:                int xacvaw = x + acvaw;
337:                int xw_acvaw = xw - acvaw;
338:                int yacvah = y + acvah;
339:                int yh_acvah = yh - acvah;
340:                int xaw2 = x + aw2;
341:                int xw_aw2 = xw - aw2;
342:                int yah2 = y + ah2;
343:                int yh_ah2 = yh - ah2;
344:
345:                PathStore strokedPath = new PathStore();
346:                PathSink stroker = createStroker(strokedPath, gp);
347:
348:                stroker.moveTo(x, yah2);
349:                stroker.lineTo(x, yh_ah2);
350:                stroker.cubicTo(x, yh_acvah, xacvaw, yh, xaw2, yh);
351:                stroker.lineTo(xw_aw2, yh);
352:                stroker.cubicTo(xw_acvaw, yh, xw, yh_acvah, xw, yh_ah2);
353:                stroker.lineTo(xw, yah2);
354:                stroker.cubicTo(xw, yacvah, xw_acvaw, y, xw_aw2, y);
355:                stroker.lineTo(xaw2, y);
356:                stroker.cubicTo(xacvaw, y, x, yacvah, x, yah2);
357:                stroker.close();
358:                stroker.end();
359:
360:                return strokedPath;
361:            }
362:
363:            /**
364:             * @param x1 the line's x-axis starting position.
365:             * @param y1 the line's y-axis starting position.
366:             * @param x2 the line's x-axis end position.
367:             * @param y2 the line's y-axis end position.
368:             * @param gp the GraphicsProperties defining rendering conditions.
369:             *
370:             * @return the stroked outline.
371:             */
372:            public static Object getStrokedLine(final float x1, final float y1,
373:                    final float x2, final float y2, final GraphicsProperties gp) {
374:                PathStore strokedPath = new PathStore();
375:                PathSink stroker = createStroker(strokedPath, gp);
376:
377:                stroker.moveTo(toFixed(x1), toFixed(y1));
378:                stroker.lineTo(toFixed(x2), toFixed(y2));
379:                stroker.end();
380:
381:                return strokedPath;
382:            }
383:
384:            private static final double CtrlVal = 0.5522847498307933;
385:            private static long pcv_ = (long) (65536.0 * (0.5 + CtrlVal * 0.5));
386:            private static long ncv_ = (long) (65536.0 * (0.5 - CtrlVal * 0.5));
387:
388:            /**
389:             * @param x the ellipse's x-axis origin
390:             * @param y the ellipse's y-axis origin
391:             * @param width the ellipse's x-axis length
392:             * @param height the ellipse's y-axis length.
393:             * @param gp the GraphicsProperties defining rendering conditions.
394:             *
395:             * @return the stroked outline.
396:             */
397:            public static Object getStrokedEllipse(final float x,
398:                    final float y, final float width, final float height,
399:                    final GraphicsProperties gp) {
400:
401:                PathStore strokedPath = new PathStore();
402:                PathSink stroker = createStroker(strokedPath, gp);
403:
404:                int x_ = toFixed(x);
405:                int y_ = toFixed(y);
406:                int width_ = toFixed(width);
407:                int height_ = toFixed(height);
408:
409:                int xw_ = x_ + width_;
410:                int xw2_ = x_ + (width_ >> 1);
411:                int yh_ = y_ + height_;
412:                int yh2_ = y_ + (height_ >> 1);
413:                int xpcvw_ = x_ + (int) (pcv_ * width_ >> 16);
414:                int ypcvh_ = y_ + (int) (pcv_ * height_ >> 16);
415:                int xncvw_ = x_ + (int) (ncv_ * width_ >> 16);
416:                int yncvh_ = y_ + (int) (ncv_ * height_ >> 16);
417:
418:                stroker.moveTo(xw_, yh2_);
419:                stroker.cubicTo(xw_, ypcvh_, xpcvw_, yh_, xw2_, yh_);
420:                stroker.cubicTo(xncvw_, yh_, x_, ypcvh_, x_, yh2_);
421:                stroker.cubicTo(x_, yncvh_, xncvw_, y_, xw2_, y_);
422:                stroker.cubicTo(xpcvw_, y_, xw_, yncvh_, xw_, yh2_);
423:                stroker.close();
424:                stroker.end();
425:
426:                return strokedPath;
427:            }
428:        }
429:
430:        class HitTester extends PathSink {
431:
432:            int windingRule;
433:            int px, py;
434:            int x0, y0, sx0, sy0;
435:
436:            int crossings = 0;
437:
438:            public HitTester(int windingRule, int px, int py) {
439:                this .windingRule = windingRule;
440:                this .px = px;
441:                this .py = py;
442:            }
443:
444:            public void moveTo(int x0, int y0) {
445:                this .x0 = this .sx0 = x0;
446:                this .y0 = this .sy0 = y0;
447:            }
448:
449:            public void lineJoin() {
450:            }
451:
452:            public void lineTo(int x1, int y1) {
453:                int orientation;
454:                int hity;
455:
456:                int dy = y1 - y0;
457:                if (dy > 0) {
458:                    orientation = 1;
459:                    hity = py - y0;
460:                } else {
461:                    orientation = -1;
462:                    hity = py - y1;
463:                    dy = -dy;
464:                }
465:
466:                // If line's Y extent includes py, find the X value where the line
467:                // intersects the horizontal line y = py.  If the intersection lies
468:                // to the left of px, accumulate the line orientation into the
469:                // count of crossings.
470:
471:                if (hity >= 0 && hity < dy) {
472:                    int hitx, dx;
473:
474:                    if (orientation == 1) {
475:                        hitx = px - x0;
476:                        dx = x1 - x0;
477:                    } else {
478:                        hitx = px - x1;
479:                        dx = x0 - x1;
480:                    }
481:
482:                    if ((long) hity * dx < (long) hitx * dy) {
483:                        crossings += orientation;
484:                    }
485:                }
486:
487:                this .x0 = x1;
488:                this .y0 = y1;
489:            }
490:
491:            public void quadTo(int x1, int y1, int x2, int y2) {
492:                System.err
493:                        .println(">>>>>>>>>>>> path for hit testing should not contain quadTo!");
494:            }
495:
496:            public void cubicTo(int x1, int y1, int x2, int y2, int x3, int y3) {
497:                System.err
498:                        .println(">>>>>>>>>>>> path for hit testing should not contain cubicTo!");
499:            }
500:
501:            public void close() {
502:                lineTo(sx0, sy0);
503:            }
504:
505:            public void end() {
506:            }
507:
508:            public boolean containsPoint() {
509:                return (windingRule == Path.WIND_NON_ZERO) ? (crossings != 0)
510:                        : ((crossings & 0x1) == 0x1);
511:            }
512:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.