-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
anim,bridge: continue rendering if x/y/width/height attributes of lin…
…e,image,svg,use are wrong [SVG2] See #113.
- Loading branch information
Showing
16 changed files
with
310 additions
and
226 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,7 @@ | |
import org.w3c.dom.svg.SVGFitToViewBox; | ||
import org.w3c.dom.svg.SVGTransformable; | ||
|
||
import io.sf.carte.echosvg.anim.dom.AbstractSVGAnimatedLength; | ||
import io.sf.carte.echosvg.anim.dom.AnimatedLiveAttributeValue; | ||
import io.sf.carte.echosvg.anim.dom.SVGOMAnimatedTransformList; | ||
import io.sf.carte.echosvg.anim.dom.SVGOMElement; | ||
|
@@ -66,8 +67,10 @@ | |
* <li>visibility</li> | ||
* </ul> | ||
* | ||
* @author <a href="mailto:[email protected]">Thierry Kormann</a> | ||
* @author For later modifications, see Git history. | ||
* <p> | ||
* Original author: <a href="mailto:[email protected]">Thierry Kormann</a>. | ||
* For later modifications, see Git history. | ||
* </p> | ||
* @version $Id$ | ||
*/ | ||
public abstract class AbstractGraphicsNodeBridge extends AnimatableSVGBridge | ||
|
@@ -150,6 +153,49 @@ public void buildGraphicsNode(BridgeContext ctx, Element e, GraphicsNode node) { | |
initializeDynamicSupport(ctx, e, node); | ||
} | ||
|
||
/** | ||
* Give a safe value for an animated length, regardless of exceptions. | ||
* | ||
* @param animValue the animated length. | ||
* @return the value. | ||
*/ | ||
float safeAnimatedLength(AbstractSVGAnimatedLength animValue) throws BridgeException { | ||
float value; | ||
try { | ||
value = animValue.getCheckedValue(); | ||
} catch (LiveAttributeException ex) { | ||
BridgeException be = new BridgeException(ctx, ex); | ||
if (ctx.userAgent == null) { | ||
throw be; | ||
} | ||
ctx.userAgent.displayError(be); | ||
value = animValue.getDefault(); | ||
} | ||
return value; | ||
} | ||
|
||
/** | ||
* Give a safe value for an animated length, regardless of exceptions. | ||
* | ||
* @param animValue the animated length. | ||
* @param defValue the default value. | ||
* @return the value. | ||
*/ | ||
float safeAnimatedLength(AbstractSVGAnimatedLength animValue, float defValue) throws BridgeException { | ||
float value; | ||
try { | ||
value = animValue.getCheckedValue(); | ||
} catch (LiveAttributeException ex) { | ||
BridgeException be = new BridgeException(ctx, ex); | ||
if (ctx.userAgent == null) { | ||
throw be; | ||
} | ||
ctx.userAgent.displayError(be); | ||
value = defValue; | ||
} | ||
return value; | ||
} | ||
|
||
/** | ||
* Returns true if the graphics node has to be displayed, false otherwise. | ||
*/ | ||
|
@@ -162,7 +208,8 @@ public boolean getDisplay(Element e) { | |
* Returns an {@link AffineTransform} that is the transformation to be applied | ||
* to the node. | ||
*/ | ||
protected AffineTransform computeTransform(SVGTransformable te, BridgeContext ctx) { | ||
protected AffineTransform computeTransform(SVGTransformable te, BridgeContext ctx) | ||
throws BridgeException { | ||
try { | ||
AffineTransform at = new AffineTransform(); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,8 +33,10 @@ | |
/** | ||
* Bridge class for the <circle> element. | ||
* | ||
* @author <a href="mailto:[email protected]">Thierry Kormann</a> | ||
* @author For later modifications, see Git history. | ||
* <p> | ||
* Original author: <a href="mailto:[email protected]">Thierry Kormann</a>. | ||
* For later modifications, see Git history. | ||
* </p> | ||
* @version $Id$ | ||
*/ | ||
public class SVGCircleElementBridge extends SVGShapeElementBridge { | ||
|
@@ -75,15 +77,15 @@ protected void buildShape(BridgeContext ctx, Element e, ShapeNode shapeNode) { | |
|
||
// 'cx' attribute - default is 0 | ||
AbstractSVGAnimatedLength _cx = (AbstractSVGAnimatedLength) ce.getCx(); | ||
float cx = safeAnimatedCheckedValue(_cx, 0f); | ||
float cx = safeAnimatedLength(_cx, 0f); | ||
|
||
// 'cy' attribute - default is 0 | ||
AbstractSVGAnimatedLength _cy = (AbstractSVGAnimatedLength) ce.getCy(); | ||
float cy = safeAnimatedCheckedValue(_cy, 0f); | ||
float cy = safeAnimatedLength(_cy, 0f); | ||
|
||
// 'r' attribute - default is 0 (SVG2) | ||
AbstractSVGAnimatedLength _r = (AbstractSVGAnimatedLength) ce.getR(); | ||
float r = safeAnimatedCheckedValue(_r, 0f); | ||
float r = safeAnimatedLength(_r, 0f); | ||
|
||
float x = cx - r; | ||
float y = cy - r; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,8 +33,10 @@ | |
/** | ||
* Bridge class for the <ellipse> element. | ||
* | ||
* @author <a href="mailto:[email protected]">Thierry Kormann</a> | ||
* @author For later modifications, see Git history. | ||
* <p> | ||
* Original author: <a href="mailto:[email protected]">Thierry Kormann</a>. | ||
* For later modifications, see Git history. | ||
* </p> | ||
* @version $Id$ | ||
*/ | ||
public class SVGEllipseElementBridge extends SVGShapeElementBridge { | ||
|
@@ -69,58 +71,59 @@ public Bridge getInstance() { | |
* @param shapeNode the shape node to initialize | ||
*/ | ||
@Override | ||
protected void buildShape(BridgeContext ctx, Element e, ShapeNode shapeNode) { | ||
protected void buildShape(BridgeContext ctx, Element e, ShapeNode shapeNode) | ||
throws BridgeException { | ||
SVGOMEllipseElement ee = (SVGOMEllipseElement) e; | ||
|
||
// 'cx' attribute - default is 0 | ||
AbstractSVGAnimatedLength _cx = (AbstractSVGAnimatedLength) ee.getCx(); | ||
float cx = safeAnimatedLength(_cx, 0f); | ||
|
||
// 'cy' attribute - default is 0 | ||
AbstractSVGAnimatedLength _cy = (AbstractSVGAnimatedLength) ee.getCy(); | ||
float cy = safeAnimatedLength(_cy, 0f); | ||
|
||
// 'rx' attribute - default is auto (SVG2) | ||
boolean rxAuto = false; | ||
AbstractSVGAnimatedLength _rx = (AbstractSVGAnimatedLength) ee.getRx(); | ||
float rx; | ||
try { | ||
SVGOMEllipseElement ee = (SVGOMEllipseElement) e; | ||
|
||
// 'cx' attribute - default is 0 | ||
AbstractSVGAnimatedLength _cx = (AbstractSVGAnimatedLength) ee.getCx(); | ||
float cx = safeAnimatedCheckedValue(_cx, 0f); | ||
|
||
// 'cy' attribute - default is 0 | ||
AbstractSVGAnimatedLength _cy = (AbstractSVGAnimatedLength) ee.getCy(); | ||
float cy = safeAnimatedCheckedValue(_cy, 0f); | ||
|
||
// 'rx' attribute - default is auto (SVG2) | ||
boolean rxAuto = false; | ||
AbstractSVGAnimatedLength _rx = (AbstractSVGAnimatedLength) ee.getRx(); | ||
float rx; | ||
try { | ||
rx = _rx.getCheckedValue(); | ||
} catch (LiveAttributeException ex) { | ||
rx = 0f; | ||
rxAuto = true; | ||
BridgeException be = new BridgeException(ctx, ex); | ||
if (ctx.userAgent == null) { | ||
throw be; | ||
} | ||
ctx.userAgent.displayError(be); | ||
rx = _rx.getCheckedValue(); | ||
} catch (LiveAttributeException ex) { | ||
rx = 0f; | ||
rxAuto = true; | ||
BridgeException be = new BridgeException(ctx, ex); | ||
if (ctx.userAgent == null) { | ||
throw be; | ||
} | ||
ctx.userAgent.displayError(be); | ||
} | ||
|
||
// 'ry' attribute - default is auto (SVG2) | ||
AbstractSVGAnimatedLength _ry = (AbstractSVGAnimatedLength) ee.getRy(); | ||
float ry; | ||
try { | ||
ry = _ry.getCheckedValue(); | ||
} catch (LiveAttributeException ex) { | ||
ry = rx; | ||
BridgeException be = new BridgeException(ctx, ex); | ||
if (ctx.userAgent == null) { | ||
throw be; | ||
} | ||
ctx.userAgent.displayError(be); | ||
// 'ry' attribute - default is auto (SVG2) | ||
AbstractSVGAnimatedLength _ry = (AbstractSVGAnimatedLength) ee.getRy(); | ||
float ry; | ||
try { | ||
ry = _ry.getCheckedValue(); | ||
} catch (LiveAttributeException ex) { | ||
ry = rx; | ||
BridgeException be = new BridgeException(ctx, ex); | ||
if (ctx.userAgent == null) { | ||
throw be; | ||
} | ||
ctx.userAgent.displayError(be); | ||
} | ||
|
||
// Check whether rx was auto | ||
/* | ||
* SVG2 §7.4: "When the computed value of ‘rx’ is auto, the used radius is equal | ||
* to the absolute length used for ry, creating a circular arc. If both ‘rx’ and | ||
* ‘ry’ have a computed value of auto, the used value is 0." | ||
*/ | ||
if (rxAuto) { | ||
rx = ry; | ||
} | ||
// Check whether rx was auto | ||
/* | ||
* SVG2 §7.4: "When the computed value of ‘rx’ is auto, the used radius is equal | ||
* to the absolute length used for ry, creating a circular arc. If both ‘rx’ and | ||
* ‘ry’ have a computed value of auto, the used value is 0." | ||
*/ | ||
if (rxAuto) { | ||
rx = ry; | ||
} | ||
|
||
try { | ||
shapeNode.setShape(new Ellipse2D.Float(cx - rx, cy - ry, rx * 2f, ry * 2f)); | ||
} catch (LiveAttributeException ex) { | ||
throw new BridgeException(ctx, ex); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,8 +72,10 @@ | |
/** | ||
* Bridge class for the <image> element. | ||
* | ||
* @author <a href="mailto:[email protected]">Thierry Kormann</a> | ||
* @author For later modifications, see Git history. | ||
* <p> | ||
* Original author: <a href="mailto:[email protected]">Thierry Kormann</a>. | ||
* For later modifications, see Git history. | ||
* </p> | ||
* @version $Id$ | ||
*/ | ||
public class SVGImageElementBridge extends AbstractGraphicsNodeBridge { | ||
|
@@ -481,7 +483,7 @@ protected void initializeDynamicSupport(BridgeContext ctx, Element e, GraphicsNo | |
* Invoked when the animated value of an animatable attribute has changed. | ||
*/ | ||
@Override | ||
public void handleAnimatedAttributeChanged(AnimatedLiveAttributeValue alav) { | ||
public void handleAnimatedAttributeChanged(AnimatedLiveAttributeValue alav) throws BridgeException { | ||
try { | ||
String ns = alav.getNamespaceURI(); | ||
String ln = alav.getLocalName(); | ||
|
@@ -921,18 +923,19 @@ protected static ICCColorSpaceWithIntent extractColorSpace(Element element, Brid | |
* @param ctx the bridge context | ||
* @param element the image element | ||
*/ | ||
protected static Rectangle2D getImageBounds(BridgeContext ctx, Element element) { | ||
try { | ||
SVGImageElement ie = (SVGImageElement) element; | ||
protected static Rectangle2D getImageBounds(BridgeContext ctx, Element element) | ||
throws BridgeException { | ||
SVGImageElement ie = (SVGImageElement) element; | ||
|
||
// 'x' attribute - default is 0 | ||
AbstractSVGAnimatedLength _x = (AbstractSVGAnimatedLength) ie.getX(); | ||
float x = _x.getCheckedValue(); | ||
// 'x' attribute - default is 0 | ||
AbstractSVGAnimatedLength _x = (AbstractSVGAnimatedLength) ie.getX(); | ||
float x = safeLength(_x, ctx); | ||
|
||
// 'y' attribute - default is 0 | ||
AbstractSVGAnimatedLength _y = (AbstractSVGAnimatedLength) ie.getY(); | ||
float y = _y.getCheckedValue(); | ||
// 'y' attribute - default is 0 | ||
AbstractSVGAnimatedLength _y = (AbstractSVGAnimatedLength) ie.getY(); | ||
float y = safeLength(_y, ctx); | ||
|
||
try { | ||
// 'width' attribute - required | ||
AbstractSVGAnimatedLength _width = (AbstractSVGAnimatedLength) ie.getWidth(); | ||
float w = _width.getCheckedValue(); | ||
|
@@ -947,6 +950,29 @@ protected static Rectangle2D getImageBounds(BridgeContext ctx, Element element) | |
} | ||
} | ||
|
||
/** | ||
* Give a safe value for an animated length, regardless of exceptions. | ||
* | ||
* @param animValue the animated length. | ||
* @param defValue the default value. | ||
* @return the value. | ||
*/ | ||
private static float safeLength(AbstractSVGAnimatedLength animValue, BridgeContext ctx) | ||
throws BridgeException { | ||
float value; | ||
try { | ||
value = animValue.getCheckedValue(); | ||
} catch (LiveAttributeException ex) { | ||
BridgeException be = new BridgeException(ctx, ex); | ||
if (ctx.userAgent == null) { | ||
throw be; | ||
} | ||
ctx.userAgent.displayError(be); | ||
value = 0f; | ||
} | ||
return value; | ||
} | ||
|
||
GraphicsNode createBrokenImageNode(BridgeContext ctx, Element e, String uri, String message) { | ||
SVGDocument doc = ctx.getUserAgent().getBrokenLinkDocument(e, uri, | ||
Messages.formatMessage(URI_IMAGE_ERROR, new Object[] { message })); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,8 +32,10 @@ | |
/** | ||
* Bridge class for the <line> element. | ||
* | ||
* @author <a href="mailto:[email protected]">Thierry Kormann</a> | ||
* @author For later modifications, see Git history. | ||
* <p> | ||
* Original author: <a href="mailto:[email protected]">Thierry Kormann</a>. | ||
* For later modifications, see Git history. | ||
* </p> | ||
* @version $Id$ | ||
*/ | ||
public class SVGLineElementBridge extends SVGDecoratedShapeElementBridge { | ||
|
@@ -92,27 +94,27 @@ protected ShapePainter createFillStrokePainter(BridgeContext ctx, Element e, Sha | |
* @param shapeNode the shape node to initialize | ||
*/ | ||
@Override | ||
protected void buildShape(BridgeContext ctx, Element e, ShapeNode shapeNode) { | ||
protected void buildShape(BridgeContext ctx, Element e, ShapeNode shapeNode) | ||
throws BridgeException { | ||
SVGOMLineElement le = (SVGOMLineElement) e; | ||
|
||
try { | ||
SVGOMLineElement le = (SVGOMLineElement) e; | ||
|
||
// 'x1' attribute - default is 0 | ||
AbstractSVGAnimatedLength _x1 = (AbstractSVGAnimatedLength) le.getX1(); | ||
float x1 = _x1.getCheckedValue(); | ||
// 'x1' attribute - default is 0 | ||
AbstractSVGAnimatedLength _x1 = (AbstractSVGAnimatedLength) le.getX1(); | ||
float x1 = safeAnimatedLength(_x1, 0f); | ||
|
||
// 'y1' attribute - default is 0 | ||
AbstractSVGAnimatedLength _y1 = (AbstractSVGAnimatedLength) le.getY1(); | ||
float y1 = _y1.getCheckedValue(); | ||
// 'y1' attribute - default is 0 | ||
AbstractSVGAnimatedLength _y1 = (AbstractSVGAnimatedLength) le.getY1(); | ||
float y1 = safeAnimatedLength(_y1, 0f); | ||
|
||
// 'x2' attribute - default is 0 | ||
AbstractSVGAnimatedLength _x2 = (AbstractSVGAnimatedLength) le.getX2(); | ||
float x2 = _x2.getCheckedValue(); | ||
// 'x2' attribute - default is 0 | ||
AbstractSVGAnimatedLength _x2 = (AbstractSVGAnimatedLength) le.getX2(); | ||
float x2 = safeAnimatedLength(_x2, 0f); | ||
|
||
// 'y2' attribute - default is 0 | ||
AbstractSVGAnimatedLength _y2 = (AbstractSVGAnimatedLength) le.getY2(); | ||
float y2 = _y2.getCheckedValue(); | ||
// 'y2' attribute - default is 0 | ||
AbstractSVGAnimatedLength _y2 = (AbstractSVGAnimatedLength) le.getY2(); | ||
float y2 = safeAnimatedLength(_y2, 0f); | ||
|
||
try { | ||
shapeNode.setShape(new Line2D.Float(x1, y1, x2, y2)); | ||
} catch (LiveAttributeException ex) { | ||
throw new BridgeException(ctx, ex); | ||
|
Oops, something went wrong.