/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */
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 SvgCreator() { }
public static Element createRectangle(Document doc, Rectangle rect) {
return createRectangular(doc, rect);
}
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;
}
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 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 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 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 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 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 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 colorMatches(Color a, Color b) {
return a.getRed() == b.getRed() && a.getGreen() == b.getGreen()
&& a.getBlue() == b.getBlue();
}
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 boolean showOpacity(Color color) {
return color.getAlpha() != 255;
}
private static String getOpacityString(Color color) {
return String.format("%5.3f", Double.valueOf(color.getAlpha() / 255.0));
}
}