Commit d58c15e
Add view box to SVG parser
Changed files (5)
modifiedlibbirdfont/DrawingTools.valamodifiedlibbirdfont/SvgParser.valamodifiedlibsvgbird/SvgDrawing.valamodifiedlibsvgbird/SvgFile.valamodifiedlibsvgbird/ViewBox.vala
Diff
@@ -601,6 +601,7 @@ public class DrawingTools : ToolCollection { monochrome_tool = new Tool ("svg_to_birdfont", t_("Convert SVG file to monochrome glyph")); monochrome_tool.select_action.connect ((self) => {+ MainWindow.get_current_glyph ().store_undo_state (); move_tool.convert_svg_to_monochrome (); }); @@ -221,6 +221,19 @@ public class SvgParser { } private PathList parse_svg_tag (XmlElement tag, Layer pl) {+ double width = 1;+ double height = 1;++ foreach (Attribute attribute in tag.get_attributes ()) { + if (attribute.get_name () == "width") {+ width = parse_double (attribute.get_content ());+ }+ + if (attribute.get_name () == "height") {+ height = parse_double (attribute.get_content ());+ }+ }+ foreach (XmlElement t in tag) { if (t.get_name () == "g") {@@ -264,7 +277,28 @@ public class SvgParser { } } - return LayerUtils.get_all_paths (pl);+ PathList paths = LayerUtils.get_all_paths (pl);++ ViewBox? box = SvgFile.parse_view_box (tag);+ if (box != null) {+ ViewBox view_box = (!) box;+ Cairo.Matrix matrix = Cairo.Matrix.identity ();+ //+ double x = 0;+ double y = 0;+ to_svg_coordinate (ref x, ref y);+ + //matrix.translate (x, y);++ Cairo.Matrix view_box_matrix = view_box.get_matrix (width, height);+ view_box_matrix.multiply (view_box_matrix, matrix);+ + //view_box_matrix.scale (1, -1);+ SvgTransform t = new SvgTransform.for_matrix (view_box_matrix);+ transform (t.get_xml (), pl);+ }+ + return paths; } private void parse_layer (XmlElement tag, Layer pl) {@@ -300,7 +334,7 @@ public class SvgParser { if (t.get_name () == "svg") { layer = new Layer ();- parse_layer (t, layer);+ parse_svg_tag (t, layer); pl.objects.add (layer); } @@ -413,7 +447,7 @@ public class SvgParser { apply_matrix_on_handle (left, a, b, c, d, e, f); } - ep.independent_y = font.top_position - ep.independent_y;+ ep.independent_y = font.top_limit - ep.independent_y; ep.independent_x -= glyph.left_limit; dx = a * ep.independent_x + c * ep.independent_y + e;@@ -422,7 +456,7 @@ public class SvgParser { ep.independent_x = dx; ep.independent_y = dy; - ep.independent_y = font.top_position - ep.independent_y;+ ep.independent_y = font.top_limit - ep.independent_y; ep.independent_x += glyph.left_limit; } }@@ -435,7 +469,7 @@ public class SvgParser { Font font = BirdFont.get_current_font (); Glyph glyph = MainWindow.get_current_glyph (); - h.y = font.top_position - h.y;+ h.y = font.top_limit - h.y; h.x -= glyph.left_limit; dx = a * h.x + c * h.y + e;@@ -444,7 +478,7 @@ public class SvgParser { h.x = dx; h.y = dy; - h.y = font.top_position - h.y;+ h.y = font.top_limit - h.y; h.x += glyph.left_limit; } @@ -1130,6 +1164,15 @@ public class SvgParser { return path_list; } + void to_svg_coordinate (ref double x, ref double y) {+ Font font = BirdFont.get_current_font ();+ Glyph glyph = MainWindow.get_current_glyph ();+ x -= glyph.left_limit;+ y -= font.base_line;+ x -= glyph.left_limit; + y -= font.top_limit;+ }+ void move_and_resize (BezierPoints[] b, int num_b, bool svg_glyph, double units, Glyph glyph) { Font font = BirdFont.get_current_font (); @@ -44,48 +44,12 @@ public class SvgDrawing : Object { } void apply_view_box (Context cr) {- double scale_x = 1;- double scale_y = 1;- double scale = 1;- if (view_box != null) { ViewBox box = (!) view_box;- - cr.translate (box.minx, box.miny);- scale_x = width / box.width;- scale_y = height / box.height;- - bool scale_width = scale_x > scale_y;- - if (scale_width) {- scale = scale_y;- } else {- scale = scale_x;- }- - if (box.preserve_aspect_ratio) {- if ((box.alignment & ViewBox.XMID) > 0) {- cr.translate ((width - box.width * scale) / 2, 0);- } else if ((box.alignment & ViewBox.XMAX) > 0) {- cr.translate ((width - box.width * scale), 0);- }-- if ((box.alignment & ViewBox.YMID) > 0) {- cr.translate ((height - box.height * scale) / 2, 0);- } else if ((box.alignment & ViewBox.YMAX) > 0) {- cr.translate ((height - box.height * scale), 0);- }- }-- if (!box.preserve_aspect_ratio) {- cr.scale (scale_x, scale_y);- } else if (scale_width) {- scale = scale_y;- cr.scale (scale, scale);- } else {- scale = scale_x;- cr.scale (scale, scale);- } + Matrix view_box_matrix = box.get_matrix (width, height);+ Matrix view_matrix = cr.get_matrix ();+ view_box_matrix.multiply (view_box_matrix, view_matrix); + cr.set_matrix (view_box_matrix); } } @@ -112,6 +76,11 @@ public class SvgDrawing : Object { drawing.defs = defs.copy (); drawing.width = width; drawing.height = height;+ + if (view_box != null) {+ drawing.view_box = ((!) view_box).copy ();+ }+ return drawing; } @@ -46,7 +46,7 @@ public class SvgFile : GLib.Object { } if (attr.get_name () == "viewBox") {- drawing.view_box = parse_view_box (attr.get_content (), svg_tag);+ drawing.view_box = parse_view_box (svg_tag); } } @@ -78,13 +78,18 @@ public class SvgFile : GLib.Object { return drawing; } - ViewBox? parse_view_box (string parameters, XmlElement tag) {- string arguments = parameters.replace (",", " ");+ public static ViewBox? parse_view_box (XmlElement tag) {+ string arguments;+ string parameters = ""; string aspect_ratio = ""; bool slice = true; bool preserve_aspect_ratio = true; foreach (Attribute attribute in tag.get_attributes ()) {+ if (attribute.get_name () == "viewBox") {+ parameters = attribute.get_content ();+ }+ if (attribute.get_name () == "preserveAspectRatio") { aspect_ratio = attribute.get_content (); @@ -102,6 +107,8 @@ public class SvgFile : GLib.Object { } } + arguments = parameters.replace (",", " ");+ while (arguments.index_of (" ") > -1) { arguments = arguments.replace (" ", " "); }@@ -49,6 +49,9 @@ public class ViewBox : GLib.Object { public bool preserve_aspect_ratio; + public ViewBox.empty () {+ }+ public ViewBox (double minx, double miny, double width, double height, uint alignment, bool slice, bool preserve_aspect_ratio) { @@ -61,7 +64,71 @@ public class ViewBox : GLib.Object { this.slice = slice; this.preserve_aspect_ratio = preserve_aspect_ratio; }- ++ public ViewBox copy () {+ ViewBox box = new ViewBox.empty (); + + box.minx = minx;+ box.miny = miny;+ box.width = width;+ box.height = height;+ + box.alignment = alignment;+ box.slice = slice;+ box.preserve_aspect_ratio = preserve_aspect_ratio;+ + return box;+ }++ public Matrix get_matrix (double original_width, double original_height) {+ double scale_x = 1;+ double scale_y = 1;+ double scale = 1;++ Matrix matrix = Matrix.identity ();++ if (original_width == 0 || original_height == 0 || width == 0 || height == 0) {+ return matrix;+ }+ + matrix.translate (minx, miny);+ scale_x = original_width / width;+ scale_y = original_height / height;+ + bool scale_width = scale_x > scale_y;+ + if (scale_width) {+ scale = scale_y;+ } else {+ scale = scale_x;+ }+ + if (preserve_aspect_ratio) {+ if ((alignment & ViewBox.XMID) > 0) {+ matrix.translate ((original_width - width * scale) / 2, 0);+ } else if ((alignment & ViewBox.XMAX) > 0) {+ matrix.translate ((original_width - width * scale), 0);+ }++ if ((alignment & ViewBox.YMID) > 0) {+ matrix.translate ((original_height - height * scale) / 2, 0);+ } else if ((alignment & ViewBox.YMAX) > 0) {+ matrix.translate ((original_height - height * scale), 0);+ }+ }++ if (!preserve_aspect_ratio) {+ matrix.scale (scale_x, scale_y);+ } else if (scale_width) {+ scale = scale_y;+ matrix.scale (scale, scale);+ } else {+ scale = scale_x;+ matrix.scale (scale, scale);+ }+ + return matrix;+ } } }