The Birdfont Source Code


All Repositories / birdfont.git / commit – RSS feed

Add view box to SVG parser

These changes was commited to the Birdfont repository Tue, 05 Jul 2016 15:34:28 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
author Johan Mattsson <johan.mattsson.m@gmail.com>
Tue, 05 Jul 2016 15:34:28 +0000 (17:34 +0200)
committer Johan Mattsson <johan.mattsson.m@gmail.com>
Tue, 05 Jul 2016 15:34:28 +0000 (17:34 +0200)
commit d58c15e77cf368fd473bc9c70c76897e16d64b1e
tree e9e861c6bd4a16e589ee37307db0c9e0c17e5dd5
parent a020eb0bb50a7a90974083fb1c5f46611c93aaa4
Add view box to SVG parser

libbirdfont/DrawingTools.vala
libbirdfont/SvgParser.vala
libsvgbird/SvgDrawing.vala
libsvgbird/SvgFile.vala
libsvgbird/ViewBox.vala
--- a/libbirdfont/DrawingTools.vala +++ b/libbirdfont/DrawingTools.vala @@ -601,6 +601,7 @@ 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 (); });
--- a/libbirdfont/SvgParser.vala +++ b/libbirdfont/SvgParser.vala @@ -221,6 +221,19 @@ } 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 @@ } } - 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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; } @@ -1128,6 +1162,15 @@ // TODO: Find out if it is possible to tie handles. 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) {
--- a/libsvgbird/SvgDrawing.vala +++ b/libsvgbird/SvgDrawing.vala @@ -44,48 +44,12 @@ } 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 @@ drawing.defs = defs.copy (); drawing.width = width; drawing.height = height; + + if (view_box != null) { + drawing.view_box = ((!) view_box).copy (); + } + return drawing; }
--- a/libsvgbird/SvgFile.vala +++ b/libsvgbird/SvgFile.vala @@ -46,7 +46,7 @@ } 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 @@ 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 (); @@ -101,6 +106,8 @@ preserve_aspect_ratio = false; } } + + arguments = parameters.replace (",", " "); while (arguments.index_of (" ") > -1) { arguments = arguments.replace (" ", " ");
--- a/libsvgbird/ViewBox.vala +++ b/libsvgbird/ViewBox.vala @@ -48,6 +48,9 @@ public bool slice; 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,8 +64,72 @@ 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; + } } }