public void paint(Graphics2D g, Node dom, Rectangle2D viewRect) throws InvalidXMLException { if (g == null) throw new NullPointerException("g is null"); if (dom == null) throw new NullPointerException("dom is null"); Element root = null; if (dom.getNodeType() == Node.DOCUMENT_NODE) { root = Document.class.cast(dom).getDocumentElement(); } else if (dom.getNodeType() == Node.ELEMENT_NODE) { root = Element.class.cast(dom); } if (root == null) throw new InvalidXMLException(dom, "no root"); if (!XMLUtilities.isA(root, SVG.NS, "svg")) throw new InvalidXMLException(root, "not a SVG root"); Dimension2D srcSize = getSize(root); Rectangle2D viewBox = null; Attr viewBoxAttr = root.getAttributeNode("viewBox"); if (viewBoxAttr != null) { String tokens[] = viewBoxAttr.getValue().trim().split("[ \t\n]+"); if (tokens.length != 4) throw new InvalidXMLException(viewBoxAttr, "invalid "); viewBox = new Rectangle2D.Double( Double.parseDouble(tokens[0]), Double.parseDouble(tokens[1]), Double.parseDouble(tokens[2]), Double.parseDouble(tokens[3])); srcSize = new Dimension2D.Double(viewBox.getWidth(), viewBox.getHeight()); } AffineTransform originalTr = null; if (viewRect == null) { viewRect = new Rectangle2D.Double(0, 0, srcSize.getWidth(), srcSize.getHeight()); } else { if (srcSize.getWidth() > 0 && srcSize.getHeight() > 0) { originalTr = g.getTransform(); double ratio = Math.min( viewRect.getWidth() / srcSize.getWidth(), viewRect.getHeight() / srcSize.getHeight()); g.translate( (viewRect.getWidth() - srcSize.getWidth() * ratio) / 2.0, (viewRect.getHeight() - srcSize.getHeight() * ratio) / 2.0); g.scale(ratio, ratio); } } Shape oldclip = g.getClip(); Shuttle shuttle = new Shuttle(g, root); if (viewBox != null) { AffineTransform tr = AffineTransform.getTranslateInstance(-viewBox.getX(), -viewBox.getY()); shuttle.transform.concatenate(tr); Area area = new Area(shuttle.clip); area.intersect( new Area(new Rectangle2D.Double(0, 0, viewBox.getWidth(), viewBox.getHeight()))); shuttle.clip = area; } paint(shuttle); if (originalTr != null) { g.setTransform(originalTr); } g.setClip(oldclip); }