Clone in a terminal:
Commit d58c15e
Johan Mattsson - 2016-07-05T15:34:28+00:00
d58c15e77cf368fd473bc9c70c76897e16d64b1ejohan.mattsson.m@gmail.com

Add view box to SVG parser

Changed files (5)

Diff

diff --git a/libbirdfont/DrawingTools.vala b/libbirdfont/DrawingTools.valaindex 6e10951..8a5f411 100644--- a/libbirdfont/DrawingTools.vala+++ b/libbirdfont/DrawingTools.vala@@ -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 (); 		}); diff --git a/libbirdfont/SvgParser.vala b/libbirdfont/SvgParser.valaindex b2f9adf..5cfb92b 100644--- a/libbirdfont/SvgParser.vala+++ b/libbirdfont/SvgParser.vala@@ -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 (); 		diff --git a/libsvgbird/SvgDrawing.vala b/libsvgbird/SvgDrawing.valaindex 412d233..0f638ad 100644--- a/libsvgbird/SvgDrawing.vala+++ b/libsvgbird/SvgDrawing.vala@@ -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; 	} 	diff --git a/libsvgbird/SvgFile.vala b/libsvgbird/SvgFile.valaindex b246b73..4bea11a 100644--- a/libsvgbird/SvgFile.vala+++ b/libsvgbird/SvgFile.vala@@ -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 ("  ", " "); 		}diff --git a/libsvgbird/ViewBox.vala b/libsvgbird/ViewBox.valaindex a0f2e38..aff3799 100644--- a/libsvgbird/ViewBox.vala+++ b/libsvgbird/ViewBox.vala@@ -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;+	}	 }  }

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112