Use svg viewbox
This commit is contained in:
@@ -26,18 +26,18 @@ public final class SvgNodeLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Pane loadSquare(String resourcePath, double size) {
|
public static Pane loadSquare(String resourcePath, double size) {
|
||||||
Group content = readSvg(resourcePath);
|
SvgDocument svg = readSvg(resourcePath);
|
||||||
var bounds = content.getLayoutBounds();
|
|
||||||
double inset = size * 0.08;
|
double inset = size * 0.08;
|
||||||
double available = size - (inset * 2);
|
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);
|
Group graphic = svg.content();
|
||||||
content.setScaleY(scale);
|
graphic.setScaleX(scale);
|
||||||
content.setLayoutX(inset + ((available - (bounds.getWidth() * scale)) / 2) - (bounds.getMinX() * scale));
|
graphic.setScaleY(scale);
|
||||||
content.setLayoutY(inset + ((available - (bounds.getHeight() * scale)) / 2) - (bounds.getMinY() * scale));
|
graphic.setLayoutX(inset);
|
||||||
|
graphic.setLayoutY(inset);
|
||||||
|
|
||||||
Pane pane = new Pane(content);
|
Pane pane = new Pane(graphic);
|
||||||
pane.setMinSize(size, size);
|
pane.setMinSize(size, size);
|
||||||
pane.setPrefSize(size, size);
|
pane.setPrefSize(size, size);
|
||||||
pane.setMaxSize(size, size);
|
pane.setMaxSize(size, size);
|
||||||
@@ -45,16 +45,19 @@ public final class SvgNodeLoader {
|
|||||||
return pane;
|
return pane;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Group readSvg(String resourcePath) {
|
private static SvgDocument readSvg(String resourcePath) {
|
||||||
try (Reader reader = requireResource(resourcePath)) {
|
try (Reader reader = requireResource(resourcePath)) {
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
factory.setNamespaceAware(false);
|
factory.setNamespaceAware(false);
|
||||||
Document document = factory.newDocumentBuilder().parse(new InputSource(reader));
|
Document document = factory.newDocumentBuilder().parse(new InputSource(reader));
|
||||||
Element root = document.getDocumentElement();
|
Element root = document.getDocumentElement();
|
||||||
|
double[] viewBox = parseViewBox(root.getAttribute("viewBox"));
|
||||||
Map<String, Map<String, String>> styles = parseStyles(root);
|
Map<String, Map<String, String>> styles = parseStyles(root);
|
||||||
Group content = new Group();
|
Group content = new Group();
|
||||||
appendChildren(root, content, styles);
|
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) {
|
} catch (Exception e) {
|
||||||
throw new IllegalStateException("Unable to load SVG: " + resourcePath, 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);
|
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<String, Map<String, String>> parseStyles(Element root) {
|
private static Map<String, Map<String, String>> parseStyles(Element root) {
|
||||||
Map<String, Map<String, String>> styles = new HashMap<>();
|
Map<String, Map<String, String>> styles = new HashMap<>();
|
||||||
NodeList styleNodes = root.getElementsByTagName("style");
|
NodeList styleNodes = root.getElementsByTagName("style");
|
||||||
@@ -179,4 +195,7 @@ public final class SvgNodeLoader {
|
|||||||
styleMap.put(attribute, value);
|
styleMap.put(attribute, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private record SvgDocument(Group content, double width, double height) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user