From d68f7a8b2f03fec71bd4f6ecf8345eca0d9d8dbb Mon Sep 17 00:00:00 2001 From: Dan Royer Date: Thu, 22 Aug 2024 13:07:13 -0700 Subject: [PATCH] fix #752 handles 'g' element. better finding of 'stroke ' value in nested items. no longer ignores lines same color as background. --- pom.xml | 2 +- .../makelangelo/makeart/io/LoadSVG.java | 60 ++++++++++++++++--- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index b0beb58bd..c95b1d740 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.marginallyclever Makelangelo - 7.55.6 + 7.55.7 Makelangelo Makelangelo Software is a Java program that prepares art for CNC plotters. It is especially designed for the Makelangelo Robot. It pairs really well with Marlin-polargraph, the code in the brain of the robot that receives instructions and moves the motors. diff --git a/src/main/java/com/marginallyclever/makelangelo/makeart/io/LoadSVG.java b/src/main/java/com/marginallyclever/makelangelo/makeart/io/LoadSVG.java index cf1d131e4..0ab9cd27a 100644 --- a/src/main/java/com/marginallyclever/makelangelo/makeart/io/LoadSVG.java +++ b/src/main/java/com/marginallyclever/makelangelo/makeart/io/LoadSVG.java @@ -91,6 +91,11 @@ private void parseAll(Document document) throws Exception { processElement(documentElement); } + /** + * Process the given element and all its children. + * @param element the source of the elements + * @throws Exception if the child elements have a problem. + */ private void processElement(Element element) throws Exception { if(setStrokeToElementColorBecomesNone(element)) return; @@ -103,6 +108,7 @@ private void processElement(Element element) throws Exception { case "rect" -> parseRectElement(element); case "circle" -> parseCircleElement(element); case "ellipse" -> parseEllipseElement(element); + case "g" -> parseGroupElement(element); default -> logger.debug("Unknown element {}", element.getTagName()); } @@ -116,6 +122,15 @@ private void processElement(Element element) throws Exception { } } + /** + * Parse through all the SVG group elements and raster them to gcode. + * @param element the source of the elements + * @throws Exception if the child elements have a problem. + */ + private void parseGroupElement(Element element) throws Exception { + // do nothing, the children will be processed by processElement(). + } + /** * Parse through all the SVG polyline elements and raster them to gcode. * @param pathNodes the source of the elements @@ -149,7 +164,7 @@ private boolean setStrokeToElementColorBecomesNone(Element element) { Color color = getStroke(element); if(color==null) return false; // none if(color.getAlpha()==0) return false; // transparent - if(color.equals(paperColor)) return true; + //if(color.equals(paperColor)) return true; if(!color.equals(myTurtle.getColor())) { logger.debug("Setting stroke color to {}",color); @@ -176,6 +191,23 @@ private void parseLineElement(Element element) { } private Color getStroke(Element element) { + Color strokeColor = null; + while (element != null) { + strokeColor = extractStrokeColor(element); + if (strokeColor != null) { + break; + } + Node parentNode = element.getParentNode(); + if (parentNode instanceof Element) { + element = (Element) parentNode; + } else { + element = null; + } + } + return strokeColor; + } + + private Color extractStrokeColor(Element element) { Color c=null; if(element.hasAttribute("style")) { String style = element.getAttribute("style").toLowerCase().replace("\\s+",""); @@ -183,20 +215,30 @@ private Color getStroke(Element element) { // default SVG stroke is "none", which isn't even transparent - it's nothing! } else { int k = style.indexOf(LABEL_STROKE); - String strokeStyleName = style.substring(k + LABEL_STROKE.length()); - c = stringToColor(strokeStyleName); - if(c!=null) { - k = style.indexOf("stroke-opacity:"); - if (k >= 0) { - style = style.substring(k + 15, style.indexOf(";", k + 15)); - c = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int) (Double.parseDouble(style) * 255.0)); + if(k>=0) { + String strokeStyleName = style.substring(k + LABEL_STROKE.length()); + // chop off the rest of the style string + if(strokeStyleName.contains(";")) { + strokeStyleName = strokeStyleName.substring(0, strokeStyleName.indexOf(";")).trim(); + } + // extract the color + c = stringToColor(strokeStyleName); + if (c != null) { + final String STROKE_OPACITY = "stroke-opacity:"; + k = style.indexOf(STROKE_OPACITY); + if (k >= 0) { + style = style.substring(k+STROKE_OPACITY.length()); + if(style.contains(";")) { + style = style.substring(0, style.indexOf(";")).trim(); + } + c = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int) (Double.parseDouble(style) * 255.0)); + } } } } } if(c==null) { if (element.hasAttribute("stroke")) { - String strokeStyleName = element.getAttribute("stroke").toLowerCase().replace("\\s+", ""); c = stringToColor(strokeStyleName); }