193
// in sources/org/apache/batik/extension/svg/BatikFlowTextElementBridge.java
protected RegionInfo buildRegion(UnitProcessor.Context uctx,
Element e,
float verticalAlignment) {
String s;
// 'x' attribute - default is 0
s = e.getAttribute(BATIK_EXT_X_ATTRIBUTE);
float x = 0;
if (s.length() != 0) {
x = UnitProcessor.svgHorizontalCoordinateToUserSpace
(s, BATIK_EXT_X_ATTRIBUTE, uctx);
}
// 'y' attribute - default is 0
s = e.getAttribute(BATIK_EXT_Y_ATTRIBUTE);
float y = 0;
if (s.length() != 0) {
y = UnitProcessor.svgVerticalCoordinateToUserSpace
(s, BATIK_EXT_Y_ATTRIBUTE, uctx);
}
// 'width' attribute - required
s = e.getAttribute(BATIK_EXT_WIDTH_ATTRIBUTE);
float w;
if (s.length() != 0) {
w = UnitProcessor.svgHorizontalLengthToUserSpace
(s, BATIK_EXT_WIDTH_ATTRIBUTE, uctx);
} else {
throw new BridgeException
(ctx, e, ERR_ATTRIBUTE_MISSING,
new Object[] {BATIK_EXT_WIDTH_ATTRIBUTE, s});
}
// A value of zero disables rendering of the element
if (w == 0) {
return null;
}
// 'height' attribute - required
s = e.getAttribute(BATIK_EXT_HEIGHT_ATTRIBUTE);
float h;
if (s.length() != 0) {
h = UnitProcessor.svgVerticalLengthToUserSpace
(s, BATIK_EXT_HEIGHT_ATTRIBUTE, uctx);
} else {
throw new BridgeException
(ctx, e, ERR_ATTRIBUTE_MISSING,
new Object[] {BATIK_EXT_HEIGHT_ATTRIBUTE, s});
}
// A value of zero disables rendering of the element
if (h == 0) {
return null;
}
return new RegionInfo(x,y,w,h,verticalAlignment);
}
// in sources/org/apache/batik/extension/svg/BatikStarElementBridge.java
protected void buildShape(BridgeContext ctx,
Element e,
ShapeNode shapeNode) {
UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, e);
String s;
// 'cx' attribute - default is 0
s = e.getAttributeNS(null, SVG_CX_ATTRIBUTE);
float cx = 0;
if (s.length() != 0) {
cx = UnitProcessor.svgHorizontalCoordinateToUserSpace
(s, SVG_CX_ATTRIBUTE, uctx);
}
// 'cy' attribute - default is 0
s = e.getAttributeNS(null, SVG_CY_ATTRIBUTE);
float cy = 0;
if (s.length() != 0) {
cy = UnitProcessor.svgVerticalCoordinateToUserSpace
(s, SVG_CY_ATTRIBUTE, uctx);
}
// 'r' attribute - required
s = e.getAttributeNS(null, SVG_R_ATTRIBUTE);
float r;
if (s.length() == 0)
throw new BridgeException(ctx, e, ERR_ATTRIBUTE_MISSING,
new Object[] {SVG_R_ATTRIBUTE, s});
r = UnitProcessor.svgOtherLengthToUserSpace
(s, SVG_R_ATTRIBUTE, uctx);
// 'ir' attribute - required
s = e.getAttributeNS(null, BATIK_EXT_IR_ATTRIBUTE);
float ir;
if (s.length() == 0)
throw new BridgeException
(ctx, e, ERR_ATTRIBUTE_MISSING,
new Object[] {BATIK_EXT_IR_ATTRIBUTE, s});
ir = UnitProcessor.svgOtherLengthToUserSpace
(s, BATIK_EXT_IR_ATTRIBUTE, uctx);
// 'sides' attribute - default is 3
int sides = convertSides(e, BATIK_EXT_SIDES_ATTRIBUTE, 3, ctx);
GeneralPath gp = new GeneralPath();
double angle, x, y;
final double SECTOR = 2.0 * Math.PI/sides;
final double HALF_PI = Math.PI / 2.0;
for (int i=0; i<sides; i++) {
angle = i * SECTOR - HALF_PI;
x = cx + ir*Math.cos(angle);
y = cy - ir*Math.sin(angle);
if (i==0)
gp.moveTo((float)x, (float)y);
else
gp.lineTo((float)x, (float)y);
angle = (i+0.5) * SECTOR - HALF_PI;
x = cx + r*Math.cos(angle);
y = cy - r*Math.sin(angle);
gp.lineTo((float)x, (float)y);
}
gp.closePath();
shapeNode.setShape(gp);
}
// in sources/org/apache/batik/extension/svg/BatikStarElementBridge.java
protected static int convertSides(Element filterElement,
String attrName,
int defaultValue,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, attrName);
if (s.length() == 0) {
return defaultValue;
} else {
int ret = 0;
try {
ret = SVGUtilities.convertSVGInteger(s);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attrName, s});
}
if (ret <3)
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attrName, s});
return ret;
}
}
// in sources/org/apache/batik/extension/svg/BatikRegularPolygonElementBridge.java
protected void buildShape(BridgeContext ctx,
Element e,
ShapeNode shapeNode) {
UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, e);
String s;
// 'cx' attribute - default is 0
s = e.getAttributeNS(null, SVG_CX_ATTRIBUTE);
float cx = 0;
if (s.length() != 0) {
cx = UnitProcessor.svgHorizontalCoordinateToUserSpace
(s, SVG_CX_ATTRIBUTE, uctx);
}
// 'cy' attribute - default is 0
s = e.getAttributeNS(null, SVG_CY_ATTRIBUTE);
float cy = 0;
if (s.length() != 0) {
cy = UnitProcessor.svgVerticalCoordinateToUserSpace
(s, SVG_CY_ATTRIBUTE, uctx);
}
// 'r' attribute - required
s = e.getAttributeNS(null, SVG_R_ATTRIBUTE);
float r;
if (s.length() != 0) {
r = UnitProcessor.svgOtherLengthToUserSpace
(s, SVG_R_ATTRIBUTE, uctx);
} else {
throw new BridgeException(ctx, e, ERR_ATTRIBUTE_MISSING,
new Object[] {SVG_R_ATTRIBUTE, s});
}
// 'sides' attribute - default is 3
int sides = convertSides(e, BATIK_EXT_SIDES_ATTRIBUTE, 3, ctx);
GeneralPath gp = new GeneralPath();
for (int i=0; i<sides; i++) {
double angle = (i+0.5)*(2*Math.PI/sides) - (Math.PI/2);
double x = cx + r*Math.cos(angle);
double y = cy - r*Math.sin(angle);
if (i==0)
gp.moveTo((float)x, (float)y);
else
gp.lineTo((float)x, (float)y);
}
gp.closePath();
shapeNode.setShape(gp);
}
// in sources/org/apache/batik/extension/svg/BatikRegularPolygonElementBridge.java
protected static int convertSides(Element filterElement,
String attrName,
int defaultValue,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, attrName);
if (s.length() == 0) {
return defaultValue;
} else {
int ret = 0;
try {
ret = SVGUtilities.convertSVGInteger(s);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attrName, s});
}
if (ret <3)
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attrName, s});
return ret;
}
}
// in sources/org/apache/batik/extension/svg/BatikHistogramNormalizationElementBridge.java
public Filter createFilter(BridgeContext ctx,
Element filterElement,
Element filteredElement,
GraphicsNode filteredNode,
Filter inputFilter,
Rectangle2D filterRegion,
Map filterMap) {
// 'in' attribute
Filter in = getIn(filterElement,
filteredElement,
filteredNode,
inputFilter,
filterMap,
ctx);
if (in == null) {
return null; // disable the filter
}
// The default region is the union of the input sources
// regions unless 'in' is 'SourceGraphic' in which case the
// default region is the filterChain's region
Filter sourceGraphics = (Filter)filterMap.get(SVG_SOURCE_GRAPHIC_VALUE);
Rectangle2D defaultRegion;
if (in == sourceGraphics) {
defaultRegion = filterRegion;
} else {
defaultRegion = in.getBounds2D();
}
Rectangle2D primitiveRegion
= SVGUtilities.convertFilterPrimitiveRegion(filterElement,
filteredElement,
filteredNode,
defaultRegion,
filterRegion,
ctx);
float trim = 1;
String s = filterElement.getAttributeNS
(null, BATIK_EXT_TRIM_ATTRIBUTE);
if (s.length() != 0) {
try {
trim = SVGUtilities.convertSVGNumber(s);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {BATIK_EXT_TRIM_ATTRIBUTE, s});
}
}
if (trim < 0) trim =0;
else if (trim > 100) trim=100;
Filter filter = in;
filter = new BatikHistogramNormalizationFilter8Bit(filter, trim/100);
filter = new PadRable8Bit(filter, primitiveRegion, PadMode.ZERO_PAD);
// update the filter Map
updateFilterMap(filterElement, filter, filterMap);
// handle the 'color-interpolation-filters' property
handleColorInterpolationFilters(filter, filterElement);
return filter;
}
// in sources/org/apache/batik/extension/svg/BatikHistogramNormalizationElementBridge.java
protected static int convertSides(Element filterElement,
String attrName,
int defaultValue,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, attrName);
if (s.length() == 0) {
return defaultValue;
} else {
int ret = 0;
try {
ret = SVGUtilities.convertSVGInteger(s);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attrName, s});
}
if (ret <3)
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attrName, s});
return ret;
}
}
// in sources/org/apache/batik/swing/svg/JSVGComponent.java
public SVGDocument getBrokenLinkDocument(Element e,
String url,
String message) {
Class cls = JSVGComponent.class;
URL blURL = cls.getResource("resources/BrokenLink.svg");
if (blURL == null)
throw new BridgeException
(bridgeContext, e, ErrorConstants.ERR_URI_IMAGE_BROKEN,
new Object[] { url, message });
DocumentLoader loader = bridgeContext.getDocumentLoader();
SVGDocument doc = null;
try {
doc = (SVGDocument)loader.loadDocument(blURL.toString());
if (doc == null) return doc;
DOMImplementation impl;
impl = SVGDOMImplementation.getDOMImplementation();
doc = (SVGDocument)DOMUtilities.deepCloneDocument(doc, impl);
String title;
Element infoE, titleE, descE;
infoE = doc.getElementById("__More_About");
if (infoE == null) return doc;
titleE = doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
SVGConstants.SVG_TITLE_TAG);
title = Messages.formatMessage(BROKEN_LINK_TITLE, null);
titleE.appendChild(doc.createTextNode(title));
descE = doc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
SVGConstants.SVG_DESC_TAG);
descE.appendChild(doc.createTextNode(message));
infoE.insertBefore(descE, infoE.getFirstChild());
infoE.insertBefore(titleE, descE);
} catch (Exception ex) {
throw new BridgeException
(bridgeContext, e, ex, ErrorConstants.ERR_URI_IMAGE_BROKEN,
new Object[] {url, message });
}
return doc;
}
// in sources/org/apache/batik/bridge/SVGPolylineElementBridge.java
protected void buildShape(BridgeContext ctx,
Element e,
ShapeNode shapeNode) {
SVGOMPolylineElement pe = (SVGOMPolylineElement) e;
try {
SVGOMAnimatedPoints _points = pe.getSVGOMAnimatedPoints();
_points.check();
SVGPointList pl = _points.getAnimatedPoints();
int size = pl.getNumberOfItems();
if (size == 0) {
shapeNode.setShape(DEFAULT_SHAPE);
} else {
AWTPolylineProducer app = new AWTPolylineProducer();
app.setWindingRule(CSSUtilities.convertFillRule(e));
app.startPoints();
for (int i = 0; i < size; i++) {
SVGPoint p = pl.getItem(i);
app.point(p.getX(), p.getY());
}
app.endPoints();
shapeNode.setShape(app.getShape());
}
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// in sources/org/apache/batik/bridge/SVGPathElementBridge.java
protected void buildShape(BridgeContext ctx,
Element e,
ShapeNode shapeNode) {
SVGOMPathElement pe = (SVGOMPathElement) e;
AWTPathProducer app = new AWTPathProducer();
try {
// 'd' attribute - required
SVGOMAnimatedPathData _d = pe.getAnimatedPathData();
_d.check();
SVGPathSegList p = _d.getAnimatedPathSegList();
app.setWindingRule(CSSUtilities.convertFillRule(e));
SVGAnimatedPathDataSupport.handlePathSegList(p, app);
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
} finally {
shapeNode.setShape(app.getShape());
}
}
// in sources/org/apache/batik/bridge/SVGFeComponentTransferElementBridge.java
protected static float [] convertTableValues(Element e, BridgeContext ctx) {
String s = e.getAttributeNS(null, SVG_TABLE_VALUES_ATTRIBUTE);
if (s.length() == 0) {
return null;
}
StringTokenizer tokens = new StringTokenizer(s, " ,");
float [] v = new float[tokens.countTokens()];
try {
for (int i = 0; tokens.hasMoreTokens(); ++i) {
v[i] = SVGUtilities.convertSVGNumber(tokens.nextToken());
}
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, e, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_TABLE_VALUES_ATTRIBUTE, s});
}
return v;
}
// in sources/org/apache/batik/bridge/SVGFeComponentTransferElementBridge.java
protected static int convertType(Element e, BridgeContext ctx) {
String s = e.getAttributeNS(null, SVG_TYPE_ATTRIBUTE);
if (s.length() == 0) {
throw new BridgeException(ctx, e, ERR_ATTRIBUTE_MISSING,
new Object[] {SVG_TYPE_ATTRIBUTE});
}
if (SVG_DISCRETE_VALUE.equals(s)) {
return ComponentTransferFunction.DISCRETE;
}
if (SVG_IDENTITY_VALUE.equals(s)) {
return ComponentTransferFunction.IDENTITY;
}
if (SVG_GAMMA_VALUE.equals(s)) {
return ComponentTransferFunction.GAMMA;
}
if (SVG_LINEAR_VALUE.equals(s)) {
return ComponentTransferFunction.LINEAR;
}
if (SVG_TABLE_VALUE.equals(s)) {
return ComponentTransferFunction.TABLE;
}
throw new BridgeException(ctx, e, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_TYPE_ATTRIBUTE, s});
}
// in sources/org/apache/batik/bridge/svg12/SVGMultiImageElementBridge.java
protected static
Rectangle2D getImageBounds(BridgeContext ctx, Element element) {
UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, element);
// 'x' attribute - default is 0
String s = element.getAttributeNS(null, SVG_X_ATTRIBUTE);
float x = 0;
if (s.length() != 0) {
x = UnitProcessor.svgHorizontalCoordinateToUserSpace
(s, SVG_X_ATTRIBUTE, uctx);
}
// 'y' attribute - default is 0
s = element.getAttributeNS(null, SVG_Y_ATTRIBUTE);
float y = 0;
if (s.length() != 0) {
y = UnitProcessor.svgVerticalCoordinateToUserSpace
(s, SVG_Y_ATTRIBUTE, uctx);
}
// 'width' attribute - required
s = element.getAttributeNS(null, SVG_WIDTH_ATTRIBUTE);
float w;
if (s.length() == 0) {
throw new BridgeException(ctx, element, ERR_ATTRIBUTE_MISSING,
new Object[] {SVG_WIDTH_ATTRIBUTE});
} else {
w = UnitProcessor.svgHorizontalLengthToUserSpace
(s, SVG_WIDTH_ATTRIBUTE, uctx);
}
// 'height' attribute - required
s = element.getAttributeNS(null, SVG_HEIGHT_ATTRIBUTE);
float h;
if (s.length() == 0) {
throw new BridgeException(ctx, element, ERR_ATTRIBUTE_MISSING,
new Object[] {SVG_HEIGHT_ATTRIBUTE});
} else {
h = UnitProcessor.svgVerticalLengthToUserSpace
(s, SVG_HEIGHT_ATTRIBUTE, uctx);
}
return new Rectangle2D.Float(x, y, w, h);
}
// in sources/org/apache/batik/bridge/svg12/SVGMultiImageElementBridge.java
protected void addRefInfo(Element e, Collection elems,
Collection minDim, Collection maxDim,
Rectangle2D bounds) {
String uriStr = XLinkSupport.getXLinkHref(e);
if (uriStr.length() == 0) {
throw new BridgeException(ctx, e, ERR_ATTRIBUTE_MISSING,
new Object[] {"xlink:href"});
}
String baseURI = AbstractNode.getBaseURI(e);
ParsedURL purl;
if (baseURI == null) purl = new ParsedURL(uriStr);
else purl = new ParsedURL(baseURI, uriStr);
Document doc = e.getOwnerDocument();
Element imgElem = doc.createElementNS(SVG_NAMESPACE_URI,
SVG_IMAGE_TAG);
imgElem.setAttributeNS(XLINK_NAMESPACE_URI,
XLINK_HREF_ATTRIBUTE, purl.toString());
// move the attributes from <subImageRef> to the <image> element
NamedNodeMap attrs = e.getAttributes();
int len = attrs.getLength();
for (int i = 0; i < len; i++) {
Attr attr = (Attr)attrs.item(i);
imgElem.setAttributeNS(attr.getNamespaceURI(),
attr.getName(),
attr.getValue());
}
String s;
s = e.getAttribute("x");
if (s.length() == 0) imgElem.setAttribute("x", "0");
s = e.getAttribute("y");
if (s.length() == 0) imgElem.setAttribute("y", "0");
s = e.getAttribute("width");
if (s.length() == 0) imgElem.setAttribute("width", "100%");
s = e.getAttribute("height");
if (s.length() == 0) imgElem.setAttribute("height", "100%");
e.appendChild(imgElem);
elems.add(imgElem);
minDim.add(getElementMinPixel(e, bounds));
maxDim.add(getElementMaxPixel(e, bounds));
}
// in sources/org/apache/batik/bridge/svg12/SVGSolidColorElementBridge.java
protected static float extractOpacity(Element paintElement,
float opacity,
BridgeContext ctx) {
Map refs = new HashMap();
CSSEngine eng = CSSUtilities.getCSSEngine(paintElement);
int pidx = eng.getPropertyIndex
(SVG12CSSConstants.CSS_SOLID_OPACITY_PROPERTY);
for (;;) {
Value opacityVal =
CSSUtilities.getComputedStyle(paintElement, pidx);
// Was solid-opacity explicity set on this element?
StyleMap sm =
((CSSStylableElement)paintElement).getComputedStyleMap(null);
if (!sm.isNullCascaded(pidx)) {
// It was explicit...
float attr = PaintServer.convertOpacity(opacityVal);
return (opacity * attr);
}
String uri = XLinkSupport.getXLinkHref(paintElement);
if (uri.length() == 0) {
return opacity; // no xlink:href found, exit
}
SVGOMDocument doc = (SVGOMDocument)paintElement.getOwnerDocument();
ParsedURL purl = new ParsedURL(doc.getURL(), uri);
// check if there is circular dependencies
if (refs.containsKey(purl)) {
throw new BridgeException
(ctx, paintElement,
ErrorConstants.ERR_XLINK_HREF_CIRCULAR_DEPENDENCIES,
new Object[] {uri});
}
refs.put(purl, purl);
paintElement = ctx.getReferencedElement(paintElement, uri);
}
}
// in sources/org/apache/batik/bridge/svg12/SVGSolidColorElementBridge.java
protected static Color extractColor(Element paintElement,
float opacity,
BridgeContext ctx) {
Map refs = new HashMap();
CSSEngine eng = CSSUtilities.getCSSEngine(paintElement);
int pidx = eng.getPropertyIndex
(SVG12CSSConstants.CSS_SOLID_COLOR_PROPERTY);
for (;;) {
Value colorDef =
CSSUtilities.getComputedStyle(paintElement, pidx);
// Was solid-color explicity set on this element?
StyleMap sm =
((CSSStylableElement)paintElement).getComputedStyleMap(null);
if (!sm.isNullCascaded(pidx)) {
// It was explicit...
if (colorDef.getCssValueType() ==
CSSValue.CSS_PRIMITIVE_VALUE) {
return PaintServer.convertColor(colorDef, opacity);
} else {
return PaintServer.convertRGBICCColor
(paintElement, colorDef.item(0),
(ICCColor)colorDef.item(1),
opacity, ctx);
}
}
String uri = XLinkSupport.getXLinkHref(paintElement);
if (uri.length() == 0) {
// no xlink:href found, exit
return new Color(0, 0, 0, opacity);
}
SVGOMDocument doc = (SVGOMDocument)paintElement.getOwnerDocument();
ParsedURL purl = new ParsedURL(doc.getURL(), uri);
// check if there is circular dependencies
if (refs.containsKey(purl)) {
throw new BridgeException
(ctx, paintElement,
ErrorConstants.ERR_XLINK_HREF_CIRCULAR_DEPENDENCIES,
new Object[] {uri});
}
refs.put(purl, purl);
paintElement = ctx.getReferencedElement(paintElement, uri);
}
}
// in sources/org/apache/batik/bridge/svg12/DefaultXBLManager.java
protected void addDefinitionRef(Element defRef) {
String ref = defRef.getAttributeNS(null, XBL_REF_ATTRIBUTE);
Element e = ctx.getReferencedElement(defRef, ref);
if (!XBL_NAMESPACE_URI.equals(e.getNamespaceURI())
|| !XBL_DEFINITION_TAG.equals(e.getLocalName())) {
throw new BridgeException
(ctx, defRef, ErrorConstants.ERR_URI_BAD_TARGET,
new Object[] { ref });
}
ImportRecord ir = new ImportRecord(defRef, e);
imports.put(defRef, ir);
NodeEventTarget et = (NodeEventTarget) defRef;
et.addEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMAttrModified",
refAttrListener, false, null);
XBLOMDefinitionElement d = (XBLOMDefinitionElement) defRef;
String ns = d.getElementNamespaceURI();
String ln = d.getElementLocalName();
addDefinition(ns, ln, (XBLOMDefinitionElement) e, defRef);
}
// in sources/org/apache/batik/bridge/svg12/DefaultXBLManager.java
protected void addImport(Element imp) {
String bindings = imp.getAttributeNS(null, XBL_BINDINGS_ATTRIBUTE);
Node n = ctx.getReferencedNode(imp, bindings);
if (n.getNodeType() == Node.ELEMENT_NODE
&& !(XBL_NAMESPACE_URI.equals(n.getNamespaceURI())
&& XBL_XBL_TAG.equals(n.getLocalName()))) {
throw new BridgeException
(ctx, imp, ErrorConstants.ERR_URI_BAD_TARGET,
new Object[] { n });
}
ImportRecord ir = new ImportRecord(imp, n);
imports.put(imp, ir);
NodeEventTarget et = (NodeEventTarget) imp;
et.addEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMAttrModified",
importAttrListener, false, null);
et = (NodeEventTarget) n;
et.addEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMNodeInserted",
ir.importInsertedListener, false, null);
et.addEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMNodeRemoved",
ir.importRemovedListener, false, null);
et.addEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMSubtreeModified",
ir.importSubtreeListener, false, null);
addImportedDefinitions(imp, n);
}
// in sources/org/apache/batik/bridge/SVGAnimationElementBridge.java
protected void initializeAnimation() {
// Determine the target element.
String uri = XLinkSupport.getXLinkHref(element);
Node t;
if (uri.length() == 0) {
t = element.getParentNode();
} else {
t = ctx.getReferencedElement(element, uri);
if (t.getOwnerDocument() != element.getOwnerDocument()) {
throw new BridgeException
(ctx, element, ErrorConstants.ERR_URI_BAD_TARGET,
new Object[] { uri });
}
}
animationTarget = null;
if (t instanceof SVGOMElement) {
targetElement = (SVGOMElement) t;
animationTarget = targetElement;
}
if (animationTarget == null) {
throw new BridgeException
(ctx, element, ErrorConstants.ERR_URI_BAD_TARGET,
new Object[] { uri });
}
// Get the attribute/property name.
String an = element.getAttributeNS(null, SVG_ATTRIBUTE_NAME_ATTRIBUTE);
int ci = an.indexOf(':');
if (ci == -1) {
if (element.hasProperty(an)) {
animationType = AnimationEngine.ANIM_TYPE_CSS;
attributeLocalName = an;
} else {
animationType = AnimationEngine.ANIM_TYPE_XML;
attributeLocalName = an;
}
} else {
animationType = AnimationEngine.ANIM_TYPE_XML;
String prefix = an.substring(0, ci);
attributeNamespaceURI = element.lookupNamespaceURI(prefix);
attributeLocalName = an.substring(ci + 1);
}
if (animationType == AnimationEngine.ANIM_TYPE_CSS
&& !targetElement.isPropertyAnimatable(attributeLocalName)
|| animationType == AnimationEngine.ANIM_TYPE_XML
&& !targetElement.isAttributeAnimatable(attributeNamespaceURI,
attributeLocalName)) {
throw new BridgeException
(ctx, element, "attribute.not.animatable",
new Object[] { targetElement.getNodeName(), an });
}
// Check that the attribute/property is animatable with this
// animation element.
int type;
if (animationType == AnimationEngine.ANIM_TYPE_CSS) {
type = targetElement.getPropertyType(attributeLocalName);
} else {
type = targetElement.getAttributeType(attributeNamespaceURI,
attributeLocalName);
}
if (!canAnimateType(type)) {
throw new BridgeException
(ctx, element, "type.not.animatable",
new Object[] { targetElement.getNodeName(), an,
element.getNodeName() });
}
// Add the animation.
timedElement = createTimedElement();
animation = createAnimation(animationTarget);
eng.addAnimation(animationTarget, animationType, attributeNamespaceURI,
attributeLocalName, animation);
}
// in sources/org/apache/batik/bridge/SVGAnimationElementBridge.java
protected AnimatableValue parseAnimatableValue(String an) {
if (!element.hasAttributeNS(null, an)) {
return null;
}
String s = element.getAttributeNS(null, an);
AnimatableValue val = eng.parseAnimatableValue
(element, animationTarget, attributeNamespaceURI,
attributeLocalName, animationType == AnimationEngine.ANIM_TYPE_CSS,
s);
if (!checkValueType(val)) {
throw new BridgeException
(ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { an, s });
}
return val;
}
// in sources/org/apache/batik/bridge/SVGSVGElementBridge.java
public void handleAnimatedAttributeChanged
(AnimatedLiveAttributeValue alav) {
try {
boolean rebuild = false;
if (alav.getNamespaceURI() == null) {
String ln = alav.getLocalName();
if (ln.equals(SVG_WIDTH_ATTRIBUTE)
|| ln.equals(SVG_HEIGHT_ATTRIBUTE)) {
rebuild = true;
} else if (ln.equals(SVG_X_ATTRIBUTE)
|| ln.equals(SVG_Y_ATTRIBUTE)) {
SVGDocument doc = (SVGDocument)e.getOwnerDocument();
SVGOMSVGElement se = (SVGOMSVGElement) e;
// X & Y are ignored on outermost SVG.
boolean isOutermost = doc.getRootElement() == e;
if (!isOutermost) {
// 'x' attribute - default is 0
AbstractSVGAnimatedLength _x =
(AbstractSVGAnimatedLength) se.getX();
float x = _x.getCheckedValue();
// 'y' attribute - default is 0
AbstractSVGAnimatedLength _y =
(AbstractSVGAnimatedLength) se.getY();
float y = _y.getCheckedValue();
AffineTransform positionTransform =
AffineTransform.getTranslateInstance(x, y);
CanvasGraphicsNode cgn;
cgn = (CanvasGraphicsNode)node;
cgn.setPositionTransform(positionTransform);
return;
}
} else if (ln.equals(SVG_VIEW_BOX_ATTRIBUTE)
|| ln.equals(SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE)) {
SVGDocument doc = (SVGDocument)e.getOwnerDocument();
SVGOMSVGElement se = (SVGOMSVGElement) e;
boolean isOutermost = doc.getRootElement() == e;
// X & Y are ignored on outermost SVG.
float x = 0;
float y = 0;
if (!isOutermost) {
// 'x' attribute - default is 0
AbstractSVGAnimatedLength _x =
(AbstractSVGAnimatedLength) se.getX();
x = _x.getCheckedValue();
// 'y' attribute - default is 0
AbstractSVGAnimatedLength _y =
(AbstractSVGAnimatedLength) se.getY();
y = _y.getCheckedValue();
}
// 'width' attribute - default is 100%
AbstractSVGAnimatedLength _width =
(AbstractSVGAnimatedLength) se.getWidth();
float w = _width.getCheckedValue();
// 'height' attribute - default is 100%
AbstractSVGAnimatedLength _height =
(AbstractSVGAnimatedLength) se.getHeight();
float h = _height.getCheckedValue();
CanvasGraphicsNode cgn;
cgn = (CanvasGraphicsNode)node;
// 'viewBox' and "preserveAspectRatio' attributes
SVGOMAnimatedRect vb = (SVGOMAnimatedRect) se.getViewBox();
SVGAnimatedPreserveAspectRatio par = se.getPreserveAspectRatio();
AffineTransform newVT = ViewBox.getPreserveAspectRatioTransform
(e, vb, par, w, h, ctx);
AffineTransform oldVT = cgn.getViewingTransform();
if ((newVT.getScaleX() != oldVT.getScaleX()) ||
(newVT.getScaleY() != oldVT.getScaleY()) ||
(newVT.getShearX() != oldVT.getShearX()) ||
(newVT.getShearY() != oldVT.getShearY()))
rebuild = true;
else {
// Only differs in translate.
cgn.setViewingTransform(newVT);
// 'overflow' and 'clip'
Shape clip = null;
if (CSSUtilities.convertOverflow(e)) { // overflow:hidden
float [] offsets = CSSUtilities.convertClip(e);
if (offsets == null) { // clip:auto
clip = new Rectangle2D.Float(x, y, w, h);
} else { // clip:rect(<x> <y> <w> <h>)
// offsets[0] = top
// offsets[1] = right
// offsets[2] = bottom
// offsets[3] = left
clip = new Rectangle2D.Float(x+offsets[3],
y+offsets[0],
w-offsets[1]-offsets[3],
h-offsets[2]-offsets[0]);
}
}
if (clip != null) {
try {
AffineTransform at;
at = cgn.getPositionTransform();
if (at == null) at = new AffineTransform();
else at = new AffineTransform(at);
at.concatenate(newVT);
at = at.createInverse(); // clip in user space
clip = at.createTransformedShape(clip);
Filter filter = cgn.getGraphicsNodeRable(true);
cgn.setClip(new ClipRable8Bit(filter, clip));
} catch (NoninvertibleTransformException ex) {}
}
}
}
if (rebuild) {
CompositeGraphicsNode gn = node.getParent();
gn.remove(node);
disposeTree(e, false);
handleElementAdded(gn, e.getParentNode(), e);
return;
}
}
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
super.handleAnimatedAttributeChanged(alav);
}
// in sources/org/apache/batik/bridge/UserAgentAdapter.java
public SVGDocument getBrokenLinkDocument(Element e,
String url,
String message) {
throw new BridgeException(ctx, e, ErrorConstants.ERR_URI_IMAGE_BROKEN,
new Object[] {url, message });
}
// in sources/org/apache/batik/bridge/SVGFeBlendElementBridge.java
protected static CompositeRule convertMode(Element filterElement,
BridgeContext ctx) {
String rule = filterElement.getAttributeNS(null, SVG_MODE_ATTRIBUTE);
if (rule.length() == 0) {
return CompositeRule.OVER;
}
if (SVG_NORMAL_VALUE.equals(rule)) {
return CompositeRule.OVER;
}
if (SVG_MULTIPLY_VALUE.equals(rule)) {
return CompositeRule.MULTIPLY;
}
if (SVG_SCREEN_VALUE.equals(rule)) {
return CompositeRule.SCREEN;
}
if (SVG_DARKEN_VALUE.equals(rule)) {
return CompositeRule.DARKEN;
}
if (SVG_LIGHTEN_VALUE.equals(rule)) {
return CompositeRule.LIGHTEN;
}
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_MODE_ATTRIBUTE, rule});
}
// in sources/org/apache/batik/bridge/SVGFontFaceElementBridge.java
public SVGFontFace createFontFace(BridgeContext ctx,
Element fontFaceElement) {
// get all the font-face attributes
String familyNames = fontFaceElement.getAttributeNS
(null, SVG_FONT_FAMILY_ATTRIBUTE);
// units per em
String unitsPerEmStr = fontFaceElement.getAttributeNS
(null, SVG_UNITS_PER_EM_ATTRIBUTE);
if (unitsPerEmStr.length() == 0) {
unitsPerEmStr = SVG_FONT_FACE_UNITS_PER_EM_DEFAULT_VALUE;
}
float unitsPerEm;
try {
unitsPerEm = SVGUtilities.convertSVGNumber(unitsPerEmStr);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_UNITS_PER_EM_ATTRIBUTE, unitsPerEmStr});
}
// font-weight
String fontWeight = fontFaceElement.getAttributeNS
(null, SVG_FONT_WEIGHT_ATTRIBUTE);
if (fontWeight.length() == 0) {
fontWeight = SVG_FONT_FACE_FONT_WEIGHT_DEFAULT_VALUE;
}
// font-style
String fontStyle = fontFaceElement.getAttributeNS
(null, SVG_FONT_STYLE_ATTRIBUTE);
if (fontStyle.length() == 0) {
fontStyle = SVG_FONT_FACE_FONT_STYLE_DEFAULT_VALUE;
}
// font-variant
String fontVariant = fontFaceElement.getAttributeNS
(null, SVG_FONT_VARIANT_ATTRIBUTE);
if (fontVariant.length() == 0) {
fontVariant = SVG_FONT_FACE_FONT_VARIANT_DEFAULT_VALUE;
}
// font-stretch
String fontStretch = fontFaceElement.getAttributeNS
(null, SVG_FONT_STRETCH_ATTRIBUTE);
if (fontStretch.length() == 0) {
fontStretch = SVG_FONT_FACE_FONT_STRETCH_DEFAULT_VALUE;
}
// slopeStr
String slopeStr = fontFaceElement.getAttributeNS
(null, SVG_SLOPE_ATTRIBUTE);
if (slopeStr.length() == 0) {
slopeStr = SVG_FONT_FACE_SLOPE_DEFAULT_VALUE;
}
float slope;
try {
slope = SVGUtilities.convertSVGNumber(slopeStr);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE, slopeStr});
}
// panose-1
String panose1 = fontFaceElement.getAttributeNS
(null, SVG_PANOSE_1_ATTRIBUTE);
if (panose1.length() == 0) {
panose1 = SVG_FONT_FACE_PANOSE_1_DEFAULT_VALUE;
}
// ascent
String ascentStr = fontFaceElement.getAttributeNS
(null, SVG_ASCENT_ATTRIBUTE);
if (ascentStr.length() == 0) {
// set it to be unitsPerEm * .8
ascentStr = String.valueOf( unitsPerEm * 0.8);
}
float ascent;
try {
ascent = SVGUtilities.convertSVGNumber(ascentStr);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE, ascentStr});
}
// descent
String descentStr = fontFaceElement.getAttributeNS
(null, SVG_DESCENT_ATTRIBUTE);
if (descentStr.length() == 0) {
// set it to be unitsPerEm *.2.
descentStr = String.valueOf(unitsPerEm*0.2);
}
float descent;
try {
descent = SVGUtilities.convertSVGNumber(descentStr);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE, descentStr });
}
// underline-position
String underlinePosStr = fontFaceElement.getAttributeNS
(null, SVG_UNDERLINE_POSITION_ATTRIBUTE);
if (underlinePosStr.length() == 0) {
underlinePosStr = String.valueOf(-3*unitsPerEm/40);
}
float underlinePos;
try {
underlinePos = SVGUtilities.convertSVGNumber(underlinePosStr);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE,
underlinePosStr});
}
// underline-thickness
String underlineThicknessStr = fontFaceElement.getAttributeNS
(null, SVG_UNDERLINE_THICKNESS_ATTRIBUTE);
if (underlineThicknessStr.length() == 0) {
underlineThicknessStr = String.valueOf(unitsPerEm/20);
}
float underlineThickness;
try {
underlineThickness =
SVGUtilities.convertSVGNumber(underlineThicknessStr);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE,
underlineThicknessStr});
}
// strikethrough-position
String strikethroughPosStr = fontFaceElement.getAttributeNS
(null, SVG_STRIKETHROUGH_POSITION_ATTRIBUTE);
if (strikethroughPosStr.length() == 0) {
strikethroughPosStr = String.valueOf(3*ascent/8);
}
float strikethroughPos;
try {
strikethroughPos =
SVGUtilities.convertSVGNumber(strikethroughPosStr);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE,
strikethroughPosStr});
}
// strikethrough-thickness
String strikethroughThicknessStr = fontFaceElement.getAttributeNS
(null, SVG_STRIKETHROUGH_THICKNESS_ATTRIBUTE);
if (strikethroughThicknessStr.length() == 0) {
strikethroughThicknessStr = String.valueOf(unitsPerEm/20);
}
float strikethroughThickness;
try {
strikethroughThickness =
SVGUtilities.convertSVGNumber(strikethroughThicknessStr);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE,
strikethroughThicknessStr});
}
// overline-position
String overlinePosStr = fontFaceElement.getAttributeNS
(null, SVG_OVERLINE_POSITION_ATTRIBUTE);
if (overlinePosStr.length() == 0) {
overlinePosStr = String.valueOf(ascent);
}
float overlinePos;
try {
overlinePos = SVGUtilities.convertSVGNumber(overlinePosStr);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE,
overlinePosStr});
}
// overline-thickness
String overlineThicknessStr = fontFaceElement.getAttributeNS
(null, SVG_OVERLINE_THICKNESS_ATTRIBUTE);
if (overlineThicknessStr.length() == 0) {
overlineThicknessStr = String.valueOf(unitsPerEm/20);
}
float overlineThickness;
try {
overlineThickness =
SVGUtilities.convertSVGNumber(overlineThicknessStr);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE,
overlineThicknessStr});
}
List srcs = null;
Element fontElt = SVGUtilities.getParentElement(fontFaceElement);
if (!fontElt.getNamespaceURI().equals(SVG_NAMESPACE_URI) ||
!fontElt.getLocalName().equals(SVG_FONT_TAG)) {
srcs = getFontFaceSrcs(fontFaceElement);
}
// TODO: get the rest of the attributes
return new SVGFontFace(fontFaceElement, srcs,
familyNames, unitsPerEm, fontWeight, fontStyle,
fontVariant, fontStretch, slope, panose1,
ascent, descent, strikethroughPos,
strikethroughThickness, underlinePos,
underlineThickness, overlinePos,
overlineThickness);
}
// in sources/org/apache/batik/bridge/ViewBox.java
public static AffineTransform getViewTransform(String ref,
Element e,
float w,
float h,
BridgeContext ctx) {
// no reference has been specified, no extra viewBox is defined
if (ref == null || ref.length() == 0) {
return getPreserveAspectRatioTransform(e, w, h, ctx);
}
ViewHandler vh = new ViewHandler();
FragmentIdentifierParser p = new FragmentIdentifierParser();
p.setFragmentIdentifierHandler(vh);
p.parse(ref);
// Determine the 'view' element that ref refers to.
Element viewElement = e;
if (vh.hasId) {
Document document = e.getOwnerDocument();
viewElement = document.getElementById(vh.id);
}
if (viewElement == null) {
throw new BridgeException(ctx, e, ERR_URI_MALFORMED,
new Object[] {ref});
}
if (!(viewElement.getNamespaceURI().equals(SVG_NAMESPACE_URI)
&& viewElement.getLocalName().equals(SVG_VIEW_TAG))) {
viewElement = null;
}
Element ancestorSVG = getClosestAncestorSVGElement(e);
// 'viewBox'
float[] vb;
if (vh.hasViewBox) {
vb = vh.viewBox;
} else {
Element elt;
if (DOMUtilities.isAttributeSpecifiedNS
(viewElement, null, SVG_VIEW_BOX_ATTRIBUTE)) {
elt = viewElement;
} else {
elt = ancestorSVG;
}
String viewBoxStr = elt.getAttributeNS(null, SVG_VIEW_BOX_ATTRIBUTE);
vb = parseViewBoxAttribute(elt, viewBoxStr, ctx);
}
// 'preserveAspectRatio'
short align;
boolean meet;
if (vh.hasPreserveAspectRatio) {
align = vh.align;
meet = vh.meet;
} else {
Element elt;
if (DOMUtilities.isAttributeSpecifiedNS
(viewElement, null, SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE)) {
elt = viewElement;
} else {
elt = ancestorSVG;
}
String aspectRatio =
elt.getAttributeNS(null, SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE);
PreserveAspectRatioParser pp = new PreserveAspectRatioParser();
ViewHandler ph = new ViewHandler();
pp.setPreserveAspectRatioHandler(ph);
try {
pp.parse(aspectRatio);
} catch (ParseException pEx) {
throw new BridgeException
(ctx, elt, pEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE,
aspectRatio, pEx });
}
align = ph.align;
meet = ph.meet;
}
// the additional transform that may appear on the URI
AffineTransform transform
= getPreserveAspectRatioTransform(vb, align, meet, w, h);
if (vh.hasTransform) {
transform.concatenate(vh.getAffineTransform());
}
return transform;
}
// in sources/org/apache/batik/bridge/ViewBox.java
public static
AffineTransform getPreserveAspectRatioTransform(Element e,
String viewBox,
String aspectRatio,
float w,
float h,
BridgeContext ctx) {
// no viewBox specified
if (viewBox.length() == 0) {
return new AffineTransform();
}
float[] vb = parseViewBoxAttribute(e, viewBox, ctx);
// 'preserveAspectRatio' attribute
PreserveAspectRatioParser p = new PreserveAspectRatioParser();
ViewHandler ph = new ViewHandler();
p.setPreserveAspectRatioHandler(ph);
try {
p.parse(aspectRatio);
} catch (ParseException pEx ) {
throw new BridgeException
(ctx, e, pEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE,
aspectRatio, pEx });
}
return getPreserveAspectRatioTransform(vb, ph.align, ph.meet, w, h);
}
// in sources/org/apache/batik/bridge/ViewBox.java
public static
AffineTransform getPreserveAspectRatioTransform(Element e,
float[] vb,
float w,
float h,
BridgeContext ctx) {
String aspectRatio
= e.getAttributeNS(null, SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE);
// 'preserveAspectRatio' attribute
PreserveAspectRatioParser p = new PreserveAspectRatioParser();
ViewHandler ph = new ViewHandler();
p.setPreserveAspectRatioHandler(ph);
try {
p.parse(aspectRatio);
} catch (ParseException pEx ) {
throw new BridgeException
(ctx, e, pEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE,
aspectRatio, pEx });
}
return getPreserveAspectRatioTransform(vb, ph.align, ph.meet, w, h);
}
// in sources/org/apache/batik/bridge/ViewBox.java
public static AffineTransform getPreserveAspectRatioTransform
(Element e, float[] vb, float w, float h,
SVGAnimatedPreserveAspectRatio aPAR, BridgeContext ctx) {
// 'preserveAspectRatio' attribute
try {
SVGPreserveAspectRatio pAR = aPAR.getAnimVal();
short align = pAR.getAlign();
boolean meet = pAR.getMeetOrSlice() ==
SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET;
return getPreserveAspectRatioTransform(vb, align, meet, w, h);
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// in sources/org/apache/batik/bridge/ViewBox.java
public static float[] parseViewBoxAttribute(Element e, String value,
BridgeContext ctx) {
if (value.length() == 0) {
return null;
}
int i = 0;
float[] vb = new float[4];
StringTokenizer st = new StringTokenizer(value, " ,");
try {
while (i < 4 && st.hasMoreTokens()) {
vb[i] = Float.parseFloat(st.nextToken());
i++;
}
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, e, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_VIEW_BOX_ATTRIBUTE, value, nfEx });
}
if (i != 4) {
throw new BridgeException
(ctx, e, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_VIEW_BOX_ATTRIBUTE, value});
}
// A negative value for <width> or <height> is an error
if (vb[2] < 0 || vb[3] < 0) {
throw new BridgeException
(ctx, e, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_VIEW_BOX_ATTRIBUTE, value});
}
// A value of zero for width or height disables rendering of the element
if (vb[2] == 0 || vb[3] == 0) {
return null; // <!> FIXME : must disable !
}
return vb;
}
// in sources/org/apache/batik/bridge/AbstractSVGLightingElementBridge.java
protected static double[] convertKernelUnitLength(Element filterElement,
BridgeContext ctx) {
String s = filterElement.getAttributeNS
(null, SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE);
if (s.length() == 0) {
return null;
}
double [] units = new double[2];
StringTokenizer tokens = new StringTokenizer(s, " ,");
try {
units[0] = SVGUtilities.convertSVGNumber(tokens.nextToken());
if (tokens.hasMoreTokens()) {
units[1] = SVGUtilities.convertSVGNumber(tokens.nextToken());
} else {
units[1] = units[0];
}
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE, s});
}
if (tokens.hasMoreTokens() || units[0] <= 0 || units[1] <= 0) {
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE, s});
}
return units;
}
// in sources/org/apache/batik/bridge/AbstractSVGGradientElementBridge.java
protected static MultipleGradientPaint.CycleMethodEnum convertSpreadMethod
(Element paintElement, String s, BridgeContext ctx) {
if (SVG_REPEAT_VALUE.equals(s)) {
return MultipleGradientPaint.REPEAT;
}
if (SVG_REFLECT_VALUE.equals(s)) {
return MultipleGradientPaint.REFLECT;
}
if (SVG_PAD_VALUE.equals(s)) {
return MultipleGradientPaint.NO_CYCLE;
}
throw new BridgeException
(ctx, paintElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_SPREAD_METHOD_ATTRIBUTE, s});
}
// in sources/org/apache/batik/bridge/AbstractSVGGradientElementBridge.java
protected static List extractStop(Element paintElement,
float opacity,
BridgeContext ctx) {
List refs = new LinkedList();
for (;;) {
List stops = extractLocalStop(paintElement, opacity, ctx);
if (stops != null) {
return stops; // stop elements found, exit
}
String uri = XLinkSupport.getXLinkHref(paintElement);
if (uri.length() == 0) {
return null; // no xlink:href found, exit
}
// check if there is circular dependencies
String baseURI = ((AbstractNode) paintElement).getBaseURI();
ParsedURL purl = new ParsedURL(baseURI, uri);
if (contains(refs, purl)) {
throw new BridgeException(ctx, paintElement,
ERR_XLINK_HREF_CIRCULAR_DEPENDENCIES,
new Object[] {uri});
}
refs.add(purl);
paintElement = ctx.getReferencedElement(paintElement, uri);
}
}
// in sources/org/apache/batik/bridge/AbstractSVGGradientElementBridge.java
public Stop createStop(BridgeContext ctx,
Element gradientElement,
Element stopElement,
float opacity) {
String s = stopElement.getAttributeNS(null, SVG_OFFSET_ATTRIBUTE);
if (s.length() == 0) {
throw new BridgeException
(ctx, stopElement, ERR_ATTRIBUTE_MISSING,
new Object[] {SVG_OFFSET_ATTRIBUTE});
}
float offset;
try {
offset = SVGUtilities.convertRatio(s);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, stopElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_OFFSET_ATTRIBUTE, s, nfEx });
}
Color color
= CSSUtilities.convertStopColor(stopElement, opacity, ctx);
return new Stop(color, offset);
}
// in sources/org/apache/batik/bridge/SVGFeColorMatrixElementBridge.java
protected static float[][] convertValuesToMatrix(Element filterElement,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, SVG_VALUES_ATTRIBUTE);
float [][] matrix = new float[4][5];
if (s.length() == 0) {
matrix[0][0] = 1;
matrix[1][1] = 1;
matrix[2][2] = 1;
matrix[3][3] = 1;
return matrix;
}
StringTokenizer tokens = new StringTokenizer(s, " ,");
int n = 0;
try {
while (n < 20 && tokens.hasMoreTokens()) {
matrix[n/5][n%5]
= SVGUtilities.convertSVGNumber(tokens.nextToken());
n++;
}
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_VALUES_ATTRIBUTE, s, nfEx });
}
if (n != 20 || tokens.hasMoreTokens()) {
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_VALUES_ATTRIBUTE, s});
}
for (int i = 0; i < 4; ++i) {
matrix[i][4] *= 255;
}
return matrix;
}
// in sources/org/apache/batik/bridge/SVGFeColorMatrixElementBridge.java
protected static float convertValuesToSaturate(Element filterElement,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, SVG_VALUES_ATTRIBUTE);
if (s.length() == 0)
return 1; // default is 1
try {
return SVGUtilities.convertSVGNumber(s);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_VALUES_ATTRIBUTE, s});
}
}
// in sources/org/apache/batik/bridge/SVGFeColorMatrixElementBridge.java
protected static float convertValuesToHueRotate(Element filterElement,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, SVG_VALUES_ATTRIBUTE);
if (s.length() == 0)
return 0; // default is 0
try {
return (float) Math.toRadians( SVGUtilities.convertSVGNumber(s) );
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_VALUES_ATTRIBUTE, s});
}
}
// in sources/org/apache/batik/bridge/SVGFeColorMatrixElementBridge.java
protected static int convertType(Element filterElement, BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, SVG_TYPE_ATTRIBUTE);
if (s.length() == 0) {
return ColorMatrixRable.TYPE_MATRIX;
}
if (SVG_HUE_ROTATE_VALUE.equals(s)) {
return ColorMatrixRable.TYPE_HUE_ROTATE;
}
if (SVG_LUMINANCE_TO_ALPHA_VALUE.equals(s)) {
return ColorMatrixRable.TYPE_LUMINANCE_TO_ALPHA;
}
if (SVG_MATRIX_VALUE.equals(s)) {
return ColorMatrixRable.TYPE_MATRIX;
}
if (SVG_SATURATE_VALUE.equals(s)) {
return ColorMatrixRable.TYPE_SATURATE;
}
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_TYPE_ATTRIBUTE, s});
}
// in sources/org/apache/batik/bridge/SVGFeDisplacementMapElementBridge.java
protected static
ARGBChannel convertChannelSelector(Element filterElement,
String attrName,
ARGBChannel defaultChannel,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, attrName);
if (s.length() == 0) {
return defaultChannel;
}
if (SVG_A_VALUE.equals(s)) {
return ARGBChannel.A;
}
if (SVG_R_VALUE.equals(s)) {
return ARGBChannel.R;
}
if (SVG_G_VALUE.equals(s)) {
return ARGBChannel.G;
}
if (SVG_B_VALUE.equals(s)) {
return ARGBChannel.B;
}
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attrName, s});
}
// in sources/org/apache/batik/bridge/AbstractGraphicsNodeBridge.java
protected AffineTransform computeTransform(SVGTransformable te,
BridgeContext ctx) {
try {
AffineTransform at = new AffineTransform();
// 'transform'
SVGOMAnimatedTransformList atl =
(SVGOMAnimatedTransformList) te.getTransform();
if (atl.isSpecified()) {
atl.check();
AbstractSVGTransformList tl =
(AbstractSVGTransformList) te.getTransform().getAnimVal();
at.concatenate(tl.getAffineTransform());
}
// motion animation
if (e instanceof SVGMotionAnimatableElement) {
SVGMotionAnimatableElement mae = (SVGMotionAnimatableElement) e;
AffineTransform mat = mae.getMotionTransform();
if (mat != null) {
at.concatenate(mat);
}
}
return at;
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// in sources/org/apache/batik/bridge/CursorManager.java
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);
if (uriStr.length() == 0) {
throw new BridgeException(ctx, cursorElement, ERR_ATTRIBUTE_MISSING,
new Object[] {"xlink:href"});
}
String baseURI = AbstractNode.getBaseURI(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 = cursorCache.getCursor(desc);
if (cachedCursor != null) {
return cachedCursor;
}
//
// Load image into Filter f and transform hotSpot to
// cursor space.
//
Point2D.Float hotSpot = new Point2D.Float(x, y);
Filter f = cursorHrefToFilter(cursorElement,
purl,
hotSpot);
if (f == null) {
cursorCache.clearCursor(desc);
return null;
}
// The returned Filter is guaranteed to create a
// default rendering of the desired size
Rectangle cursorSize = f.getBounds2D().getBounds();
RenderedImage ri = f.createScaledRendering(cursorSize.width,
cursorSize.height,
null);
Image img = null;
if (ri instanceof Image) {
img = (Image)ri;
} else {
img = renderedImageToImage(ri);
}
// Make sure the not spot does not fall out of the cursor area. If it
// does, then clamp the coordinates to the image space.
hotSpot.x = hotSpot.x < 0 ? 0 : hotSpot.x;
hotSpot.y = hotSpot.y < 0 ? 0 : hotSpot.y;
hotSpot.x = hotSpot.x > (cursorSize.width-1) ? cursorSize.width - 1 : hotSpot.x;
hotSpot.y = hotSpot.y > (cursorSize.height-1) ? cursorSize.height - 1: hotSpot.y;
//
// The cursor image is now into 'img'
//
Cursor c = Toolkit.getDefaultToolkit()
.createCustomCursor(img,
new Point(Math.round(hotSpot.x),
Math.round(hotSpot.y)),
purl.toString());
cursorCache.putCursor(desc, c);
return c;
}
// in sources/org/apache/batik/bridge/CursorManager.java
protected Filter cursorHrefToFilter(Element cursorElement,
ParsedURL purl,
Point2D hotSpot) {
AffineRable8Bit f = null;
String uriStr = purl.toString();
Dimension cursorSize = null;
// Try to load as an SVG Document
DocumentLoader loader = ctx.getDocumentLoader();
SVGDocument svgDoc = (SVGDocument)cursorElement.getOwnerDocument();
URIResolver resolver = ctx.createURIResolver(svgDoc, loader);
try {
Element rootElement = null;
Node n = resolver.getNode(uriStr, cursorElement);
if (n.getNodeType() == Node.DOCUMENT_NODE) {
SVGDocument doc = (SVGDocument)n;
// FIXX: really should be subCtx here.
ctx.initializeDocument(doc);
rootElement = doc.getRootElement();
} else {
throw new BridgeException
(ctx, cursorElement, ERR_URI_IMAGE_INVALID,
new Object[] {uriStr});
}
GraphicsNode node = ctx.getGVTBuilder().build(ctx, rootElement);
//
// The cursorSize define the viewport into which the
// cursor is displayed. That viewport is platform
// dependant and is not defined by the SVG content.
//
float width = DEFAULT_PREFERRED_WIDTH;
float height = DEFAULT_PREFERRED_HEIGHT;
UnitProcessor.Context uctx
= UnitProcessor.createContext(ctx, rootElement);
String s = rootElement.getAttribute(SVG_WIDTH_ATTRIBUTE);
if (s.length() != 0) {
width = UnitProcessor.svgHorizontalLengthToUserSpace
(s, SVG_WIDTH_ATTRIBUTE, uctx);
}
s = rootElement.getAttribute(SVG_HEIGHT_ATTRIBUTE);
if (s.length() != 0) {
height = UnitProcessor.svgVerticalLengthToUserSpace
(s, SVG_HEIGHT_ATTRIBUTE, uctx);
}
cursorSize
= Toolkit.getDefaultToolkit().getBestCursorSize
(Math.round(width), Math.round(height));
// Handle the viewBox transform
AffineTransform at = ViewBox.getPreserveAspectRatioTransform
(rootElement, cursorSize.width, cursorSize.height, ctx);
Filter filter = node.getGraphicsNodeRable(true);
f = new AffineRable8Bit(filter, at);
} catch (BridgeException ex) {
throw ex;
} catch (SecurityException ex) {
throw new BridgeException(ctx, cursorElement, ex, ERR_URI_UNSECURE,
new Object[] {uriStr});
} catch (Exception ex) {
/* Nothing to do */
}
// If f is null, it means that we are not dealing with
// an SVG image. Try as a raster image.
if (f == null) {
ImageTagRegistry reg = ImageTagRegistry.getRegistry();
Filter filter = reg.readURL(purl);
if (filter == null) {
return null;
}
// Check if we got a broken image
if (BrokenLinkProvider.hasBrokenLinkProperty(filter)) {
return null;
}
Rectangle preferredSize = filter.getBounds2D().getBounds();
cursorSize = Toolkit.getDefaultToolkit().getBestCursorSize
(preferredSize.width, preferredSize.height);
if (preferredSize != null && preferredSize.width >0
&& preferredSize.height > 0 ) {
AffineTransform at = new AffineTransform();
if (preferredSize.width > cursorSize.width
||
preferredSize.height > cursorSize.height) {
at = ViewBox.getPreserveAspectRatioTransform
(new float[] {0, 0, preferredSize.width, preferredSize.height},
SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMIN,
true,
cursorSize.width,
cursorSize.height);
}
f = new AffineRable8Bit(filter, at);
} else {
// Invalid Size
return null;
}
}
//
// Transform the hot spot from image space to cursor space
//
AffineTransform at = f.getAffine();
at.transform(hotSpot, hotSpot);
//
// In all cases, clip to the cursor boundaries
//
Rectangle cursorViewport
= new Rectangle(0, 0, cursorSize.width, cursorSize.height);
PadRable8Bit cursorImage
= new PadRable8Bit(f, cursorViewport,
PadMode.ZERO_PAD);
return cursorImage;
}
// in sources/org/apache/batik/bridge/SVGPolygonElementBridge.java
protected void buildShape(BridgeContext ctx,
Element e,
ShapeNode shapeNode) {
SVGOMPolygonElement pe = (SVGOMPolygonElement) e;
try {
SVGOMAnimatedPoints _points = pe.getSVGOMAnimatedPoints();
_points.check();
SVGPointList pl = _points.getAnimatedPoints();
int size = pl.getNumberOfItems();
if (size == 0) {
shapeNode.setShape(DEFAULT_SHAPE);
} else {
AWTPolygonProducer app = new AWTPolygonProducer();
app.setWindingRule(CSSUtilities.convertFillRule(e));
app.startPoints();
for (int i = 0; i < size; i++) {
SVGPoint p = pl.getItem(i);
app.point(p.getX(), p.getY());
}
app.endPoints();
shapeNode.setShape(app.getShape());
}
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// in sources/org/apache/batik/bridge/SVGFeConvolveMatrixElementBridge.java
protected static int[] convertOrder(Element filterElement,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, SVG_ORDER_ATTRIBUTE);
if (s.length() == 0) {
return new int[] {3, 3};
}
int [] orderXY = new int[2];
StringTokenizer tokens = new StringTokenizer(s, " ,");
try {
orderXY[0] = SVGUtilities.convertSVGInteger(tokens.nextToken());
if (tokens.hasMoreTokens()) {
orderXY[1] = SVGUtilities.convertSVGInteger(tokens.nextToken());
} else {
orderXY[1] = orderXY[0];
}
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_ORDER_ATTRIBUTE, s, nfEx });
}
if (tokens.hasMoreTokens() || orderXY[0] <= 0 || orderXY[1] <= 0) {
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_ORDER_ATTRIBUTE, s});
}
return orderXY;
}
// in sources/org/apache/batik/bridge/SVGFeConvolveMatrixElementBridge.java
protected static float[] convertKernelMatrix(Element filterElement,
int[] orderXY,
BridgeContext ctx) {
String s =
filterElement.getAttributeNS(null, SVG_KERNEL_MATRIX_ATTRIBUTE);
if (s.length() == 0) {
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_MISSING,
new Object[] {SVG_KERNEL_MATRIX_ATTRIBUTE});
}
int size = orderXY[0]*orderXY[1];
float [] kernelMatrix = new float[size];
StringTokenizer tokens = new StringTokenizer(s, " ,");
int i = 0;
try {
while (tokens.hasMoreTokens() && i < size) {
kernelMatrix[i++]
= SVGUtilities.convertSVGNumber(tokens.nextToken());
}
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_KERNEL_MATRIX_ATTRIBUTE, s, nfEx });
}
if (i != size) {
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_KERNEL_MATRIX_ATTRIBUTE, s});
}
return kernelMatrix;
}
// in sources/org/apache/batik/bridge/SVGFeConvolveMatrixElementBridge.java
protected static float convertDivisor(Element filterElement,
float[] kernelMatrix,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, SVG_DIVISOR_ATTRIBUTE);
if (s.length() == 0) {
// default is sum of kernel values (if sum is zero then 1.0)
float sum = 0;
for (int i=0; i < kernelMatrix.length; ++i) {
sum += kernelMatrix[i];
}
return (sum == 0) ? 1.0f : sum;
} else {
try {
return SVGUtilities.convertSVGNumber(s);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_DIVISOR_ATTRIBUTE, s, nfEx });
}
}
}
// in sources/org/apache/batik/bridge/SVGFeConvolveMatrixElementBridge.java
protected static int[] convertTarget(Element filterElement, int[] orderXY,
BridgeContext ctx) {
int[] targetXY = new int[2];
// 'targetX' attribute - default is floor(orderX / 2)
String s = filterElement.getAttributeNS(null, SVG_TARGET_X_ATTRIBUTE);
if (s.length() == 0) {
targetXY[0] = orderXY[0] / 2;
} else {
try {
int v = SVGUtilities.convertSVGInteger(s);
if (v < 0 || v >= orderXY[0]) {
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_TARGET_X_ATTRIBUTE, s});
}
targetXY[0] = v;
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_TARGET_X_ATTRIBUTE, s, nfEx });
}
}
// 'targetY' attribute - default is floor(orderY / 2)
s = filterElement.getAttributeNS(null, SVG_TARGET_Y_ATTRIBUTE);
if (s.length() == 0) {
targetXY[1] = orderXY[1] / 2;
} else {
try {
int v = SVGUtilities.convertSVGInteger(s);
if (v < 0 || v >= orderXY[1]) {
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_TARGET_Y_ATTRIBUTE, s});
}
targetXY[1] = v;
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_TARGET_Y_ATTRIBUTE, s, nfEx });
}
}
return targetXY;
}
// in sources/org/apache/batik/bridge/SVGFeConvolveMatrixElementBridge.java
protected static double[] convertKernelUnitLength(Element filterElement,
BridgeContext ctx) {
String s = filterElement.getAttributeNS
(null, SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE);
if (s.length() == 0) {
return null;
}
double [] units = new double[2];
StringTokenizer tokens = new StringTokenizer(s, " ,");
try {
units[0] = SVGUtilities.convertSVGNumber(tokens.nextToken());
if (tokens.hasMoreTokens()) {
units[1] = SVGUtilities.convertSVGNumber(tokens.nextToken());
} else {
units[1] = units[0];
}
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE, s});
}
if (tokens.hasMoreTokens() || units[0] <= 0 || units[1] <= 0) {
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_KERNEL_UNIT_LENGTH_ATTRIBUTE, s});
}
return units;
}
// in sources/org/apache/batik/bridge/SVGFeConvolveMatrixElementBridge.java
protected static PadMode convertEdgeMode(Element filterElement,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, SVG_EDGE_MODE_ATTRIBUTE);
if (s.length() == 0) {
return PadMode.REPLICATE;
}
if (SVG_DUPLICATE_VALUE.equals(s)) {
return PadMode.REPLICATE;
}
if (SVG_WRAP_VALUE.equals(s)) {
return PadMode.WRAP;
}
if (SVG_NONE_VALUE.equals(s)) {
return PadMode.ZERO_PAD;
}
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_EDGE_MODE_ATTRIBUTE, s});
}
// in sources/org/apache/batik/bridge/SVGFeConvolveMatrixElementBridge.java
protected static boolean convertPreserveAlpha(Element filterElement,
BridgeContext ctx) {
String s
= filterElement.getAttributeNS(null, SVG_PRESERVE_ALPHA_ATTRIBUTE);
if (s.length() == 0) {
return false;
}
if (SVG_TRUE_VALUE.equals(s)) {
return true;
}
if (SVG_FALSE_VALUE.equals(s)) {
return false;
}
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_PRESERVE_ALPHA_ATTRIBUTE, s});
}
// in sources/org/apache/batik/bridge/SVGFilterElementBridge.java
protected static Filter buildFilterPrimitives(Element filterElement,
Rectangle2D filterRegion,
Element filteredElement,
GraphicsNode filteredNode,
Filter in,
Map filterNodeMap,
BridgeContext ctx) {
List refs = new LinkedList();
for (;;) {
Filter newIn = buildLocalFilterPrimitives(filterElement,
filterRegion,
filteredElement,
filteredNode,
in,
filterNodeMap,
ctx);
if (newIn != in) {
return newIn; // filter primitives found, exit
}
String uri = XLinkSupport.getXLinkHref(filterElement);
if (uri.length() == 0) {
return in; // no xlink:href found, exit
}
// check if there is circular dependencies
SVGOMDocument doc = (SVGOMDocument)filterElement.getOwnerDocument();
ParsedURL url = new ParsedURL(doc.getURLObject(), uri);
if (refs.contains(url)) {
throw new BridgeException(ctx, filterElement,
ERR_XLINK_HREF_CIRCULAR_DEPENDENCIES,
new Object[] {uri});
}
refs.add(url);
filterElement = ctx.getReferencedElement(filterElement, uri);
}
}
// in sources/org/apache/batik/bridge/SVGColorProfileElementBridge.java
public ICCColorSpaceExt createICCColorSpaceExt(BridgeContext ctx,
Element paintedElement,
String iccProfileName) {
// Check if there is one if the cache.
ICCColorSpaceExt cs = cache.request(iccProfileName.toLowerCase()); // todo locale??
if (cs != null){
return cs;
}
// There was no cached copies for the profile. Load it now.
// Search for a color-profile element with specific name
Document doc = paintedElement.getOwnerDocument();
NodeList list = doc.getElementsByTagNameNS(SVG_NAMESPACE_URI,
SVG_COLOR_PROFILE_TAG);
int n = list.getLength();
Element profile = null;
for(int i=0; i<n; i++){
Node node = list.item(i);
if(node.getNodeType() == Node.ELEMENT_NODE){
Element profileNode = (Element)node;
String nameAttr
= profileNode.getAttributeNS(null, SVG_NAME_ATTRIBUTE);
if(iccProfileName.equalsIgnoreCase(nameAttr)){
profile = profileNode;
}
}
}
if(profile == null)
return null;
// Now that we have a profile element,
// try to load the corresponding ICC profile xlink:href
String href = XLinkSupport.getXLinkHref(profile);
ICC_Profile p = null;
if (href != null) {
String baseURI = ((AbstractNode) profile).getBaseURI();
ParsedURL pDocURL = null;
if (baseURI != null) {
pDocURL = new ParsedURL(baseURI);
}
ParsedURL purl = new ParsedURL(pDocURL, href);
if (!purl.complete())
throw new BridgeException(ctx, paintedElement, ERR_URI_MALFORMED,
new Object[] {href});
try {
ctx.getUserAgent().checkLoadExternalResource(purl, pDocURL);
p = ICC_Profile.getInstance(purl.openStream());
} catch (IOException ioEx) {
throw new BridgeException(ctx, paintedElement, ioEx, ERR_URI_IO,
new Object[] {href});
// ??? IS THAT AN ERROR FOR THE SVG SPEC ???
} catch (SecurityException secEx) {
throw new BridgeException(ctx, paintedElement, secEx, ERR_URI_UNSECURE,
new Object[] {href});
}
}
if (p == null) {
return null;
}
// Extract the rendering intent from profile element
int intent = convertIntent(profile, ctx);
cs = new ICCColorSpaceExt(p, intent);
// Add profile to cache
cache.put(iccProfileName.toLowerCase(), cs);
return cs;
}
// in sources/org/apache/batik/bridge/SVGColorProfileElementBridge.java
private static int convertIntent(Element profile, BridgeContext ctx) {
String intent
= profile.getAttributeNS(null, SVG_RENDERING_INTENT_ATTRIBUTE);
if (intent.length() == 0) {
return ICCColorSpaceExt.AUTO;
}
if (SVG_PERCEPTUAL_VALUE.equals(intent)) {
return ICCColorSpaceExt.PERCEPTUAL;
}
if (SVG_AUTO_VALUE.equals(intent)) {
return ICCColorSpaceExt.AUTO;
}
if (SVG_RELATIVE_COLORIMETRIC_VALUE.equals(intent)) {
return ICCColorSpaceExt.RELATIVE_COLORIMETRIC;
}
if (SVG_ABSOLUTE_COLORIMETRIC_VALUE.equals(intent)) {
return ICCColorSpaceExt.ABSOLUTE_COLORIMETRIC;
}
if (SVG_SATURATION_VALUE.equals(intent)) {
return ICCColorSpaceExt.SATURATION;
}
throw new BridgeException
(ctx, profile, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_RENDERING_INTENT_ATTRIBUTE, intent});
}
// in sources/org/apache/batik/bridge/SVGFeMorphologyElementBridge.java
protected static float[] convertRadius(Element filterElement,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, SVG_RADIUS_ATTRIBUTE);
if (s.length() == 0) {
return new float[] {0, 0};
}
float [] radii = new float[2];
StringTokenizer tokens = new StringTokenizer(s, " ,");
try {
radii[0] = SVGUtilities.convertSVGNumber(tokens.nextToken());
if (tokens.hasMoreTokens()) {
radii[1] = SVGUtilities.convertSVGNumber(tokens.nextToken());
} else {
radii[1] = radii[0];
}
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_RADIUS_ATTRIBUTE, s, nfEx });
}
if (tokens.hasMoreTokens() || radii[0] < 0 || radii[1] < 0) {
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_RADIUS_ATTRIBUTE, s});
}
return radii;
}
// in sources/org/apache/batik/bridge/SVGFeMorphologyElementBridge.java
protected static boolean convertOperator(Element filterElement,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, SVG_OPERATOR_ATTRIBUTE);
if (s.length() == 0) {
return false;
}
if (SVG_ERODE_VALUE.equals(s)) {
return false;
}
if (SVG_DILATE_VALUE.equals(s)) {
return true;
}
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_OPERATOR_ATTRIBUTE, s});
}
// in sources/org/apache/batik/bridge/SVGGlyphElementBridge.java
public Glyph createGlyph(BridgeContext ctx,
Element glyphElement,
Element textElement,
int glyphCode,
float fontSize,
GVTFontFace fontFace,
TextPaintInfo tpi) {
float fontHeight = fontFace.getUnitsPerEm();
float scale = fontSize/fontHeight;
AffineTransform scaleTransform
= AffineTransform.getScaleInstance(scale, -scale);
// create a shape that represents the d attribute
String d = glyphElement.getAttributeNS(null, SVG_D_ATTRIBUTE);
Shape dShape = null;
if (d.length() != 0) {
AWTPathProducer app = new AWTPathProducer();
// Glyph is supposed to use properties from text element.
app.setWindingRule(CSSUtilities.convertFillRule(textElement));
try {
PathParser pathParser = new PathParser();
pathParser.setPathHandler(app);
pathParser.parse(d);
} catch (ParseException pEx) {
throw new BridgeException(ctx, glyphElement,
pEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_D_ATTRIBUTE});
} finally {
// transform the shape into the correct coord system
Shape shape = app.getShape();
Shape transformedShape
= scaleTransform.createTransformedShape(shape);
dShape = transformedShape;
}
}
// process any glyph children
// first see if there are any, because don't want to do the following
// bit of code if we can avoid it
NodeList glyphChildren = glyphElement.getChildNodes();
int numChildren = glyphChildren.getLength();
int numGlyphChildren = 0;
for (int i = 0; i < numChildren; i++) {
Node childNode = glyphChildren.item(i);
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
numGlyphChildren++;
}
}
CompositeGraphicsNode glyphContentNode = null;
if (numGlyphChildren > 0) { // the glyph has child elements
// build the GVT tree that represents the glyph children
GVTBuilder builder = ctx.getGVTBuilder();
glyphContentNode = new CompositeGraphicsNode();
//
// need to clone the parent font element and glyph element
// this is so that the glyph doesn't inherit anything past the font element
//
Element fontElementClone
= (Element)glyphElement.getParentNode().cloneNode(false);
// copy all font attributes over
NamedNodeMap fontAttributes
= glyphElement.getParentNode().getAttributes();
int numAttributes = fontAttributes.getLength();
for (int i = 0; i < numAttributes; i++) {
fontElementClone.setAttributeNode((Attr)fontAttributes.item(i));
}
Element clonedGlyphElement = (Element)glyphElement.cloneNode(true);
fontElementClone.appendChild(clonedGlyphElement);
textElement.appendChild(fontElementClone);
CompositeGraphicsNode glyphChildrenNode
= new CompositeGraphicsNode();
glyphChildrenNode.setTransform(scaleTransform);
NodeList clonedGlyphChildren = clonedGlyphElement.getChildNodes();
int numClonedChildren = clonedGlyphChildren.getLength();
for (int i = 0; i < numClonedChildren; i++) {
Node childNode = clonedGlyphChildren.item(i);
if (childNode.getNodeType() == Node.ELEMENT_NODE) {
Element childElement = (Element)childNode;
GraphicsNode childGraphicsNode =
builder.build(ctx, childElement);
glyphChildrenNode.add(childGraphicsNode);
}
}
glyphContentNode.add(glyphChildrenNode);
textElement.removeChild(fontElementClone);
}
// set up glyph attributes
// unicode
String unicode
= glyphElement.getAttributeNS(null, SVG_UNICODE_ATTRIBUTE);
// glyph-name
String nameList
= glyphElement.getAttributeNS(null, SVG_GLYPH_NAME_ATTRIBUTE);
List names = new ArrayList();
StringTokenizer st = new StringTokenizer(nameList, " ,");
while (st.hasMoreTokens()) {
names.add(st.nextToken());
}
// orientation
String orientation
= glyphElement.getAttributeNS(null, SVG_ORIENTATION_ATTRIBUTE);
// arabicForm
String arabicForm
= glyphElement.getAttributeNS(null, SVG_ARABIC_FORM_ATTRIBUTE);
// lang
String lang = glyphElement.getAttributeNS(null, SVG_LANG_ATTRIBUTE);
Element parentFontElement = (Element)glyphElement.getParentNode();
// horz-adv-x
String s = glyphElement.getAttributeNS(null, SVG_HORIZ_ADV_X_ATTRIBUTE);
if (s.length() == 0) {
// look for attribute on parent font element
s = parentFontElement.getAttributeNS(null, SVG_HORIZ_ADV_X_ATTRIBUTE);
if (s.length() == 0) {
// throw an exception since this attribute is required on the font element
throw new BridgeException
(ctx, parentFontElement, ERR_ATTRIBUTE_MISSING,
new Object[] {SVG_HORIZ_ADV_X_ATTRIBUTE});
}
}
float horizAdvX;
try {
horizAdvX = SVGUtilities.convertSVGNumber(s) * scale;
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, glyphElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_HORIZ_ADV_X_ATTRIBUTE, s});
}
// vert-adv-y
s = glyphElement.getAttributeNS(null, SVG_VERT_ADV_Y_ATTRIBUTE);
if (s.length() == 0) {
// look for attribute on parent font element
s = parentFontElement.getAttributeNS(null, SVG_VERT_ADV_Y_ATTRIBUTE);
if (s.length() == 0) {
// not specified on parent either, use one em
s = String.valueOf(fontFace.getUnitsPerEm());
}
}
float vertAdvY;
try {
vertAdvY = SVGUtilities.convertSVGNumber(s) * scale;
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, glyphElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_VERT_ADV_Y_ATTRIBUTE, s});
}
// vert-origin-x
s = glyphElement.getAttributeNS(null, SVG_VERT_ORIGIN_X_ATTRIBUTE);
if (s.length() == 0) {
// look for attribute on parent font element
s = parentFontElement.getAttributeNS(null, SVG_VERT_ORIGIN_X_ATTRIBUTE);
if (s.length() == 0) {
// not specified so use the default value which is horizAdvX/2
s = Float.toString(horizAdvX/2);
}
}
float vertOriginX;
try {
vertOriginX = SVGUtilities.convertSVGNumber(s) * scale;
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, glyphElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_VERT_ORIGIN_X_ATTRIBUTE, s});
}
// vert-origin-y
s = glyphElement.getAttributeNS(null, SVG_VERT_ORIGIN_Y_ATTRIBUTE);
if (s.length() == 0) {
// look for attribute on parent font element
s = parentFontElement.getAttributeNS(null, SVG_VERT_ORIGIN_Y_ATTRIBUTE);
if (s.length() == 0) {
// not specified so use the default value which is the fonts ascent
s = String.valueOf(fontFace.getAscent());
}
}
float vertOriginY;
try {
vertOriginY = SVGUtilities.convertSVGNumber(s) * -scale;
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, glyphElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_VERT_ORIGIN_Y_ATTRIBUTE, s});
}
Point2D vertOrigin = new Point2D.Float(vertOriginX, vertOriginY);
// get the horizontal origin from the parent font element
// horiz-origin-x
s = parentFontElement.getAttributeNS(null, SVG_HORIZ_ORIGIN_X_ATTRIBUTE);
if (s.length() == 0) {
// not specified so use the default value which is 0
s = SVG_HORIZ_ORIGIN_X_DEFAULT_VALUE;
}
float horizOriginX;
try {
horizOriginX = SVGUtilities.convertSVGNumber(s) * scale;
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, parentFontElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_HORIZ_ORIGIN_X_ATTRIBUTE, s});
}
// horiz-origin-y
s = parentFontElement.getAttributeNS(null, SVG_HORIZ_ORIGIN_Y_ATTRIBUTE);
if (s.length() == 0) {
// not specified so use the default value which is 0
s = SVG_HORIZ_ORIGIN_Y_DEFAULT_VALUE;
}
float horizOriginY;
try {
horizOriginY = SVGUtilities.convertSVGNumber(s) * -scale;
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, glyphElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_HORIZ_ORIGIN_Y_ATTRIBUTE, s});
}
Point2D horizOrigin = new Point2D.Float(horizOriginX, horizOriginY);
// return a new Glyph
return new Glyph(unicode, names, orientation,
arabicForm, lang, horizOrigin, vertOrigin,
horizAdvX, vertAdvY, glyphCode,
tpi, dShape, glyphContentNode);
}
// in sources/org/apache/batik/bridge/SVGTextElementBridge.java
protected Point2D getLocation(BridgeContext ctx, Element e) {
try {
SVGOMTextPositioningElement te = (SVGOMTextPositioningElement) e;
// 'x' attribute - default is 0
SVGOMAnimatedLengthList _x = (SVGOMAnimatedLengthList) te.getX();
_x.check();
SVGLengthList xs = _x.getAnimVal();
float x = 0;
if (xs.getNumberOfItems() > 0) {
x = xs.getItem(0).getValue();
}
// 'y' attribute - default is 0
SVGOMAnimatedLengthList _y = (SVGOMAnimatedLengthList) te.getY();
_y.check();
SVGLengthList ys = _y.getAnimVal();
float y = 0;
if (ys.getNumberOfItems() > 0) {
y = ys.getItem(0).getValue();
}
return new Point2D.Float(x, y);
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// in sources/org/apache/batik/bridge/SVGTextElementBridge.java
protected void addGlyphPositionAttributes(AttributedString as,
Element element,
BridgeContext ctx) {
// 'requiredFeatures', 'requiredExtensions' and 'systemLanguage'
if ((!SVGUtilities.matchUserAgent(element, ctx.getUserAgent())) ||
(!CSSUtilities.convertDisplay(element))) {
return;
}
if (element.getLocalName().equals(SVG_TEXT_PATH_TAG)) {
// 'textPath' doesn't support position attributes.
addChildGlyphPositionAttributes(as, element, ctx);
return;
}
// calculate which chars in the string belong to this element
int firstChar = getElementStartIndex(element);
// No match so no chars to annotate.
if (firstChar == -1) return;
int lastChar = getElementEndIndex(element);
// 'a' elements aren't SVGTextPositioningElements, so don't process
// their positioning attributes on them.
if (!(element instanceof SVGTextPositioningElement)) {
addChildGlyphPositionAttributes(as, element, ctx);
return;
}
// get all of the glyph position attribute values
SVGTextPositioningElement te = (SVGTextPositioningElement) element;
try {
SVGOMAnimatedLengthList _x =
(SVGOMAnimatedLengthList) te.getX();
_x.check();
SVGOMAnimatedLengthList _y =
(SVGOMAnimatedLengthList) te.getY();
_y.check();
SVGOMAnimatedLengthList _dx =
(SVGOMAnimatedLengthList) te.getDx();
_dx.check();
SVGOMAnimatedLengthList _dy =
(SVGOMAnimatedLengthList) te.getDy();
_dy.check();
SVGOMAnimatedNumberList _rotate =
(SVGOMAnimatedNumberList) te.getRotate();
_rotate.check();
SVGLengthList xs = _x.getAnimVal();
SVGLengthList ys = _y.getAnimVal();
SVGLengthList dxs = _dx.getAnimVal();
SVGLengthList dys = _dy.getAnimVal();
SVGNumberList rs = _rotate.getAnimVal();
int len;
// process the x attribute
len = xs.getNumberOfItems();
for (int i = 0; i < len && firstChar + i <= lastChar; i++) {
as.addAttribute
(GVTAttributedCharacterIterator.TextAttribute.X,
new Float(xs.getItem(i).getValue()), firstChar + i,
firstChar + i + 1);
}
// process the y attribute
len = ys.getNumberOfItems();
for (int i = 0; i < len && firstChar + i <= lastChar; i++) {
as.addAttribute
(GVTAttributedCharacterIterator.TextAttribute.Y,
new Float(ys.getItem(i).getValue()), firstChar + i,
firstChar + i + 1);
}
// process dx attribute
len = dxs.getNumberOfItems();
for (int i = 0; i < len && firstChar + i <= lastChar; i++) {
as.addAttribute
(GVTAttributedCharacterIterator.TextAttribute.DX,
new Float(dxs.getItem(i).getValue()), firstChar + i,
firstChar + i + 1);
}
// process dy attribute
len = dys.getNumberOfItems();
for (int i = 0; i < len && firstChar + i <= lastChar; i++) {
as.addAttribute
(GVTAttributedCharacterIterator.TextAttribute.DY,
new Float(dys.getItem(i).getValue()), firstChar + i,
firstChar + i + 1);
}
// process rotate attribute
len = rs.getNumberOfItems();
if (len == 1) { // not a list
// each char will have the same rotate value
Float rad = new Float(Math.toRadians(rs.getItem(0).getValue()));
as.addAttribute
(GVTAttributedCharacterIterator.TextAttribute.ROTATION,
rad, firstChar, lastChar + 1);
} else if (len > 1) { // it's a list
// set each rotate value from the list
for (int i = 0; i < len && firstChar + i <= lastChar; i++) {
Float rad = new Float(Math.toRadians(rs.getItem(i).getValue()));
as.addAttribute
(GVTAttributedCharacterIterator.TextAttribute.ROTATION,
rad, firstChar + i, firstChar + i + 1);
}
}
addChildGlyphPositionAttributes(as, element, ctx);
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// in sources/org/apache/batik/bridge/SVGTextElementBridge.java
protected Map getAttributeMap(BridgeContext ctx,
Element element,
TextPath textPath,
Integer bidiLevel,
Map result) {
SVGTextContentElement tce = null;
if (element instanceof SVGTextContentElement) {
// 'a' elements aren't SVGTextContentElements, so they shouldn't
// be checked for 'textLength' or 'lengthAdjust' attributes.
tce = (SVGTextContentElement) element;
}
Map inheritMap = null;
String s;
if (SVG_NAMESPACE_URI.equals(element.getNamespaceURI()) &&
element.getLocalName().equals(SVG_ALT_GLYPH_TAG)) {
result.put(ALT_GLYPH_HANDLER,
new SVGAltGlyphHandler(ctx, element));
}
// Add null TPI objects to the text (after we set it on the
// Text we will swap in the correct values.
TextPaintInfo pi = new TextPaintInfo();
// Set some basic props so we can get bounds info for complex paints.
pi.visible = true;
pi.fillPaint = Color.black;
result.put(PAINT_INFO, pi);
elemTPI.put(element, pi);
if (textPath != null) {
result.put(TEXTPATH, textPath);
}
// Text-anchor
TextNode.Anchor a = TextUtilities.convertTextAnchor(element);
result.put(ANCHOR_TYPE, a);
// Font family
List fontList = getFontList(ctx, element, result);
result.put(GVT_FONTS, fontList);
// Text baseline adjustment.
Object bs = TextUtilities.convertBaselineShift(element);
if (bs != null) {
result.put(BASELINE_SHIFT, bs);
}
// Unicode-bidi mode
Value val = CSSUtilities.getComputedStyle
(element, SVGCSSEngine.UNICODE_BIDI_INDEX);
s = val.getStringValue();
if (s.charAt(0) == 'n') {
if (bidiLevel != null)
result.put(TextAttribute.BIDI_EMBEDDING, bidiLevel);
} else {
// Text direction
// XXX: this needs to coordinate with the unicode-bidi
// property, so that when an explicit reversal
// occurs, the BIDI_EMBEDDING level is
// appropriately incremented or decremented.
// Note that direction is implicitly handled by unicode
// BiDi algorithm in most cases, this property
// is only needed when one wants to override the
// normal writing direction for a string/substring.
val = CSSUtilities.getComputedStyle
(element, SVGCSSEngine.DIRECTION_INDEX);
String rs = val.getStringValue();
int cbidi = 0;
if (bidiLevel != null) cbidi = bidiLevel.intValue();
// We don't care if it was embed or override we just want
// it's level here. So map override to positive value.
if (cbidi < 0) cbidi = -cbidi;
switch (rs.charAt(0)) {
case 'l':
result.put(TextAttribute.RUN_DIRECTION,
TextAttribute.RUN_DIRECTION_LTR);
if ((cbidi & 0x1) == 1) cbidi++; // was odd now even
else cbidi+=2; // next greater even number
break;
case 'r':
result.put(TextAttribute.RUN_DIRECTION,
TextAttribute.RUN_DIRECTION_RTL);
if ((cbidi & 0x1) == 1) cbidi+=2; // next greater odd number
else cbidi++; // was even now odd
break;
}
switch (s.charAt(0)) {
case 'b': // bidi-override
cbidi = -cbidi; // For bidi-override we want a negative number.
break;
}
result.put(TextAttribute.BIDI_EMBEDDING, new Integer(cbidi));
}
// Writing mode
val = CSSUtilities.getComputedStyle
(element, SVGCSSEngine.WRITING_MODE_INDEX);
s = val.getStringValue();
switch (s.charAt(0)) {
case 'l':
result.put(GVTAttributedCharacterIterator.
TextAttribute.WRITING_MODE,
GVTAttributedCharacterIterator.
TextAttribute.WRITING_MODE_LTR);
break;
case 'r':
result.put(GVTAttributedCharacterIterator.
TextAttribute.WRITING_MODE,
GVTAttributedCharacterIterator.
TextAttribute.WRITING_MODE_RTL);
break;
case 't':
result.put(GVTAttributedCharacterIterator.
TextAttribute.WRITING_MODE,
GVTAttributedCharacterIterator.
TextAttribute.WRITING_MODE_TTB);
break;
}
// glyph-orientation-vertical
val = CSSUtilities.getComputedStyle
(element, SVGCSSEngine.GLYPH_ORIENTATION_VERTICAL_INDEX);
int primitiveType = val.getPrimitiveType();
switch ( primitiveType ) {
case CSSPrimitiveValue.CSS_IDENT: // auto
result.put(GVTAttributedCharacterIterator.
TextAttribute.VERTICAL_ORIENTATION,
GVTAttributedCharacterIterator.
TextAttribute.ORIENTATION_AUTO);
break;
case CSSPrimitiveValue.CSS_DEG:
result.put(GVTAttributedCharacterIterator.
TextAttribute.VERTICAL_ORIENTATION,
GVTAttributedCharacterIterator.
TextAttribute.ORIENTATION_ANGLE);
result.put(GVTAttributedCharacterIterator.
TextAttribute.VERTICAL_ORIENTATION_ANGLE,
new Float(val.getFloatValue()));
break;
case CSSPrimitiveValue.CSS_RAD:
result.put(GVTAttributedCharacterIterator.
TextAttribute.VERTICAL_ORIENTATION,
GVTAttributedCharacterIterator.
TextAttribute.ORIENTATION_ANGLE);
result.put(GVTAttributedCharacterIterator.
TextAttribute.VERTICAL_ORIENTATION_ANGLE,
new Float( Math.toDegrees( val.getFloatValue() ) ));
break;
case CSSPrimitiveValue.CSS_GRAD:
result.put(GVTAttributedCharacterIterator.
TextAttribute.VERTICAL_ORIENTATION,
GVTAttributedCharacterIterator.
TextAttribute.ORIENTATION_ANGLE);
result.put(GVTAttributedCharacterIterator.
TextAttribute.VERTICAL_ORIENTATION_ANGLE,
new Float(val.getFloatValue() * 9 / 5));
break;
default:
// Cannot happen
throw new IllegalStateException("unexpected primitiveType (V):" + primitiveType );
}
// glyph-orientation-horizontal
val = CSSUtilities.getComputedStyle
(element, SVGCSSEngine.GLYPH_ORIENTATION_HORIZONTAL_INDEX);
primitiveType = val.getPrimitiveType();
switch ( primitiveType ) {
case CSSPrimitiveValue.CSS_DEG:
result.put(GVTAttributedCharacterIterator.
TextAttribute.HORIZONTAL_ORIENTATION_ANGLE,
new Float(val.getFloatValue()));
break;
case CSSPrimitiveValue.CSS_RAD:
result.put(GVTAttributedCharacterIterator.
TextAttribute.HORIZONTAL_ORIENTATION_ANGLE,
new Float( Math.toDegrees( val.getFloatValue() ) ));
break;
case CSSPrimitiveValue.CSS_GRAD:
result.put(GVTAttributedCharacterIterator.
TextAttribute.HORIZONTAL_ORIENTATION_ANGLE,
new Float(val.getFloatValue() * 9 / 5));
break;
default:
// Cannot happen
throw new IllegalStateException("unexpected primitiveType (H):" + primitiveType );
}
// text spacing properties...
// Letter Spacing
Float sp = TextUtilities.convertLetterSpacing(element);
if (sp != null) {
result.put(GVTAttributedCharacterIterator.
TextAttribute.LETTER_SPACING,
sp);
result.put(GVTAttributedCharacterIterator.
TextAttribute.CUSTOM_SPACING,
Boolean.TRUE);
}
// Word spacing
sp = TextUtilities.convertWordSpacing(element);
if (sp != null) {
result.put(GVTAttributedCharacterIterator.
TextAttribute.WORD_SPACING,
sp);
result.put(GVTAttributedCharacterIterator.
TextAttribute.CUSTOM_SPACING,
Boolean.TRUE);
}
// Kerning
sp = TextUtilities.convertKerning(element);
if (sp != null) {
result.put(GVTAttributedCharacterIterator.TextAttribute.KERNING,
sp);
result.put(GVTAttributedCharacterIterator.
TextAttribute.CUSTOM_SPACING,
Boolean.TRUE);
}
if (tce == null) {
return inheritMap;
}
try {
// textLength
AbstractSVGAnimatedLength textLength =
(AbstractSVGAnimatedLength) tce.getTextLength();
if (textLength.isSpecified()) {
if (inheritMap == null) {
inheritMap = new HashMap();
}
Object value = new Float(textLength.getCheckedValue());
result.put
(GVTAttributedCharacterIterator.TextAttribute.BBOX_WIDTH,
value);
inheritMap.put
(GVTAttributedCharacterIterator.TextAttribute.BBOX_WIDTH,
value);
// lengthAdjust
SVGOMAnimatedEnumeration _lengthAdjust =
(SVGOMAnimatedEnumeration) tce.getLengthAdjust();
if (_lengthAdjust.getCheckedVal() ==
SVGTextContentElement.LENGTHADJUST_SPACINGANDGLYPHS) {
result.put(GVTAttributedCharacterIterator.
TextAttribute.LENGTH_ADJUST,
GVTAttributedCharacterIterator.
TextAttribute.ADJUST_ALL);
inheritMap.put(GVTAttributedCharacterIterator.
TextAttribute.LENGTH_ADJUST,
GVTAttributedCharacterIterator.
TextAttribute.ADJUST_ALL);
} else {
result.put(GVTAttributedCharacterIterator.
TextAttribute.LENGTH_ADJUST,
GVTAttributedCharacterIterator.
TextAttribute.ADJUST_SPACING);
inheritMap.put(GVTAttributedCharacterIterator.
TextAttribute.LENGTH_ADJUST,
GVTAttributedCharacterIterator.
TextAttribute.ADJUST_SPACING);
result.put(GVTAttributedCharacterIterator.
TextAttribute.CUSTOM_SPACING,
Boolean.TRUE);
inheritMap.put(GVTAttributedCharacterIterator.
TextAttribute.CUSTOM_SPACING,
Boolean.TRUE);
}
}
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
return inheritMap;
}
// in sources/org/apache/batik/bridge/SVGAnimateMotionElementBridge.java
protected AbstractAnimation createAnimation(AnimationTarget target) {
animationType = AnimationEngine.ANIM_TYPE_OTHER;
attributeLocalName = "motion";
AnimatableValue from = parseLengthPair(SVG_FROM_ATTRIBUTE);
AnimatableValue to = parseLengthPair(SVG_TO_ATTRIBUTE);
AnimatableValue by = parseLengthPair(SVG_BY_ATTRIBUTE);
boolean rotateAuto = false, rotateAutoReverse = false;
float rotateAngle = 0;
short rotateAngleUnit = SVGAngle.SVG_ANGLETYPE_UNKNOWN;
String rotateString = element.getAttributeNS(null,
SVG_ROTATE_ATTRIBUTE);
if (rotateString.length() != 0) {
if (rotateString.equals("auto")) {
rotateAuto = true;
} else if (rotateString.equals("auto-reverse")) {
rotateAuto = true;
rotateAutoReverse = true;
} else {
class Handler implements AngleHandler {
float theAngle;
short theUnit = SVGAngle.SVG_ANGLETYPE_UNSPECIFIED;
public void startAngle() throws ParseException {
}
public void angleValue(float v) throws ParseException {
theAngle = v;
}
public void deg() throws ParseException {
theUnit = SVGAngle.SVG_ANGLETYPE_DEG;
}
public void grad() throws ParseException {
theUnit = SVGAngle.SVG_ANGLETYPE_GRAD;
}
public void rad() throws ParseException {
theUnit = SVGAngle.SVG_ANGLETYPE_RAD;
}
public void endAngle() throws ParseException {
}
}
AngleParser ap = new AngleParser();
Handler h = new Handler();
ap.setAngleHandler(h);
try {
ap.parse(rotateString);
} catch (ParseException pEx ) {
throw new BridgeException
(ctx, element,
pEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_ROTATE_ATTRIBUTE, rotateString });
}
rotateAngle = h.theAngle;
rotateAngleUnit = h.theUnit;
}
}
return new MotionAnimation(timedElement,
this,
parseCalcMode(),
parseKeyTimes(),
parseKeySplines(),
parseAdditive(),
parseAccumulate(),
parseValues(),
from,
to,
by,
parsePath(),
parseKeyPoints(),
rotateAuto,
rotateAutoReverse,
rotateAngle,
rotateAngleUnit);
}
// in sources/org/apache/batik/bridge/SVGAnimateMotionElementBridge.java
protected ExtendedGeneralPath parsePath() {
Node n = element.getFirstChild();
while (n != null) {
if (n.getNodeType() == Node.ELEMENT_NODE
&& SVG_NAMESPACE_URI.equals(n.getNamespaceURI())
&& SVG_MPATH_TAG.equals(n.getLocalName())) {
String uri = XLinkSupport.getXLinkHref((Element) n);
Element path = ctx.getReferencedElement(element, uri);
if (!SVG_NAMESPACE_URI.equals(path.getNamespaceURI())
|| !SVG_PATH_TAG.equals(path.getLocalName())) {
throw new BridgeException
(ctx, element, ErrorConstants.ERR_URI_BAD_TARGET,
new Object[] { uri });
}
SVGOMPathElement pathElt = (SVGOMPathElement) path;
AWTPathProducer app = new AWTPathProducer();
SVGAnimatedPathDataSupport.handlePathSegList
(pathElt.getPathSegList(), app);
return (ExtendedGeneralPath) app.getShape();
}
n = n.getNextSibling();
}
String pathString = element.getAttributeNS(null, SVG_PATH_ATTRIBUTE);
if (pathString.length() == 0) {
return null;
}
try {
AWTPathProducer app = new AWTPathProducer();
PathParser pp = new PathParser();
pp.setPathHandler(app);
pp.parse(pathString);
return (ExtendedGeneralPath) app.getShape();
} catch (ParseException pEx ) {
throw new BridgeException
(ctx, element, pEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_PATH_ATTRIBUTE, pathString });
}
}
// in sources/org/apache/batik/bridge/SVGAnimateMotionElementBridge.java
protected float[] parseKeyPoints() {
String keyPointsString =
element.getAttributeNS(null, SVG_KEY_POINTS_ATTRIBUTE);
int len = keyPointsString.length();
if (len == 0) {
return null;
}
List keyPoints = new ArrayList(7);
int i = 0, start = 0, end;
char c;
outer: while (i < len) {
while (keyPointsString.charAt(i) == ' ') {
i++;
if (i == len) {
break outer;
}
}
start = i++;
if (i != len) {
c = keyPointsString.charAt(i);
while (c != ' ' && c != ';' && c != ',') {
i++;
if (i == len) {
break;
}
c = keyPointsString.charAt(i);
}
}
end = i++;
try {
float keyPointCoord =
Float.parseFloat(keyPointsString.substring(start, end));
keyPoints.add(new Float(keyPointCoord));
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, element, nfEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_KEY_POINTS_ATTRIBUTE, keyPointsString });
}
}
len = keyPoints.size();
float[] ret = new float[len];
for (int j = 0; j < len; j++) {
ret[j] = ((Float) keyPoints.get(j)).floatValue();
}
return ret;
}
// in sources/org/apache/batik/bridge/SVGAnimateMotionElementBridge.java
protected AnimatableValue[] parseValues(String s) {
try {
LengthPairListParser lplp = new LengthPairListParser();
LengthArrayProducer lap = new LengthArrayProducer();
lplp.setLengthListHandler(lap);
lplp.parse(s);
short[] types = lap.getLengthTypeArray();
float[] values = lap.getLengthValueArray();
AnimatableValue[] ret = new AnimatableValue[types.length / 2];
for (int i = 0; i < types.length; i += 2) {
float x = animationTarget.svgToUserSpace
(values[i], types[i], AnimationTarget.PERCENTAGE_VIEWPORT_WIDTH);
float y = animationTarget.svgToUserSpace
(values[i + 1], types[i + 1], AnimationTarget.PERCENTAGE_VIEWPORT_HEIGHT);
ret[i / 2] = new AnimatableMotionPointValue(animationTarget, x, y, 0);
}
return ret;
} catch (ParseException pEx ) {
throw new BridgeException
(ctx, element, pEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_VALUES_ATTRIBUTE, s });
}
}
// in sources/org/apache/batik/bridge/SVGAnimateMotionElementBridge.java
protected void initializeAnimation() {
// Determine the target element.
String uri = XLinkSupport.getXLinkHref(element);
Node t;
if (uri.length() == 0) {
t = element.getParentNode();
} else {
t = ctx.getReferencedElement(element, uri);
if (t.getOwnerDocument() != element.getOwnerDocument()) {
throw new BridgeException
(ctx, element, ErrorConstants.ERR_URI_BAD_TARGET,
new Object[] { uri });
}
}
animationTarget = null;
if (t instanceof SVGOMElement) {
targetElement = (SVGOMElement) t;
animationTarget = targetElement;
}
if (animationTarget == null) {
throw new BridgeException
(ctx, element, ErrorConstants.ERR_URI_BAD_TARGET,
new Object[] { uri });
}
// Add the animation.
timedElement = createTimedElement();
animation = createAnimation(animationTarget);
eng.addAnimation(animationTarget, AnimationEngine.ANIM_TYPE_OTHER,
attributeNamespaceURI, attributeLocalName, animation);
}
// in sources/org/apache/batik/bridge/SVGTextPathElementBridge.java
public TextPath createTextPath(BridgeContext ctx, Element textPathElement) {
// get the referenced element
String uri = XLinkSupport.getXLinkHref(textPathElement);
Element pathElement = ctx.getReferencedElement(textPathElement, uri);
if ((pathElement == null) ||
(!SVG_NAMESPACE_URI.equals(pathElement.getNamespaceURI())) ||
(!pathElement.getLocalName().equals(SVG_PATH_TAG))) {
// couldn't find the referenced element
// or the referenced element was not a path
throw new BridgeException(ctx, textPathElement, ERR_URI_BAD_TARGET,
new Object[] {uri});
}
// construct a shape for the referenced path element
String s = pathElement.getAttributeNS(null, SVG_D_ATTRIBUTE);
Shape pathShape = null;
if (s.length() != 0) {
AWTPathProducer app = new AWTPathProducer();
app.setWindingRule(CSSUtilities.convertFillRule(pathElement));
try {
PathParser pathParser = new PathParser();
pathParser.setPathHandler(app);
pathParser.parse(s);
} catch (ParseException pEx ) {
throw new BridgeException
(ctx, pathElement, pEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_D_ATTRIBUTE});
} finally {
pathShape = app.getShape();
}
} else {
throw new BridgeException(ctx, pathElement, ERR_ATTRIBUTE_MISSING,
new Object[] {SVG_D_ATTRIBUTE});
}
// if the reference path element has a transform apply the transform
// to the path shape
s = pathElement.getAttributeNS(null, SVG_TRANSFORM_ATTRIBUTE);
if (s.length() != 0) {
AffineTransform tr =
SVGUtilities.convertTransform(pathElement,
SVG_TRANSFORM_ATTRIBUTE, s, ctx);
pathShape = tr.createTransformedShape(pathShape);
}
// create the TextPath object that we are going to return
TextPath textPath = new TextPath(new GeneralPath(pathShape));
// set the start offset if specified
s = textPathElement.getAttributeNS(null, SVG_START_OFFSET_ATTRIBUTE);
if (s.length() > 0) {
float startOffset = 0;
int percentIndex = s.indexOf('%');
if (percentIndex != -1) {
// its a percentage of the length of the path
float pathLength = textPath.lengthOfPath();
String percentString = s.substring(0,percentIndex);
float startOffsetPercent = 0;
try {
startOffsetPercent = SVGUtilities.convertSVGNumber(percentString);
} catch (NumberFormatException e) {
throw new BridgeException
(ctx, textPathElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_START_OFFSET_ATTRIBUTE, s});
}
startOffset = (float)(startOffsetPercent * pathLength/100.0);
} else {
// its an absolute length
UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, textPathElement);
startOffset = UnitProcessor.svgOtherLengthToUserSpace(s, SVG_START_OFFSET_ATTRIBUTE, uctx);
}
textPath.setStartOffset(startOffset);
}
return textPath;
}
// in sources/org/apache/batik/bridge/SVGRectElementBridge.java
protected void buildShape(BridgeContext ctx,
Element e,
ShapeNode shapeNode) {
try {
SVGOMRectElement re = (SVGOMRectElement) e;
// 'x' attribute - default is 0
AbstractSVGAnimatedLength _x =
(AbstractSVGAnimatedLength) re.getX();
float x = _x.getCheckedValue();
// 'y' attribute - default is 0
AbstractSVGAnimatedLength _y =
(AbstractSVGAnimatedLength) re.getY();
float y = _y.getCheckedValue();
// 'width' attribute - required
AbstractSVGAnimatedLength _width =
(AbstractSVGAnimatedLength) re.getWidth();
float w = _width.getCheckedValue();
// 'height' attribute - required
AbstractSVGAnimatedLength _height =
(AbstractSVGAnimatedLength) re.getHeight();
float h = _height.getCheckedValue();
// 'rx' attribute - default is 0
AbstractSVGAnimatedLength _rx =
(AbstractSVGAnimatedLength) re.getRx();
float rx = _rx.getCheckedValue();
if (rx > w / 2) {
rx = w / 2;
}
// 'ry' attribute - default is rx
AbstractSVGAnimatedLength _ry =
(AbstractSVGAnimatedLength) re.getRy();
float ry = _ry.getCheckedValue();
if (ry > h / 2) {
ry = h / 2;
}
Shape shape;
if (rx == 0 || ry == 0) {
shape = new Rectangle2D.Float(x, y, w, h);
} else {
shape = new RoundRectangle2D.Float(x, y, w, h, rx * 2, ry * 2);
}
shapeNode.setShape(shape);
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// in sources/org/apache/batik/bridge/SVGPatternElementBridge.java
protected static
RootGraphicsNode extractPatternContent(Element patternElement,
BridgeContext ctx) {
List refs = new LinkedList();
for (;;) {
RootGraphicsNode content
= extractLocalPatternContent(patternElement, ctx);
if (content != null) {
return content; // pattern content found, exit
}
String uri = XLinkSupport.getXLinkHref(patternElement);
if (uri.length() == 0) {
return null; // no xlink:href found, exit
}
// check if there is circular dependencies
SVGOMDocument doc =
(SVGOMDocument)patternElement.getOwnerDocument();
ParsedURL purl = new ParsedURL(doc.getURL(), uri);
if (!purl.complete())
throw new BridgeException(ctx, patternElement,
ERR_URI_MALFORMED,
new Object[] {uri});
if (contains(refs, purl)) {
throw new BridgeException(ctx, patternElement,
ERR_XLINK_HREF_CIRCULAR_DEPENDENCIES,
new Object[] {uri});
}
refs.add(purl);
patternElement = ctx.getReferencedElement(patternElement, uri);
}
}
// in sources/org/apache/batik/bridge/SVGImageElementBridge.java
public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) {
ImageNode imageNode = (ImageNode)super.createGraphicsNode(ctx, e);
if (imageNode == null) {
return null;
}
associateSVGContext(ctx, e, imageNode);
hitCheckChildren = false;
GraphicsNode node = buildImageGraphicsNode(ctx,e);
if (node == null) {
SVGImageElement ie = (SVGImageElement) e;
String uriStr = ie.getHref().getAnimVal();
throw new BridgeException(ctx, e, ERR_URI_IMAGE_INVALID,
new Object[] {uriStr});
}
imageNode.setImage(node);
imageNode.setHitCheckChildren(hitCheckChildren);
// 'image-rendering' and 'color-rendering'
RenderingHints hints = null;
hints = CSSUtilities.convertImageRendering(e, hints);
hints = CSSUtilities.convertColorRendering(e, hints);
if (hints != null)
imageNode.setRenderingHints(hints);
return imageNode;
}
// in sources/org/apache/batik/bridge/SVGImageElementBridge.java
protected GraphicsNode buildImageGraphicsNode
(BridgeContext ctx, Element e){
SVGImageElement ie = (SVGImageElement) e;
// 'xlink:href' attribute - required
String uriStr = ie.getHref().getAnimVal();
if (uriStr.length() == 0) {
throw new BridgeException(ctx, e, ERR_ATTRIBUTE_MISSING,
new Object[] {"xlink:href"});
}
if (uriStr.indexOf('#') != -1) {
throw new BridgeException(ctx, e, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {"xlink:href", uriStr});
}
// Build the URL.
String baseURI = AbstractNode.getBaseURI(e);
ParsedURL purl;
if (baseURI == null) {
purl = new ParsedURL(uriStr);
} else {
purl = new ParsedURL(baseURI, uriStr);
}
return createImageGraphicsNode(ctx, e, purl);
}
// in sources/org/apache/batik/bridge/SVGImageElementBridge.java
protected GraphicsNode createImageGraphicsNode(BridgeContext ctx,
Element e,
ParsedURL purl) {
Rectangle2D bounds = getImageBounds(ctx, e);
if ((bounds.getWidth() == 0) || (bounds.getHeight() == 0)) {
ShapeNode sn = new ShapeNode();
sn.setShape(bounds);
return sn;
}
SVGDocument svgDoc = (SVGDocument)e.getOwnerDocument();
String docURL = svgDoc.getURL();
ParsedURL pDocURL = null;
if (docURL != null)
pDocURL = new ParsedURL(docURL);
UserAgent userAgent = ctx.getUserAgent();
try {
userAgent.checkLoadExternalResource(purl, pDocURL);
} catch (SecurityException secEx ) {
throw new BridgeException(ctx, e, secEx, ERR_URI_UNSECURE,
new Object[] {purl});
}
DocumentLoader loader = ctx.getDocumentLoader();
ImageTagRegistry reg = ImageTagRegistry.getRegistry();
ICCColorSpaceExt colorspace = extractColorSpace(e, ctx);
{
/**
* Before we open the URL we see if we have the
* URL already cached and parsed
*/
try {
/* Check the document loader cache */
Document doc = loader.checkCache(purl.toString());
if (doc != null) {
imgDocument = (SVGDocument)doc;
return createSVGImageNode(ctx, e, imgDocument);
}
} catch (BridgeException ex) {
throw ex;
} catch (Exception ex) {
/* Nothing to do */
}
/* Check the ImageTagRegistry Cache */
Filter img = reg.checkCache(purl, colorspace);
if (img != null) {
return createRasterImageNode(ctx, e, img, purl);
}
}
/* The Protected Stream ensures that the stream doesn't
* get closed unless we want it to. It is also based on
* a Buffered Reader so in general we can mark the start
* and reset rather than reopening the stream. Finally
* it hides the mark/reset methods so only we get to
* use them.
*/
ProtectedStream reference = null;
try {
reference = openStream(e, purl);
} catch (SecurityException secEx ) {
throw new BridgeException(ctx, e, secEx, ERR_URI_UNSECURE,
new Object[] {purl});
} catch (IOException ioe) {
return createBrokenImageNode(ctx, e, purl.toString(),
ioe.getLocalizedMessage());
}
{
/**
* First see if we can id the file as a Raster via magic
* number. This is probably the fastest mechanism.
* We tell the registry what the source purl is but we
* tell it not to open that url.
*/
Filter img = reg.readURL(reference, purl, colorspace,
false, false);
if (img != null) {
try {
reference.tie();
} catch (IOException ioe) {
// This would be from a close, Let it slide...
}
// It's a bouncing baby Raster...
return createRasterImageNode(ctx, e, img, purl);
}
}
try {
// Reset the stream for next try.
reference.retry();
} catch (IOException ioe) {
reference.release();
reference = null;
try {
// Couldn't reset stream so reopen it.
reference = openStream(e, purl);
} catch (IOException ioe2) {
// Since we already opened the stream this is unlikely.
return createBrokenImageNode(ctx, e, purl.toString(),
ioe2.getLocalizedMessage());
}
}
try {
/**
* Next see if it's an XML document.
*/
Document doc = loader.loadDocument(purl.toString(), reference);
reference.release();
imgDocument = (SVGDocument)doc;
return createSVGImageNode(ctx, e, imgDocument);
} catch (BridgeException ex) {
reference.release();
throw ex;
} catch (SecurityException secEx ) {
reference.release();
throw new BridgeException(ctx, e, secEx, ERR_URI_UNSECURE,
new Object[] {purl});
} catch (InterruptedIOException iioe) {
reference.release();
if (HaltingThread.hasBeenHalted())
throw new InterruptedBridgeException();
} catch (InterruptedBridgeException ibe) {
reference.release();
throw ibe;
} catch (Exception ex) {
/* Do nothing drop out... */
// ex.printStackTrace();
}
try {
reference.retry();
} catch (IOException ioe) {
reference.release();
reference = null;
try {
// Couldn't reset stream so reopen it.
reference = openStream(e, purl);
} catch (IOException ioe2) {
return createBrokenImageNode(ctx, e, purl.toString(),
ioe2.getLocalizedMessage());
}
}
try {
// Finally try to load the image as a raster image (JPG or
// PNG) allowing the registry to open the url (so the
// JDK readers can be checked).
Filter img = reg.readURL(reference, purl, colorspace,
true, true);
if (img != null) {
// It's a bouncing baby Raster...
return createRasterImageNode(ctx, e, img, purl);
}
} finally {
reference.release();
}
return null;
}
// in sources/org/apache/batik/bridge/SVGImageElementBridge.java
public void handleAnimatedAttributeChanged
(AnimatedLiveAttributeValue alav) {
try {
String ns = alav.getNamespaceURI();
String ln = alav.getLocalName();
if (ns == null) {
if (ln.equals(SVG_X_ATTRIBUTE)
|| ln.equals(SVG_Y_ATTRIBUTE)) {
updateImageBounds();
return;
} else if (ln.equals(SVG_WIDTH_ATTRIBUTE)
|| ln.equals(SVG_HEIGHT_ATTRIBUTE)) {
SVGImageElement ie = (SVGImageElement) e;
ImageNode imageNode = (ImageNode) node;
AbstractSVGAnimatedLength _attr;
if (ln.charAt(0) == 'w') {
_attr = (AbstractSVGAnimatedLength) ie.getWidth();
} else {
_attr = (AbstractSVGAnimatedLength) ie.getHeight();
}
float val = _attr.getCheckedValue();
if (val == 0 || imageNode.getImage() instanceof ShapeNode) {
rebuildImageNode();
} else {
updateImageBounds();
}
return;
} else if (ln.equals(SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE)) {
updateImageBounds();
return;
}
} else if (ns.equals(XLINK_NAMESPACE_URI)
&& ln.equals(XLINK_HREF_ATTRIBUTE)) {
rebuildImageNode();
return;
}
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
super.handleAnimatedAttributeChanged(alav);
}
// in sources/org/apache/batik/bridge/SVGImageElementBridge.java
protected void rebuildImageNode() {
// Reference copy of the imgDocument
if ((imgDocument != null) && (listener != null)) {
NodeEventTarget tgt = (NodeEventTarget)imgDocument.getRootElement();
tgt.removeEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, SVG_EVENT_CLICK,
listener, false);
tgt.removeEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, SVG_EVENT_KEYDOWN,
listener, false);
tgt.removeEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, SVG_EVENT_KEYPRESS,
listener, false);
tgt.removeEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, SVG_EVENT_KEYUP,
listener, false);
tgt.removeEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, SVG_EVENT_MOUSEDOWN,
listener, false);
tgt.removeEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, SVG_EVENT_MOUSEMOVE,
listener, false);
tgt.removeEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, SVG_EVENT_MOUSEOUT,
listener, false);
tgt.removeEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, SVG_EVENT_MOUSEOVER,
listener, false);
tgt.removeEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, SVG_EVENT_MOUSEUP,
listener, false);
listener = null;
}
if (imgDocument != null) {
SVGSVGElement svgElement = imgDocument.getRootElement();
disposeTree(svgElement);
}
imgDocument = null;
subCtx = null;
//update of the reference of the image.
GraphicsNode inode = buildImageGraphicsNode(ctx,e);
ImageNode imgNode = (ImageNode)node;
imgNode.setImage(inode);
if (inode == null) {
SVGImageElement ie = (SVGImageElement) e;
String uriStr = ie.getHref().getAnimVal();
throw new BridgeException(ctx, e, ERR_URI_IMAGE_INVALID,
new Object[] {uriStr});
}
}
// in sources/org/apache/batik/bridge/SVGImageElementBridge.java
protected static void initializeViewport(BridgeContext ctx,
Element e,
GraphicsNode node,
float[] vb,
Rectangle2D bounds) {
float x = (float)bounds.getX();
float y = (float)bounds.getY();
float w = (float)bounds.getWidth();
float h = (float)bounds.getHeight();
try {
SVGImageElement ie = (SVGImageElement) e;
SVGOMAnimatedPreserveAspectRatio _par =
(SVGOMAnimatedPreserveAspectRatio) ie.getPreserveAspectRatio();
_par.check();
AffineTransform at = ViewBox.getPreserveAspectRatioTransform
(e, vb, w, h, _par, ctx);
at.preConcatenate(AffineTransform.getTranslateInstance(x, y));
node.setTransform(at);
// 'overflow' and 'clip'
Shape clip = null;
if (CSSUtilities.convertOverflow(e)) { // overflow:hidden
float [] offsets = CSSUtilities.convertClip(e);
if (offsets == null) { // clip:auto
clip = new Rectangle2D.Float(x, y, w, h);
} else { // clip:rect(<x> <y> <w> <h>)
// offsets[0] = top
// offsets[1] = right
// offsets[2] = bottom
// offsets[3] = left
clip = new Rectangle2D.Float(x+offsets[3],
y+offsets[0],
w-offsets[1]-offsets[3],
h-offsets[2]-offsets[0]);
}
}
if (clip != null) {
try {
at = at.createInverse(); // clip in user space
Filter filter = node.getGraphicsNodeRable(true);
clip = at.createTransformedShape(clip);
node.setClip(new ClipRable8Bit(filter, clip));
} catch (java.awt.geom.NoninvertibleTransformException ex) {}
}
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// in sources/org/apache/batik/bridge/SVGImageElementBridge.java
protected static Rectangle2D getImageBounds(BridgeContext ctx,
Element element) {
try {
SVGImageElement ie = (SVGImageElement) element;
// 'x' attribute - default is 0
AbstractSVGAnimatedLength _x =
(AbstractSVGAnimatedLength) ie.getX();
float x = _x.getCheckedValue();
// 'y' attribute - default is 0
AbstractSVGAnimatedLength _y =
(AbstractSVGAnimatedLength) ie.getY();
float y = _y.getCheckedValue();
// 'width' attribute - required
AbstractSVGAnimatedLength _width =
(AbstractSVGAnimatedLength) ie.getWidth();
float w = _width.getCheckedValue();
// 'height' attribute - required
AbstractSVGAnimatedLength _height =
(AbstractSVGAnimatedLength) ie.getHeight();
float h = _height.getCheckedValue();
return new Rectangle2D.Float(x, y, w, h);
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// in sources/org/apache/batik/bridge/AbstractSVGFilterPrimitiveElementBridge.java
protected static Filter getIn2(Element filterElement,
Element filteredElement,
GraphicsNode filteredNode,
Filter inputFilter,
Map filterMap,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, SVG_IN2_ATTRIBUTE);
if (s.length() == 0) {
throw new BridgeException(ctx, filterElement, ERR_ATTRIBUTE_MISSING,
new Object [] {SVG_IN2_ATTRIBUTE});
}
return getFilterSource(filterElement,
s,
filteredElement,
filteredNode,
filterMap,
ctx);
}
// in sources/org/apache/batik/bridge/AbstractSVGFilterPrimitiveElementBridge.java
protected static int convertInteger(Element filterElement,
String attrName,
int defaultValue,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, attrName);
if (s.length() == 0) {
return defaultValue;
} else {
try {
return SVGUtilities.convertSVGInteger(s);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attrName, s});
}
}
}
// in sources/org/apache/batik/bridge/AbstractSVGFilterPrimitiveElementBridge.java
protected static float convertNumber(Element filterElement,
String attrName,
float defaultValue,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, attrName);
if (s.length() == 0) {
return defaultValue;
} else {
try {
return SVGUtilities.convertSVGNumber(s);
} catch (NumberFormatException nfEx) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attrName, s, nfEx});
}
}
}
// in sources/org/apache/batik/bridge/UnitProcessor.java
public static float svgLengthToObjectBoundingBox(String s,
String attr,
short d,
Context ctx) {
float v = svgToObjectBoundingBox(s, attr, d, ctx);
if (v < 0) {
throw new BridgeException(getBridgeContext(ctx), ctx.getElement(),
ErrorConstants.ERR_LENGTH_NEGATIVE,
new Object[] {attr, s});
}
return v;
}
// in sources/org/apache/batik/bridge/UnitProcessor.java
public static float svgToObjectBoundingBox(String s,
String attr,
short d,
Context ctx) {
try {
return org.apache.batik.parser.UnitProcessor.
svgToObjectBoundingBox(s, attr, d, ctx);
} catch (ParseException pEx ) {
throw new BridgeException
(getBridgeContext(ctx), ctx.getElement(),
pEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attr, s, pEx });
}
}
// in sources/org/apache/batik/bridge/UnitProcessor.java
public static float svgLengthToUserSpace(String s,
String attr,
short d,
Context ctx) {
float v = svgToUserSpace(s, attr, d, ctx);
if (v < 0) {
throw new BridgeException(getBridgeContext(ctx), ctx.getElement(),
ErrorConstants.ERR_LENGTH_NEGATIVE,
new Object[] {attr, s});
} else {
return v;
}
}
// in sources/org/apache/batik/bridge/UnitProcessor.java
public static float svgToUserSpace(String s,
String attr,
short d,
Context ctx) {
try {
return org.apache.batik.parser.UnitProcessor.
svgToUserSpace(s, attr, d, ctx);
} catch (ParseException pEx ) {
throw new BridgeException
(getBridgeContext(ctx), ctx.getElement(),
pEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attr, s, pEx, });
}
}
// in sources/org/apache/batik/bridge/SVGMarkerElementBridge.java
public Marker createMarker(BridgeContext ctx,
Element markerElement,
Element paintedElement) {
GVTBuilder builder = ctx.getGVTBuilder();
CompositeGraphicsNode markerContentNode
= new CompositeGraphicsNode();
// build the GVT tree that represents the marker
boolean hasChildren = false;
for(Node n = markerElement.getFirstChild();
n != null;
n = n.getNextSibling()) {
// check if the node is a valid Element
if (n.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
Element child = (Element)n;
GraphicsNode markerNode = builder.build(ctx, child) ;
// check if a GVT node has been created
if (markerNode == null) {
continue; // skip element as <marker> can contain <defs>...
}
hasChildren = true;
markerContentNode.getChildren().add(markerNode);
}
if (!hasChildren) {
return null; // no marker content defined
}
String s;
UnitProcessor.Context uctx
= UnitProcessor.createContext(ctx, paintedElement);
// 'markerWidth' attribute - default is 3
float markerWidth = 3;
s = markerElement.getAttributeNS(null, SVG_MARKER_WIDTH_ATTRIBUTE);
if (s.length() != 0) {
markerWidth = UnitProcessor.svgHorizontalLengthToUserSpace
(s, SVG_MARKER_WIDTH_ATTRIBUTE, uctx);
}
if (markerWidth == 0) {
// A value of zero disables rendering of the element.
return null;
}
// 'markerHeight' attribute - default is 3
float markerHeight = 3;
s = markerElement.getAttributeNS(null, SVG_MARKER_HEIGHT_ATTRIBUTE);
if (s.length() != 0) {
markerHeight = UnitProcessor.svgVerticalLengthToUserSpace
(s, SVG_MARKER_HEIGHT_ATTRIBUTE, uctx);
}
if (markerHeight == 0) {
// A value of zero disables rendering of the element.
return null;
}
// 'orient' attribute - default is '0'
double orient;
s = markerElement.getAttributeNS(null, SVG_ORIENT_ATTRIBUTE);
if (s.length() == 0) {
orient = 0;
} else if (SVG_AUTO_VALUE.equals(s)) {
orient = Double.NaN;
} else {
try {
orient = SVGUtilities.convertSVGNumber(s);
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, markerElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {SVG_ORIENT_ATTRIBUTE, s});
}
}
// 'stroke-width' property
Value val = CSSUtilities.getComputedStyle
(paintedElement, SVGCSSEngine.STROKE_WIDTH_INDEX);
float strokeWidth = val.getFloatValue();
// 'markerUnits' attribute - default is 'strokeWidth'
short unitsType;
s = markerElement.getAttributeNS(null, SVG_MARKER_UNITS_ATTRIBUTE);
if (s.length() == 0) {
unitsType = SVGUtilities.STROKE_WIDTH;
} else {
unitsType = SVGUtilities.parseMarkerCoordinateSystem
(markerElement, SVG_MARKER_UNITS_ATTRIBUTE, s, ctx);
}
//
//
//
// compute an additional transform for 'strokeWidth' coordinate system
AffineTransform markerTxf;
if (unitsType == SVGUtilities.STROKE_WIDTH) {
markerTxf = new AffineTransform();
markerTxf.scale(strokeWidth, strokeWidth);
} else {
markerTxf = new AffineTransform();
}
// 'viewBox' and 'preserveAspectRatio' attributes
// viewBox -> viewport(0, 0, markerWidth, markerHeight)
AffineTransform preserveAspectRatioTransform
= ViewBox.getPreserveAspectRatioTransform(markerElement,
markerWidth,
markerHeight, ctx);
if (preserveAspectRatioTransform == null) {
// disable the rendering of the element
return null;
} else {
markerTxf.concatenate(preserveAspectRatioTransform);
}
// now we can set the transform to the 'markerContentNode'
markerContentNode.setTransform(markerTxf);
// 'overflow' property
if (CSSUtilities.convertOverflow(markerElement)) { // overflow:hidden
Rectangle2D markerClip;
float [] offsets = CSSUtilities.convertClip(markerElement);
if (offsets == null) { // clip:auto
markerClip
= new Rectangle2D.Float(0,
0,
strokeWidth * markerWidth,
strokeWidth * markerHeight);
} else { // clip:rect(<x>, <y>, <w>, <h>)
// offsets[0] = top
// offsets[1] = right
// offsets[2] = bottom
// offsets[3] = left
markerClip = new Rectangle2D.Float
(offsets[3],
offsets[0],
strokeWidth * markerWidth - offsets[1] - offsets[3],
strokeWidth * markerHeight - offsets[2] - offsets[0]);
}
CompositeGraphicsNode comp = new CompositeGraphicsNode();
comp.getChildren().add(markerContentNode);
Filter clipSrc = comp.getGraphicsNodeRable(true);
comp.setClip(new ClipRable8Bit(clipSrc, markerClip));
markerContentNode = comp;
}
// 'refX' attribute - default is 0
float refX = 0;
s = markerElement.getAttributeNS(null, SVG_REF_X_ATTRIBUTE);
if (s.length() != 0) {
refX = UnitProcessor.svgHorizontalCoordinateToUserSpace
(s, SVG_REF_X_ATTRIBUTE, uctx);
}
// 'refY' attribute - default is 0
float refY = 0;
s = markerElement.getAttributeNS(null, SVG_REF_Y_ATTRIBUTE);
if (s.length() != 0) {
refY = UnitProcessor.svgVerticalCoordinateToUserSpace
(s, SVG_REF_Y_ATTRIBUTE, uctx);
}
// TK: Warning at this time, refX and refY are relative to the
// paintedElement's coordinate system. We need to move the
// reference point to the marker's coordinate system
// Watch out: the reference point is defined a little weirdly in the
// SVG spec., but the bottom line is that the marker content should
// not be translated. Rather, the reference point should be computed
// in viewport space (this is what the following transform
// does) and used when placing the marker.
//
float[] ref = {refX, refY};
markerTxf.transform(ref, 0, ref, 0, 1);
Marker marker = new Marker(markerContentNode,
new Point2D.Float(ref[0], ref[1]),
orient);
return marker;
}
// in sources/org/apache/batik/bridge/SVGAnimateElementBridge.java
protected int parseCalcMode() {
// If the attribute being animated has only non-additive values, take
// the animation as having calcMode="discrete".
if (animationType == AnimationEngine.ANIM_TYPE_CSS
&& !targetElement.isPropertyAdditive(attributeLocalName)
|| animationType == AnimationEngine.ANIM_TYPE_XML
&& !targetElement.isAttributeAdditive(attributeNamespaceURI,
attributeLocalName)) {
return SimpleAnimation.CALC_MODE_DISCRETE;
}
String calcModeString = element.getAttributeNS(null,
SVG_CALC_MODE_ATTRIBUTE);
if (calcModeString.length() == 0) {
return getDefaultCalcMode();
} else if (calcModeString.equals(SMILConstants.SMIL_LINEAR_VALUE)) {
return SimpleAnimation.CALC_MODE_LINEAR;
} else if (calcModeString.equals(SMILConstants.SMIL_DISCRETE_VALUE)) {
return SimpleAnimation.CALC_MODE_DISCRETE;
} else if (calcModeString.equals(SMILConstants.SMIL_PACED_VALUE)) {
return SimpleAnimation.CALC_MODE_PACED;
} else if (calcModeString.equals(SMILConstants.SMIL_SPLINE_VALUE)) {
return SimpleAnimation.CALC_MODE_SPLINE;
}
throw new BridgeException
(ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_CALC_MODE_ATTRIBUTE, calcModeString });
}
// in sources/org/apache/batik/bridge/SVGAnimateElementBridge.java
protected boolean parseAdditive() {
String additiveString = element.getAttributeNS(null,
SVG_ADDITIVE_ATTRIBUTE);
if (additiveString.length() == 0
|| additiveString.equals(SMILConstants.SMIL_REPLACE_VALUE)) {
return false;
} else if (additiveString.equals(SMILConstants.SMIL_SUM_VALUE)) {
return true;
}
throw new BridgeException
(ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_ADDITIVE_ATTRIBUTE, additiveString });
}
// in sources/org/apache/batik/bridge/SVGAnimateElementBridge.java
protected boolean parseAccumulate() {
String accumulateString =
element.getAttributeNS(null, SVG_ACCUMULATE_ATTRIBUTE);
if (accumulateString.length() == 0 ||
accumulateString.equals(SMILConstants.SMIL_NONE_VALUE)) {
return false;
} else if (accumulateString.equals(SMILConstants.SMIL_SUM_VALUE)) {
return true;
}
throw new BridgeException
(ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_ACCUMULATE_ATTRIBUTE, accumulateString });
}
// in sources/org/apache/batik/bridge/SVGAnimateElementBridge.java
protected AnimatableValue[] parseValues() {
boolean isCSS = animationType == AnimationEngine.ANIM_TYPE_CSS;
String valuesString = element.getAttributeNS(null,
SVG_VALUES_ATTRIBUTE);
int len = valuesString.length();
if (len == 0) {
return null;
}
ArrayList values = new ArrayList(7);
int i = 0, start = 0, end;
char c;
outer: while (i < len) {
while (valuesString.charAt(i) == ' ') {
i++;
if (i == len) {
break outer;
}
}
start = i++;
if (i != len) {
c = valuesString.charAt(i);
while (c != ';') {
i++;
if (i == len) {
break;
}
c = valuesString.charAt(i);
}
}
end = i++;
AnimatableValue val = eng.parseAnimatableValue
(element, animationTarget, attributeNamespaceURI,
attributeLocalName, isCSS, valuesString.substring(start, end));
if (!checkValueType(val)) {
throw new BridgeException
(ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_VALUES_ATTRIBUTE, valuesString });
}
values.add(val);
}
AnimatableValue[] ret = new AnimatableValue[values.size()];
return (AnimatableValue[]) values.toArray(ret);
}
// in sources/org/apache/batik/bridge/SVGAnimateElementBridge.java
protected float[] parseKeyTimes() {
String keyTimesString =
element.getAttributeNS(null, SVG_KEY_TIMES_ATTRIBUTE);
int len = keyTimesString.length();
if (len == 0) {
return null;
}
ArrayList keyTimes = new ArrayList(7);
int i = 0, start = 0, end;
char c;
outer: while (i < len) {
while (keyTimesString.charAt(i) == ' ') {
i++;
if (i == len) {
break outer;
}
}
start = i++;
if (i != len) {
c = keyTimesString.charAt(i);
while (c != ' ' && c != ';') {
i++;
if (i == len) {
break;
}
c = keyTimesString.charAt(i);
}
}
end = i++;
try {
float keyTime =
Float.parseFloat(keyTimesString.substring(start, end));
keyTimes.add(new Float(keyTime));
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, element, nfEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_KEY_TIMES_ATTRIBUTE, keyTimesString });
}
}
len = keyTimes.size();
float[] ret = new float[len];
for (int j = 0; j < len; j++) {
ret[j] = ((Float) keyTimes.get(j)).floatValue();
}
return ret;
}
// in sources/org/apache/batik/bridge/SVGAnimateElementBridge.java
protected float[] parseKeySplines() {
String keySplinesString =
element.getAttributeNS(null, SVG_KEY_SPLINES_ATTRIBUTE);
int len = keySplinesString.length();
if (len == 0) {
return null;
}
List keySplines = new ArrayList(7);
int count = 0, i = 0, start = 0, end;
char c;
outer: while (i < len) {
while (keySplinesString.charAt(i) == ' ') {
i++;
if (i == len) {
break outer;
}
}
start = i++;
if (i != len) {
c = keySplinesString.charAt(i);
while (c != ' ' && c != ',' && c != ';') {
i++;
if (i == len) {
break;
}
c = keySplinesString.charAt(i);
}
end = i++;
if (c == ' ') {
do {
if (i == len) {
break;
}
c = keySplinesString.charAt(i++);
} while (c == ' ');
if (c != ';' && c != ',') {
i--;
}
}
if (c == ';') {
if (count == 3) {
count = 0;
} else {
throw new BridgeException
(ctx, element,
ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_KEY_SPLINES_ATTRIBUTE,
keySplinesString });
}
} else {
count++;
}
} else {
end = i++;
}
try {
float keySplineValue =
Float.parseFloat(keySplinesString.substring(start, end));
keySplines.add(new Float(keySplineValue));
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, element, nfEx, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_KEY_SPLINES_ATTRIBUTE, keySplinesString });
}
}
len = keySplines.size();
float[] ret = new float[len];
for (int j = 0; j < len; j++) {
ret[j] = ((Float) keySplines.get(j)).floatValue();
}
return ret;
}
// in sources/org/apache/batik/bridge/BridgeContext.java
public Node getReferencedNode(Element e, String uri) {
try {
SVGDocument document = (SVGDocument)e.getOwnerDocument();
URIResolver ur = createURIResolver(document, documentLoader);
Node ref = ur.getNode(uri, e);
if (ref == null) {
throw new BridgeException(this, e, ERR_URI_BAD_TARGET,
new Object[] {uri});
} else {
SVGOMDocument refDoc =
(SVGOMDocument) (ref.getNodeType() == Node.DOCUMENT_NODE
? ref
: ref.getOwnerDocument());
// This is new rather than attaching this BridgeContext
// with the new document we now create a whole new
// BridgeContext to go with the new document.
// This means that the new document has it's own
// world of stuff and it should avoid memory leaks
// since the new document isn't 'tied into' this
// bridge context.
if (refDoc != document) {
createSubBridgeContext(refDoc);
}
return ref;
}
} catch (MalformedURLException ex) {
throw new BridgeException(this, e, ex, ERR_URI_MALFORMED,
new Object[] {uri});
} catch (InterruptedIOException ex) {
throw new InterruptedBridgeException();
} catch (IOException ex) {
//ex.printStackTrace();
throw new BridgeException(this, e, ex, ERR_URI_IO,
new Object[] {uri});
} catch (SecurityException ex) {
throw new BridgeException(this, e, ex, ERR_URI_UNSECURE,
new Object[] {uri});
}
}
// in sources/org/apache/batik/bridge/BridgeContext.java
public Element getReferencedElement(Element e, String uri) {
Node ref = getReferencedNode(e, uri);
if (ref != null && ref.getNodeType() != Node.ELEMENT_NODE) {
throw new BridgeException(this, e, ERR_URI_REFERENCE_A_DOCUMENT,
new Object[] {uri});
}
return (Element) ref;
}
// in sources/org/apache/batik/bridge/SVGCircleElementBridge.java
protected void buildShape(BridgeContext ctx,
Element e,
ShapeNode shapeNode) {
try {
SVGOMCircleElement ce = (SVGOMCircleElement) e;
// 'cx' attribute - default is 0
AbstractSVGAnimatedLength _cx =
(AbstractSVGAnimatedLength) ce.getCx();
float cx = _cx.getCheckedValue();
// 'cy' attribute - default is 0
AbstractSVGAnimatedLength _cy =
(AbstractSVGAnimatedLength) ce.getCy();
float cy = _cy.getCheckedValue();
// 'r' attribute - required
AbstractSVGAnimatedLength _r =
(AbstractSVGAnimatedLength) ce.getR();
float r = _r.getCheckedValue();
float x = cx - r;
float y = cy - r;
float w = r * 2;
shapeNode.setShape(new Ellipse2D.Float(x, y, w, w));
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// in sources/org/apache/batik/bridge/SVGFeCompositeElementBridge.java
protected static CompositeRule convertOperator(Element filterElement,
BridgeContext ctx) {
String s = filterElement.getAttributeNS(null, SVG_OPERATOR_ATTRIBUTE);
if (s.length() == 0) {
return CompositeRule.OVER; // default is over
}
if (SVG_ATOP_VALUE.equals(s)) {
return CompositeRule.ATOP;
}
if (SVG_IN_VALUE.equals(s)) {
return CompositeRule.IN;
}
if (SVG_OVER_VALUE.equals(s)) {
return CompositeRule.OVER;
}
if (SVG_OUT_VALUE.equals(s)) {
return CompositeRule.OUT;
}
if (SVG_XOR_VALUE.equals(s)) {
return CompositeRule.XOR;
}
if (SVG_ARITHMETIC_VALUE.equals(s)) {
float k1 = convertNumber(filterElement, SVG_K1_ATTRIBUTE, 0, ctx);
float k2 = convertNumber(filterElement, SVG_K2_ATTRIBUTE, 0, ctx);
float k3 = convertNumber(filterElement, SVG_K3_ATTRIBUTE, 0, ctx);
float k4 = convertNumber(filterElement, SVG_K4_ATTRIBUTE, 0, ctx);
return CompositeRule.ARITHMETIC(k1, k2, k3, k4);
}
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_OPERATOR_ATTRIBUTE, s});
}
// in sources/org/apache/batik/bridge/SVGFeSpecularLightingElementBridge.java
protected static float convertSpecularExponent(Element filterElement,
BridgeContext ctx) {
String s = filterElement.getAttributeNS
(null, SVG_SPECULAR_EXPONENT_ATTRIBUTE);
if (s.length() == 0) {
return 1; // default is 1
} else {
try {
float v = SVGUtilities.convertSVGNumber(s);
if (v < 1 || v > 128) {
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_SPECULAR_CONSTANT_ATTRIBUTE, s});
}
return v;
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_SPECULAR_CONSTANT_ATTRIBUTE, s, nfEx });
}
}
}
// in sources/org/apache/batik/bridge/SVGUseElementBridge.java
public CompositeGraphicsNode buildCompositeGraphicsNode
(BridgeContext ctx, Element e, CompositeGraphicsNode gn) {
// get the referenced element
SVGOMUseElement ue = (SVGOMUseElement) e;
String uri = ue.getHref().getAnimVal();
if (uri.length() == 0) {
throw new BridgeException(ctx, e, ERR_ATTRIBUTE_MISSING,
new Object[] {"xlink:href"});
}
Element refElement = ctx.getReferencedElement(e, uri);
SVGOMDocument document, refDocument;
document = (SVGOMDocument)e.getOwnerDocument();
refDocument = (SVGOMDocument)refElement.getOwnerDocument();
boolean isLocal = (refDocument == document);
BridgeContext theCtx = ctx;
subCtx = null;
if (!isLocal) {
subCtx = (BridgeContext)refDocument.getCSSEngine().getCSSContext();
theCtx = subCtx;
}
// import or clone the referenced element in current document
Element localRefElement;
localRefElement = (Element)document.importNode(refElement, true, true);
if (SVG_SYMBOL_TAG.equals(localRefElement.getLocalName())) {
// The referenced 'symbol' and its contents are deep-cloned into
// the generated tree, with the exception that the 'symbol' is
// replaced by an 'svg'.
Element svgElement = document.createElementNS(SVG_NAMESPACE_URI,
SVG_SVG_TAG);
// move the attributes from <symbol> to the <svg> element
NamedNodeMap attrs = localRefElement.getAttributes();
int len = attrs.getLength();
for (int i = 0; i < len; i++) {
Attr attr = (Attr)attrs.item(i);
svgElement.setAttributeNS(attr.getNamespaceURI(),
attr.getName(),
attr.getValue());
}
// move the children from <symbol> to the <svg> element
for (Node n = localRefElement.getFirstChild();
n != null;
n = localRefElement.getFirstChild()) {
svgElement.appendChild(n);
}
localRefElement = svgElement;
}
if (SVG_SVG_TAG.equals(localRefElement.getLocalName())) {
// The referenced 'svg' and its contents are deep-cloned into the
// generated tree. If attributes width and/or height are provided
// on the 'use' element, then these values will override the
// corresponding attributes on the 'svg' in the generated tree.
try {
SVGOMAnimatedLength al = (SVGOMAnimatedLength) ue.getWidth();
if (al.isSpecified()) {
localRefElement.setAttributeNS
(null, SVG_WIDTH_ATTRIBUTE,
al.getAnimVal().getValueAsString());
}
al = (SVGOMAnimatedLength) ue.getHeight();
if (al.isSpecified()) {
localRefElement.setAttributeNS
(null, SVG_HEIGHT_ATTRIBUTE,
al.getAnimVal().getValueAsString());
}
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// attach the referenced element to the current document
SVGOMUseShadowRoot root;
root = new SVGOMUseShadowRoot(document, e, isLocal);
root.appendChild(localRefElement);
if (gn == null) {
gn = new CompositeGraphicsNode();
associateSVGContext(ctx, e, node);
} else {
int s = gn.size();
for (int i=0; i<s; i++)
gn.remove(0);
}
Node oldRoot = ue.getCSSFirstChild();
if (oldRoot != null) {
disposeTree(oldRoot);
}
ue.setUseShadowTree(root);
Element g = localRefElement;
// compute URIs and style sheets for the used element
CSSUtilities.computeStyleAndURIs(refElement, localRefElement, uri);
GVTBuilder builder = ctx.getGVTBuilder();
GraphicsNode refNode = builder.build(ctx, g);
///////////////////////////////////////////////////////////////////////
gn.getChildren().add(refNode);
gn.setTransform(computeTransform((SVGTransformable) e, ctx));
// set an affine transform to take into account the (x, y)
// coordinates of the <use> element
// 'visibility'
gn.setVisible(CSSUtilities.convertVisibility(e));
RenderingHints hints = null;
hints = CSSUtilities.convertColorRendering(e, hints);
if (hints != null)
gn.setRenderingHints(hints);
// 'enable-background'
Rectangle2D r = CSSUtilities.convertEnableBackground(e);
if (r != null)
gn.setBackgroundEnable(r);
if (l != null) {
// Remove event listeners
NodeEventTarget target = l.target;
target.removeEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMAttrModified",
l, true);
target.removeEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMNodeInserted",
l, true);
target.removeEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMNodeRemoved",
l, true);
target.removeEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMCharacterDataModified",
l, true);
l = null;
}
///////////////////////////////////////////////////////////////////////
// Handle mutations on content referenced in the same file if
// we are in a dynamic context.
if (isLocal && ctx.isDynamic()) {
l = new ReferencedElementMutationListener();
NodeEventTarget target = (NodeEventTarget)refElement;
l.target = target;
target.addEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMAttrModified",
l, true, null);
theCtx.storeEventListenerNS
(target, XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMAttrModified",
l, true);
target.addEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMNodeInserted",
l, true, null);
theCtx.storeEventListenerNS
(target, XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMNodeInserted",
l, true);
target.addEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMNodeRemoved",
l, true, null);
theCtx.storeEventListenerNS
(target, XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMNodeRemoved",
l, true);
target.addEventListenerNS
(XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMCharacterDataModified",
l, true, null);
theCtx.storeEventListenerNS
(target, XMLConstants.XML_EVENTS_NAMESPACE_URI, "DOMCharacterDataModified",
l, true);
}
return gn;
}
// in sources/org/apache/batik/bridge/SVGUseElementBridge.java
protected AffineTransform computeTransform(SVGTransformable e,
BridgeContext ctx) {
AffineTransform at = super.computeTransform(e, ctx);
SVGUseElement ue = (SVGUseElement) e;
try {
// 'x' attribute - default is 0
AbstractSVGAnimatedLength _x =
(AbstractSVGAnimatedLength) ue.getX();
float x = _x.getCheckedValue();
// 'y' attribute - default is 0
AbstractSVGAnimatedLength _y =
(AbstractSVGAnimatedLength) ue.getY();
float y = _y.getCheckedValue();
AffineTransform xy = AffineTransform.getTranslateInstance(x, y);
xy.preConcatenate(at);
return xy;
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// in sources/org/apache/batik/bridge/SVGUseElementBridge.java
public void handleAnimatedAttributeChanged
(AnimatedLiveAttributeValue alav) {
try {
String ns = alav.getNamespaceURI();
String ln = alav.getLocalName();
if (ns == null) {
if (ln.equals(SVG_X_ATTRIBUTE) ||
ln.equals(SVG_Y_ATTRIBUTE) ||
ln.equals(SVG_TRANSFORM_ATTRIBUTE)) {
node.setTransform
(computeTransform((SVGTransformable) e, ctx));
handleGeometryChanged();
}
else if (ln.equals(SVG_WIDTH_ATTRIBUTE) ||
ln.equals(SVG_HEIGHT_ATTRIBUTE))
buildCompositeGraphicsNode
(ctx, e, (CompositeGraphicsNode)node);
} else {
if (ns.equals(XLINK_NAMESPACE_URI) &&
ln.equals(XLINK_HREF_ATTRIBUTE))
buildCompositeGraphicsNode
(ctx, e, (CompositeGraphicsNode)node);
}
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
super.handleAnimatedAttributeChanged(alav);
}
// in sources/org/apache/batik/bridge/SVGAnimationEngine.java
public AnimatableValue parseAnimatableValue(Element animElt,
AnimationTarget target,
String ns, String ln,
boolean isCSS,
String s) {
SVGOMElement elt = (SVGOMElement) target.getElement();
int type;
if (isCSS) {
type = elt.getPropertyType(ln);
} else {
type = elt.getAttributeType(ns, ln);
}
Factory factory = factories[type];
if (factory == null) {
String an = ns == null ? ln : '{' + ns + '}' + ln;
throw new BridgeException
(ctx, animElt, "attribute.not.animatable",
new Object[] { target.getElement().getNodeName(), an });
}
return factories[type].createValue(target, ns, ln, isCSS, s);
}
// in sources/org/apache/batik/bridge/SVGAnimationEngine.java
public AnimatableValue getUnderlyingCSSValue(Element animElt,
AnimationTarget target,
String pn) {
ValueManager[] vms = cssEngine.getValueManagers();
int idx = cssEngine.getPropertyIndex(pn);
if (idx != -1) {
int type = vms[idx].getPropertyType();
Factory factory = factories[type];
if (factory == null) {
throw new BridgeException
(ctx, animElt, "attribute.not.animatable",
new Object[] { target.getElement().getNodeName(), pn });
}
SVGStylableElement e = (SVGStylableElement) target.getElement();
CSSStyleDeclaration over = e.getOverrideStyle();
String oldValue = over.getPropertyValue(pn);
if (oldValue != null) {
over.removeProperty(pn);
}
Value v = cssEngine.getComputedStyle(e, null, idx);
if (oldValue != null && !oldValue.equals("")) {
over.setProperty(pn, oldValue, null);
}
return factories[type].createValue(target, pn, v);
}
// XXX Doesn't handle shorthands.
return null;
}
// in sources/org/apache/batik/bridge/SVGAnimationEngine.java
public void start(long documentStartTime) {
if (started) {
return;
}
started = true;
try {
try {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(documentStartTime));
timedDocumentRoot.resetDocument(cal);
Object[] bridges = initialBridges.toArray();
initialBridges = null;
for (int i = 0; i < bridges.length; i++) {
SVGAnimationElementBridge bridge =
(SVGAnimationElementBridge) bridges[i];
bridge.initializeAnimation();
}
for (int i = 0; i < bridges.length; i++) {
SVGAnimationElementBridge bridge =
(SVGAnimationElementBridge) bridges[i];
bridge.initializeTimedElement();
}
// tick(0, false);
// animationThread = new AnimationThread();
// animationThread.start();
UpdateManager um = ctx.getUpdateManager();
if (um != null) {
RunnableQueue q = um.getUpdateRunnableQueue();
animationTickRunnable = new AnimationTickRunnable(q, this);
q.setIdleRunnable(animationTickRunnable);
if (initialStartTime != 0) {
setCurrentTime(initialStartTime);
}
}
} catch (AnimationException ex) {
throw new BridgeException(ctx, ex.getElement().getElement(),
ex.getMessage());
}
} catch (Exception ex) {
if (ctx.getUserAgent() == null) {
ex.printStackTrace();
} else {
ctx.getUserAgent().displayError(ex);
}
}
}
// in sources/org/apache/batik/bridge/SVGAnimationEngine.java
public void run() {
SVGAnimationEngine eng = getAnimationEngine();
synchronized (eng) {
try {
try {
eng.tick(t, false);
} catch (AnimationException ex) {
throw new BridgeException
(eng.ctx, ex.getElement().getElement(),
ex.getMessage());
}
} catch (Exception ex) {
if (eng.ctx.getUserAgent() == null) {
ex.printStackTrace();
} else {
eng.ctx.getUserAgent().displayError(ex);
}
}
}
}
// in sources/org/apache/batik/bridge/SVGAnimationEngine.java
public void run() {
SVGAnimationEngine eng = getAnimationEngine();
synchronized (eng) {
int animationLimitingMode = eng.animationLimitingMode;
float animationLimitingAmount = eng.animationLimitingAmount;
try {
try {
long before = System.currentTimeMillis();
time.setTime(new Date(before));
float t = eng.timedDocumentRoot.convertWallclockTime(time);
// if (Math.floor(t) > second) {
// second = Math.floor(t);
// System.err.println("fps: " + frames);
// frames = 0;
// }
float t2 = eng.tick(t, false);
long after = System.currentTimeMillis();
long dur = after - before;
if (dur == 0) {
dur = 1;
}
sumTime -= times[timeIndex];
sumTime += dur;
times[timeIndex] = dur;
timeIndex = (timeIndex + 1) % NUM_TIMES;
if (t2 == Float.POSITIVE_INFINITY) {
waitTime = Long.MAX_VALUE;
} else {
waitTime = before + (long) (t2 * 1000) - 1000;
if (waitTime < after) {
waitTime = after;
}
if (animationLimitingMode != 0) {
float ave = (float) sumTime / NUM_TIMES;
float delay;
if (animationLimitingMode == 1) {
// %cpu
delay = ave / animationLimitingAmount - ave;
} else {
// fps
delay = 1000f / animationLimitingAmount - ave;
}
long newWaitTime = after + (long) delay;
if (newWaitTime > waitTime) {
waitTime = newWaitTime;
}
}
}
// frames++;
} catch (AnimationException ex) {
throw new BridgeException
(eng.ctx, ex.getElement().getElement(),
ex.getMessage());
}
exceptionCount = 0;
} catch (Exception ex) {
if (++exceptionCount < MAX_EXCEPTION_COUNT) {
if (eng.ctx.getUserAgent() == null) {
ex.printStackTrace();
} else {
eng.ctx.getUserAgent().displayError(ex);
}
}
}
if (animationLimitingMode == 0) {
// so we don't steal too much time from the Swing thread
try {
Thread.sleep(1);
} catch (InterruptedException ie) {
}
}
}
}
// in sources/org/apache/batik/bridge/SVGFeImageElementBridge.java
public Filter createFilter(BridgeContext ctx,
Element filterElement,
Element filteredElement,
GraphicsNode filteredNode,
Filter inputFilter,
Rectangle2D filterRegion,
Map filterMap) {
// 'xlink:href' attribute
String uriStr = XLinkSupport.getXLinkHref(filterElement);
if (uriStr.length() == 0) {
throw new BridgeException(ctx, filterElement, ERR_ATTRIBUTE_MISSING,
new Object[] {"xlink:href"});
}
//
// According the the SVG specification, feImage behaves like
// <image> if it references an SVG document or a raster image
// and it behaves like a <use> if it references a document
// fragment.
//
// To provide this behavior, depending on whether the uri
// contains a fragment identifier, we create either an
// <image> or a <use> element and request the corresponding
// bridges to build the corresponding GraphicsNode for us.
//
// Then, we take care of the possible transformation needed
// from objectBoundingBox space to user space.
//
Document document = filterElement.getOwnerDocument();
boolean isUse = uriStr.indexOf('#') != -1;
Element contentElement = null;
if (isUse) {
contentElement = document.createElementNS(SVG_NAMESPACE_URI,
SVG_USE_TAG);
} else {
contentElement = document.createElementNS(SVG_NAMESPACE_URI,
SVG_IMAGE_TAG);
}
contentElement.setAttributeNS(XLINK_NAMESPACE_URI,
XLINK_HREF_QNAME,
uriStr);
Element proxyElement = document.createElementNS(SVG_NAMESPACE_URI,
SVG_G_TAG);
proxyElement.appendChild(contentElement);
// feImage's default region is that of the filter chain.
Rectangle2D defaultRegion = filterRegion;
Element filterDefElement = (Element)(filterElement.getParentNode());
Rectangle2D primitiveRegion =
SVGUtilities.getBaseFilterPrimitiveRegion(filterElement,
filteredElement,
filteredNode,
defaultRegion,
ctx);
// System.err.println(">>>>>>>> primitiveRegion : " + primitiveRegion);
contentElement.setAttributeNS(null, SVG_X_ATTRIBUTE, String.valueOf( primitiveRegion.getX() ) );
contentElement.setAttributeNS(null, SVG_Y_ATTRIBUTE, String.valueOf( primitiveRegion.getY() ) );
contentElement.setAttributeNS(null, SVG_WIDTH_ATTRIBUTE, String.valueOf( primitiveRegion.getWidth() ) );
contentElement.setAttributeNS(null, SVG_HEIGHT_ATTRIBUTE, String.valueOf( primitiveRegion.getHeight() ) );
GraphicsNode node = ctx.getGVTBuilder().build(ctx, proxyElement);
Filter filter = node.getGraphicsNodeRable(true);
// 'primitiveUnits' attribute - default is userSpaceOnUse
short coordSystemType;
String s = SVGUtilities.getChainableAttributeNS
(filterDefElement, null, SVG_PRIMITIVE_UNITS_ATTRIBUTE, ctx);
if (s.length() == 0) {
coordSystemType = SVGUtilities.USER_SPACE_ON_USE;
} else {
coordSystemType = SVGUtilities.parseCoordinateSystem
(filterDefElement, SVG_PRIMITIVE_UNITS_ATTRIBUTE, s, ctx);
}
// Compute the transform from object bounding box to user
// space if needed.
AffineTransform at = new AffineTransform();
if (coordSystemType == SVGUtilities.OBJECT_BOUNDING_BOX) {
at = SVGUtilities.toObjectBBox(at, filteredNode);
}
filter = new AffineRable8Bit(filter, at);
// handle the 'color-interpolation-filters' property
handleColorInterpolationFilters(filter, filterElement);
// get filter primitive chain region
Rectangle2D primitiveRegionUserSpace
= SVGUtilities.convertFilterPrimitiveRegion(filterElement,
filteredElement,
filteredNode,
defaultRegion,
filterRegion,
ctx);
filter = new PadRable8Bit(filter, primitiveRegionUserSpace,
PadMode.ZERO_PAD);
// update the filter Map
updateFilterMap(filterElement, filter, filterMap);
return filter;
}
// in sources/org/apache/batik/bridge/TextUtilities.java
public static ArrayList svgRotateArrayToFloats(Element element,
String attrName,
String valueStr,
BridgeContext ctx) {
StringTokenizer st = new StringTokenizer(valueStr, ", ", false);
ArrayList values = new ArrayList();
String s;
while (st.hasMoreTokens()) {
try {
s = st.nextToken();
values.add
(new Float(Math.toRadians
(SVGUtilities.convertSVGNumber(s))));
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, element, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object [] {attrName, valueStr});
}
}
return values;
}
// in sources/org/apache/batik/bridge/SVGEllipseElementBridge.java
protected void buildShape(BridgeContext ctx,
Element e,
ShapeNode shapeNode) {
try {
SVGOMEllipseElement ee = (SVGOMEllipseElement) e;
// 'cx' attribute - default is 0
AbstractSVGAnimatedLength _cx =
(AbstractSVGAnimatedLength) ee.getCx();
float cx = _cx.getCheckedValue();
// 'cy' attribute - default is 0
AbstractSVGAnimatedLength _cy =
(AbstractSVGAnimatedLength) ee.getCy();
float cy = _cy.getCheckedValue();
// 'rx' attribute - required
AbstractSVGAnimatedLength _rx =
(AbstractSVGAnimatedLength) ee.getRx();
float rx = _rx.getCheckedValue();
// 'ry' attribute - required
AbstractSVGAnimatedLength _ry =
(AbstractSVGAnimatedLength) ee.getRy();
float ry = _ry.getCheckedValue();
shapeNode.setShape(new Ellipse2D.Float(cx - rx, cy - ry,
rx * 2, ry * 2));
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// in sources/org/apache/batik/bridge/SVGFeGaussianBlurElementBridge.java
public Filter createFilter(BridgeContext ctx,
Element filterElement,
Element filteredElement,
GraphicsNode filteredNode,
Filter inputFilter,
Rectangle2D filterRegion,
Map filterMap) {
// 'stdDeviation' attribute - default is [0, 0]
float[] stdDeviationXY = convertStdDeviation(filterElement, ctx);
if (stdDeviationXY[0] < 0 || stdDeviationXY[1] < 0) {
throw new BridgeException(ctx, filterElement,
ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_STD_DEVIATION_ATTRIBUTE,
String.valueOf( stdDeviationXY[ 0 ] ) +
stdDeviationXY[1]});
}
// 'in' attribute
Filter in = getIn(filterElement,
filteredElement,
filteredNode,
inputFilter,
filterMap,
ctx);
if (in == null) {
return null; // disable the filter
}
// Default region is the size of in (if in is SourceGraphic or
// SourceAlpha it will already include a pad/crop to the
// proper filter region size).
Rectangle2D defaultRegion = in.getBounds2D();
Rectangle2D primitiveRegion
= SVGUtilities.convertFilterPrimitiveRegion(filterElement,
filteredElement,
filteredNode,
defaultRegion,
filterRegion,
ctx);
// Take the filter primitive region into account, we need to
// pad/crop the input and output.
PadRable pad = new PadRable8Bit(in, primitiveRegion, PadMode.ZERO_PAD);
// build filter
Filter blur = new GaussianBlurRable8Bit
(pad, stdDeviationXY[0], stdDeviationXY[1]);
// handle the 'color-interpolation-filters' property
handleColorInterpolationFilters(blur, filterElement);
PadRable filter
= new PadRable8Bit(blur, primitiveRegion, PadMode.ZERO_PAD);
// update the filter Map
updateFilterMap(filterElement, filter, filterMap);
return filter;
}
// in sources/org/apache/batik/bridge/SVGFeGaussianBlurElementBridge.java
protected static float[] convertStdDeviation(Element filterElement,
BridgeContext ctx) {
String s
= filterElement.getAttributeNS(null, SVG_STD_DEVIATION_ATTRIBUTE);
if (s.length() == 0) {
return new float[] {0, 0};
}
float [] stdDevs = new float[2];
StringTokenizer tokens = new StringTokenizer(s, " ,");
try {
stdDevs[0] = SVGUtilities.convertSVGNumber(tokens.nextToken());
if (tokens.hasMoreTokens()) {
stdDevs[1] = SVGUtilities.convertSVGNumber(tokens.nextToken());
} else {
stdDevs[1] = stdDevs[0];
}
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, filterElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_STD_DEVIATION_ATTRIBUTE, s, nfEx });
}
if (tokens.hasMoreTokens()) {
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_STD_DEVIATION_ATTRIBUTE, s});
}
return stdDevs;
}
// in sources/org/apache/batik/bridge/PaintServer.java
public static Marker convertMarker(Element e,
Value v,
BridgeContext ctx) {
if (v.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
return null; // 'none'
} else {
String uri = v.getStringValue();
Element markerElement = ctx.getReferencedElement(e, uri);
Bridge bridge = ctx.getBridge(markerElement);
if (bridge == null || !(bridge instanceof MarkerBridge)) {
throw new BridgeException(ctx, e, ERR_CSS_URI_BAD_TARGET,
new Object[] {uri});
}
return ((MarkerBridge)bridge).createMarker(ctx, markerElement, e);
}
}
// in sources/org/apache/batik/bridge/PaintServer.java
public static Paint convertURIPaint(Element paintedElement,
GraphicsNode paintedNode,
Value paintDef,
float opacity,
BridgeContext ctx) {
String uri = paintDef.getStringValue();
Element paintElement = ctx.getReferencedElement(paintedElement, uri);
Bridge bridge = ctx.getBridge(paintElement);
if (bridge == null || !(bridge instanceof PaintBridge)) {
throw new BridgeException
(ctx, paintedElement, ERR_CSS_URI_BAD_TARGET,
new Object[] {uri});
}
return ((PaintBridge)bridge).createPaint(ctx,
paintElement,
paintedElement,
paintedNode,
opacity);
}
// in sources/org/apache/batik/bridge/SVGLineElementBridge.java
protected void buildShape(BridgeContext ctx,
Element e,
ShapeNode shapeNode) {
try {
SVGOMLineElement le = (SVGOMLineElement) e;
// 'x1' attribute - default is 0
AbstractSVGAnimatedLength _x1 =
(AbstractSVGAnimatedLength) le.getX1();
float x1 = _x1.getCheckedValue();
// 'y1' attribute - default is 0
AbstractSVGAnimatedLength _y1 =
(AbstractSVGAnimatedLength) le.getY1();
float y1 = _y1.getCheckedValue();
// 'x2' attribute - default is 0
AbstractSVGAnimatedLength _x2 =
(AbstractSVGAnimatedLength) le.getX2();
float x2 = _x2.getCheckedValue();
// 'y2' attribute - default is 0
AbstractSVGAnimatedLength _y2 =
(AbstractSVGAnimatedLength) le.getY2();
float y2 = _y2.getCheckedValue();
shapeNode.setShape(new Line2D.Float(x1, y1, x2, y2));
} catch (LiveAttributeException ex) {
throw new BridgeException(ctx, ex);
}
}
// in sources/org/apache/batik/bridge/SVGUtilities.java
public static String getChainableAttributeNS(Element element,
String namespaceURI,
String attrName,
BridgeContext ctx) {
DocumentLoader loader = ctx.getDocumentLoader();
Element e = element;
List refs = new LinkedList();
for (;;) {
String v = e.getAttributeNS(namespaceURI, attrName);
if (v.length() > 0) { // exit if attribute defined
return v;
}
String uriStr = XLinkSupport.getXLinkHref(e);
if (uriStr.length() == 0) { // exit if no more xlink:href
return "";
}
String baseURI = ((AbstractNode) e).getBaseURI();
ParsedURL purl = new ParsedURL(baseURI, uriStr);
Iterator iter = refs.iterator();
while (iter.hasNext()) {
if (purl.equals(iter.next()))
throw new BridgeException
(ctx, e, ERR_XLINK_HREF_CIRCULAR_DEPENDENCIES,
new Object[] {uriStr});
}
try {
SVGDocument svgDoc = (SVGDocument)e.getOwnerDocument();
URIResolver resolver = ctx.createURIResolver(svgDoc, loader);
e = resolver.getElement(purl.toString(), e);
refs.add(purl);
} catch(IOException ioEx ) {
throw new BridgeException(ctx, e, ioEx, ERR_URI_IO,
new Object[] {uriStr});
} catch(SecurityException secEx ) {
throw new BridgeException(ctx, e, secEx, ERR_URI_UNSECURE,
new Object[] {uriStr});
}
}
}
// in sources/org/apache/batik/bridge/SVGUtilities.java
public static Rectangle2D convertPatternRegion(Element patternElement,
Element paintedElement,
GraphicsNode paintedNode,
BridgeContext ctx) {
// 'x' attribute - default is 0%
String xStr = getChainableAttributeNS
(patternElement, null, SVG_X_ATTRIBUTE, ctx);
if (xStr.length() == 0) {
xStr = SVG_PATTERN_X_DEFAULT_VALUE;
}
// 'y' attribute - default is 0%
String yStr = getChainableAttributeNS
(patternElement, null, SVG_Y_ATTRIBUTE, ctx);
if (yStr.length() == 0) {
yStr = SVG_PATTERN_Y_DEFAULT_VALUE;
}
// 'width' attribute - required
String wStr = getChainableAttributeNS
(patternElement, null, SVG_WIDTH_ATTRIBUTE, ctx);
if (wStr.length() == 0) {
throw new BridgeException
(ctx, patternElement, ERR_ATTRIBUTE_MISSING,
new Object[] {SVG_WIDTH_ATTRIBUTE});
}
// 'height' attribute - required
String hStr = getChainableAttributeNS
(patternElement, null, SVG_HEIGHT_ATTRIBUTE, ctx);
if (hStr.length() == 0) {
throw new BridgeException
(ctx, patternElement, ERR_ATTRIBUTE_MISSING,
new Object[] {SVG_HEIGHT_ATTRIBUTE});
}
// 'patternUnits' attribute - default is 'objectBoundingBox'
short unitsType;
String units = getChainableAttributeNS
(patternElement, null, SVG_PATTERN_UNITS_ATTRIBUTE, ctx);
if (units.length() == 0) {
unitsType = OBJECT_BOUNDING_BOX;
} else {
unitsType = parseCoordinateSystem
(patternElement, SVG_PATTERN_UNITS_ATTRIBUTE, units, ctx);
}
// resolve units in the (referenced) paintedElement's coordinate system
UnitProcessor.Context uctx
= UnitProcessor.createContext(ctx, paintedElement);
return convertRegion(xStr,
yStr,
wStr,
hStr,
unitsType,
paintedNode,
uctx);
}
// in sources/org/apache/batik/bridge/SVGUtilities.java
public static
float [] convertFilterRes(Element filterElement, BridgeContext ctx) {
float [] filterRes = new float[2];
String s = getChainableAttributeNS
(filterElement, null, SVG_FILTER_RES_ATTRIBUTE, ctx);
Float [] vals = convertSVGNumberOptionalNumber
(filterElement, SVG_FILTER_RES_ATTRIBUTE, s, ctx);
if (filterRes[0] < 0 || filterRes[1] < 0) {
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_FILTER_RES_ATTRIBUTE, s});
}
if (vals[0] == null)
filterRes[0] = -1;
else {
filterRes[0] = vals[0].floatValue();
if (filterRes[0] < 0)
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_FILTER_RES_ATTRIBUTE, s});
}
if (vals[1] == null)
filterRes[1] = filterRes[0];
else {
filterRes[1] = vals[1].floatValue();
if (filterRes[1] < 0)
throw new BridgeException
(ctx, filterElement, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_FILTER_RES_ATTRIBUTE, s});
}
return filterRes;
}
// in sources/org/apache/batik/bridge/SVGUtilities.java
public static Float[] convertSVGNumberOptionalNumber(Element elem,
String attrName,
String attrValue,
BridgeContext ctx) {
Float[] ret = new Float[2];
if (attrValue.length() == 0)
return ret;
try {
StringTokenizer tokens = new StringTokenizer(attrValue, " ");
ret[0] = new Float(Float.parseFloat(tokens.nextToken()));
if (tokens.hasMoreTokens()) {
ret[1] = new Float(Float.parseFloat(tokens.nextToken()));
}
if (tokens.hasMoreTokens()) {
throw new BridgeException
(ctx, elem, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attrName, attrValue});
}
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, elem, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attrName, attrValue, nfEx });
}
return ret;
}
// in sources/org/apache/batik/bridge/SVGUtilities.java
public static short parseCoordinateSystem(Element e,
String attr,
String coordinateSystem,
BridgeContext ctx) {
if (SVG_USER_SPACE_ON_USE_VALUE.equals(coordinateSystem)) {
return USER_SPACE_ON_USE;
} else if (SVG_OBJECT_BOUNDING_BOX_VALUE.equals(coordinateSystem)) {
return OBJECT_BOUNDING_BOX;
} else {
throw new BridgeException(ctx, e, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attr, coordinateSystem});
}
}
// in sources/org/apache/batik/bridge/SVGUtilities.java
public static short parseMarkerCoordinateSystem(Element e,
String attr,
String coordinateSystem,
BridgeContext ctx) {
if (SVG_USER_SPACE_ON_USE_VALUE.equals(coordinateSystem)) {
return USER_SPACE_ON_USE;
} else if (SVG_STROKE_WIDTH_VALUE.equals(coordinateSystem)) {
return STROKE_WIDTH;
} else {
throw new BridgeException(ctx, e, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attr, coordinateSystem});
}
}
// in sources/org/apache/batik/bridge/SVGUtilities.java
public static AffineTransform convertTransform(Element e,
String attr,
String transform,
BridgeContext ctx) {
try {
return AWTTransformProducer.createAffineTransform(transform);
} catch (ParseException pEx) {
throw new BridgeException(ctx, e, pEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {attr, transform, pEx });
}
}
// in sources/org/apache/batik/bridge/SVGUtilities.java
public static float convertSnapshotTime(Element e, BridgeContext ctx) {
if (!e.hasAttributeNS(null, SVG_SNAPSHOT_TIME_ATTRIBUTE)) {
return 0f;
}
String t = e.getAttributeNS(null, SVG_SNAPSHOT_TIME_ATTRIBUTE);
if (t.equals(SVG_NONE_VALUE)) {
return 0f;
}
class Handler implements ClockHandler {
float time;
public void clockValue(float t) {
time = t;
}
}
ClockParser p = new ClockParser(false);
Handler h = new Handler();
p.setClockHandler(h);
try {
p.parse(t);
} catch (ParseException pEx ) {
throw new BridgeException
(null, e, pEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_SNAPSHOT_TIME_ATTRIBUTE, t, pEx });
}
return h.time;
}
// in sources/org/apache/batik/bridge/SVGAnimateTransformElementBridge.java
protected short parseType() {
String typeString = element.getAttributeNS(null, SVG_TYPE_ATTRIBUTE);
if (typeString.equals("translate")) {
return SVGTransform.SVG_TRANSFORM_TRANSLATE;
} else if (typeString.equals("scale")) {
return SVGTransform.SVG_TRANSFORM_SCALE;
} else if (typeString.equals("rotate")) {
return SVGTransform.SVG_TRANSFORM_ROTATE;
} else if (typeString.equals("skewX")) {
return SVGTransform.SVG_TRANSFORM_SKEWX;
} else if (typeString.equals("skewY")) {
return SVGTransform.SVG_TRANSFORM_SKEWY;
}
throw new BridgeException
(ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_TYPE_ATTRIBUTE, typeString });
}
// in sources/org/apache/batik/bridge/SVGAnimateTransformElementBridge.java
protected AnimatableValue[] parseValues(short type,
AnimationTarget target) {
String valuesString = element.getAttributeNS(null,
SVG_VALUES_ATTRIBUTE);
int len = valuesString.length();
if (len == 0) {
return null;
}
ArrayList values = new ArrayList(7);
int i = 0, start = 0, end;
char c;
outer: while (i < len) {
while (valuesString.charAt(i) == ' ') {
i++;
if (i == len) {
break outer;
}
}
start = i++;
if (i < len) {
c = valuesString.charAt(i);
while (c != ';') {
i++;
if (i == len) {
break;
}
c = valuesString.charAt(i);
}
}
end = i++;
String valueString = valuesString.substring(start, end);
AnimatableValue value = parseValue(valueString, type, target);
if (value == null) {
throw new BridgeException
(ctx, element, ErrorConstants.ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] { SVG_VALUES_ATTRIBUTE, valuesString });
}
values.add(value);
}
AnimatableValue[] ret = new AnimatableValue[values.size()];
return (AnimatableValue[]) values.toArray(ret);
}
// in sources/org/apache/batik/bridge/SVGFeTurbulenceElementBridge.java
protected static float[] convertBaseFrenquency(Element e,
BridgeContext ctx) {
String s = e.getAttributeNS(null, SVG_BASE_FREQUENCY_ATTRIBUTE);
if (s.length() == 0) {
return new float[] {0.001f, 0.001f};
}
float[] v = new float[2];
StringTokenizer tokens = new StringTokenizer(s, " ,");
try {
v[0] = SVGUtilities.convertSVGNumber(tokens.nextToken());
if (tokens.hasMoreTokens()) {
v[1] = SVGUtilities.convertSVGNumber(tokens.nextToken());
} else {
v[1] = v[0];
}
if (tokens.hasMoreTokens()) {
throw new BridgeException
(ctx, e, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_BASE_FREQUENCY_ATTRIBUTE, s});
}
} catch (NumberFormatException nfEx ) {
throw new BridgeException
(ctx, e, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_BASE_FREQUENCY_ATTRIBUTE, s});
}
if (v[0] < 0 || v[1] < 0) {
throw new BridgeException
(ctx, e, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_BASE_FREQUENCY_ATTRIBUTE, s});
}
return v;
}
// in sources/org/apache/batik/bridge/SVGFeTurbulenceElementBridge.java
protected static boolean convertStitchTiles(Element e, BridgeContext ctx) {
String s = e.getAttributeNS(null, SVG_STITCH_TILES_ATTRIBUTE);
if (s.length() == 0) {
return false;
}
if (SVG_STITCH_VALUE.equals(s)) {
return true;
}
if (SVG_NO_STITCH_VALUE.equals(s)) {
return false;
}
throw new BridgeException(ctx, e, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_STITCH_TILES_ATTRIBUTE, s});
}
// in sources/org/apache/batik/bridge/SVGFeTurbulenceElementBridge.java
protected static boolean convertType(Element e, BridgeContext ctx) {
String s = e.getAttributeNS(null, SVG_TYPE_ATTRIBUTE);
if (s.length() == 0) {
return false;
}
if (SVG_FRACTAL_NOISE_VALUE.equals(s)) {
return true;
}
if (SVG_TURBULENCE_VALUE.equals(s)) {
return false;
}
throw new BridgeException(ctx, e, ERR_ATTRIBUTE_VALUE_MALFORMED,
new Object[] {SVG_TYPE_ATTRIBUTE, s});
}
// in sources/org/apache/batik/bridge/CSSUtilities.java
public static Filter convertFilter(Element filteredElement,
GraphicsNode filteredNode,
BridgeContext ctx) {
Value v = getComputedStyle(filteredElement, SVGCSSEngine.FILTER_INDEX);
int primitiveType = v.getPrimitiveType();
switch ( primitiveType ) {
case CSSPrimitiveValue.CSS_IDENT:
return null; // 'filter:none'
case CSSPrimitiveValue.CSS_URI:
String uri = v.getStringValue();
Element filter = ctx.getReferencedElement(filteredElement, uri);
Bridge bridge = ctx.getBridge(filter);
if (bridge == null || !(bridge instanceof FilterBridge)) {
throw new BridgeException(ctx, filteredElement,
ERR_CSS_URI_BAD_TARGET,
new Object[] {uri});
}
return ((FilterBridge)bridge).createFilter(ctx,
filter,
filteredElement,
filteredNode);
default:
throw new IllegalStateException("Unexpected primitive type:" + primitiveType ); // can't be reached
}
}
// in sources/org/apache/batik/bridge/CSSUtilities.java
public static ClipRable convertClipPath(Element clippedElement,
GraphicsNode clippedNode,
BridgeContext ctx) {
Value v = getComputedStyle(clippedElement,
SVGCSSEngine.CLIP_PATH_INDEX);
int primitiveType = v.getPrimitiveType();
switch ( primitiveType ) {
case CSSPrimitiveValue.CSS_IDENT:
return null; // 'clip-path:none'
case CSSPrimitiveValue.CSS_URI:
String uri = v.getStringValue();
Element cp = ctx.getReferencedElement(clippedElement, uri);
Bridge bridge = ctx.getBridge(cp);
if (bridge == null || !(bridge instanceof ClipBridge)) {
throw new BridgeException(ctx, clippedElement,
ERR_CSS_URI_BAD_TARGET,
new Object[] {uri});
}
return ((ClipBridge)bridge).createClip(ctx,
cp,
clippedElement,
clippedNode);
default:
throw new IllegalStateException("Unexpected primitive type:" + primitiveType ); // can't be reached
}
}
// in sources/org/apache/batik/bridge/CSSUtilities.java
public static Mask convertMask(Element maskedElement,
GraphicsNode maskedNode,
BridgeContext ctx) {
Value v = getComputedStyle(maskedElement, SVGCSSEngine.MASK_INDEX);
int primitiveType = v.getPrimitiveType();
switch ( primitiveType ) {
case CSSPrimitiveValue.CSS_IDENT:
return null; // 'mask:none'
case CSSPrimitiveValue.CSS_URI:
String uri = v.getStringValue();
Element m = ctx.getReferencedElement(maskedElement, uri);
Bridge bridge = ctx.getBridge(m);
if (bridge == null || !(bridge instanceof MaskBridge)) {
throw new BridgeException(ctx, maskedElement,
ERR_CSS_URI_BAD_TARGET,
new Object[] {uri});
}
return ((MaskBridge)bridge).createMask(ctx,
m,
maskedElement,
maskedNode);
default:
throw new IllegalStateException("Unexpected primitive type:" + primitiveType ); // can't be reached
}
}