Use svg viewbox
This commit is contained in:
@@ -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<String, Map<String, String>> 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<String, Map<String, String>> parseStyles(Element root) {
|
||||
Map<String, Map<String, String>> 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) {
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user