From 2777ca2a7425eb93ca1754e611ae7956f2fadb81 Mon Sep 17 00:00:00 2001 From: Harkamal Randhawa Date: Wed, 11 Mar 2026 13:39:47 -0600 Subject: [PATCH] Use svg viewbox --- .../petshopdesktop/ui/SvgNodeLoader.java | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/example/petshopdesktop/ui/SvgNodeLoader.java b/src/main/java/org/example/petshopdesktop/ui/SvgNodeLoader.java index e1d1a10a..262aab23 100644 --- a/src/main/java/org/example/petshopdesktop/ui/SvgNodeLoader.java +++ b/src/main/java/org/example/petshopdesktop/ui/SvgNodeLoader.java @@ -26,18 +26,18 @@ public final class SvgNodeLoader { } public static Pane loadSquare(String resourcePath, double size) { - Group content = readSvg(resourcePath); - var bounds = content.getLayoutBounds(); + SvgDocument svg = readSvg(resourcePath); double inset = size * 0.08; double available = size - (inset * 2); - double scale = Math.min(available / bounds.getWidth(), available / bounds.getHeight()); + double scale = Math.min(available / svg.width(), available / svg.height()); - content.setScaleX(scale); - content.setScaleY(scale); - content.setLayoutX(inset + ((available - (bounds.getWidth() * scale)) / 2) - (bounds.getMinX() * scale)); - content.setLayoutY(inset + ((available - (bounds.getHeight() * scale)) / 2) - (bounds.getMinY() * scale)); + Group graphic = svg.content(); + graphic.setScaleX(scale); + graphic.setScaleY(scale); + graphic.setLayoutX(inset); + graphic.setLayoutY(inset); - Pane pane = new Pane(content); + Pane pane = new Pane(graphic); pane.setMinSize(size, size); pane.setPrefSize(size, size); pane.setMaxSize(size, size); @@ -45,16 +45,19 @@ public final class SvgNodeLoader { return pane; } - private static Group readSvg(String resourcePath) { + private static SvgDocument readSvg(String resourcePath) { try (Reader reader = requireResource(resourcePath)) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(false); Document document = factory.newDocumentBuilder().parse(new InputSource(reader)); Element root = document.getDocumentElement(); + double[] viewBox = parseViewBox(root.getAttribute("viewBox")); Map> styles = parseStyles(root); Group content = new Group(); appendChildren(root, content, styles); - return content; + content.setTranslateX(-viewBox[0]); + content.setTranslateY(-viewBox[1]); + return new SvgDocument(content, viewBox[2], viewBox[3]); } catch (Exception e) { throw new IllegalStateException("Unable to load SVG: " + resourcePath, e); } @@ -68,6 +71,19 @@ public final class SvgNodeLoader { return new InputStreamReader(stream, StandardCharsets.UTF_8); } + private static double[] parseViewBox(String viewBox) { + String[] parts = viewBox.trim().split("\\s+"); + if (parts.length != 4) { + throw new IllegalArgumentException("Invalid viewBox: " + viewBox); + } + return new double[] { + Double.parseDouble(parts[0]), + Double.parseDouble(parts[1]), + Double.parseDouble(parts[2]), + Double.parseDouble(parts[3]) + }; + } + private static Map> parseStyles(Element root) { Map> styles = new HashMap<>(); NodeList styleNodes = root.getElementsByTagName("style"); @@ -179,4 +195,7 @@ public final class SvgNodeLoader { styleMap.put(attribute, value); } } + + private record SvgDocument(Group content, double width, double height) { + } }