/******************************************************************************* * This file is part of logisim-evolution. * * logisim-evolution is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * logisim-evolution is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with logisim-evolution. If not, see <http://www.gnu.org/licenses/>. * * Original code by Carl Burch (http://www.cburch.com), 2011. * Subsequent modifications by : * + Haute École Spécialisée Bernoise * http://www.bfh.ch * + Haute École du paysage, d'ingénierie et d'architecture de Genève * http://hepia.hesge.ch/ * + Haute École d'Ingénierie et de Gestion du Canton de Vaud * http://www.heig-vd.ch/ * The project is currently maintained by : * + REDS Institute - HEIG-VD * Yverdon-les-Bains, Switzerland * http://reds.heig-vd.ch *******************************************************************************/ package com.cburch.draw.shapes; import java.awt.Color; import java.awt.Font; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.cburch.draw.model.AbstractCanvasObject; import com.cburch.draw.model.Handle; import com.cburch.logisim.data.Location; class SvgCreator { private static boolean colorMatches(Color a, Color b) { return a.getRed() == b.getRed() && a.getGreen() == b.getGreen() && a.getBlue() == b.getBlue(); } public static Element createCurve(Document doc, Curve curve) { Element elt = doc.createElement("path"); Location e0 = curve.getEnd0(); Location e1 = curve.getEnd1(); Location ct = curve.getControl(); elt.setAttribute( "d", "M" + e0.getX() + "," + e0.getY() + " Q" + ct.getX() + "," + ct.getY() + " " + e1.getX() + "," + e1.getY()); populateFill(elt, curve); return elt; } public static Element createLine(Document doc, Line line) { Element elt = doc.createElement("line"); Location v1 = line.getEnd0(); Location v2 = line.getEnd1(); elt.setAttribute("x1", "" + v1.getX()); elt.setAttribute("y1", "" + v1.getY()); elt.setAttribute("x2", "" + v2.getX()); elt.setAttribute("y2", "" + v2.getY()); populateStroke(elt, line); return elt; } public static Element createOval(Document doc, Oval oval) { double x = oval.getX(); double y = oval.getY(); double width = oval.getWidth(); double height = oval.getHeight(); Element elt = doc.createElement("ellipse"); elt.setAttribute("cx", "" + (x + width / 2)); elt.setAttribute("cy", "" + (y + height / 2)); elt.setAttribute("rx", "" + (width / 2)); elt.setAttribute("ry", "" + (height / 2)); populateFill(elt, oval); return elt; } public static Element createPoly(Document doc, Poly poly) { Element elt; if (poly.isClosed()) { elt = doc.createElement("polygon"); } else { elt = doc.createElement("polyline"); } StringBuilder points = new StringBuilder(); boolean first = true; for (Handle h : poly.getHandles(null)) { if (!first) points.append(" "); points.append(h.getX() + "," + h.getY()); first = false; } elt.setAttribute("points", points.toString()); populateFill(elt, poly); return elt; } public static Element createRectangle(Document doc, Rectangle rect) { return createRectangular(doc, rect); } private static Element createRectangular(Document doc, Rectangular rect) { Element elt = doc.createElement("rect"); elt.setAttribute("x", "" + rect.getX()); elt.setAttribute("y", "" + rect.getY()); elt.setAttribute("width", "" + rect.getWidth()); elt.setAttribute("height", "" + rect.getHeight()); populateFill(elt, rect); return elt; } public static Element createRoundRectangle(Document doc, RoundRectangle rrect) { Element elt = createRectangular(doc, rrect); int r = rrect.getValue(DrawAttr.CORNER_RADIUS).intValue(); elt.setAttribute("rx", "" + r); elt.setAttribute("ry", "" + r); return elt; } public static Element createText(Document doc, Text text) { Element elt = doc.createElement("text"); Location loc = text.getLocation(); Font font = text.getValue(DrawAttr.FONT); Color fill = text.getValue(DrawAttr.FILL_COLOR); Object halign = text.getValue(DrawAttr.ALIGNMENT); elt.setAttribute("x", "" + loc.getX()); elt.setAttribute("y", "" + loc.getY()); if (!colorMatches(fill, Color.BLACK)) { elt.setAttribute("fill", getColorString(fill)); } if (showOpacity(fill)) { elt.setAttribute("fill-opacity", getOpacityString(fill)); } elt.setAttribute("font-family", font.getFamily()); elt.setAttribute("font-size", "" + font.getSize()); int style = font.getStyle(); if ((style & Font.ITALIC) != 0) { elt.setAttribute("font-style", "italic"); } if ((style & Font.BOLD) != 0) { elt.setAttribute("font-weight", "bold"); } if (halign == DrawAttr.ALIGN_LEFT) { elt.setAttribute("text-anchor", "start"); } else if (halign == DrawAttr.ALIGN_RIGHT) { elt.setAttribute("text-anchor", "end"); } else { elt.setAttribute("text-anchor", "middle"); } elt.appendChild(doc.createTextNode(text.getText())); return elt; } private static String getColorString(Color color) { return String.format("#%02x%02x%02x", Integer.valueOf(color.getRed()), Integer.valueOf(color.getGreen()), Integer.valueOf(color.getBlue())); } private static String getOpacityString(Color color) { return String.format("%5.3f", Double.valueOf(color.getAlpha() / 255.0)); } private static void populateFill(Element elt, AbstractCanvasObject shape) { Object type = shape.getValue(DrawAttr.PAINT_TYPE); if (type == DrawAttr.PAINT_FILL) { elt.setAttribute("stroke", "none"); } else { populateStroke(elt, shape); } if (type == DrawAttr.PAINT_STROKE) { elt.setAttribute("fill", "none"); } else { Color fill = shape.getValue(DrawAttr.FILL_COLOR); if (colorMatches(fill, Color.BLACK)) { elt.removeAttribute("fill"); } else { elt.setAttribute("fill", getColorString(fill)); } if (showOpacity(fill)) { elt.setAttribute("fill-opacity", getOpacityString(fill)); } } } private static void populateStroke(Element elt, AbstractCanvasObject shape) { Integer width = shape.getValue(DrawAttr.STROKE_WIDTH); if (width != null && width.intValue() != 1) { elt.setAttribute("stroke-width", width.toString()); } Color stroke = shape.getValue(DrawAttr.STROKE_COLOR); elt.setAttribute("stroke", getColorString(stroke)); if (showOpacity(stroke)) { elt.setAttribute("stroke-opacity", getOpacityString(stroke)); } elt.setAttribute("fill", "none"); } private static boolean showOpacity(Color color) { return color.getAlpha() != 255; } private SvgCreator() { } }