mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-17 08:55:05 -04:00
improved exporter for SVG
This commit is contained in:
parent
953c3b9edf
commit
9a98599da7
@ -19,7 +19,11 @@ public class GraphicSVG implements Graphic, Closeable {
|
||||
}
|
||||
|
||||
public GraphicSVG(File file, Vector min, Vector max, File source, int svgScale) throws IOException {
|
||||
w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
|
||||
this(new FileOutputStream(file), min, max, source, svgScale);
|
||||
}
|
||||
|
||||
public GraphicSVG(OutputStream out, Vector min, Vector max, File source, int svgScale) throws IOException {
|
||||
w = new BufferedWriter(new OutputStreamWriter(out, "utf-8"));
|
||||
w.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +
|
||||
"<!-- Created with Digital by H.Neemann -->\n");
|
||||
w.write("<!-- created: " + new Date() + " -->\n");
|
||||
@ -55,7 +59,7 @@ public class GraphicSVG implements Graphic, Closeable {
|
||||
// addStrokeDash(w, style.getDashArray());
|
||||
w.write(" />\n");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +78,7 @@ public class GraphicSVG implements Graphic, Closeable {
|
||||
// addStrokeDash(w, style.getDashArray());
|
||||
w.write(" stroke=\"" + getColor(style) + "\" stroke-width=\"" + getStrokeWidth(style) + "\" fill=\"none\"/>\n");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,7 +100,7 @@ public class GraphicSVG implements Graphic, Closeable {
|
||||
w.write(" />\n");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,7 +109,7 @@ public class GraphicSVG implements Graphic, Closeable {
|
||||
if (text == null || text.length() == 0) return;
|
||||
|
||||
try {
|
||||
text = escapeXML(text);
|
||||
text = formatText(text, style.getFontSize());
|
||||
|
||||
boolean rotateText = false;
|
||||
if (p1.y == p2.y) { // 0 and 180 deg
|
||||
@ -137,15 +141,19 @@ public class GraphicSVG implements Graphic, Closeable {
|
||||
else
|
||||
w.write("<text text-anchor=\"" + getAchor(orientation.getX()) + "\" x=\"" + p.x + "\" y=\"" + p.y + "\" fill=\"" + getColor(style) + "\" style=\"font-size:" + style.getFontSize() + "\">" + text + "</text>\n");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String formatText(String text, int fontSize) {
|
||||
return escapeXML(text);
|
||||
}
|
||||
|
||||
public String getColor(Style style) {
|
||||
return "#" + Integer.toHexString(style.getColor().getRGB()).substring(2);
|
||||
}
|
||||
|
||||
private String escapeXML(String text) {
|
||||
public String escapeXML(String text) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
char c = text.charAt(i);
|
||||
|
@ -0,0 +1,56 @@
|
||||
package de.neemann.digital.draw.graphics;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class GraphicSVGIndex extends GraphicSVG {
|
||||
|
||||
public GraphicSVGIndex(File file, Vector min, Vector max) throws IOException {
|
||||
super(file, min, max);
|
||||
}
|
||||
|
||||
public GraphicSVGIndex(OutputStream out, Vector min, Vector max, File source, int svgScale) throws IOException {
|
||||
super(out, min, max, source, svgScale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatText(String text, int fontSize) {
|
||||
return formatSVGIndex(escapeXML(formatIndex(text)));
|
||||
}
|
||||
|
||||
public String formatIndex(String text) {
|
||||
int p = text.lastIndexOf("_");
|
||||
if (p > 0) {
|
||||
text = text.substring(0, p) + "_{" + text.substring(p + 1) + "}";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
private String formatSVGIndex(String text) {
|
||||
int p1;
|
||||
while ((p1 = text.indexOf("_{")) >= 0) {
|
||||
int p2 = text.indexOf('}', p1);
|
||||
if (p2 >= 0) {
|
||||
String ind = text.substring(p1 + 2, p2);
|
||||
if (ind.length() > 0)
|
||||
ind = "<tspan style=\"font-size:80%;baseline-shift:sub\">" + ind + "</tspan>";
|
||||
text = text.substring(0, p1) + ind + text.substring(p2 + 1);
|
||||
}
|
||||
}
|
||||
while ((p1 = text.indexOf("^{")) >= 0) {
|
||||
int p2 = text.indexOf('}', p1);
|
||||
if (p2 >= 0) {
|
||||
String ind = text.substring(p1 + 2, p2);
|
||||
if (ind.length() > 0)
|
||||
ind = "<tspan style=\"font-size:80%;baseline-shift:super\">" + ind + "</tspan>";
|
||||
text = text.substring(0, p1) + ind + text.substring(p2 + 1);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package de.neemann.digital.draw.graphics;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
@ -11,8 +12,13 @@ public class GraphicSVGLaTeX extends GraphicSVG {
|
||||
super(file, min, max);
|
||||
}
|
||||
|
||||
public GraphicSVGLaTeX(OutputStream out, Vector min, Vector max, File source, int svgScale) throws IOException {
|
||||
super(out, min, max, source, svgScale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawText(Vector p1, Vector p2, String text, Orientation orientation, Style style) {
|
||||
public String formatText(String text, int fontSize) {
|
||||
text = formatIndex(text);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
char c = text.charAt(i);
|
||||
@ -31,9 +37,21 @@ public class GraphicSVGLaTeX extends GraphicSVG {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
super.drawText(p1, p2, sb.toString(), orientation, style);
|
||||
text = sb.toString();
|
||||
if (fontSize < Style.NORMAL.getFontSize())
|
||||
text = "{\\scriptsize " + text + "}";
|
||||
return escapeXML(text);
|
||||
}
|
||||
|
||||
public String formatIndex(String text) {
|
||||
int p = text.lastIndexOf("_");
|
||||
if (p > 0) {
|
||||
text = "$" + text.substring(0, p) + "_{" + text.substring(p + 1) + "}$";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void drawCircle(Vector p1, Vector p2, Style style) {
|
||||
if ((style != Style.WIRE && style != Style.WIRE_OUT) || Math.abs(p1.x - p2.x) > 2)
|
||||
|
@ -99,15 +99,15 @@ public class GenericShape implements Shape {
|
||||
|
||||
graphic.drawPolygon(new Polygon(true)
|
||||
.add(1, -SIZE2)
|
||||
.add(SIZE * width - 1, -SIZE2)
|
||||
.add(SIZE * width - 1, height)
|
||||
.add(SIZE * width - (invert ? 0 : 1), -SIZE2)
|
||||
.add(SIZE * width - (invert ? 0 : 1), height)
|
||||
.add(1, height), Style.NORMAL);
|
||||
|
||||
if (invert) {
|
||||
int offs = symmetric ? inputs.length / 2 * SIZE : 0;
|
||||
for (int i = 0; i < outputs.length; i++)
|
||||
graphic.drawCircle(new Vector(SIZE * width, i * SIZE - SIZE2 + 1 + offs),
|
||||
new Vector(SIZE * (width + 1) - 2, i * SIZE + SIZE2 - 1 + offs), Style.NORMAL);
|
||||
graphic.drawCircle(new Vector(SIZE * width + 1, i * SIZE - SIZE2 + 1 + offs),
|
||||
new Vector(SIZE * (width + 1) - 1, i * SIZE + SIZE2 - 1 + offs), Style.NORMAL);
|
||||
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ public class LEDShape implements Shape {
|
||||
fill = true;
|
||||
}
|
||||
|
||||
Vector center = new Vector(2 + SIZE, 0);
|
||||
Vector center = new Vector(1 + SIZE, 0);
|
||||
graphic.drawCircle(center.sub(RADL), center.add(RADL), Style.FILLED);
|
||||
if (fill)
|
||||
graphic.drawCircle(center.sub(RAD), center.add(RAD), onStyle);
|
||||
|
@ -48,7 +48,7 @@ public class OutputShape implements Shape {
|
||||
}
|
||||
}
|
||||
|
||||
Vector center = new Vector(2 + SIZE, 0);
|
||||
Vector center = new Vector(1 + SIZE, 0);
|
||||
graphic.drawCircle(center.sub(RAD), center.add(RAD), style);
|
||||
graphic.drawCircle(center.sub(RADL), center.add(RADL), Style.NORMAL);
|
||||
Vector textPos = new Vector(SIZE * 3, 0);
|
||||
|
@ -160,7 +160,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave {
|
||||
|
||||
|
||||
JMenu export = new JMenu(Lang.get("menu_export"));
|
||||
export.add(new ExportAction(Lang.get("menu_exportSVG"), "svg", GraphicSVG::new));
|
||||
export.add(new ExportAction(Lang.get("menu_exportSVG"), "svg", GraphicSVGIndex::new));
|
||||
export.add(new ExportAction(Lang.get("menu_exportSVGLaTex"), "svg", GraphicSVGLaTeX::new));
|
||||
|
||||
|
||||
|
@ -0,0 +1,16 @@
|
||||
package de.neemann.digital.draw.graphics;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class GraphicSVGIndexTest extends TestCase {
|
||||
public void testFormatText() throws Exception {
|
||||
GraphicSVGIndex gs = new GraphicSVGIndex(System.out, new Vector(0, 0), new Vector(30, 30), null, 30);
|
||||
|
||||
assertEquals("Z<tspan style=\"font-size:80%;baseline-shift:sub\">0</tspan>", gs.formatText("Z0", 0));
|
||||
assertEquals("<a>", gs.formatText("<a>", 0));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package de.neemann.digital.draw.graphics;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class GraphicSVGLaTeXTest extends TestCase {
|
||||
public void testFormatText() throws Exception {
|
||||
GraphicSVGLaTeX gs = new GraphicSVGLaTeX(System.out, new Vector(0, 0), new Vector(30, 30), null, 30);
|
||||
|
||||
assertEquals("$Z_{0}$", gs.formatText("Z_0", Style.NORMAL.getFontSize()));
|
||||
assertEquals("\\&", gs.formatText("&", Style.NORMAL.getFontSize()));
|
||||
assertEquals("$\\geq$1", gs.formatText("\u22651", Style.NORMAL.getFontSize()));
|
||||
assertEquals("$\\neg$Q", gs.formatText("~Q", Style.NORMAL.getFontSize()));
|
||||
assertEquals("<a>", gs.formatText("<a>", Style.NORMAL.getFontSize()));
|
||||
assertEquals("Grün", gs.formatText("Grün", Style.NORMAL.getFontSize()));
|
||||
|
||||
|
||||
assertEquals("{\\scriptsize Grün}", gs.formatText("Grün", Style.SHAPE_PIN.getFontSize()));
|
||||
assertEquals("{\\scriptsize $Z_{0}$}", gs.formatText("Z_0", Style.SHAPE_PIN.getFontSize()));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package de.neemann.digital.draw.graphics;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author hneemann
|
||||
*/
|
||||
public class GraphicSVGTest extends TestCase {
|
||||
public void testFormatText() throws Exception {
|
||||
GraphicSVG gs = new GraphicSVG(System.out, new Vector(0, 0), new Vector(30, 30), null, 30);
|
||||
|
||||
assertEquals("Z0", gs.formatText("Z0", 0));
|
||||
assertEquals("<a>", gs.formatText("<a>", 0));
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user