You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-dev@xmlgraphics.apache.org by vh...@apache.org on 2002/11/15 19:44:52 UTC
cvs commit: xml-batik/sources/org/apache/batik/bridge CSSUtilities.java CursorManager.java
vhardy 2002/11/15 10:44:52
Modified: samples/tests/spec/interactivity cursor4.svg
sources/org/apache/batik/bridge CSSUtilities.java
CursorManager.java
Log:
No longers shows a broken image if an image referenced by a cursor
cannot be retrieved. Instead, use the follow on <cursor> element
or use the built-in cursor at the end of the list (thanks Thomas for
pointing out the BROKEN_IMAGE property).
Moved all of cursor code to CursorManager except the high-level
conversion methods still available through CSSUtilities.
Revision Changes Path
1.2 +6 -5 xml-batik/samples/tests/spec/interactivity/cursor4.svg
Index: cursor4.svg
===================================================================
RCS file: /home/cvs/xml-batik/samples/tests/spec/interactivity/cursor4.svg,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- cursor4.svg 14 Nov 2002 14:57:25 -0000 1.1
+++ cursor4.svg 15 Nov 2002 18:44:52 -0000 1.2
@@ -15,7 +15,8 @@
<!-- 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. -->
+<!-- 'broken images'. The cursor falls back to the built in cursor specified -->
+<!-- at the end of the cursor list values. -->
<!-- -->
<!-- @author vhardy@apache.org -->
<!-- @version $Id$ -->
@@ -103,7 +104,7 @@
<g transform="translate(337.5, 394)" visibility="hidden" >
<g id="refbrokenImage" visibility="visible">
- <text class="label" text-anchor="middle" y="40">Broken Image</text>
+ <text class="label" text-anchor="middle" y="40">Broken Image<tspan dy="1.5em" x="0">defaults to crosshair</tspan></text>
<use xlink:href="#brokenImage" />
</g>
<g id="reftiffImage">
@@ -119,11 +120,11 @@
<use xlink:href="#jpegImage" />
</g>
<g id="refunsupportedImage">
- <text class="label" text-anchor="middle" y="40">Unsupported Image (BMP)</text>
+ <text class="label" text-anchor="middle" y="40">Unsupported Image (BMP)<tspan dy="1.5em" x="0">defaults to crosshair</tspan></text>
<use xlink:href="#unsupportedImage" />
</g>
<g id="refsvgImage">
- <text class="label" text-anchor="middle" y="40">SVG Image</text>
+ <text class="label" text-anchor="middle" y="40">SVG Image<tspan dy="1.5em" x="0">defaults to crosshair</tspan></text>
<use xlink:href="#svgImage" />
</g>
1.40 +2 -138 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.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- CSSUtilities.java 14 Nov 2002 14:57:13 -0000 1.39
+++ CSSUtilities.java 15 Nov 2002 18:44:52 -0000 1.40
@@ -269,145 +269,9 @@
*/
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.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.getCssValueType() == CSSValue.CSS_VALUE_LIST) {
- ListValue l = (ListValue)cursorValue;
- int nValues = l.getLength();
- 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;
-
- // 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;
+ return ctx.getCursorManager().convertCursor(e);
}
-
////////////////////////////////////////////////////////////////////////
// 'color-rendering', 'text-rendering', 'image-rendering',
// 'shape-rendering'
1.5 +191 -11 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.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- CursorManager.java 14 Nov 2002 19:44:49 -0000 1.4
+++ CursorManager.java 15 Nov 2002 18:44:52 -0000 1.5
@@ -30,6 +30,11 @@
import org.apache.batik.ext.awt.image.spi.ImageTagRegistry;
import org.apache.batik.ext.awt.image.renderable.Filter;
+import org.apache.batik.css.engine.SVGCSSEngine;
+import org.apache.batik.css.engine.value.ListValue;
+import org.apache.batik.css.engine.value.StringValue;
+import org.apache.batik.css.engine.value.Value;
+
import org.apache.batik.dom.util.XLinkSupport;
import org.apache.batik.dom.svg.XMLBaseSupport;
import org.apache.batik.util.SVGConstants;
@@ -37,6 +42,9 @@
import org.apache.batik.util.SoftReferenceCache;
import org.w3c.dom.Element;
+import org.w3c.dom.css.CSSPrimitiveValue;
+import org.w3c.dom.css.CSSValue;
+
/**
* The CursorManager class is a helper class which preloads the cursors
@@ -45,7 +53,7 @@
* @author <a href="mailto:vincent.hardy@sun.com">Vincent Hardy</a>
* @version $Id$
*/
-public class CursorManager implements SVGConstants {
+public class CursorManager implements SVGConstants, ErrorConstants {
/**
* Maps SVG Cursor Values to Java Cursors
*/
@@ -134,11 +142,168 @@
public static Cursor getPredefinedCursor(String cursorName){
return (Cursor)cursorMap.get(cursorName);
}
+
+ /**
+ * Returns the Cursor corresponding to the input element's cursor property
+ *
+ * @param e the element on which the cursor property is set
+ */
+ public Cursor convertCursor(Element e) {
+ Value cursorValue
+ = CSSUtilities.getComputedStyle(e,
+ SVGCSSEngine.CURSOR_INDEX);
+
+ String cursorStr = SVGConstants.SVG_AUTO_VALUE;
+
+ if (cursorValue != null) {
+ 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();
+ return convertBuiltInCursor(e, cursorStr);
+ } else if (cursorValue.getCssValueType() == CSSValue.CSS_VALUE_LIST) {
+ ListValue l = (ListValue)cursorValue;
+ int nValues = l.getLength();
+ if (nValues == 1) {
+ cursorValue = l.item(nValues-1);
+ if (cursorValue.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
+ cursorStr = cursorValue.getStringValue();
+ return convertBuiltInCursor(e, cursorStr);
+ }
+ } else if (nValues > 1) {
+ //
+ // Look for the first cursor url we can handle.
+ // That would be a reference to a <cursor> element.
+ //
+ return convertSVGCursor(e, l);
+ }
+ }
+ }
+
+ return convertBuiltInCursor(e, cursorStr);
+ }
+ public Cursor convertBuiltInCursor(Element e, String cursorStr) {
+ Cursor cursor = null;
+
+ // 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;
+ }
+
+
/**
- * Returns a cursor for the given cursorElement
+ * Returns a cursor for the given value list. Note that the
+ * code assumes that the input value has at least two entries.
+ * So the caller should check that before calling the method.
+ * For example, CSSUtilities.convertCursor performs that check.
+ */
+ public Cursor convertSVGCursor(Element e, ListValue l) {
+ int nValues = l.getLength();
+ Element cursorElement = null;
+ for (int i=0; i<nValues-1; i++) {
+ Value 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())) {
+ Cursor c = convertSVGCursorElement(cursorElement);
+ if (c != null) {
+ return c;
+ }
+ }
+ }
+ }
+ }
+
+ // If we got to that point, it means that no cursorElement
+ // produced a valid cursor, i.e., either a format we support
+ // or a valid referenced image (no broken image).
+ // Fallback on the built in cursor property.
+ Value cursorValue = l.item(nValues-1);
+ String cursorStr = SVGConstants.SVG_AUTO_VALUE;
+ if (cursorValue.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
+ cursorStr = cursorValue.getStringValue();
+ }
+
+ return convertBuiltInCursor(e, cursorStr);
+ }
+
+ /**
+ * Returns a cursor for a given element
*/
- public Cursor convertSVGCursor(Element cursorElement) {
+ public Cursor convertSVGCursorElement(Element cursorElement) {
// One of the cursor url resolved to a <cursor> element
// Try to handle its image.
String uriStr = XLinkSupport.getXLinkHref(cursorElement);
@@ -182,12 +347,23 @@
ImageTagRegistry reg = ImageTagRegistry.getRegistry();
Filter f = reg.readURL(purl);
+
+ //
+ // Check if we got a broken image
+ //
+ if (f.getProperty
+ (SVGBrokenLinkProvider.SVG_BROKEN_LINK_DOCUMENT_PROPERTY) != null) {
+ cursorCache.clearCursor(desc);
+ return null;
+ }
+
//
// Now, get the preferred cursor dimension
//
Rectangle preferredSize = f.getBounds2D().getBounds();
if (preferredSize == null || preferredSize.width <=0
|| preferredSize.height <=0 ) {
+ cursorCache.clearCursor(desc);
return null;
}
@@ -215,14 +391,14 @@
rh = cursorSize.height;
}
- RenderedImage img = f.createScaledRendering((int)Math.round(rw),
- (int)Math.round(rh),
- null);
+ RenderedImage ri = f.createScaledRendering((int)Math.round(rw),
+ (int)Math.round(rh),
+ null);
- if (img instanceof Image) {
- bi = (Image)img;
+ if (ri instanceof Image) {
+ bi = (Image)ri;
} else {
- bi = renderedImageToImage(img);
+ bi = renderedImageToImage(ri);
}
// Apply the scale transform that is applied to the image
@@ -252,7 +428,7 @@
y = y > (cursorSize.height-1) ? cursorSize.height - 1: y;
//
- // The cursor image is not into the bi image
+ // The cursor image is now into the bi image
//
Cursor c = Toolkit.getDefaultToolkit()
.createCustomCursor(bi,
@@ -349,6 +525,10 @@
public void putCursor(CursorDescriptor desc,
Cursor cursor) {
putImpl(desc, cursor);
+ }
+
+ public void clearCursor(CursorDescriptor desc) {
+ clearImpl(desc);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-dev-help@xml.apache.org