Clone in a terminal:
Commit 2af1bde
Johan Mattsson - 2017-10-12T19:14:06+00:00
2af1bde166a9469731bf18e130a77b94388a5100johan.mattsson.m@gmail.com

Fix SVG parser (Inkscape)

Changed files (3)

Diff

diff --git a/libbirdfont/Glyph.vala b/libbirdfont/Glyph.valaindex 319b895..440ffe9 100644--- a/libbirdfont/Glyph.vala+++ b/libbirdfont/Glyph.vala@@ -2418,7 +2418,7 @@ public class Glyph : FontDisplay { 			foreach (Path p2 in get_visible_paths ()) { 				if (p1 != p2) { 					inside = true;-					outline = p2.flatten ();+					outline = p2.flatten (100);  					foreach (EditPoint ep in p1.points) { 						if (!SvgParser.is_inside (ep, outline)) {diff --git a/libbirdfont/SvgArc.vala b/libbirdfont/SvgArc.valaindex 92f3689..984e700 100644--- a/libbirdfont/SvgArc.vala+++ b/libbirdfont/SvgArc.vala@@ -172,7 +172,7 @@ static void add_arc_points (BezierPoints[] bezier_points, ref int bi, double x0, 		 		bezier_points[bi].x2 = cx + rx * cos (theta + 2 * step / 4); 		bezier_points[bi].y2 = cy + ry * sin (theta + 2 * step / 4);-						+		 		bi++; 	} }diff --git a/libbirdfont/SvgParser.vala b/libbirdfont/SvgParser.valaindex f1d2acd..bc28a3d 100644--- a/libbirdfont/SvgParser.vala+++ b/libbirdfont/SvgParser.vala@@ -142,7 +142,8 @@ public class SvgParser { 			p.update_region_boundaries (); 		} 		-		glyph.close_path ();	+		glyph.close_path ();+		glyph.fix_curve_orientation (); 	} 	 	public static string replace (string content, string start, string stop, string replacement) {@@ -1052,12 +1053,15 @@ public class SvgParser { 		int large_arc; 		int arc_sweep; 		double arc_dest_x, arc_dest_y;-+		double first_point_x = 0; +		double first_point_y = 0;+		bool set_first = true;+		 		font = BirdFont.get_current_font (); 		 		data = add_separators (d); 		c = data.split (" ");-		bezier_points = new BezierPoints[8 * c.length + 1]; // the arc instruction can use up to eight points+		bezier_points = new BezierPoints[8 * c.length + 2]; // the arc instruction can use up to eight points 		 		for (int i = 0; i < 2 * c.length + 1; i++) { 			bezier_points[i] = new BezierPoints ();@@ -1072,7 +1076,7 @@ public class SvgParser { 				while (i + 2 < c.length && is_point (c[i + 1])) { 					bezier_points[bi].type = 'M'; 					bezier_points[bi].svg_type = 'm';-					+							 					px += parse_double (c[++i]); 					 					if (svg_glyph) {@@ -1083,6 +1087,11 @@ public class SvgParser { 					 					bezier_points[bi].x0 = px; 					bezier_points[bi].y0 = py;++					first_point_x = px; +					first_point_y = py;+					set_first = false;+					 					bi++; 				} 			} else if (c[i] == "M") {@@ -1100,21 +1109,26 @@ public class SvgParser { 					 					bezier_points[bi].x0 = px; 					bezier_points[bi].y0 = py;++					first_point_x = px; +					first_point_y = py;+					set_first = false;+					 					bi++; 				} 			} else if (c[i] == "h") { 				while (i + 1 < c.length && is_point (c[i + 1])) { 					bezier_points[bi].type = 'L'; 					bezier_points[bi].svg_type = 'h';-					-					px += parse_double (c[++i]); +					px += parse_double (c[++i]);+					 					bezier_points[bi].x0 = px; 					bezier_points[bi].y0 = py; 					bi++; 				}-			} else if (i + 1 < c.length && c[i] == "H") {-				while (is_point (c[i + 1])) {+			} else if (c[i] == "H") {+				while (i + 1 < c.length && is_point (c[i + 1])) { 					bezier_points[bi].type = 'L'; 					bezier_points[bi].svg_type = 'H'; 					@@ -1505,7 +1519,7 @@ public class SvgParser { 					bi++;				 				} 			} else if (c[i] == "a") {-				while (i + 7 < c.length && is_point (c[i + 1])) {					+				while (i + 7 < c.length && is_point (c[i + 1])) { 					arc_rx = parse_double (c[++i]); 					arc_ry = parse_double (c[++i]); 					@@ -1528,11 +1542,9 @@ public class SvgParser { 					 					px = cx; 					py = cy;-					-					 				} 			} else if (i + 7 < c.length && c[i] == "A") {-				while (is_point (c[i + 1])) {					+				while (is_point (c[i + 1])) {			 					arc_rx = parse_double (c[++i]); 					arc_ry = parse_double (c[++i]); 					@@ -1558,20 +1570,37 @@ public class SvgParser { 					 					 				}-			} else if (c[i] == "z") {-				bezier_points[bi].type = 'z';-				bezier_points[bi].svg_type = 'z';+			} else if (c[i] == "z" || c[i] == "Z") {+				if (format == SvgFormat.INKSCAPE +					&& Path.distance (px, first_point_x, py, first_point_y) > 0.001) {+					+					px = first_point_x;+					py = first_point_y;+					+					bezier_points[bi].type = 'L';+					bezier_points[bi].svg_type = 'l';+					bezier_points[bi].x0 = px;+					bezier_points[bi].y0 = py;+					+					bi++;+				} 				-				bi++;-			} else if (c[i] == "Z") { 				bezier_points[bi].type = 'z'; 				bezier_points[bi].svg_type = 'z';-									+				+				set_first = true; 				bi++; 			} else if (c[i] == "") { 			} else if (c[i] == " ") { 			} else {-				warning (@"Unknown instruction: $(c[i])");+				+				print (@"\n\nSVG:");+				for (int dd = 0; dd <= i; dd++) {+					print (@"$(c[dd]) ");+				}+				print (@"\n");+				+				warning (@"Unknown instruction: $(c[i]), i: $(i)"); 			} 		} 		@@ -1838,7 +1867,7 @@ public class SvgParser { 		}  		foreach (Path p in path_list.paths) {-			p.remove_points_on_points ();+			p.remove_points_on_points (0.2); 		} 				 		return path_list;

Contact

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