/** Turns a List<CubicCurve2D.Float> into a SVG Element representing a sketch of that spline. */ Element splineToSketch(SVGDocument document, List<CubicCurve2D.Float> spline) { String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; // <g> is an SVG group // TODO: add a random(ish) rotation to the group Element group = document.createElementNS(svgNS, "g"); // For each curve in the path, draw along it using a "brush". In // our case the brush is a simple circle, but this could be changed // to something more advanced. for (CubicCurve2D.Float curve : spline) { // TODO: magic number & step in loop guard for (double i = 0.0; i <= 1.0; i += 0.01) { Point2D result = evalParametric(curve, i); // Add random jitter at some random positive or negative // distance along the unit normal to the tangent of the // curve Point2D n = vectorUnitNormal(evalParametricTangent(curve, i)); float dx = (float) ((Math.random() - 0.5) * n.getX()); float dy = (float) ((Math.random() - 0.5) * n.getY()); Element brush = document.createElementNS(svgNS, "circle"); brush.setAttribute("cx", Double.toString(result.getX() + dx)); brush.setAttribute("cy", Double.toString(result.getY() + dy)); // TODO: magic number for circle radius brush.setAttribute("r", Double.toString(1.0)); brush.setAttribute("fill", "green"); brush.setAttributeNS(null, "z-index", Integer.toString(zOrder.CONTOUR.ordinal())); group.appendChild(brush); } } return group; }
protected void updateSvgDocument() { getBrowserExtension().clearLocalHyperlinkCache(); getBrowserExtension().clearResourceCache(); SVGDocument doc = getSvgDocument(); if (doc == null) { getUiField().setText(""); return; } try { // set the dimensions of the svg element to the size of the browser field Rectangle browserBounds = getAbsoluteBrowserBounds(); doc.getRootElement() .setAttribute(SVGConstants.SVG_HEIGHT_ATTRIBUTE, browserBounds.height + "px"); doc.getRootElement() .setAttribute(SVGConstants.SVG_WIDTH_ATTRIBUTE, browserBounds.width + "px"); // get the svg code as string and rewrite the local links String svgText = getBrowserExtension().adaptLocalHyperlinks(getSvgContentFromDocument(doc), 2); // bugfix for SVG fields to ensure all context menus are closed when the user clicks into the // svg field String contextMenuHideScript = "parent.parent.org.eclipse.rwt.MenuManager.getInstance().update(null, 'mousedown');"; // bugfix so that the svg field inherits the color of the parent container. otherwise it is // always defined white. String backgroundColorInheritScript = null; if (getScoutObject().getBackgroundColor() == null) { backgroundColorInheritScript = "var iframes = parent.document.getElementsByTagName('iframe');" + "for(var i=0;i<iframes.length;i++) {" + " var field=iframes[i].parentNode;" + " var color=field.style.backgroundColor;" + " if(color && color.toLowerCase() === 'rgb(255, 255, 255)') " + " field.style.backgroundColor='';" + "}"; } else { backgroundColorInheritScript = ""; } // set the html content to the browser getUiField() .setText( "<html><body width=\"100%\" height=\"100%\" onload=\"" + backgroundColorInheritScript + "\" onclick=\"" + contextMenuHideScript + "\">" + svgText + "</body></html>"); } catch (Exception e) { LOG.error("preparing svg browser content", e); getUiField().setText(""); } }
public Document(InputStream stream) throws IOException { f = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName()); doc = f.createSVGDocument(null, stream); // Boot the CSS engine userAgent = new UserAgentAdapter(); loader = new DocumentLoader(userAgent); ctx = new BridgeContext(userAgent, loader); ctx.setDynamicState(BridgeContext.DYNAMIC); builder = new GVTBuilder(); rootGN = builder.build(ctx, doc); svgRoot = doc.getRootElement(); vcss = (ViewCSS) doc.getDocumentElement(); }
public void handleEvent(Event evt) { String cx = String.valueOf(Math.floor(Math.random() * 1200)); String cy = String.valueOf(Math.floor(Math.random() * 400)); String r = String.valueOf(Math.floor(Math.random() * 100)); SVGCircleElement circle = (SVGCircleElement) doc.createElementNS(svgNS, "circle"); circle.setAttribute("cx", cx); circle.setAttribute("cy", cy); circle.setAttribute("r", r); circle.setAttribute("fill", "red"); circle.setAttribute("stroke", "blue"); circle.setAttribute("stroke-width", "10"); doc.getDocumentElement().appendChild(circle); System.out.println("Added circle at (" + cx + ", " + cy + ")"); }
private Element getLinkArrows(SVGDocument doc) { Element group = doc.createElementNS("http://www.w3.org/2000/svg", "g"); if (links != null && !links.isEmpty()) { Set linksSet = links.entrySet(); Iterator linksIterator = linksSet.iterator(); while (linksIterator.hasNext()) { Map.Entry<String, Link> link = (Map.Entry<String, Link>) linksIterator.next(); ActivityInterface startActivity = link.getValue().getSource(); ActivityInterface endActivity = link.getValue().getTarget(); String linkName = link.getKey(); // Element pathGroup = doc.createElementNS("http://www.w3.org/2000/svg", "g"); // group.setAttributeNS("xlink", "title", linkName); group.appendChild( drawLink( doc, startActivity.getExitArrowCoords().getXLeft(), startActivity.getExitArrowCoords().getYTop(), endActivity.getEntryArrowCoords().getXLeft(), endActivity.getEntryArrowCoords().getYTop(), startActivity.getStartIconWidth(), link.getKey(), linkName)); // group.appendChild(pathGroup); } } return group; }
protected Element getArrows(SVGDocument doc) { Element group = doc.createElementNS("http://www.w3.org/2000/svg", "g"); if (subActivities != null) { ActivityInterface startActivity = subActivities.get(0); ActivityInterface endActivity = subActivities.get(subActivities.size() - 1); startActivity = endActivity; // Should ignore event/fault handlers org.wso2.carbon.bpel.ui.bpel2svg.SVGCoordinates exitCoords = getExitArrowCoords(); group.appendChild( getArrowDefinition( doc, exitCoords.getXLeft(), exitCoords.getYTop(), startActivity.getEntryArrowCoords().getXLeft(), startActivity.getEntryArrowCoords().getYTop(), name, startActivity, endActivity)); org.wso2.carbon.bpel.ui.bpel2svg.SVGCoordinates entryCoords = getEndEntryArrowCoords(); group.appendChild( getArrowDefinition( doc, endActivity.getExitArrowCoords().getXLeft(), endActivity.getExitArrowCoords().getYTop(), entryCoords.getXLeft(), entryCoords.getYTop(), name, startActivity, endActivity)); } return group; }
public void setDocument(SVGDocument doc) { Element el = doc.getElementById("draft"); prepare(el.getChildNodes()); String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; // we parse the viewBox String s = doc.getDocumentElement().getAttribute("viewBox"); String[] data = s.split("\\s+"); // we create a invisible rectangle for the capturing the mouse events double y = Double.parseDouble(data[1]); double width = Double.parseDouble(data[2]); fontSize = width / 5; this.labelID = doc.createElementNS(svgNS, "text"); this.labelID.setAttributeNS(null, "x", data[0]); this.labelID.setAttributeNS(null, "y", "" + (y + fontSize)); this.labelID.setAttributeNS(null, "style", "stroke-width:12pt"); this.labelID.setAttributeNS(null, "visibility", "hidden"); this.text = doc.createTextNode("Handle"); this.labelID.appendChild(text); doc.getDocumentElement().insertBefore(this.labelID, doc.getDocumentElement().getFirstChild()); }
@Override public SVGDocument toSVG(ConcreteDiagram cd) { /* * Use a Plain drawer to generate an SVG Document, then * "post-process" any SVG circles in the document to convert them * into "sketches". */ SVGDocument document = (new PlainCircleSVGDrawer()).toSVG(cd); // return document; // find each circle in the document and turn it into a sketch. We // need to keep track of the circles and their eventual replacements // as each circle is replaced by 10's of smaller circles, thus the // DOM updates and we get the 10's of circles in our NodeList circles. NodeList circles = document.getElementsByTagName("circle"); List<Node> replaceable = nodeListToList(circles); for (Node n : replaceable) { Node circleAsSketch = circleToSketch(document, (SVGCircleElement) n); n.getParentNode().replaceChild(circleAsSketch, n); } return document; }
public static void main(String[] args) throws Exception { // Create an SVG document. DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; SVGDocument doc = (SVGDocument) impl.createDocument(svgNS, "svg", null); // Create a converter for this document. SVGGraphics2D g = new SVGGraphics2D(doc); // Do some drawing. Shape circle = new Ellipse2D.Double(0, 0, 50, 50); g.setPaint(Color.red); g.fill(circle); g.translate(60, 0); g.setPaint(Color.green); g.fill(circle); g.translate(60, 0); g.setPaint(Color.blue); g.fill(circle); g.setSVGCanvasSize(new Dimension(180, 50)); // Populate the document root with the generated SVG content. Element root = doc.getDocumentElement(); g.getRoot(root); Writer out = new OutputStreamWriter(System.out, "UTF-8"); g.stream(out, true); // Display the document. JSVGCanvas canvas = new JSVGCanvas(); JFrame f = new JFrame(); f.getContentPane().add(canvas); canvas.setSVGDocument(doc); f.pack(); f.setVisible(true); }
protected static String getSvgContentFromDocument(SVGDocument doc) throws ProcessingException { try { ByteArrayOutputStream out = new ByteArrayOutputStream(); DOMSource domSource = new DOMSource(doc.getRootElement()); StreamResult streamResult = new StreamResult(out); Transformer t = TransformerFactory.newInstance().newTransformer(); t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); t.setOutputProperty(OutputKeys.ENCODING, DOCUMENT_ENCODING); t.transform(domSource, streamResult); out.close(); return new String(out.toByteArray(), DOCUMENT_ENCODING); } catch (Exception e) { throw new ProcessingException("Writing SVG Failed", e); } }
protected Element getDefs(SVGDocument doc) { Element defs = doc.createElementNS("http://www.w3.org/2000/svg", "defs"); defs.setAttributeNS(null, "id", "defs4"); Element marker1 = doc.createElementNS("http://www.w3.org/2000/svg", "marker"); marker1.setAttributeNS(null, "refX", "0"); marker1.setAttributeNS(null, "refY", "0"); marker1.setAttributeNS(null, "orient", "auto"); marker1.setAttributeNS(null, "id", "Arrow1Lend"); marker1.setAttributeNS(null, "style", "overflow:visible"); Element path1 = doc.createElementNS("http://www.w3.org/2000/svg", "path"); path1.setAttributeNS(null, "d", "M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"); path1.setAttributeNS(null, "transform", "matrix(-0.8,0,0,-0.8,-10,0)"); path1.setAttributeNS(null, "id", "path3166"); path1.setAttributeNS( null, "style", "fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"); Element marker2 = doc.createElementNS("http://www.w3.org/2000/svg", "marker"); marker2.setAttributeNS(null, "refX", "0"); marker2.setAttributeNS(null, "refY", "0"); marker2.setAttributeNS(null, "orient", "auto"); marker2.setAttributeNS(null, "id", "Arrow1Mend"); marker2.setAttributeNS(null, "style", "overflow:visible"); Element path2 = doc.createElementNS("http://www.w3.org/2000/svg", "path"); path2.setAttributeNS(null, "d", "M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"); path2.setAttributeNS(null, "transform", "matrix(-0.8,0,0,-0.8,-10,0)"); path2.setAttributeNS(null, "id", "path3193"); path2.setAttributeNS( null, "style", "fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"); Element linkMarker = doc.createElementNS("http://www.w3.org/2000/svg", "marker"); linkMarker.setAttributeNS(null, "refX", "0"); linkMarker.setAttributeNS(null, "refY", "0"); linkMarker.setAttributeNS(null, "orient", "auto"); linkMarker.setAttributeNS(null, "id", "LinkArrow"); linkMarker.setAttributeNS(null, "style", "overflow:visible"); Element linkPath = doc.createElementNS("http://www.w3.org/2000/svg", "path"); // linkPath.setAttributeNS(null, "d", "M 0,0 L 2.5,-7.5 L -1,0 L 2.5,7.5 L 0,0 z"); linkPath.setAttributeNS(null, "d", "M -11.5,0 L -7,-7.5 L -12.5,0 L -7,7.5 L -11.5,0 z"); linkPath.setAttributeNS(null, "transform", "matrix(-0.8,0,0,-0.8,-10,0)"); linkPath.setAttributeNS(null, "id", "linkPath"); linkPath.setAttributeNS( null, "style", "fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"); Element linearGradient = doc.createElementNS("http://www.w3.org/2000/svg", "linearGradient"); linearGradient.setAttributeNS(null, "id", "orange_red"); linearGradient.setAttributeNS(null, "x1", "0%"); linearGradient.setAttributeNS(null, "y1", "0%"); linearGradient.setAttributeNS(null, "x2", "0%"); linearGradient.setAttributeNS(null, "y2", "100%"); Element stop1 = doc.createElementNS("http://www.w3.org/2000/svg", "stop"); stop1.setAttributeNS(null, "offset", "0%"); stop1.setAttributeNS(null, "style", "stop-color:rgb(255,255,255);stop-opacity:1"); Element stop2 = doc.createElementNS( "http://www.w3.org/2000/svg", "stop"); // these should be taken from the svg factory stop2.setAttributeNS(null, "offset", "100%"); stop2.setAttributeNS( null, "style", "stop-color:rgb(0,0,255);stop-opacity:1"); // these should be taken from the svg factory marker1.appendChild(path1); marker2.appendChild(path2); linkMarker.appendChild(linkPath); defs.appendChild(marker1); defs.appendChild(marker2); defs.appendChild(linkMarker); linearGradient.appendChild(stop1); linearGradient.appendChild(stop2); defs.appendChild(linearGradient); return defs; }
/** * Draws a concreteDiagram as an SVG. * * <p>This approach is wholly declarative. It currently knows nothing about the on screen * rendering of the diagram. To make decisions based on the on screen rendering (such as better * label placement) we will, in future, have to build a GVT (from the Batik library) of the * SVGDocument. * * @returns An SVGDocument DOM structure representing the SVG. */ @Override public SVGDocument toSVG(ConcreteDiagram cd) { // Get a DOMImplementation. DOMImplementation domImpl = SVGDOMImplementation.getDOMImplementation(); // Create an instance of org.w3c.dom.Document. String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; SVGDocument document = (SVGDocument) domImpl.createDocument(svgNS, "svg", null); // Get the root element (the 'svg' element). Element svgRoot = document.getDocumentElement(); // Set the width and height attributes on the root 'svg' element. svgRoot.setAttributeNS(null, "width", Integer.toString(cd.getSize())); svgRoot.setAttributeNS(null, "height", Integer.toString(cd.getSize())); // Draw the shaded zones for (ConcreteZone z : cd.getShadedZones()) { Element path = document.createElementNS(svgNS, "path"); path.setAttributeNS(null, "d", toSVGPath(z.getShape(cd.getBox()))); path.setAttributeNS(null, "fill", "#cccccc"); // grey path.setAttributeNS(null, "z-index", Integer.toString(zOrder.SHADING.ordinal())); svgRoot.appendChild(path); } // TODO: Concrete* should return themselves as DocumentFragments for (CircleContour c : cd.getCircles()) { // Draw the circle Element circle = document.createElementNS(svgNS, "circle"); circle.setAttributeNS(null, "cx", Double.toString(c.get_cx())); circle.setAttributeNS(null, "cy", Double.toString(c.get_cy())); circle.setAttributeNS(null, "r", Double.toString(c.get_radius())); circle.setAttributeNS(null, "z-index", Integer.toString(zOrder.CONTOUR.ordinal())); // Not pretty, but it works. Color strokeColor = c.color(); circle.setAttributeNS( null, "stroke", (null == strokeColor) ? "black" : "#" + toHexString(c.color())); circle.setAttributeNS(null, "stroke-width", "2"); circle.setAttributeNS(null, "fill", "none"); svgRoot.appendChild(circle); // TODO: Put this text in a path around the circle // alternatively come up with some better label placement // algorithm Element text = document.createElementNS(svgNS, "text"); text.setAttributeNS(null, "x", Double.toString(c.get_cx())); text.setAttributeNS(null, "y", Double.toString(c.get_cy() + c.get_radius())); text.setAttributeNS(null, "text-anchor", "middle"); text.setAttributeNS( null, "fill", (null == strokeColor) ? "black" : "#" + toHexString(c.color())); text.setAttributeNS(null, "z-index", Integer.toString(zOrder.LABEL.ordinal())); Text textNode = document.createTextNode(c.ac.getLabel().getLabel()); text.appendChild(textNode); svgRoot.appendChild(text); } for (ConcreteSpider cs : cd.getSpiders()) { for (ConcreteSpiderFoot f : cs.feet) { // Draw the foot Element circle = document.createElementNS(svgNS, "circle"); circle.setAttributeNS(null, "cx", Double.toString(f.getX())); circle.setAttributeNS(null, "cy", Double.toString(f.getY())); circle.setAttributeNS(null, "r", Double.toString(ConcreteSpiderFoot.FOOT_RADIUS)); circle.setAttributeNS(null, "z-index", Integer.toString(zOrder.SPIDER.ordinal())); circle.setAttributeNS(null, "stroke", "black"); circle.setAttributeNS(null, "stroke-width", "2"); circle.setAttributeNS(null, "fill", "black"); svgRoot.appendChild(circle); } for (ConcreteSpiderLeg l : cs.legs) { Element line = document.createElementNS(svgNS, "line"); line.setAttributeNS(null, "x1", Double.toString(l.from.getX())); line.setAttributeNS(null, "y1", Double.toString(l.from.getY())); line.setAttributeNS(null, "x2", Double.toString(l.to.getX())); line.setAttributeNS(null, "y2", Double.toString(l.to.getY())); line.setAttributeNS(null, "z-index", Integer.toString(zOrder.SPIDER.ordinal())); line.setAttributeNS(null, "stroke", "black"); line.setAttributeNS(null, "stroke-width", "2"); line.setAttributeNS(null, "fill", "black"); svgRoot.appendChild(line); } } return document; }
private Element drawLink( SVGDocument doc, int startX, int startY, int endX, int endY, int startIconWidth, String id, String linkName) { Element path = doc.createElementNS("http://www.w3.org/2000/svg", "path"); int firstBend = 20; if (layoutManager.isVerticalLayout()) { if (startY < endY) { path.setAttributeNS( null, "d", "M " + startX + "," + startY + " L " + startX + "," + (startY + firstBend) + " L " + startX + "," + (startY + firstBend) + " L " + endX + "," + (startY + firstBend) + " L " + endX + "," + endY); // use constants for these propotions } else { if (startX > endX) { path.setAttributeNS( null, "d", "M " + startX + "," + startY + " L " + startX + "," + (startY + firstBend) + " L " + (startX - (startIconWidth / 2 + firstBend)) + "," + (startY + firstBend) + " L " + (startX - (startIconWidth / 2 + firstBend)) + "," + (endY - firstBend) + " L " + endX + "," + (endY - firstBend) + " L " + endX + "," + endY); // use constants for these propotions } else { path.setAttributeNS( null, "d", "M " + startX + "," + startY + " L " + startX + "," + (startY + firstBend) + " L " + (startX + (startIconWidth / 2 + firstBend)) + "," + (startY + firstBend) + " L " + (startX + (startIconWidth / 2 + firstBend)) + "," + (endY - firstBend) + " L " + endX + "," + (endY - firstBend) + " L " + endX + "," + endY); } } } else { path.setAttributeNS( null, "d", "M " + startX + "," + startY + " L " + ((startX + 1 * endX) / 2) + "," + startY + " L " + ((startX + 1 * endX) / 2) + "," + endY + " L " + endX + "," + endY); // use constants for these propotions } path.setAttributeNS(null, "id", id); path.setAttributeNS(null, "style", getLinkArrowStyle()); path.setAttributeNS("xlink", "title", linkName); // path.setAttributeNS(null, "style", "opacity:" + getIconOpacity()); // path.setAttributeNS(null, "onmouseover", // "this.style.opacity=1;this.filters.alpha.opacity=100"); // path.setAttributeNS(null, "onmouseout", "this.style.opacity=" + getIconOpacity() + // ";this.filters.alpha.opacity=25"); path.setAttributeNS(null, "onmouseover", "this.style.opacity=1;this.filters.alpha.opacity=100"); path.setAttributeNS( null, "onmouseout", "this.style.opacity=" + getIconOpacity(getState()) + ";this.filters.alpha.opacity=100"); // path.setAttributeNS(null, "onload", "this.style.opacity=" + getIconOpacity() + // ";this.filters.alpha.opacity=100"); // path.setAttributeNS(null, "onmousemove", // "this.style.opacity=1;this.filters.alpha.opacity=100"); return path; }
/** * Default implementation uses the root element of the document associated with BridgeContext. * This is useful for CSS case. */ protected Element getBaseElement(BridgeContext ctx) { SVGDocument d = (SVGDocument) ctx.getDocument(); return d.getRootElement(); }
/** Tries to build a GVTFontFamily from a URL reference */ protected GVTFontFamily getFontFamily(BridgeContext ctx, ParsedURL purl) { String purlStr = purl.toString(); Element e = getBaseElement(ctx); SVGDocument svgDoc = (SVGDocument) e.getOwnerDocument(); String docURL = svgDoc.getURL(); ParsedURL pDocURL = null; if (docURL != null) pDocURL = new ParsedURL(docURL); // try to load an SVG document String baseURI = AbstractNode.getBaseURI(e); purl = new ParsedURL(baseURI, purlStr); UserAgent userAgent = ctx.getUserAgent(); try { userAgent.checkLoadExternalResource(purl, pDocURL); } catch (SecurityException ex) { // Can't load font - Security violation. // We should not throw the error that is for certain, just // move down the font list, but do we display the error or not??? // I'll vote yes just because it is a security exception (other // exceptions like font not available etc I would skip). userAgent.displayError(ex); return null; } if (purl.getRef() != null) { // Reference must be to a SVGFont. Element ref = ctx.getReferencedElement(e, purlStr); if (!ref.getNamespaceURI().equals(SVG_NAMESPACE_URI) || !ref.getLocalName().equals(SVG_FONT_TAG)) { return null; } SVGDocument doc = (SVGDocument) e.getOwnerDocument(); SVGDocument rdoc = (SVGDocument) ref.getOwnerDocument(); Element fontElt = ref; if (doc != rdoc) { fontElt = (Element) doc.importNode(ref, true); String base = AbstractNode.getBaseURI(ref); Element g = doc.createElementNS(SVG_NAMESPACE_URI, SVG_G_TAG); g.appendChild(fontElt); g.setAttributeNS(XMLConstants.XML_NAMESPACE_URI, "xml:base", base); CSSUtilities.computeStyleAndURIs(ref, fontElt, purlStr); } // Search for a font-face element Element fontFaceElt = null; for (Node n = fontElt.getFirstChild(); n != null; n = n.getNextSibling()) { if ((n.getNodeType() == Node.ELEMENT_NODE) && n.getNamespaceURI().equals(SVG_NAMESPACE_URI) && n.getLocalName().equals(SVG_FONT_FACE_TAG)) { fontFaceElt = (Element) n; break; } } // todo : if the above loop fails to find a fontFaceElt, a null is passed to createFontFace() SVGFontFaceElementBridge fontFaceBridge; fontFaceBridge = (SVGFontFaceElementBridge) ctx.getBridge(SVG_NAMESPACE_URI, SVG_FONT_FACE_TAG); GVTFontFace gff = fontFaceBridge.createFontFace(ctx, fontFaceElt); return new SVGFontFamily(gff, fontElt, ctx); } // Must be a reference to a 'Web Font'. try { return ctx.getFontFamilyResolver().loadFont(purl.openStream(), this); } catch (Exception ex) { } return null; }
/** Auxiliary method for dispatchSVGLoad. */ protected void dispatchSVGLoad(Element elt, boolean checkCanRun, String lang) { for (Node n = elt.getFirstChild(); n != null; n = n.getNextSibling()) { if (n.getNodeType() == Node.ELEMENT_NODE) { dispatchSVGLoad((Element) n, checkCanRun, lang); } } DocumentEvent de = (DocumentEvent) elt.getOwnerDocument(); AbstractEvent ev = (AbstractEvent) de.createEvent("SVGEvents"); String type; if (bridgeContext.isSVG12()) { type = "load"; } else { type = "SVGLoad"; } ev.initEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI, type, false, false); NodeEventTarget t = (NodeEventTarget) elt; final String s = elt.getAttributeNS(null, SVGConstants.SVG_ONLOAD_ATTRIBUTE); if (s.length() == 0) { // No script to run so just dispatch the event to DOM // (For java presumably). t.dispatchEvent(ev); return; } final Interpreter interp = getInterpreter(); if (interp == null) { // Can't load interpreter so just dispatch normal event // to the DOM (for java presumably). t.dispatchEvent(ev); return; } if (checkCanRun) { // Check that it is ok to run embeded scripts checkCompatibleScriptURL(lang, docPURL); checkCanRun = false; // we only check once for onload handlers } DocumentLoader dl = bridgeContext.getDocumentLoader(); SVGDocument d = (SVGDocument) elt.getOwnerDocument(); int line = dl.getLineNumber(elt); final String desc = Messages.formatMessage( EVENT_SCRIPT_DESCRIPTION, new Object[] {d.getURL(), SVGConstants.SVG_ONLOAD_ATTRIBUTE, new Integer(line)}); EventListener l = new EventListener() { public void handleEvent(Event evt) { try { Object event; if (evt instanceof ScriptEventWrapper) { event = ((ScriptEventWrapper) evt).getEventObject(); } else { event = evt; } interp.bindObject(EVENT_NAME, event); interp.bindObject(ALTERNATE_EVENT_NAME, event); interp.evaluate(new StringReader(s), desc); } catch (IOException io) { } catch (InterpreterException e) { handleInterpreterException(e); } } }; t.addEventListenerNS(XMLConstants.XML_EVENTS_NAMESPACE_URI, type, l, false, null); t.dispatchEvent(ev); t.removeEventListenerNS(XMLConstants.XML_EVENTS_NAMESPACE_URI, type, l, false); }
/** Loads the scripts contained in the <script> elements. */ public void loadScripts() { org.apache.batik.script.Window window = null; NodeList scripts = document.getElementsByTagNameNS( SVGConstants.SVG_NAMESPACE_URI, SVGConstants.SVG_SCRIPT_TAG); int len = scripts.getLength(); if (len == 0) { return; } for (int i = 0; i < len; i++) { AbstractElement script = (AbstractElement) scripts.item(i); String type = script.getAttributeNS(null, SVGConstants.SVG_TYPE_ATTRIBUTE); if (type.length() == 0) { type = SVGConstants.SVG_SCRIPT_TYPE_DEFAULT_VALUE; } // // Java code invocation. // if (type.equals(SVGConstants.SVG_SCRIPT_TYPE_JAVA)) { try { String href = XLinkSupport.getXLinkHref(script); ParsedURL purl = new ParsedURL(script.getBaseURI(), href); checkCompatibleScriptURL(type, purl); DocumentJarClassLoader cll; URL docURL = null; try { docURL = new URL(docPURL.toString()); } catch (MalformedURLException mue) { /* nothing just let docURL be null */ } cll = new DocumentJarClassLoader(new URL(purl.toString()), docURL); // Get the 'Script-Handler' entry in the manifest. URL url = cll.findResource("META-INF/MANIFEST.MF"); if (url == null) { continue; } Manifest man = new Manifest(url.openStream()); String sh; sh = man.getMainAttributes().getValue("Script-Handler"); if (sh != null) { // Run the script handler. ScriptHandler h; h = (ScriptHandler) cll.loadClass(sh).newInstance(); if (window == null) { window = createWindow(); } h.run(document, window); } sh = man.getMainAttributes().getValue("SVG-Handler-Class"); if (sh != null) { // Run the initializer EventListenerInitializer initializer; initializer = (EventListenerInitializer) cll.loadClass(sh).newInstance(); if (window == null) { window = createWindow(); } initializer.initializeEventListeners((SVGDocument) document); } } catch (Exception e) { if (userAgent != null) { userAgent.displayError(e); } } continue; } // // Scripting language invocation. // Interpreter interpreter = getInterpreter(type); if (interpreter == null) // Can't find interpreter so just skip this script block. continue; try { String href = XLinkSupport.getXLinkHref(script); String desc = null; Reader reader = null; if (href.length() > 0) { desc = href; // External script. ParsedURL purl = new ParsedURL(script.getBaseURI(), href); checkCompatibleScriptURL(type, purl); InputStream is = purl.openStream(); String mediaType = purl.getContentTypeMediaType(); String enc = purl.getContentTypeCharset(); if (enc != null) { try { reader = new InputStreamReader(is, enc); } catch (UnsupportedEncodingException uee) { enc = null; } } if (reader == null) { if (APPLICATION_ECMASCRIPT.equals(mediaType)) { // No encoding was specified in the MIME type, so // infer it according to RFC 4329. if (purl.hasContentTypeParameter("version")) { // Future versions of application/ecmascript // are not supported, so skip this script // element if the version parameter is present. continue; } PushbackInputStream pbis = new PushbackInputStream(is, 8); byte[] buf = new byte[4]; int read = pbis.read(buf); if (read > 0) { pbis.unread(buf, 0, read); if (read >= 2) { if (buf[0] == (byte) 0xff && buf[1] == (byte) 0xfe) { if (read >= 4 && buf[2] == 0 && buf[3] == 0) { enc = "UTF32-LE"; pbis.skip(4); } else { enc = "UTF-16LE"; pbis.skip(2); } } else if (buf[0] == (byte) 0xfe && buf[1] == (byte) 0xff) { enc = "UTF-16BE"; pbis.skip(2); } else if (read >= 3 && buf[0] == (byte) 0xef && buf[1] == (byte) 0xbb && buf[2] == (byte) 0xbf) { enc = "UTF-8"; pbis.skip(3); } else if (read >= 4 && buf[0] == 0 && buf[1] == 0 && buf[2] == (byte) 0xfe && buf[3] == (byte) 0xff) { enc = "UTF-32BE"; pbis.skip(4); } } if (enc == null) { enc = "UTF-8"; } } reader = new InputStreamReader(pbis, enc); } else { reader = new InputStreamReader(is); } } } else { checkCompatibleScriptURL(type, docPURL); DocumentLoader dl = bridgeContext.getDocumentLoader(); Element e = script; SVGDocument d = (SVGDocument) e.getOwnerDocument(); int line = dl.getLineNumber(script); desc = Messages.formatMessage( INLINE_SCRIPT_DESCRIPTION, new Object[] {d.getURL(), "<" + script.getNodeName() + ">", new Integer(line)}); // Inline script. Node n = script.getFirstChild(); if (n != null) { StringBuffer sb = new StringBuffer(); while (n != null) { if (n.getNodeType() == Node.CDATA_SECTION_NODE || n.getNodeType() == Node.TEXT_NODE) sb.append(n.getNodeValue()); n = n.getNextSibling(); } reader = new StringReader(sb.toString()); } else { continue; } } interpreter.evaluate(reader, desc); } catch (IOException e) { if (userAgent != null) { userAgent.displayError(e); } return; } catch (InterpreterException e) { System.err.println("InterpExcept: " + e); handleInterpreterException(e); return; } catch (SecurityException e) { if (userAgent != null) { userAgent.displayError(e); } } } }
/** * creates a new image * * @param svgHandle a svg handle * @param resourceId the id of the resource from which the image will be created */ protected void createNewImage(SVGHandle svgHandle, String resourceId) { if (svgHandle != null && resourceId != null && !resourceId.equals("")) { Element resourceElement = null; resourceElement = svgHandle.getScrollPane().getSVGCanvas().getDocument().getElementById(resourceId); final String fresourceId = resourceId; if (resourceElement != null) { final SVGHandle fhandle = svgHandle; // creating the canvas and setting its properties final JSVGCanvas canvas = new JSVGCanvas() { @Override public void dispose() { removeKeyListener(listener); removeMouseMotionListener(listener); removeMouseListener(listener); disableInteractions = true; selectableText = false; userAgent = null; bridgeContext.dispose(); super.dispose(); } }; // the element to be added Element elementToAdd = null; canvas.setDocumentState(JSVGComponent.ALWAYS_STATIC); canvas.setDisableInteractions(true); // creating the new document final String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; final SVGDocument doc = (SVGDocument) resourceElement.getOwnerDocument().cloneNode(false); // creating the root element final Element root = (Element) doc.importNode(resourceElement.getOwnerDocument().getDocumentElement(), false); doc.appendChild(root); // removing all the attributes of the root element NamedNodeMap attributes = doc.getDocumentElement().getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { if (attributes.item(i) != null) { doc.getDocumentElement().removeAttribute(attributes.item(i).getNodeName()); } } // adding the new attributes for the root root.setAttributeNS(null, "width", imageSize.width + ""); root.setAttributeNS(null, "height", imageSize.height + ""); root.setAttributeNS(null, "viewBox", "0 0 " + imageSize.width + " " + imageSize.height); // the defs element that will contain the cloned resource node final Element defs = (Element) doc.importNode(resourceElement.getParentNode(), true); root.appendChild(defs); if (resourceElement.getNodeName().equals("linearGradient") || resourceElement.getNodeName().equals("radialGradient") || resourceElement.getNodeName().equals("pattern")) { // the rectangle that will be drawn final Element rect = doc.createElementNS(svgNS, "rect"); rect.setAttributeNS(null, "x", "0"); rect.setAttributeNS(null, "y", "0"); rect.setAttributeNS(null, "width", imageSize.width + ""); rect.setAttributeNS(null, "height", imageSize.height + ""); elementToAdd = rect; // setting that the rectangle uses the resource String id = resourceElement.getAttribute("id"); if (id == null) { id = ""; } rect.setAttributeNS(null, "style", "fill:url(#" + id + ");"); // getting the cloned resource node Node cur = null; Element clonedResourceElement = null; String id2 = ""; for (cur = defs.getFirstChild(); cur != null; cur = cur.getNextSibling()) { if (cur instanceof Element) { id2 = ((Element) cur).getAttribute("id"); if (id2 != null && id.equals(id2)) { clonedResourceElement = (Element) cur; } } } if (clonedResourceElement != null) { // getting the root element of the initial resource // element Element initialRoot = resourceElement.getOwnerDocument().getDocumentElement(); // getting the width and height of the initial root // element double initialWidth = 0, initialHeight = 0; try { initialWidth = EditorToolkit.getPixelledNumber(initialRoot.getAttributeNS(null, "width")); initialHeight = EditorToolkit.getPixelledNumber(initialRoot.getAttributeNS(null, "height")); } catch (DOMException ex) { ex.printStackTrace(); } if (resourceElement.getNodeName().equals("linearGradient")) { if (resourceElement.getAttributeNS(null, "gradientUnits").equals("userSpaceOnUse")) { double x1 = 0, y1 = 0, x2 = 0, y2 = 0; // normalizing the values for the vector to fit // the rectangle try { x1 = Double.parseDouble(resourceElement.getAttributeNS(null, "x1")); y1 = Double.parseDouble(resourceElement.getAttributeNS(null, "y1")); x2 = Double.parseDouble(resourceElement.getAttributeNS(null, "x2")); y2 = Double.parseDouble(resourceElement.getAttributeNS(null, "y2")); x1 = x1 / initialWidth * imageSize.width; y1 = y1 / initialHeight * imageSize.height; x2 = x2 / initialWidth * imageSize.width; y2 = y2 / initialHeight * imageSize.height; } catch (NumberFormatException | DOMException ex) { ex.printStackTrace(); } clonedResourceElement.setAttributeNS(null, "x1", format.format(x1)); clonedResourceElement.setAttributeNS(null, "y1", format.format(y1)); clonedResourceElement.setAttributeNS(null, "x2", format.format(x2)); clonedResourceElement.setAttributeNS(null, "y2", format.format(y2)); } } else if (resourceElement.getNodeName().equals("radialGradient")) { if (resourceElement.getAttributeNS(null, "gradientUnits").equals("userSpaceOnUse")) { double cx = 0, cy = 0, r = 0, fx = 0, fy = 0; // normalizing the values for the circle to fit // the rectangle try { cx = Double.parseDouble(resourceElement.getAttributeNS(null, "cx")); cy = Double.parseDouble(resourceElement.getAttributeNS(null, "cy")); r = Double.parseDouble(resourceElement.getAttributeNS(null, "r")); fx = Double.parseDouble(resourceElement.getAttributeNS(null, "fx")); fy = Double.parseDouble(resourceElement.getAttributeNS(null, "fy")); cx = cx / initialWidth * imageSize.width; cy = cy / initialHeight * imageSize.height; r = r / (Math.abs( Math.sqrt(Math.pow(initialWidth, 2) + Math.pow(initialHeight, 2)))) * Math.abs( Math.sqrt( Math.pow(imageSize.width, 2) + Math.pow(imageSize.width, 2))); fx = fx / initialWidth * imageSize.width; fy = fy / initialHeight * imageSize.height; } catch (NumberFormatException | DOMException ex) { ex.printStackTrace(); } clonedResourceElement.setAttributeNS(null, "cx", format.format(cx)); clonedResourceElement.setAttributeNS(null, "cy", format.format(cy)); clonedResourceElement.setAttributeNS(null, "r", format.format(r)); clonedResourceElement.setAttributeNS(null, "fx", format.format(fx)); clonedResourceElement.setAttributeNS(null, "fy", format.format(fy)); } } else if (resourceElement.getNodeName().equals("pattern")) { if (resourceElement.getAttributeNS(null, "patternUnits").equals("userSpaceOnUse")) { double x = 0, y = 0, w = 0, h = 0; // normalizing the values for the vector to fit // the rectangle try { String xString = resourceElement.getAttributeNS(null, "x"); if (!xString.equals("")) { x = Double.parseDouble(xString); } String yString = resourceElement.getAttributeNS(null, "y"); if (!yString.equals("")) { y = Double.parseDouble(yString); } String wString = resourceElement.getAttributeNS(null, "w"); if (!wString.equals("")) { w = Double.parseDouble(wString); } String hString = resourceElement.getAttributeNS(null, "h"); if (!hString.equals("")) { h = Double.parseDouble(hString); } x = x / initialWidth * imageSize.width; y = y / initialHeight * imageSize.height; w = w / initialWidth * imageSize.width; h = h / initialHeight * imageSize.height; } catch (NumberFormatException | DOMException ex) { ex.printStackTrace(); } clonedResourceElement.setAttributeNS(null, "x", format.format(x)); clonedResourceElement.setAttributeNS(null, "y", format.format(y)); clonedResourceElement.setAttributeNS(null, "width", format.format(w)); clonedResourceElement.setAttributeNS(null, "height", format.format(h)); } } } } else if (resourceElement.getNodeName().equals("marker")) { // the line that will be drawn final Element line = doc.createElementNS(svgNS, "line"); line.setAttributeNS(null, "x1", (((double) imageSize.width) / 2) + ""); line.setAttributeNS(null, "y1", (((double) imageSize.height) / 2) + ""); line.setAttributeNS(null, "x2", ((double) imageSize.width / 2) + ""); line.setAttributeNS(null, "y2", imageSize.height + ""); elementToAdd = line; // setting that the line uses the resource String id = resourceElement.getAttribute("id"); if (id == null) id = ""; line.setAttributeNS( null, "style", "stroke:none;fill:none;marker-start:url(#" + id + ");"); } root.appendChild(elementToAdd); // adding a rendering listener to the canvas GVTTreeRendererAdapter gVTTreeRendererAdapter = new GVTTreeRendererAdapter() { @Override public void gvtRenderingCompleted(GVTTreeRendererEvent evt) { Image bufferedImage = canvas.getOffScreen(); if (bufferedImage != null) { Graphics g = bufferedImage.getGraphics(); Color borderColor = MetalLookAndFeel.getSeparatorForeground(); g.setColor(borderColor); g.drawRect(0, 0, imageSize.width - 1, imageSize.height - 1); } setImage(fhandle, fresourceId, bufferedImage); // refreshing the panels that have been created when no // image was available for them Image image = null; for (ResourceRepresentation resourceRepresentation : new LinkedList<ResourceRepresentation>(resourceRepresentationList)) { if (resourceRepresentation != null) { resourceRepresentation.refreshRepresentation(); image = resourceRepresentation.getImage(); if (image != null) { resourceRepresentationList.remove(resourceRepresentation); } } } canvas.removeGVTTreeRendererListener(this); canvas.stopProcessing(); canvas.dispose(); } }; canvas.addGVTTreeRendererListener(gVTTreeRendererAdapter); // setting the document for the canvas canvas.setSVGDocument(doc); canvas.setBackground(Color.white); canvas.setBounds(1, 1, imageSize.width, imageSize.height); } } }