adds very basic css formatting to support Adobe Illustrator

This commit is contained in:
hneemann 2018-12-04 17:57:38 +01:00
parent 814a9fd20b
commit 53c15330d7
5 changed files with 67 additions and 8 deletions

View File

@ -366,6 +366,13 @@ public class CustomShapeDescription implements Iterable<CustomShapeDescription.H
p1 = p1.transform(tr).round();
p2 = p2.transform(tr).round();
}
/**
* @return the text position
*/
public Vector getPos() {
return p1;
}
}
/**

View File

@ -5,7 +5,10 @@
*/
package de.neemann.digital.draw.shapes.custom.svg;
import de.neemann.digital.draw.graphics.*;
import de.neemann.digital.draw.graphics.Orientation;
import de.neemann.digital.draw.graphics.Transform;
import de.neemann.digital.draw.graphics.VectorFloat;
import de.neemann.digital.draw.graphics.VectorInterface;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
@ -30,6 +33,7 @@ class Context {
PARSER.put("style", Context::readStyle);
PARSER.put("text-anchor", (c, value) -> c.textAnchor = value);
PARSER.put("fill-rule", (c, value) -> c.fillRuleEvenOdd = value.equalsIgnoreCase("evenodd"));
PARSER.put("class", Context::evalClass);
}
private Transform tr;
@ -41,6 +45,7 @@ class Context {
private float fontSize;
private String textAnchor;
private boolean fillRuleEvenOdd;
private HashMap<String, String> classesMap;
Context() {
tr = Transform.IDENTITY;
@ -48,6 +53,7 @@ class Context {
stroke = Color.BLACK;
fillOpacity = 1;
strokeOpacity = 1;
classesMap = new HashMap<>();
}
private Context(Context parent) {
@ -60,6 +66,8 @@ class Context {
fontSize = parent.fontSize;
textAnchor = parent.textAnchor;
fillRuleEvenOdd = parent.fillRuleEvenOdd;
classesMap = new HashMap<>();
classesMap.putAll(parent.classesMap);
}
Context(Context parent, Element element) throws SvgException {
@ -146,6 +154,34 @@ class Context {
return fontSize;
}
void addClasses(String classes) {
classes = classes.trim();
while (classes.startsWith(".")) {
int p1 = classes.indexOf("{");
int p2 = classes.indexOf("}");
if (p1 < 0 || p2 < 0)
return;
String key = classes.substring(1, p1);
String val = classes.substring(p1 + 1, p2);
classesMap.put(key, val);
classes = classes.substring(p2 + 1).trim();
}
}
String getCssClass(String key) {
return classesMap.get(key);
}
private static void evalClass(Context c, String value) throws SvgException {
StringTokenizer st = new StringTokenizer(value, ", ");
while (st.hasMoreTokens()) {
String cl = st.nextToken();
String style = c.getCssClass(cl);
if (style != null)
readStyle(c, style);
}
}
private interface AttrParser {
void parse(Context c, String value) throws SvgException;
}

View File

@ -89,8 +89,13 @@ public class SvgImporter {
private void create(CustomShapeDescription csd, NodeList gList, Context c) throws SvgException {
for (int i = 0; i < gList.getLength(); i++) {
final Node node = gList.item(i);
if (node instanceof Element)
create(csd, (Element) node, c);
if (node instanceof Element) {
final Element element = (Element) node;
if (element.getNodeName().equals("style"))
c.addClasses(element.getTextContent());
else
create(csd, element, c);
}
}
}

View File

@ -8,7 +8,6 @@ package de.neemann.digital.draw.shapes.custom;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.graphics.Polygon;
import de.neemann.digital.draw.graphics.PolygonParser;
import de.neemann.digital.draw.graphics.Vector;
import de.neemann.digital.draw.graphics.VectorInterface;
import de.neemann.digital.draw.shapes.Drawable;
import de.neemann.digital.draw.shapes.custom.svg.SvgException;
@ -490,9 +489,10 @@ public class SvgImporterTest extends TestCase {
new CSDChecker(custom)
.checkPolygon("M 0,-10 C 0,-10 15,-10 30,-10 C 70,-10 70,50 35,50 C 20,50 0,50 0,50 L 0,-10 Z")
.checkText(10, 10, "A")
.checkText(10, 10, "B")
.checkText(10, 10, "Y")
.checkPolygon("M 0,-10 C 0,-10 15,-10 30,-10 C 70,-10 70,50 35,50 C 20,50 0,50 0,50 L 0,-10 Z")
.checkText(4, 6, "A")
.checkText(4, 45, "B")
.checkText(45, 25, "Y")
.checkPin(0, 0, "A", false)
.checkPin(0, 40, "B", false)
.checkPin(60, 20, "Y", false)
@ -596,7 +596,10 @@ public class SvgImporterTest extends TestCase {
private CSDChecker checkText(int x, int y, String text) {
checker.add(d -> {
assertTrue(d instanceof CustomShapeDescription.TextHolder);
assertTrue("Text expected, found " + d.getClass().getSimpleName(), d instanceof CustomShapeDescription.TextHolder);
CustomShapeDescription.TextHolder t = (CustomShapeDescription.TextHolder) d;
assertEquals("text x", x, t.getPos().x);
assertEquals("text y", y, t.getPos().y);
});
return this;
}

View File

@ -27,4 +27,12 @@ public class ContextTest extends TestCase {
assertEquals(new Color(0, 0, 0, 127), c.getFilled());
}
public void testCSS() {
Context c = new Context();
c.addClasses(" .z{a:1}\n .y{a:2}");
assertEquals("a:1", c.getCssClass("z"));
assertEquals("a:2", c.getCssClass("y"));
}
}