// 'requiredFeatures', 'requiredExtensions' and 'systemLanguage'
if (!SVGUtilities.matchUserAgent(e, ctx.getUserAgent())) {
return null;
}
CanvasGraphicsNode cgn = new CanvasGraphicsNode();
UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, e);
String s;
// In some cases we converted document fragments which didn't
// have a parent SVG element, this check makes sure only the
// real root of the SVG Document tries to do negotiation with
// the UA.
SVGDocument doc = (SVGDocument)((SVGElement)e).getOwnerDocument();
boolean isOutermost = (doc.getRootElement() == e);
float x = 0;
float y = 0;
// x and y have no meaning on the outermost 'svg' element
if (!isOutermost) {
// 'x' attribute - default is 0
s = e.getAttributeNS(null, SVG_X_ATTRIBUTE);
if (s.length() != 0) {
x = UnitProcessor.svgHorizontalCoordinateToUserSpace
(s, SVG_X_ATTRIBUTE, uctx);
}
// 'y' attribute - default is 0
s = e.getAttributeNS(null, SVG_Y_ATTRIBUTE);
if (s.length() != 0) {
y = UnitProcessor.svgVerticalCoordinateToUserSpace
(s, SVG_Y_ATTRIBUTE, uctx);
}
}
// 'width' attribute - default is 100%
s = e.getAttributeNS(null, SVG_WIDTH_ATTRIBUTE);
if (s.length() == 0) {
s = SVG_SVG_WIDTH_DEFAULT_VALUE;
}
float w = UnitProcessor.svgHorizontalLengthToUserSpace
(s, SVG_WIDTH_ATTRIBUTE, uctx);
// 'height' attribute - default is 100%
s = e.getAttributeNS(null, SVG_HEIGHT_ATTRIBUTE);
if (s.length() == 0) {
s = SVG_SVG_HEIGHT_DEFAULT_VALUE;
}
float h = UnitProcessor.svgVerticalLengthToUserSpace
(s, SVG_HEIGHT_ATTRIBUTE, uctx);
// 'visibility'
cgn.setVisible(CSSUtilities.convertVisibility(e));
// 'viewBox' and "preserveAspectRatio' attributes
AffineTransform viewingTransform =
ViewBox.getPreserveAspectRatioTransform(e, w, h);
float actualWidth = w;
float actualHeight = h;
try {
AffineTransform vtInv = viewingTransform.createInverse();
actualWidth = (float) (w*vtInv.getScaleX());
actualHeight = (float) (h*vtInv.getScaleY());
} catch (NoninvertibleTransformException ex) {}
AffineTransform positionTransform =
AffineTransform.getTranslateInstance(x, y);
// 'overflow' and 'clip'
// The outermost preserveAspectRatio matrix is set by the user
// agent, so we don't need to set the transform for outermost svg
Shape clip = null;
if (!isOutermost) {
cgn.setPositionTransform(positionTransform);
cgn.setViewingTransform(viewingTransform);
} else {
// <!> FIXME: hack to compute the original document's size
if (ctx.getDocumentSize() == null) {
ctx.setDocumentSize(new Dimension((int)w, (int)h));
}
}
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 = new AffineTransform(positionTransform);
at.concatenate(viewingTransform);
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) {}
}
// 'enable-background'
Rectangle2D r = CSSUtilities.convertEnableBackground(e);
if (r != null) {
cgn.setBackgroundEnable(r);
}
ctx.openViewport
(e, new SVGSVGElementViewport((SVGSVGElement)e,
actualWidth,