Source Code Cross Referenced for CursorManager.java in  » Graphic-Library » batik » org » apache » batik » bridge » 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.bridge 
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.bridge;
020:
021:        import java.awt.Cursor;
022:        import java.awt.Dimension;
023:        import java.awt.Image;
024:        import java.awt.Point;
025:        import java.awt.Rectangle;
026:        import java.awt.Toolkit;
027:        import java.awt.geom.AffineTransform;
028:        import java.awt.geom.Point2D;
029:        import java.awt.image.BufferedImage;
030:        import java.awt.image.ColorModel;
031:        import java.awt.image.Raster;
032:        import java.awt.image.RenderedImage;
033:        import java.awt.image.SampleModel;
034:        import java.awt.image.WritableRaster;
035:        import java.util.Hashtable;
036:        import java.util.Map;
037:
038:        import org.apache.batik.css.engine.SVGCSSEngine;
039:        import org.apache.batik.css.engine.value.Value;
040:        import org.apache.batik.dom.AbstractNode;
041:        import org.apache.batik.dom.util.XLinkSupport;
042:        import org.apache.batik.ext.awt.image.PadMode;
043:        import org.apache.batik.ext.awt.image.renderable.AffineRable8Bit;
044:        import org.apache.batik.ext.awt.image.renderable.Filter;
045:        import org.apache.batik.ext.awt.image.renderable.PadRable8Bit;
046:        import org.apache.batik.ext.awt.image.spi.BrokenLinkProvider;
047:        import org.apache.batik.ext.awt.image.spi.ImageTagRegistry;
048:        import org.apache.batik.gvt.GraphicsNode;
049:        import org.apache.batik.util.ParsedURL;
050:        import org.apache.batik.util.SVGConstants;
051:        import org.apache.batik.util.SoftReferenceCache;
052:        import org.w3c.dom.Element;
053:        import org.w3c.dom.Node;
054:        import org.w3c.dom.css.CSSPrimitiveValue;
055:        import org.w3c.dom.css.CSSValue;
056:        import org.w3c.dom.svg.SVGDocument;
057:        import org.w3c.dom.svg.SVGPreserveAspectRatio;
058:
059:        /**
060:         * The CursorManager class is a helper class which preloads the cursors
061:         * corresponding to the SVG built in cursors.
062:         *
063:         * @author <a href="mailto:vincent.hardy@sun.com">Vincent Hardy</a>
064:         * @version $Id: CursorManager.java 501922 2007-01-31 17:47:47Z dvholten $
065:         */
066:        public class CursorManager implements  SVGConstants, ErrorConstants {
067:            /**
068:             * Maps SVG Cursor Values to Java Cursors
069:             */
070:            protected static Map cursorMap;
071:
072:            /**
073:             * Default cursor when value is not found
074:             */
075:            public static final Cursor DEFAULT_CURSOR = Cursor
076:                    .getPredefinedCursor(Cursor.DEFAULT_CURSOR);
077:
078:            /**
079:             * Cursor used over anchors
080:             */
081:            public static final Cursor ANCHOR_CURSOR = Cursor
082:                    .getPredefinedCursor(Cursor.HAND_CURSOR);
083:
084:            /**
085:             * Cursor used over text
086:             */
087:            public static final Cursor TEXT_CURSOR = Cursor
088:                    .getPredefinedCursor(Cursor.TEXT_CURSOR);
089:
090:            /**
091:             * Default preferred cursor size, used for SVG images
092:             */
093:            public static final int DEFAULT_PREFERRED_WIDTH = 32;
094:            public static final int DEFAULT_PREFERRED_HEIGHT = 32;
095:
096:            /**
097:             * Static initialization of the cursorMap
098:             */
099:            static {
100:                cursorMap = new Hashtable();
101:                cursorMap.put(SVG_CROSSHAIR_VALUE, Cursor
102:                        .getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
103:                cursorMap.put(SVG_DEFAULT_VALUE, Cursor
104:                        .getPredefinedCursor(Cursor.DEFAULT_CURSOR));
105:                cursorMap.put(SVG_POINTER_VALUE, Cursor
106:                        .getPredefinedCursor(Cursor.HAND_CURSOR));
107:                cursorMap.put(SVG_MOVE_VALUE, Cursor
108:                        .getPredefinedCursor(Cursor.MOVE_CURSOR));
109:                cursorMap.put(SVG_E_RESIZE_VALUE, Cursor
110:                        .getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
111:                cursorMap.put(SVG_NE_RESIZE_VALUE, Cursor
112:                        .getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
113:                cursorMap.put(SVG_NW_RESIZE_VALUE, Cursor
114:                        .getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
115:                cursorMap.put(SVG_N_RESIZE_VALUE, Cursor
116:                        .getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
117:                cursorMap.put(SVG_SE_RESIZE_VALUE, Cursor
118:                        .getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
119:                cursorMap.put(SVG_SW_RESIZE_VALUE, Cursor
120:                        .getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
121:                cursorMap.put(SVG_S_RESIZE_VALUE, Cursor
122:                        .getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
123:                cursorMap.put(SVG_W_RESIZE_VALUE, Cursor
124:                        .getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
125:                cursorMap.put(SVG_TEXT_VALUE, Cursor
126:                        .getPredefinedCursor(Cursor.TEXT_CURSOR));
127:                cursorMap.put(SVG_WAIT_VALUE, Cursor
128:                        .getPredefinedCursor(Cursor.WAIT_CURSOR));
129:                cursorMap.put(SVG_HELP_VALUE, Cursor
130:                        .getPredefinedCursor(Cursor.HAND_CURSOR));
131:
132:            }
133:
134:            /**
135:             * BridgeContext associated with this CursorManager
136:             */
137:            protected BridgeContext ctx;
138:
139:            /**
140:             * Cache used to hold references to cursors
141:             */
142:            protected CursorCache cursorCache = new CursorCache();
143:
144:            /**
145:             * Creates a new CursorManager object.
146:             *
147:             * @param ctx the BridgeContext associated to this CursorManager
148:             */
149:            public CursorManager(BridgeContext ctx) {
150:                this .ctx = ctx;
151:            }
152:
153:            /**
154:             * Returns a Cursor object for a given cursor value. This initial
155:             * implementation does not handle user-defined cursors, so it
156:             * always uses the cursor at the end of the list
157:             */
158:            public static Cursor getPredefinedCursor(String cursorName) {
159:                return (Cursor) cursorMap.get(cursorName);
160:            }
161:
162:            /**
163:             * Returns the Cursor corresponding to the input element's cursor property
164:             *
165:             * @param e the element on which the cursor property is set
166:             */
167:            public Cursor convertCursor(Element e) {
168:                Value cursorValue = CSSUtilities.getComputedStyle(e,
169:                        SVGCSSEngine.CURSOR_INDEX);
170:
171:                String cursorStr = SVGConstants.SVG_AUTO_VALUE;
172:
173:                if (cursorValue != null) {
174:                    if (cursorValue.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE
175:                            && cursorValue.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
176:                        // Single Value : should be one of the predefined cursors or
177:                        // 'inherit'
178:                        cursorStr = cursorValue.getStringValue();
179:                        return convertBuiltInCursor(e, cursorStr);
180:                    } else if (cursorValue.getCssValueType() == CSSValue.CSS_VALUE_LIST) {
181:                        int nValues = cursorValue.getLength();
182:                        if (nValues == 1) {
183:                            cursorValue = cursorValue.item(0);
184:                            if (cursorValue.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
185:                                cursorStr = cursorValue.getStringValue();
186:                                return convertBuiltInCursor(e, cursorStr);
187:                            }
188:                        } else if (nValues > 1) {
189:                            //
190:                            // Look for the first cursor url we can handle.
191:                            // That would be a reference to a <cursor> element.
192:                            //
193:                            return convertSVGCursor(e, cursorValue);
194:                        }
195:                    }
196:                }
197:
198:                return convertBuiltInCursor(e, cursorStr);
199:            }
200:
201:            public Cursor convertBuiltInCursor(Element e, String cursorStr) {
202:                Cursor cursor = null;
203:
204:                // The CSS engine guarantees an non null, non empty string
205:                // as the computed value for cursor. Therefore, the following
206:                // test is safe.
207:                if (cursorStr.charAt(0) == 'a') {
208:                    //
209:                    // Handle 'auto' value.
210:                    //
211:                    // - <a> The following sets the cursor for <a> element
212:                    // enclosing text nodes. Setting the proper cursor (i.e.,
213:                    // depending on the children's 'cursor' property, is
214:                    // handled in the SVGAElementBridge so as to avoid going
215:                    // up the tree on mouseover events (looking for an anchor
216:                    // ancestor.
217:                    //
218:                    // - <image> The following does not change the cursor if
219:                    // the element's cursor property is set to
220:                    // 'auto'. Otherwise, it takes precedence over any child
221:                    // (in case of SVG content) cursor setting.  This means
222:                    // that for images referencing SVG content, a cursor
223:                    // property set to 'auto' on the <image> element will not
224:                    // override the cursor settings inside the SVG image. Any
225:                    // other cursor property will take precedence.
226:                    //
227:                    // - <use> Same behavior as for <image> except that the
228:                    // behavior is controlled from the <use> element bridge
229:                    // (SVGUseElementBridge).
230:                    //
231:                    // - <text>, <tref> and <tspan> : a cursor value of auto
232:                    // will cause the cursor to be set to a text cursor. Note
233:                    // that text content with an 'auto' cursor and descendant
234:                    // of an anchor will have its cursor set to the anchor
235:                    // cursor through the SVGAElementBridge.
236:                    //
237:                    String nameSpaceURI = e.getNamespaceURI();
238:                    if (SVGConstants.SVG_NAMESPACE_URI.equals(nameSpaceURI)) {
239:                        String tag = e.getLocalName();
240:                        if (SVGConstants.SVG_A_TAG.equals(tag)) {
241:                            cursor = CursorManager.ANCHOR_CURSOR;
242:                        } else if (SVGConstants.SVG_TEXT_TAG.equals(tag)
243:                                || SVGConstants.SVG_TSPAN_TAG.equals(tag)
244:                                || SVGConstants.SVG_TREF_TAG.equals(tag)) {
245:                            cursor = CursorManager.TEXT_CURSOR;
246:                        } else if (SVGConstants.SVG_IMAGE_TAG.equals(tag)) {
247:                            // Do not change the cursor
248:                            return null;
249:                        } else {
250:                            cursor = CursorManager.DEFAULT_CURSOR;
251:                        }
252:                    } else {
253:                        cursor = CursorManager.DEFAULT_CURSOR;
254:                    }
255:                } else {
256:                    // Specific, logical cursor
257:                    cursor = CursorManager.getPredefinedCursor(cursorStr);
258:                }
259:
260:                return cursor;
261:            }
262:
263:            /**
264:             * Returns a cursor for the given value list. Note that the
265:             * code assumes that the input value has at least two entries.
266:             * So the caller should check that before calling the method.
267:             * For example, CSSUtilities.convertCursor performs that check.
268:             */
269:            public Cursor convertSVGCursor(Element e, Value l) {
270:                int nValues = l.getLength();
271:                Element cursorElement = null;
272:                for (int i = 0; i < nValues - 1; i++) {
273:                    Value cursorValue = l.item(i);
274:                    if (cursorValue.getPrimitiveType() == CSSPrimitiveValue.CSS_URI) {
275:                        String uri = cursorValue.getStringValue();
276:
277:                        // If the uri does not resolve to a cursor element,
278:                        // then, this is not a type of cursor uri we can handle:
279:                        // go to the next or default to logical cursor
280:                        try {
281:                            cursorElement = ctx.getReferencedElement(e, uri);
282:                        } catch (BridgeException be) {
283:                            // Be only silent if this is a case where the target
284:                            // could not be found. Do not catch other errors (e.g,
285:                            // malformed URIs)
286:                            if (!ERR_URI_BAD_TARGET.equals(be.getCode())) {
287:                                throw be;
288:                            }
289:                        }
290:
291:                        if (cursorElement != null) {
292:                            // We go an element, check it is of type cursor
293:                            String cursorNS = cursorElement.getNamespaceURI();
294:                            if (SVGConstants.SVG_NAMESPACE_URI.equals(cursorNS)
295:                                    && SVGConstants.SVG_CURSOR_TAG
296:                                            .equals(cursorElement
297:                                                    .getLocalName())) {
298:                                Cursor c = convertSVGCursorElement(cursorElement);
299:                                if (c != null) {
300:                                    return c;
301:                                }
302:                            }
303:                        }
304:                    }
305:                }
306:
307:                // If we got to that point, it means that no cursorElement
308:                // produced a valid cursor, i.e., either a format we support
309:                // or a valid referenced image (no broken image).
310:                // Fallback on the built in cursor property.
311:                Value cursorValue = l.item(nValues - 1);
312:                String cursorStr = SVGConstants.SVG_AUTO_VALUE;
313:                if (cursorValue.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
314:                    cursorStr = cursorValue.getStringValue();
315:                }
316:
317:                return convertBuiltInCursor(e, cursorStr);
318:            }
319:
320:            /**
321:             * Returns a cursor for a given element
322:             */
323:            public Cursor convertSVGCursorElement(Element cursorElement) {
324:                // One of the cursor url resolved to a <cursor> element
325:                // Try to handle its image.
326:                String uriStr = XLinkSupport.getXLinkHref(cursorElement);
327:                if (uriStr.length() == 0) {
328:                    throw new BridgeException(ctx, cursorElement,
329:                            ERR_ATTRIBUTE_MISSING,
330:                            new Object[] { "xlink:href" });
331:                }
332:
333:                String baseURI = AbstractNode.getBaseURI(cursorElement);
334:                ParsedURL purl;
335:                if (baseURI == null) {
336:                    purl = new ParsedURL(uriStr);
337:                } else {
338:                    purl = new ParsedURL(baseURI, uriStr);
339:                }
340:
341:                //
342:                // Convert the cursor's hot spot
343:                //
344:                UnitProcessor.Context uctx = UnitProcessor.createContext(ctx,
345:                        cursorElement);
346:
347:                String s = cursorElement.getAttributeNS(null, SVG_X_ATTRIBUTE);
348:                float x = 0;
349:                if (s.length() != 0) {
350:                    x = UnitProcessor.svgHorizontalCoordinateToUserSpace(s,
351:                            SVG_X_ATTRIBUTE, uctx);
352:                }
353:
354:                s = cursorElement.getAttributeNS(null, SVG_Y_ATTRIBUTE);
355:                float y = 0;
356:                if (s.length() != 0) {
357:                    y = UnitProcessor.svgVerticalCoordinateToUserSpace(s,
358:                            SVG_Y_ATTRIBUTE, uctx);
359:                }
360:
361:                CursorDescriptor desc = new CursorDescriptor(purl, x, y);
362:
363:                //
364:                // Check if there is a cursor in the cache for this url
365:                //
366:                Cursor cachedCursor = cursorCache.getCursor(desc);
367:
368:                if (cachedCursor != null) {
369:                    return cachedCursor;
370:                }
371:
372:                //
373:                // Load image into Filter f and transform hotSpot to
374:                // cursor space.
375:                //
376:                Point2D.Float hotSpot = new Point2D.Float(x, y);
377:                Filter f = cursorHrefToFilter(cursorElement, purl, hotSpot);
378:                if (f == null) {
379:                    cursorCache.clearCursor(desc);
380:                    return null;
381:                }
382:
383:                // The returned Filter is guaranteed to create a
384:                // default rendering of the desired size
385:                Rectangle cursorSize = f.getBounds2D().getBounds();
386:                RenderedImage ri = f.createScaledRendering(cursorSize.width,
387:                        cursorSize.height, null);
388:                Image img = null;
389:
390:                if (ri instanceof  Image) {
391:                    img = (Image) ri;
392:                } else {
393:                    img = renderedImageToImage(ri);
394:                }
395:
396:                // Make sure the not spot does not fall out of the cursor area. If it
397:                // does, then clamp the coordinates to the image space.
398:                hotSpot.x = hotSpot.x < 0 ? 0 : hotSpot.x;
399:                hotSpot.y = hotSpot.y < 0 ? 0 : hotSpot.y;
400:                hotSpot.x = hotSpot.x > (cursorSize.width - 1) ? cursorSize.width - 1
401:                        : hotSpot.x;
402:                hotSpot.y = hotSpot.y > (cursorSize.height - 1) ? cursorSize.height - 1
403:                        : hotSpot.y;
404:
405:                //
406:                // The cursor image is now into 'img'
407:                //
408:                Cursor c = Toolkit.getDefaultToolkit()
409:                        .createCustomCursor(
410:                                img,
411:                                new Point(Math.round(hotSpot.x), Math
412:                                        .round(hotSpot.y)), purl.toString());
413:
414:                cursorCache.putCursor(desc, c);
415:                return c;
416:            }
417:
418:            /**
419:             * Converts the input ParsedURL into a Filter and transforms the
420:             * input hotSpot point (in image space) to cursor space
421:             */
422:            protected Filter cursorHrefToFilter(Element cursorElement,
423:                    ParsedURL purl, Point2D hotSpot) {
424:
425:                AffineRable8Bit f = null;
426:                String uriStr = purl.toString();
427:                Dimension cursorSize = null;
428:
429:                // Try to load as an SVG Document
430:                DocumentLoader loader = ctx.getDocumentLoader();
431:                SVGDocument svgDoc = (SVGDocument) cursorElement
432:                        .getOwnerDocument();
433:                URIResolver resolver = ctx.createURIResolver(svgDoc, loader);
434:                try {
435:                    Element rootElement = null;
436:                    Node n = resolver.getNode(uriStr, cursorElement);
437:                    if (n.getNodeType() == Node.DOCUMENT_NODE) {
438:                        SVGDocument doc = (SVGDocument) n;
439:                        // FIXX: really should be subCtx here.
440:                        ctx.initializeDocument(doc);
441:                        rootElement = doc.getRootElement();
442:                    } else {
443:                        throw new BridgeException(ctx, cursorElement,
444:                                ERR_URI_IMAGE_INVALID, new Object[] { uriStr });
445:                    }
446:                    GraphicsNode node = ctx.getGVTBuilder().build(ctx,
447:                            rootElement);
448:
449:                    //
450:                    // The cursorSize define the viewport into which the
451:                    // cursor is displayed. That viewport is platform
452:                    // dependant and is not defined by the SVG content.
453:                    //
454:                    float width = DEFAULT_PREFERRED_WIDTH;
455:                    float height = DEFAULT_PREFERRED_HEIGHT;
456:                    UnitProcessor.Context uctx = UnitProcessor.createContext(
457:                            ctx, rootElement);
458:
459:                    String s = rootElement.getAttribute(SVG_WIDTH_ATTRIBUTE);
460:                    if (s.length() != 0) {
461:                        width = UnitProcessor.svgHorizontalLengthToUserSpace(s,
462:                                SVG_WIDTH_ATTRIBUTE, uctx);
463:                    }
464:
465:                    s = rootElement.getAttribute(SVG_HEIGHT_ATTRIBUTE);
466:                    if (s.length() != 0) {
467:                        height = UnitProcessor.svgVerticalLengthToUserSpace(s,
468:                                SVG_HEIGHT_ATTRIBUTE, uctx);
469:                    }
470:
471:                    cursorSize = Toolkit.getDefaultToolkit().getBestCursorSize(
472:                            Math.round(width), Math.round(height));
473:
474:                    // Handle the viewBox transform
475:                    AffineTransform at = ViewBox
476:                            .getPreserveAspectRatioTransform(rootElement,
477:                                    cursorSize.width, cursorSize.height, ctx);
478:                    Filter filter = node.getGraphicsNodeRable(true);
479:                    f = new AffineRable8Bit(filter, at);
480:                } catch (BridgeException ex) {
481:                    throw ex;
482:                } catch (SecurityException ex) {
483:                    throw new BridgeException(ctx, cursorElement, ex,
484:                            ERR_URI_UNSECURE, new Object[] { uriStr });
485:                } catch (Exception ex) {
486:                    /* Nothing to do */
487:                }
488:
489:                // If f is null, it means that we are not dealing with
490:                // an SVG image. Try as a raster image.
491:                if (f == null) {
492:                    ImageTagRegistry reg = ImageTagRegistry.getRegistry();
493:                    Filter filter = reg.readURL(purl);
494:                    if (filter == null) {
495:                        return null;
496:                    }
497:
498:                    // Check if we got a broken image
499:                    if (BrokenLinkProvider.hasBrokenLinkProperty(filter)) {
500:                        return null;
501:                    }
502:
503:                    Rectangle preferredSize = filter.getBounds2D().getBounds();
504:                    cursorSize = Toolkit.getDefaultToolkit().getBestCursorSize(
505:                            preferredSize.width, preferredSize.height);
506:
507:                    if (preferredSize != null && preferredSize.width > 0
508:                            && preferredSize.height > 0) {
509:                        AffineTransform at = new AffineTransform();
510:                        if (preferredSize.width > cursorSize.width
511:                                || preferredSize.height > cursorSize.height) {
512:                            at = ViewBox
513:                                    .getPreserveAspectRatioTransform(
514:                                            new float[] { 0, 0,
515:                                                    preferredSize.width,
516:                                                    preferredSize.height },
517:                                            SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMIN,
518:                                            true, cursorSize.width,
519:                                            cursorSize.height);
520:                        }
521:                        f = new AffineRable8Bit(filter, at);
522:                    } else {
523:                        // Invalid Size
524:                        return null;
525:                    }
526:                }
527:
528:                //
529:                // Transform the hot spot from image space to cursor space
530:                //
531:                AffineTransform at = f.getAffine();
532:                at.transform(hotSpot, hotSpot);
533:
534:                //
535:                // In all cases, clip to the cursor boundaries
536:                //
537:                Rectangle cursorViewport = new Rectangle(0, 0,
538:                        cursorSize.width, cursorSize.height);
539:
540:                PadRable8Bit cursorImage = new PadRable8Bit(f, cursorViewport,
541:                        PadMode.ZERO_PAD);
542:
543:                return cursorImage;
544:
545:            }
546:
547:            /**
548:             * Implementation helper: converts a RenderedImage to an Image
549:             */
550:            protected Image renderedImageToImage(RenderedImage ri) {
551:                int x = ri.getMinX();
552:                int y = ri.getMinY();
553:                SampleModel sm = ri.getSampleModel();
554:                ColorModel cm = ri.getColorModel();
555:                WritableRaster wr = Raster.createWritableRaster(sm, new Point(
556:                        x, y));
557:                ri.copyData(wr);
558:
559:                return new BufferedImage(cm, wr, cm.isAlphaPremultiplied(),
560:                        null);
561:            }
562:
563:            /**
564:             * Simple inner class which holds the information describing
565:             * a cursor, i.e., the image it points to and the hot spot point
566:             * coordinates.
567:             */
568:            static class CursorDescriptor {
569:                ParsedURL purl;
570:                float x;
571:                float y;
572:                String desc;
573:
574:                public CursorDescriptor(ParsedURL purl, float x, float y) {
575:                    if (purl == null) {
576:                        throw new IllegalArgumentException();
577:                    }
578:
579:                    this .purl = purl;
580:                    this .x = x;
581:                    this .y = y;
582:
583:                    // Desc is used for hascode as well as for toString()
584:                    this .desc = this .getClass().getName() + "\n\t:["
585:                            + this .purl + "]\n\t:[" + x + "]:[" + y + "]";
586:                }
587:
588:                public boolean equals(Object obj) {
589:                    if (obj == null || !(obj instanceof  CursorDescriptor)) {
590:                        return false;
591:                    }
592:
593:                    CursorDescriptor desc = (CursorDescriptor) obj;
594:                    boolean isEqual = this .purl.equals(desc.purl)
595:                            && this .x == desc.x && this .y == desc.y;
596:
597:                    return isEqual;
598:                }
599:
600:                public String toString() {
601:                    return this .desc;
602:                }
603:
604:                public int hashCode() {
605:                    return desc.hashCode();
606:                }
607:            }
608:
609:            /**
610:             * Simple extension of the SoftReferenceCache that
611:             * offers typed interface (Kind of needed as SoftReferenceCache
612:             * mostly has protected methods).
613:             */
614:            static class CursorCache extends SoftReferenceCache {
615:                public CursorCache() {
616:                }
617:
618:                public Cursor getCursor(CursorDescriptor desc) {
619:                    return (Cursor) requestImpl(desc);
620:                }
621:
622:                public void putCursor(CursorDescriptor desc, Cursor cursor) {
623:                    putImpl(desc, cursor);
624:                }
625:
626:                public void clearCursor(CursorDescriptor desc) {
627:                    clearImpl(desc);
628:                }
629:            }
630:
631:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.