vhardy 2002/11/14 06:57:27 Modified: sources/org/apache/batik/bridge BridgeContext.java CSSUtilities.java CursorManager.java SVGAElementBridge.java SVGUseElementBridge.java resources/org/apache/batik/bridge/resources Messages.properties samples/tests/spec/interactivity cursor.svg Added: samples/tests/spec/interactivity cursor2.svg cursor3.svg cursor4.svg samples/tests/resources/images hotSpotCenter.png hotSpotCenterBig.png hotSpotCenterSmall.png hotSpotE.png hotSpotN.png hotSpotNE.png hotSpotNW.png hotSpotS.png hotSpotSE.png hotSpotSW.png hotSpotW.png bmpCursor.bmp jpegCursor.jpg tiffCursor.tif pngCursor.png svgCursor.svg Log: Added support for custom cursors. This is functional as shown by the tests (cursor.svg to cursor4.svg) but improvements are coming (caching of cursors and, may be, support for SVG cursors). Revision Changes Path 1.54 +17 -43 xml-batik/sources/org/apache/batik/bridge/BridgeContext.java Index: BridgeContext.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/BridgeContext.java,v retrieving revision 1.53 retrieving revision 1.54 diff -u -r1.53 -r1.54 --- BridgeContext.java 12 Nov 2002 09:51:34 -0000 1.53 +++ BridgeContext.java 14 Nov 2002 14:57:12 -0000 1.54 @@ -340,6 +340,13 @@ } /** + * Returns the cursor manager + */ + public CursorManager getCursorManager() { + return cursorManager; + } + + /** * Sets the interpreter pool used to handle scripts to the * specified interpreter pool. * @param interpreterPool the interpreter pool @@ -752,6 +759,11 @@ protected FocusManager focusManager; /** + * Manages cursors and performs caching when appropriate + */ + protected CursorManager cursorManager = new CursorManager(this); + + /** * Adds EventListeners to the input document to handle the cursor * property. * This is not done in the addDOMListeners method because @@ -958,49 +970,11 @@ public void handleEvent(Event evt) { Element target = (Element)evt.getTarget(); String tag = target.getNodeName(); - String cursorStr = CSSUtilities.convertCursor(target); - Cursor cursor = null; - - if (SVGConstants.SVG_AUTO_VALUE.equalsIgnoreCase(cursorStr)) { - // Handle 'auto' value. - // - // - <a> The following sets the cursor for <a> element enclosing - // text nodes. Setting the proper cursor (i.e., depending on the - // children's 'cursor' property, is handled in the SVGAElementBridge - // so as to avoid going up the tree on mouseover events (looking for - // an anchor ancestor. - // - <image> The following does not change the cursor if the - // element's cursor property is set to 'auto'. Otherwise, it takes - // precedence over any child (in case of SVG content) cursor setting. - // This means that for images referencing SVG content, a cursor - // property set to 'auto' on the <image> element will not override - // the cursor settings inside the SVG image. Any other cursor property - // will take precedence. - // - <use> Same behavior as for <image> except that the behavior - // is controlled from the <use> element bridge (SVGUseElementBridge). - // - <text>, <tref> and <tspan> : a cursor value of auto will cause the - // cursor to be set to a text cursor. Note that text content with an - // 'auto' cursor and descendant of an anchor will have its cursor - // set to the anchor cursor through the SVGAElementBridge. - // - if (SVGConstants.SVG_A_TAG.equalsIgnoreCase(tag)) { - cursor = CursorManager.ANCHOR_CURSOR; - } else if (SVGConstants.SVG_TEXT_TAG.equalsIgnoreCase(tag) || - SVGConstants.SVG_TSPAN_TAG.equalsIgnoreCase(tag) || - SVGConstants.SVG_TREF_TAG.equalsIgnoreCase(tag) ) { - cursor = CursorManager.TEXT_CURSOR; - } else if (SVGConstants.SVG_IMAGE_TAG.equalsIgnoreCase(tag)) { - // Do not change the cursor - return; - } else { - cursor = CursorManager.DEFAULT_CURSOR; - } - } else { - // Specific, logical cursor - cursor = CursorManager.getCursor(cursorStr); + Cursor cursor = CSSUtilities.convertCursor(target, BridgeContext.this); + + if (cursor != null) { + userAgent.setSVGCursor(cursor); } - - userAgent.setSVGCursor(cursor); } } 1.39 +165 -11 xml-batik/sources/org/apache/batik/bridge/CSSUtilities.java Index: CSSUtilities.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/CSSUtilities.java,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- CSSUtilities.java 12 Nov 2002 09:51:34 -0000 1.38 +++ CSSUtilities.java 14 Nov 2002 14:57:13 -0000 1.39 @@ -12,6 +12,7 @@ import java.awt.BasicStroke; import java.awt.Color; import java.awt.Composite; +import java.awt.Cursor; import java.awt.Paint; import java.awt.RenderingHints; import java.awt.Shape; @@ -223,34 +224,187 @@ ///////////////////////////////////////////////////////////////////////// /** - * Returns the cursor string corresponding to the input element's + * Checks if the cursor property on the input element is set to auto + */ + public static boolean isAutoCursor(Element e) { + Value cursorValue = + CSSUtilities.getComputedStyle(e, + SVGCSSEngine.CURSOR_INDEX); + + boolean isAuto = false; + if (cursorValue != null){ + if( + cursorValue.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE + && + cursorValue.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT + && + cursorValue.getStringValue().charAt(0) == 'a' + ) { + isAuto = true; + } else if ( + cursorValue.getCssValueType() == CSSValue.CSS_VALUE_LIST + && + cursorValue.getLength() == 1) { + Value lValue = cursorValue.item(0); + if (lValue != null + && + lValue.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE + && + lValue.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT + && + lValue.getStringValue().charAt(0) == 'a') { + isAuto = true; + } + } + } + + return isAuto; + } + + /** + * Returns the Cursor corresponding to the input element's * cursor property * * @param e the element */ - public static String - convertCursor(Element e) { + public static Cursor + convertCursor(Element e, BridgeContext ctx) { Value cursorValue = CSSUtilities.getComputedStyle(e, SVGCSSEngine.CURSOR_INDEX); String cursorStr = SVGConstants.SVG_AUTO_VALUE; - + Cursor cursor = null; + Element cursorElement = null; + if (cursorValue != null) { - if (cursorValue instanceof StringValue) { + if (cursorValue.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE + && + cursorValue.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) { // Single Value : should be one of the predefined cursors or // 'inherit' cursorStr = cursorValue.getStringValue(); - } else if (cursorValue instanceof ListValue) { - // We do not handle custom cursors yet + } else if (cursorValue.getCssValueType() == CSSValue.CSS_VALUE_LIST) { ListValue l = (ListValue)cursorValue; int nValues = l.getLength(); - if (nValues > 0) { - cursorStr = l.item(nValues-1).getStringValue(); + if (nValues == 1) { + cursorValue = l.item(nValues-1); + if (cursorValue.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) { + cursorStr = cursorValue.getStringValue(); + } + } else { + // + // Look for the first cursor url we can handle. + // That would be a reference to a <cursor> element. + // + cursorElement = null; + for (int i=0; i<nValues-1; i++) { + cursorValue = l.item(i); + if (cursorValue.getPrimitiveType() == CSSPrimitiveValue.CSS_URI) { + String uri = cursorValue.getStringValue(); + + // If the uri does not resolve to a cursor element, + // then, this is not a type of cursor uri we can handle: + // go to the next or default to logical cursor + try { + cursorElement = ctx.getReferencedElement(e, uri); + } catch (BridgeException be) { + // Be only silent if this is a case where the target + // could not be found. Do not catch other errors (e.g, + // malformed URIs) + if (!ERR_URI_BAD_TARGET.equals(be.getCode())) { + throw be; + } + } + + if (cursorElement != null) { + // We go an element, check it is of type cursor + String cursorNS = cursorElement.getNamespaceURI(); + if (SVGConstants.SVG_NAMESPACE_URI.equals(cursorNS) + && + SVGConstants.SVG_CURSOR_TAG.equals(cursorElement.getNodeName())) { + break; + } + } + cursorElement = null; + } + } + + if (cursorElement == null) { + if (nValues > 0) { + cursorValue = l.item(nValues-1); + if (cursorValue.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) { + cursorStr = cursorValue.getStringValue(); + } + } + } } } } + + if (cursorElement != null) { + return ctx.getCursorManager().convertSVGCursor(cursorElement); + } + + return convertBuiltInCursor(e, cursorStr); + } + + + public static final Cursor convertBuiltInCursor(Element e, String cursorStr) { + Cursor cursor = null; - return cursorStr; + // The CSS engine guarantees an non null, non empty string + // as the computed value for cursor. Therefore, the following + // test is safe. + if (cursorStr.charAt(0) == 'a') { + // + // Handle 'auto' value. + // + // - <a> The following sets the cursor for <a> element enclosing + // text nodes. Setting the proper cursor (i.e., depending on the + // children's 'cursor' property, is handled in the SVGAElementBridge + // so as to avoid going up the tree on mouseover events (looking for + // an anchor ancestor. + // + // - <image> The following does not change the cursor if the + // element's cursor property is set to 'auto'. Otherwise, it takes + // precedence over any child (in case of SVG content) cursor setting. + // This means that for images referencing SVG content, a cursor + // property set to 'auto' on the <image> element will not override + // the cursor settings inside the SVG image. Any other cursor property + // will take precedence. + // + // - <use> Same behavior as for <image> except that the behavior + // is controlled from the <use> element bridge (SVGUseElementBridge). + // + // - <text>, <tref> and <tspan> : a cursor value of auto will cause the + // cursor to be set to a text cursor. Note that text content with an + // 'auto' cursor and descendant of an anchor will have its cursor + // set to the anchor cursor through the SVGAElementBridge. + // + String nameSpaceURI = e.getNamespaceURI(); + String tag = e.getNodeName(); + if (SVGConstants.SVG_NAMESPACE_URI.equals(nameSpaceURI)) { + if (SVGConstants.SVG_A_TAG.equals(tag)) { + cursor = CursorManager.ANCHOR_CURSOR; + } else if (SVGConstants.SVG_TEXT_TAG.equals(tag) || + SVGConstants.SVG_TSPAN_TAG.equals(tag) || + SVGConstants.SVG_TREF_TAG.equals(tag) ) { + cursor = CursorManager.TEXT_CURSOR; + } else if (SVGConstants.SVG_IMAGE_TAG.equals(tag)) { + // Do not change the cursor + return null; + } else { + cursor = CursorManager.DEFAULT_CURSOR; + } + } else { + cursor = CursorManager.DEFAULT_CURSOR; + } + } else { + // Specific, logical cursor + cursor = CursorManager.getPredefinedCursor(cursorStr); + } + + return cursor; } 1.2 +229 -5 xml-batik/sources/org/apache/batik/bridge/CursorManager.java Index: CursorManager.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/CursorManager.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- CursorManager.java 12 Nov 2002 09:51:34 -0000 1.1 +++ CursorManager.java 14 Nov 2002 14:57:14 -0000 1.2 @@ -9,11 +9,31 @@ package org.apache.batik.bridge; import java.awt.Cursor; - +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.RenderedImage; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.awt.image.SampleModel; import java.util.Map; import java.util.Hashtable; +import org.apache.batik.ext.awt.image.spi.ImageTagRegistry; +import org.apache.batik.ext.awt.image.renderable.Filter; + +import org.apache.batik.dom.util.XLinkSupport; +import org.apache.batik.dom.svg.XMLBaseSupport; import org.apache.batik.util.SVGConstants; +import org.apache.batik.util.ParsedURL; + +import org.w3c.dom.Element; /** * The CursorManager class is a helper class which preloads the cursors @@ -85,13 +105,217 @@ } /** + * BridgeContext associated with this CursorManager + */ + protected BridgeContext ctx; + + /** + * Constructor + * + * @param BridgeContext ctx, the BridgeContext associated to this CursorManager + */ + public CursorManager(BridgeContext ctx) { + this.ctx = ctx; + } + + /** * Returns a Cursor object for a given cursor value. This initial implementation * does not handle user-defined cursors, so it always uses the cursor at the * end of the list */ - public static Cursor getCursor(String cursorName){ - Cursor c = (Cursor)cursorMap.get(cursorName); - return c != null ? c : DEFAULT_CURSOR; + public static Cursor getPredefinedCursor(String cursorName){ + return (Cursor)cursorMap.get(cursorName); } + /** + * Returns a cursor for the given cursorElement + */ + public Cursor convertSVGCursor(Element cursorElement) { + // One of the cursor url resolved to a <cursor> element + // Try to handle its image. + String uriStr = XLinkSupport.getXLinkHref(cursorElement); + String baseURI = XMLBaseSupport.getCascadedXMLBase(cursorElement); + ParsedURL purl; + if (baseURI == null) { + purl = new ParsedURL(uriStr); + } else { + purl = new ParsedURL(baseURI, uriStr); + } + + // + // Convert the cursor's hot spot + // + UnitProcessor.Context uctx + = UnitProcessor.createContext(ctx, cursorElement); + + String s = cursorElement.getAttributeNS(null, SVG_X_ATTRIBUTE); + float x = 0; + if (s.length() != 0) { + x = UnitProcessor.svgHorizontalCoordinateToUserSpace + (s, SVG_X_ATTRIBUTE, uctx); + } + + s = cursorElement.getAttributeNS(null, SVG_Y_ATTRIBUTE); + float y = 0; + if (s.length() != 0) { + y = UnitProcessor.svgVerticalCoordinateToUserSpace + (s, SVG_Y_ATTRIBUTE, uctx); + } + + CursorDescriptor desc = new CursorDescriptor(purl, x, y); + + // Check if there is a cursor in the cache for this url + Cursor cachedCursor = getCachedCursor(desc); + + if (cachedCursor != null) { + return cachedCursor; + } + + ImageTagRegistry reg = ImageTagRegistry.getRegistry(); + Filter f = reg.readURL(purl); + + // + // Now, get the preferred cursor dimension + // + Rectangle preferredSize = f.getBounds2D().getBounds(); + if (preferredSize == null || preferredSize.width <=0 + || preferredSize.height <=0 ) { + return null; + } + + Dimension cursorSize + = Toolkit.getDefaultToolkit().getBestCursorSize + (preferredSize.width, preferredSize.height); + + // + // Fit the rendered image into the cursor image + // size and aspect ratio if it does not fit into + // the cursorSize area. Otherwise, draw the cursor + // into an image the size of the preferred cursor + // size. + // + Image bi = null; + + if (cursorSize.width < preferredSize.width + || + cursorSize.height < preferredSize.height) { + float rw = cursorSize.width; + float rh = (cursorSize.width * preferredSize.height) / (float)preferredSize.width; + + if (rh > cursorSize.height) { + rw *= (cursorSize.height / rh); + rh = cursorSize.height; + } + + RenderedImage img = f.createScaledRendering((int)Math.round(rw), + (int)Math.round(rh), + null); + + if (bi instanceof Image) { + bi = (Image)img; + } else { + bi = renderedImageToImage(img); + } + + // Apply the scale transform that is applied to the image + x *= rw/preferredSize.width; + y *= rh/preferredSize.height; + + } else { + // Preferred size fits into ideal cursor size. No resize, + // just draw cursor in 0, 0. + BufferedImage tbi = new BufferedImage(cursorSize.width, + cursorSize.height, + BufferedImage.TYPE_INT_ARGB); + RenderedImage ri = f.createScaledRendering(preferredSize.width, + preferredSize.height, + null); + Graphics2D g = tbi.createGraphics(); + g.drawRenderedImage(ri, new AffineTransform()); + g.dispose(); + bi = tbi; + } + + // Make sure the not spot does not fall out of the cursor area. If it + // does, then clamp the coordinates to the image space. + x = x < 0 ? 0 : x; + y = y < 0 ? 0 : y; + x = x > (cursorSize.width-1) ? cursorSize.width - 1 : x; + y = y > (cursorSize.height-1) ? cursorSize.height - 1: y; + + // + // The cursor image is not into the bi image + // + Cursor c = Toolkit.getDefaultToolkit() + .createCustomCursor(bi, + new Point((int)Math.round(x), + (int)Math.round(y)), + purl.toString()); + + addCursorToCache(desc, c); + return c; + } + + /** + * Implementation helper: converts a RenderedImage to an Image + */ + protected Image renderedImageToImage(RenderedImage ri) { + int x = ri.getMinX(); + int y = ri.getMinY(); + SampleModel sm = ri.getSampleModel(); + ColorModel cm = ri.getColorModel(); + WritableRaster wr = Raster.createWritableRaster(sm, new Point(x,y)); + ri.copyData(wr); + + return new BufferedImage(ri.getColorModel(), + wr, + cm.isAlphaPremultiplied(), + null); + } + + /** + * Checks if the cursor referencing the input image and + * with the given hot spot is in the cache + */ + protected Cursor getCachedCursor(CursorDescriptor desc) { + return null; + } + + /** + * Puts the input Cursor in the cache + */ + protected void addCursorToCache(CursorDescriptor desc, Cursor c) { + } + + static class CursorDescriptor { + ParsedURL purl; + float x; + float y; + + public CursorDescriptor(ParsedURL purl, + float x, float y) { + if (purl == null) { + throw new IllegalArgumentException(); + } + + this.x = x; + this.y = y; + } + + public boolean equals(Object obj) { + if (obj == null + || + !(obj instanceof CursorDescriptor)) { + return false; + } + + CursorDescriptor desc = (CursorDescriptor)obj; + return + (this.purl.equals(desc.purl) + && + this.x == desc.x + && + this.y == desc.y); + } + } } 1.20 +3 -3 xml-batik/sources/org/apache/batik/bridge/SVGAElementBridge.java Index: SVGAElementBridge.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGAElementBridge.java,v retrieving revision 1.19 retrieving revision 1.20 diff -u -r1.19 -r1.20 --- SVGAElementBridge.java 12 Nov 2002 09:51:34 -0000 1.19 +++ SVGAElementBridge.java 14 Nov 2002 14:57:14 -0000 1.20 @@ -141,9 +141,9 @@ // The cursor on the inside rect will be set to the hand cursor and // not the wait cursor // - String cursorStr = CSSUtilities.convertCursor((Element)evt.getTarget()); + Element target = (Element)evt.getTarget(); - if (SVG_AUTO_VALUE.equalsIgnoreCase(cursorStr)) { + if (CSSUtilities.isAutoCursor(target)) { // The target's cursor value is 'auto': use the hand cursor userAgent.setSVGCursor(CursorManager.ANCHOR_CURSOR); } 1.27 +10 -6 xml-batik/sources/org/apache/batik/bridge/SVGUseElementBridge.java Index: SVGUseElementBridge.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGUseElementBridge.java,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- SVGUseElementBridge.java 12 Nov 2002 09:51:34 -0000 1.26 +++ SVGUseElementBridge.java 14 Nov 2002 14:57:14 -0000 1.27 @@ -10,6 +10,7 @@ import java.net.MalformedURLException; +import java.awt.Cursor; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; @@ -244,7 +245,7 @@ /** * To handle a mouseover on an anchor and set the cursor. */ - public static class CursorMouseOverListener implements EventListener { + public class CursorMouseOverListener implements EventListener { protected UserAgent userAgent; @@ -257,10 +258,13 @@ // Only modify the cursor if the current target's (i.e., the <use>) cursor // property is *not* 'auto'. // - String cursorStr = CSSUtilities.convertCursor((Element)evt.getCurrentTarget()); - - if (!SVG_AUTO_VALUE.equalsIgnoreCase(cursorStr)) { - userAgent.setSVGCursor(CursorManager.getCursor(cursorStr)); + Element currentTarget = (Element)evt.getCurrentTarget(); + + if (!CSSUtilities.isAutoCursor(currentTarget)) { + Cursor cursor = CSSUtilities.convertCursor(currentTarget, ctx); + if (cursor != null) { + userAgent.setSVGCursor(cursor); + } } } } 1.13 +3 -2 xml-batik/resources/org/apache/batik/bridge/resources/Messages.properties Index: Messages.properties =================================================================== RCS file: /home/cvs/xml-batik/resources/org/apache/batik/bridge/resources/Messages.properties,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- Messages.properties 12 Nov 2002 09:51:35 -0000 1.12 +++ Messages.properties 14 Nov 2002 14:57:21 -0000 1.13 @@ -35,8 +35,9 @@ The URI ''{3}'' specified on the element <{2}> is invalid uri.badTarget = \ -{0}\n\ -Can't find a referenced element - may be a problem of 'id' +{0}:{1}\n\ +Cannot find the referenced element ''{3}'' specified on the element <{2}> - may be a problem of 'id' + uri.io = \ {0}:{1}\n\ 1.3 +6 -2 xml-batik/samples/tests/spec/interactivity/cursor.svg Index: cursor.svg =================================================================== RCS file: /home/cvs/xml-batik/samples/tests/spec/interactivity/cursor.svg,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- cursor.svg 12 Nov 2002 09:51:35 -0000 1.2 +++ cursor.svg 14 Nov 2002 14:57:23 -0000 1.3 @@ -34,6 +34,10 @@ <use id="evenRow" xlink:href="#row" stroke="black" fill="#eeeeee" /> <use id="oddRowCursor" xlink:href="#row" stroke="black" fill="crimson" cursor="wait"/> <use id="evenRowCursor" xlink:href="#row" stroke="black" fill="gold" cursor="wait"/> + + <cursor id="customCursor" x="16" y="16" xlink:href="../../resources/images/hotSpotCenter.png" /> + <cursor id="customCursor2" x="32" y="0" xlink:href="../../resources/images/hotSpotNE.png" /> + </defs> <g transform="translate(120, 120)" class="label" text-anchor="middle"> @@ -142,7 +146,7 @@ <use xlink:href="#evenRow"/> <text>Good url, wait</text> </g> - <g transform="translate(0,200)" cursor="url(#badCustom), url(#customCursor), crosshair"> + <g transform="translate(0,200)" cursor="url(#badCustom), url(#customCursor2), crosshair"> <use xlink:href="#oddRow"/> <text>Bad url, good url, crosshair</text> </g> 1.1 xml-batik/samples/tests/spec/interactivity/cursor2.svg Index: cursor2.svg =================================================================== <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <!-- ========================================================================= --> <!-- Copyright (C) The Apache Software Foundation. All rights reserved. --> <!-- --> <!-- This software is published under the terms of the Apache Software License --> <!-- version 1.1, a copy of which has been included with this distribution in --> <!-- the LICENSE file. --> <!-- ========================================================================= --> <!-- ========================================================================= --> <!-- Tests support for the cursor property. --> <!-- --> <!-- @author [EMAIL PROTECTED] --> <!-- @version $Id: cursor2.svg,v 1.1 2002/11/14 14:57:25 vhardy Exp $ --> <!-- ========================================================================= --> <?xml-stylesheet type="text/css" href="../../resources/style/test.css" ?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="body" width="450" height="500" viewBox="0 0 450 500" > <text class="title" x="50%" y="50">Custom Cursor Hot Spot Test</text> <script type="text/ecmascript"><![CDATA[ var hitCount = document.getElementById("hitCount"); var hitCountText = hitCount.firstChild; var curHitCount = 0; function targetHit() { curHitCount++; hitCountText.data = "" + curHitCount; } var hitTargetArea = document.getElementById("hitTargetArea"); function hotTarget() { hitTargetArea.setAttribute("fill", "gold"); } function coldTarget() { hitTargetArea.setAttribute("fill", "#eeeeee"); } var cursorRef = document.getElementById("refNW"); function changeCursor(evt) { var target = evt.target; var id = target.getAttribute("id"); var cursorId = "cursor" + id; hitTargetArea.setAttribute("cursor", "url(#" + cursorId + "),crosshair"); cursorRef.setAttribute("visibility", "hidden"); cursorRef = document.getElementById("ref" + id); cursorRef.setAttribute("visibility", "visible"); } ]]></script> <text class="label" x="50%" y="125" text-anchor="middle">Try and hit the small black dot <tspan x="50%" dy="+1.4em">after selecting your cursor</tspan></text> <g id="hitTargetArea" fill="#eeeeee" transform="translate(175, 150)" shape-rendering="crispEdges" cursor="url(#cursorNW),crosshair" > <rect x="0" y="0" width="100" height="100" stroke="black"/> <rect x="44" y="44" width="12" height="12" fill="black"/> <rect x="45" y="45" width="10" height="10" fill="#eeeeee" /> <rect x="49" y="40" width="2" height="20" fill="black" /> <rect y="49" x="40" height="2" width="20" fill="black" /> <!-- <line x1="40" y1="50" x2="60" y2="50" stroke="black" /> <line y1="40" x1="50" y2="60" x2="50" stroke="black" /> --> <rect x="49" y="49" width="2" height="2" fill="black" onclick="targetHit()" onmouseover="hotTarget()" onmouseout="coldTarget()"/> </g> <text class="label" text-anchor="middle" x="50%" y="270" fill="crimson">Hit Count : <tspan id="hitCount">0</tspan></text> <text class="label" text-anchor="middle" x="25%" y="340" >Cursor Selection</text> <g onclick="changeCursor(evt)" transform="translate(112.5, 410)"> <use xlink:href="#Center" x="-16" y="-16" /> <use xlink:href="#NW" x="-50" y="-50" /> <use xlink:href="#N" x="-16" y="-50" /> <use xlink:href="#NE" x="18" y="-50" /> <use xlink:href="#E" x="18" y="-16" /> <use xlink:href="#SE" x="18" y="18" /> <use xlink:href="#S" x="-16" y="18" /> <use xlink:href="#SW" x="-50" y="18" /> <use xlink:href="#W" x="-50" y="-16" /> </g> <text class="label" text-anchor="middle" x="75%" y="340" >Current Target Area Cursor</text> <g transform="translate(321.5, 394)" visibility="hidden"> <use id="refCenter" xlink:href="#Center" /> <use id="refNW" xlink:href="#NW" visibility="visible"/> <use id="refN" xlink:href="#N" /> <use id="refNE" xlink:href="#NE" /> <use id="refE" xlink:href="#E" /> <use id="refSE" xlink:href="#SE" /> <use id="refS" xlink:href="#S" /> <use id="refSW" xlink:href="#SW" /> <use id="refW" xlink:href="#W" /> </g> <defs> <image id="Center" xlink:href="../../resources/images/hotSpotCenter.png" width="32" height="32"/> <image id="NW" xlink:href="../../resources/images/hotSpotNW.png" width="32" height="32"/> <image id="N" xlink:href="../../resources/images/hotSpotN.png" width="32" height="32"/> <image id="NE" xlink:href="../../resources/images/hotSpotNE.png" width="32" height="32"/> <image id="E" xlink:href="../../resources/images/hotSpotE.png" width="32" height="32"/> <image id="SE" xlink:href="../../resources/images/hotSpotSE.png" width="32" height="32"/> <image id="S" xlink:href="../../resources/images/hotSpotS.png" width="32" height="32"/> <image id="SW" xlink:href="../../resources/images/hotSpotSW.png" width="32" height="32"/> <image id="W" xlink:href="../../resources/images/hotSpotW.png" width="32" height="32"/> <cursor id="cursorCenter" x="16" y="16" xlink:href="../../resources/images/hotSpotCenter.png"/> <cursor id="cursorNW" x="0" y="0" xlink:href="../../resources/images/hotSpotNW.png"/> <cursor id="cursorN" x="16" y="0" xlink:href="../../resources/images/hotSpotN.png"/> <cursor id="cursorNE" x="32" y="0" xlink:href="../../resources/images/hotSpotNE.png"/> <cursor id="cursorE" x="32" y="16" xlink:href="../../resources/images/hotSpotE.png"/> <cursor id="cursorSE" x="32" y="32" xlink:href="../../resources/images/hotSpotSE.png"/> <cursor id="cursorS" x="16" y="32" xlink:href="../../resources/images/hotSpotS.png"/> <cursor id="cursorSW" x="0" y="32" xlink:href="../../resources/images/hotSpotSW.png"/> <cursor id="cursorW" x="0" y="16" xlink:href="../../resources/images/hotSpotW.png"/> </defs> </svg> 1.1 xml-batik/samples/tests/spec/interactivity/cursor3.svg Index: cursor3.svg =================================================================== <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <!-- ========================================================================= --> <!-- Copyright (C) The Apache Software Foundation. All rights reserved. --> <!-- --> <!-- This software is published under the terms of the Apache Software License --> <!-- version 1.1, a copy of which has been included with this distribution in --> <!-- the LICENSE file. --> <!-- ========================================================================= --> <!-- ========================================================================= --> <!-- Tests support for the cursor property. --> <!-- --> <!-- @author [EMAIL PROTECTED] --> <!-- @version $Id: cursor3.svg,v 1.1 2002/11/14 14:57:25 vhardy Exp $ --> <!-- ========================================================================= --> <?xml-stylesheet type="text/css" href="../../resources/style/test.css" ?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="body" width="450" height="500" viewBox="0 0 450 500" > <text class="title" x="50%" y="50">Custom Cursor Image Test</text> <script type="text/ecmascript"><![CDATA[ var hitCount = document.getElementById("hitCount"); var hitCountText = hitCount.firstChild; var curHitCount = 0; function targetHit() { curHitCount++; hitCountText.data = "" + curHitCount; } var hitTargetArea = document.getElementById("hitTargetArea"); function hotTarget() { hitTargetArea.setAttribute("fill", "gold"); } function coldTarget() { hitTargetArea.setAttribute("fill", "#eeeeee"); } var cursorRef = document.getElementById("refCenterSmall"); function changeCursor(evt) { var target = evt.target; var id = target.getAttribute("id"); var cursorId = "cursor" + id; hitTargetArea.setAttribute("cursor", "url(#" + cursorId + "),crosshair"); cursorRef.setAttribute("visibility", "hidden"); cursorRef = document.getElementById("ref" + id); cursorRef.setAttribute("visibility", "visible"); } ]]></script> <text class="label" x="50%" y="125" text-anchor="middle">Try and hit the small black dot <tspan x="50%" dy="+1.4em">after selecting your cursor</tspan></text> <g id="hitTargetArea" fill="#eeeeee" transform="translate(175, 150)" shape-rendering="crispEdges" cursor="url(#cursorCenterSmall),crosshair" > <rect x="0" y="0" width="100" height="100" stroke="black"/> <rect x="44" y="44" width="12" height="12" fill="black"/> <rect x="45" y="45" width="10" height="10" fill="#eeeeee" /> <rect x="49" y="40" width="2" height="20" fill="black" /> <rect y="49" x="40" height="2" width="20" fill="black" /> <!-- <line x1="40" y1="50" x2="60" y2="50" stroke="black" /> <line y1="40" x1="50" y2="60" x2="50" stroke="black" /> --> <rect x="49" y="49" width="2" height="2" fill="black" onclick="targetHit()" onmouseover="hotTarget()" onmouseout="coldTarget()"/> </g> <text class="label" text-anchor="middle" x="50%" y="270" fill="crimson">Hit Count : <tspan id="hitCount">0</tspan></text> <text class="label" text-anchor="middle" x="25%" y="340" >Cursor Selection</text> <g onclick="changeCursor(evt)" transform="translate(57.5, 400)"> <use xlink:href="#CenterSmall" /> <use xlink:href="#Center" x="32"/> <use xlink:href="#CenterBig" x="90"/> </g> <text class="label" text-anchor="middle" x="75%" y="340" >Current Target Area Cursor</text> <g transform="translate(337.5, 394)" visibility="hidden"> <use id="refCenter" xlink:href="#Center" /> <use id="refCenterSmall" xlink:href="#CenterSmall" visibility="visible"/> <use id="refCenterBig" xlink:href="#CenterBig" /> </g> <defs> <image id="Center" xlink:href="../../resources/images/hotSpotCenter.png" x="-16" y="-16" width="32" height="32"/> <image id="CenterSmall" xlink:href="../../resources/images/hotSpotCenterSmall.png" x="-8" y="-8" width="16" height="16"/> <image id="CenterBig" xlink:href="../../resources/images/hotSpotCenterBig.png" x="-32" y="-32" width="64" height="64"/> <cursor id="cursorCenter" x="16" y="16" xlink:href="../../resources/images/hotSpotCenter.png"/> <cursor id="cursorCenterSmall" x="8" y="8" xlink:href="../../resources/images/hotSpotCenterSmall.png"/> <cursor id="cursorCenterBig" x="32" y="32" xlink:href="../../resources/images/hotSpotCenterBig.png"/> </defs> </svg> 1.1 xml-batik/samples/tests/spec/interactivity/cursor4.svg Index: cursor4.svg =================================================================== <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <!-- ========================================================================= --> <!-- Copyright (C) The Apache Software Foundation. All rights reserved. --> <!-- --> <!-- This software is published under the terms of the Apache Software License --> <!-- version 1.1, a copy of which has been included with this distribution in --> <!-- the LICENSE file. --> <!-- ========================================================================= --> <!-- ========================================================================= --> <!-- Tests support for the cursor property. --> <!-- This test shows that JPEG, PNG and TIF formats are supported. It also --> <!-- shows that SVG images are not supported for cursors and that BMP images --> <!-- are not either. Unsupported image formats result in the same bahavior as --> <!-- 'broken images'. The cursor displays a broken image. --> <!-- --> <!-- @author [EMAIL PROTECTED] --> <!-- @version $Id: cursor4.svg,v 1.1 2002/11/14 14:57:25 vhardy Exp $ --> <!-- ========================================================================= --> <?xml-stylesheet type="text/css" href="../../resources/style/test.css" ?> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="body" width="450" height="500" viewBox="0 0 450 500" > <text class="title" x="50%" y="50">Custom Cursor Image Test (cntd)</text> <script type="text/ecmascript"><![CDATA[ var hitCount = document.getElementById("hitCount"); var hitCountText = hitCount.firstChild; var curHitCount = 0; function targetHit() { curHitCount++; hitCountText.data = "" + curHitCount; } var hitTargetArea = document.getElementById("hitTargetArea"); function hotTarget() { hitTargetArea.setAttribute("fill", "gold"); } function coldTarget() { hitTargetArea.setAttribute("fill", "#eeeeee"); } var cursorRef = document.getElementById("refbrokenImage"); function changeCursor(evt) { var target = evt.target; var id = target.getAttribute("id"); var cursorId = "cursor" + id; hitTargetArea.setAttribute("cursor", "url(#" + cursorId + "),crosshair"); cursorRef.setAttribute("visibility", "hidden"); cursorRef = document.getElementById("ref" + id); if (cursorRef == null) { alert("Cannot find " + "ref" + id); return; } cursorRef.setAttribute("visibility", "visible"); } ]]></script> <text class="label" x="50%" y="125" text-anchor="middle">Try and hit the small black dot <tspan x="50%" dy="+1.4em">after selecting your cursor</tspan></text> <g id="hitTargetArea" fill="#eeeeee" transform="translate(175, 150)" shape-rendering="crispEdges" cursor="url(#cursorbrokenImage),crosshair" > <rect x="0" y="0" width="100" height="100" stroke="black"/> <rect x="44" y="44" width="12" height="12" fill="black"/> <rect x="45" y="45" width="10" height="10" fill="#eeeeee" /> <rect x="49" y="40" width="2" height="20" fill="black" /> <rect y="49" x="40" height="2" width="20" fill="black" /> <!-- <line x1="40" y1="50" x2="60" y2="50" stroke="black" /> <line y1="40" x1="50" y2="60" x2="50" stroke="black" /> --> <rect x="49" y="49" width="2" height="2" fill="black" onclick="targetHit()" onmouseover="hotTarget()" onmouseout="coldTarget()"/> </g> <text class="label" text-anchor="middle" x="50%" y="270" fill="crimson">Hit Count : <tspan id="hitCount">0</tspan></text> <text class="label" text-anchor="middle" x="25%" y="340" >Cursor Selection</text> <g onclick="changeCursor(evt)" transform="translate(80, 390)" cursor="pointer"> <use xlink:href="#brokenImage" /> <use xlink:href="#tiffImage" x="34"/> <use xlink:href="#pngImage" x="68"/> <use xlink:href="#jpegImage" x="0" y="34"/> <use xlink:href="#unsupportedImage" x="34" y="34"/> <use xlink:href="#svgImage" x="68" y="34"/> </g> <text class="label" text-anchor="middle" x="75%" y="340" >Current Target Area Cursor</text> <g transform="translate(337.5, 394)" visibility="hidden" > <g id="refbrokenImage" visibility="visible"> <text class="label" text-anchor="middle" y="40">Broken Image</text> <use xlink:href="#brokenImage" /> </g> <g id="reftiffImage"> <text class="label" text-anchor="middle" y="40">Tiff Image</text> <use xlink:href="#tiffImage" /> </g> <g id="refpngImage"> <text class="label" text-anchor="middle" y="40">PNG Image</text> <use xlink:href="#pngImage" /> </g> <g id="refjpegImage"> <text class="label" text-anchor="middle" y="40">JPEG Image</text> <use xlink:href="#jpegImage" /> </g> <g id="refunsupportedImage"> <text class="label" text-anchor="middle" y="40">Unsupported Image (BMP)</text> <use xlink:href="#unsupportedImage" /> </g> <g id="refsvgImage"> <text class="label" text-anchor="middle" y="40">SVG Image</text> <use xlink:href="#svgImage" /> </g> </g> <defs> <image id="brokenImage" xlink:href="../../resources/images/iDontExist.png" width="32" height="32" x="-16" y="-16"/> <image id="tiffImage" xlink:href="../../resources/images/tiffCursor.tif" width="32" height="32" x="-16" y="-16"/> <image id="pngImage" xlink:href="../../resources/images/pngCursor.png" width="32" height="32" x="-16" y="-16"/> <image id="jpegImage" xlink:href="../../resources/images/jpegCursor.jpg" width="32" height="32" x="-16" y="-16"/> <image id="unsupportedImage" xlink:href="../../resources/images/bmpCursor.bmp" width="32" height="32" x="-16" y="-16"/> <image id="svgImage" xlink:href="../../resources/images/svgCursor.svg" width="32" height="32" x="-16" y="-16"/> <cursor id="cursorbrokenImage" xlink:href="../../resources/images/iDontExist.png" x="16" y="16"/> <cursor id="cursortiffImage" xlink:href="../../resources/images/tiffCursor.tif" x="16" y="16"/> <cursor id="cursorpngImage" xlink:href="../../resources/images/pngCursor.png" x="16" y="16"/> <cursor id="cursorjpegImage" xlink:href="../../resources/images/jpegCursor.jpg" x="16" y="16"/> <cursor id="cursorunsupportedImage" xlink:href="../../resources/images/bmpCursor.bmp" x="16" y="16"/> <cursor id="cursorsvgImage" xlink:href="../../resources/images/svgCursor.svg" x="16" y="16"/> </defs> </svg> 1.1 xml-batik/samples/tests/resources/images/hotSpotCenter.png <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/hotSpotCenterBig.png <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/hotSpotCenterSmall.png <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/hotSpotE.png <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/hotSpotN.png <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/hotSpotNE.png <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/hotSpotNW.png <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/hotSpotS.png <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/hotSpotSE.png <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/hotSpotSW.png <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/hotSpotW.png <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/bmpCursor.bmp <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/jpegCursor.jpg <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/tiffCursor.tif <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/pngCursor.png <<Binary file>> 1.1 xml-batik/samples/tests/resources/images/svgCursor.svg Index: svgCursor.svg =================================================================== <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="body" width="32" height="32" viewBox="0 0 32 32" > <rect x="0" y="0" width="32" height="32" fill="black" /> <rect x="2" y="2" width="28" height="28" fill="white" /> <rect x="15" y="0" width="2" height="32" fill="black" /> <rect y="15" x="0" width="32" height="2" fill="black" /> <rect x="12" y="12" width="8" height="8" fill="crimson" /> <rect x="5" y="20" width="22" height="10" fill="white" /> <text x="15.5" y="29" font-family="sans-serif" font-size="8" text-anchor="middle">SVG</text> </svg>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]