From: Marko Luukkainen Date: Tue, 14 Sep 2021 10:48:55 +0000 (+0300) Subject: SVG conversion SCL API improvements. X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=986ee0c8fa3d43e84036d99badfef64289eb6fac;p=simantics%2Fplatform.git SVG conversion SCL API improvements. * Function to dispose canvas context * Alignment setting for SVG conversion gitlab #747 Change-Id: I174604c9130f830df84468829e152444f326b6a6 --- diff --git a/bundles/org.simantics.modeling/scl/Simantics/Scenegraph.scl b/bundles/org.simantics.modeling/scl/Simantics/Scenegraph.scl index 3d1170682..401f2d8af 100644 --- a/bundles/org.simantics.modeling/scl/Simantics/Scenegraph.scl +++ b/bundles/org.simantics.modeling/scl/Simantics/Scenegraph.scl @@ -5,6 +5,9 @@ import "Simantics/Rename" importJava "org.simantics.g2d.canvas.ICanvasContext" where data ICanvasContext + @JavaName dispose + disposeCanvasContext :: ICanvasContext -> () + importJava "org.simantics.g2d.scenegraph.ICanvasSceneGraphProvider" where data ICanvasSceneGraphProvider @@ -65,6 +68,26 @@ importJava "org.simantics.modeling.SCLScenegraph" where "Render an SVG with known width and height in pixels: `renderScaledSVG context width height`" @JavaName renderSVG renderScaledSVG :: ICanvasContext -> Double -> Double -> String + + @JavaName renderSVG + renderScaledAndAlignedSVG :: ICanvasContext -> Double -> Double -> Integer -> Integer -> String + +importJava "org.eclipse.swt.SWT" where + + @JavaName LEFT + ALIGN_LEFT :: Integer + + @JavaName RIGHT + ALIGN_RIGHT :: Integer + + @JavaName CENTER + ALIGN_CENTER :: Integer + + @JavaName TOP + ALIGN_TOP :: Integer + + @JavaName BOTTOM + ALIGN_BOTTOM :: Integer getSceneGraphProvider :: Diagram -> ICanvasSceneGraphProvider getSceneGraphProvider diagram = do diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java index 70461571d..cc4489f82 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java @@ -32,6 +32,7 @@ import org.apache.batik.dom.GenericDOMImplementation; import org.apache.batik.svggen.SVGGeneratorContext; import org.apache.batik.svggen.SVGGraphics2D; import org.apache.batik.svggen.SVGIDGenerator; +import org.eclipse.swt.SWT; import org.simantics.Simantics; import org.simantics.datatypes.literal.GUID; import org.simantics.db.ReadGraph; @@ -537,7 +538,7 @@ public class SCLScenegraph { } public static String renderSVG3(ICanvasContext ctx, double width, double height) { - return renderSVG0(width, height, ctx, p0 -> p0.stream().collect(Collectors.toMap(p1 -> p1, p2 -> p2))); + return renderSVG0(width, height, SWT.LEFT, SWT.TOP, ctx, p0 -> p0.stream().collect(Collectors.toMap(p1 -> p1, p2 -> p2))); } /** @@ -559,12 +560,26 @@ public class SCLScenegraph { */ private static final Function1, Map> mapper = p0 -> p0.stream().collect(Collectors.toMap(p1 -> p1, p2 -> p2)); + + /** + * Renders CanvasContext to SVG. + * @param ctx + * @param width Width of output image. Use -1 for autosize. + * @param height Height of output image. Use -1 for autosize. + * @param ax horizontal alignment. SWT.LEFT SWT.CENTER SWT.RIGHT are accepted values. Value is not used with autosize. + * @param ay vertical alignment. SWT.TOP SWT.CENTER SWT.BOTTOM are accepted values. Value is not used with autosize. + * @return + */ + public static String renderSVG(ICanvasContext ctx, double width, double height, int ax, int ay) { + return renderSVG0(width, height, ax, ay, ctx, mapper); + } + public static String renderSVG(ICanvasContext ctx, double width, double height) { - return renderSVG0(width, height, ctx, mapper); + return renderSVG(ctx,width,height, SWT.LEFT, SWT.TOP); } public static String renderSVG(ICanvasContext ctx) { - return renderSVG(ctx, -1, -1); + return renderSVG(ctx, -1, -1, SWT.LEFT, SWT.TOP); } public static String renderSVGMapIdentifiers(ICanvasContext ctx) { @@ -579,7 +594,7 @@ public class SCLScenegraph { * @return */ public static String renderSVGMapIdentifiers(ICanvasContext ctx, double width, double height) { - return renderSVG0(width, height, ctx, new Function1, Map>() { + return renderSVG0(width, height, SWT.LEFT, SWT.TOP, ctx, new Function1, Map>() { @Override public Map apply(Set p0) { @@ -665,7 +680,7 @@ public class SCLScenegraph { - private static String renderSVG0(double width, double height, ICanvasContext ctx, Function1, Map> mappingFunction) { + private static String renderSVG0(double width, double height, int ax, int ay, ICanvasContext ctx, Function1, Map> mappingFunction) { // Get a DOMImplementation. DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation(); @@ -706,6 +721,10 @@ public class SCLScenegraph { // get the bounds of the content Rectangle2D content = rtreeBounds; +// int ax = SWT.LEFT; +// int ay = SWT.TOP; +// int ax = SWT.CENTER; +// int ay = SWT.CENTER; if (content != null) { // To account for dynamic padding of selection rectangles (5 units + stroke width) @@ -716,7 +735,29 @@ public class SCLScenegraph { AffineTransform tr = new AffineTransform(); tr.translate(offset, offset); tr.scale(scale, scale); - tr.translate(-content.getX(), -content.getY()); + double dx = -content.getX(); + double dy = -content.getY(); + if (width > 0.0 && height > 0.0) { + if (ax == SWT.LEFT) { + dx = -content.getX(); + } else if (ax == SWT.RIGHT) { + double t = ((width - 2*offset)/scale - content.getWidth()); + dx = -content.getX() + t; + } else { + double t = ((width - 2*offset)/scale - content.getWidth()) *0.5; + dx = -content.getX() + t; + } + if (ay == SWT.TOP) { + dy = -content.getY(); + } else if (ay == SWT.BOTTOM) { + double t = ((height - 2*offset)/scale - content.getHeight()); + dy = -content.getY() + t; + } else { + double t = ((height - 2*offset)/scale - content.getHeight()) * 0.5; + dy = -content.getY() + t; + } + } + tr.translate(dx, dy); tr.getMatrix(matrix); svgGenerator.setSVGCanvasSize(new Dimension((int)Math.ceil(scale * content.getWidth()) + 2*offset, (int)Math.ceil(scale * content.getHeight()) + 2*offset)); } else {