Clone in a terminal:
Commit 0f40cc1
Johan Mattsson - 2016-07-06T21:18:29+00:00
0f40cc1ec04c1b63443f886c9ba2324dae3f2b6ejohan.mattsson.m@gmail.com

Import SVG files from Illustrator

Changed files (6)

Diff

diff --git a/libbirdfont/MoveTool.vala b/libbirdfont/MoveTool.valaindex a57fc63..3da445f 100644--- a/libbirdfont/MoveTool.vala+++ b/libbirdfont/MoveTool.vala@@ -551,7 +551,8 @@ public class MoveTool : Tool { 				EmbeddedSvg svg = (EmbeddedSvg) object; 				glyph.clear_active_paths (); 				string transformed_svg_data = svg.get_transformed_svg_data ();-				PathList path_list = SvgParser.import_svg_data_in_glyph (transformed_svg_data, glyph);+				SvgParser svg_parser = new SvgParser ();+				PathList path_list = svg_parser.import_svg_data_in_glyph (transformed_svg_data, glyph); 				glyph.delete_object (svg);  				foreach (Path path in path_list.paths) {diff --git a/libbirdfont/SvgFont.vala b/libbirdfont/SvgFont.valaindex 7223c2f..1f2f501 100644--- a/libbirdfont/SvgFont.vala+++ b/libbirdfont/SvgFont.vala@@ -13,6 +13,7 @@ */  using B;+using SvgBird;  namespace BirdFont { diff --git a/libbirdfont/SvgParser.vala b/libbirdfont/SvgParser.valaindex 04d533f..a760d7b 100644--- a/libbirdfont/SvgParser.vala+++ b/libbirdfont/SvgParser.vala@@ -18,19 +18,12 @@ using SvgBird;  namespace BirdFont { -public enum SvgFormat {-	NONE,-	INKSCAPE,-	ILLUSTRATOR-}- public enum SvgType { 	COLOR, 	REGULAR }  public class SvgParser {-	 	SvgFormat format = SvgFormat.ILLUSTRATOR; 	 	public SvgParser () {@@ -142,12 +135,13 @@ public class SvgParser { 		MainWindow.file_chooser (t_("Import"), fc, FileChooser.LOAD | FileChooser.DIRECTORY); 	} 	-	public static PathList import_svg_data (string xml_data, SvgFormat format = SvgFormat.NONE) {+	public static PathList import_svg_data (string xml_data) { 		Glyph glyph = MainWindow.get_current_glyph ();-		return import_svg_data_in_glyph (xml_data, glyph, format);+		SvgParser parser = new SvgParser ();+		return parser.import_svg_data_in_glyph (xml_data, glyph); 	} 	-	public static PathList import_svg_data_in_glyph (string xml_data, Glyph glyph, SvgFormat format = SvgFormat.NONE) {+	public PathList import_svg_data_in_glyph (string xml_data, Glyph glyph) { 		PathList path_list = new PathList (); 		string[] lines = xml_data.split ("\n"); 		bool has_format = false;@@ -1145,18 +1139,22 @@ public class SvgParser { 		 		move_and_resize (bezier_points, points, svg_glyph, units, glyph); 		+		/* 		if (format == SvgFormat.ILLUSTRATOR) { 			path_list = create_paths_illustrator (bezier_points, points); 		} else {-			path_list = create_svg_paths_inkscape (d);+			 		}+		*/++		path_list = create_svg_paths (d, format);  		// TODO: Find out if it is possible to tie handles. 		return path_list; 	} 	-	public PathList create_svg_paths_inkscape (string path_data) {-		Gee.ArrayList<Points> points_set = SvgFile.parse_points (path_data);+	public PathList create_svg_paths (string path_data, SvgFormat format) {+		Gee.ArrayList<Points> points_set = SvgFile.parse_points (path_data, format); 		PathList path_list = new PathList (); 		 		foreach (Points p in points_set) {@@ -1166,6 +1164,11 @@ public class SvgParser { 			EditPoint next = new EditPoint (p.x, -p.y, PointType.CUBIC); 			EditPointHandle handle; +			if (p.size == 0) {+				warning ("No points in path.");+				return path_list;+			}+			 			if (p.size % 8 != 0) { 				warning ("Points not padded."); 				return path_list;@@ -1220,8 +1223,6 @@ public class SvgParser { 			 			if (p.closed) { 				path.close ();-				path.get_first_point ().color = Color.blue ();-				path.get_last_point ().color = Color.green (); 			}  			Font font = BirdFont.get_current_font ();@@ -1236,21 +1237,13 @@ public class SvgParser { 				e.get_left_handle ().independent_y += font.top_limit;	 			} 			+			path.recalculate_linear_handles (); 			path_list.add (path); 		} 		 		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 (); 		@@ -1736,12 +1729,9 @@ public class SvgParser { 	}  	public static EmbeddedSvg parse_embedded_svg_data (string xml_data) {-		XmlTree tree = new XmlTree (xml_data); 		SvgDrawing drawing = new SvgDrawing ();	 		SvgFile svg_file = new SvgFile (); --		XmlElement root = tree.get_root ();-		drawing = svg_file.parse_svg_file (root);+		drawing = svg_file.parse_svg_data (xml_data); 		EmbeddedSvg svg = new EmbeddedSvg (drawing); 		svg.svg_data = xml_data; 		return svg;diff --git a/libbirdfont/TestCases.vala b/libbirdfont/TestCases.valaindex 913219c..ca50411 100644--- a/libbirdfont/TestCases.vala+++ b/libbirdfont/TestCases.vala@@ -13,7 +13,7 @@ */  using B;-+using SvgBird; namespace BirdFont {  /** All the things we want to test listed is here. */diff --git a/libsvgbird/Doubles.vala b/libsvgbird/Doubles.valaindex 13f96dd..d9a8b67 100644--- a/libsvgbird/Doubles.vala+++ b/libsvgbird/Doubles.vala@@ -25,14 +25,26 @@ public class Doubles : GLib.Object { 		data = new PointValue[capacity]; 	} +	public Doubles.for_capacity (int capacity) {+		data = new PointValue[capacity];+		this.capacity = capacity;+	}+	 	~Doubles () { 		delete data; 		data = null; 	} 	-	public Doubles.for_capacity (int capacity) {-		data = new PointValue[capacity];-		this.capacity = capacity;+	public void remove_first (int n) {+		if (size < n) {+			return;+		}+		+		size -= n;+		+		for (int i = 0; i < size; i++) {+			data[i] = data[i + n];+		} 	} 	 	void increase_capacity () {@@ -86,6 +98,20 @@ public class Doubles : GLib.Object { 		return data[index].value; 	} +	public uchar get_point_type (int index) {+		if (unlikely (index < 0)) {+			warning ("index < 0");+			return 0;+		}++		if (unlikely (index >= size)) {+			warning ("index >= size");+			return 0;+		}+		+		return data[index].type;+	}+	 	public string get_string (int i) { 		return round (get_double (i)); 	}diff --git a/libsvgbird/SvgFile.vala b/libsvgbird/SvgFile.valaindex 0766605..2ba1e85 100644--- a/libsvgbird/SvgFile.vala+++ b/libsvgbird/SvgFile.vala@@ -18,20 +18,35 @@ using Math;  namespace SvgBird { +public enum SvgFormat {+	NONE,+	INKSCAPE,+	ILLUSTRATOR+}+ public class SvgFile : GLib.Object {  	SvgDrawing drawing;+	SvgFormat format = SvgFormat.ILLUSTRATOR;  	public SvgFile () {		 	} 	 	public SvgDrawing parse_svg_data (string xml_data) { 		XmlTree tree = new XmlTree (xml_data);-		return parse_svg_file (tree.get_root ());++		if (xml_data.index_of ("Illustrator") > -1 || xml_data.index_of ("illustrator") > -1) {+			format = SvgFormat.ILLUSTRATOR;+		} else if (xml_data.index_of ("Inkscape") > -1 || xml_data.index_of ("inkscape") > -1) {+			format = SvgFormat.INKSCAPE;+		}++		return parse_svg_file (tree.get_root (), format); 	} 	-	public SvgDrawing parse_svg_file (XmlElement svg_tag) {+	public SvgDrawing parse_svg_file (XmlElement svg_tag, SvgFormat format) { 		drawing = new SvgDrawing ();+		this.format = format;  		SvgStyle style = new SvgStyle (); 		SvgStyle.parse (drawing.defs, style, svg_tag, null);@@ -58,7 +73,7 @@ public class SvgFile : GLib.Object { 			}  			if (name == "svg") {-				SvgDrawing embedded = parse_svg_file (t);+				SvgDrawing embedded = parse_svg_file (t, format); 				drawing.root_layer.add_object (embedded); 			} 			@@ -396,7 +411,7 @@ public class SvgFile : GLib.Object { 		} 		 		if (name == "svg") {-			SvgDrawing embedded = parse_svg_file (tag);+			SvgDrawing embedded = parse_svg_file (tag, format); 			layer.add_object (embedded); 		} @@ -765,7 +780,7 @@ public class SvgFile : GLib.Object {  		foreach (Attribute attr in tag.get_attributes ()) { 			if (attr.get_name () == "d") {-				path.points = parse_points (attr.get_content ());+				path.points = parse_points (attr.get_content (), format); 			} 		} 		@@ -773,18 +788,18 @@ public class SvgFile : GLib.Object { 		layer.add_object (path); 	} -	public static Gee.ArrayList<Points> parse_points (string data) {+	public static Gee.ArrayList<Points> parse_points (string data, SvgFormat format) { 		Gee.ArrayList<Points> path_data = new Gee.ArrayList<Points> (); 		Points points = new Points (); 		BezierPoints[] bezier_points; 		int points_size;-	+		 		get_bezier_points (data, out bezier_points, out points_size, true); +		print (@"format $format\n");+	 		// all instructions are padded -		// FIXME: Inscape and Illustrator discrepancies- 		for (int i = 0; i < points_size; i++) { 			// FIXME: add more types 			if (bezier_points[i].type == 'M') {@@ -853,6 +868,61 @@ public class SvgFile : GLib.Object { 		if (points.size > 0) { 			path_data.add (points); 		}++		if (format == SvgFormat.ILLUSTRATOR) {+			print ("Remove first");+			+			Gee.ArrayList<Points> illustrator_path_data = new Gee.ArrayList<Points> ();+			+			foreach (Points p in path_data) {+				return_val_if_fail (p.point_data.size % 8 == 0, path_data);+				+				if (p.point_data.size > 16) {+					Points illustrator_points = new Points ();+					+					illustrator_points.x = p.point_data.get_double (p.point_data.size - 3);+					illustrator_points.y = p.point_data.get_double (p.point_data.size - 2);+						+					int start = p.point_data.get_point_type (0) == POINT_CUBIC ? 8 : 0;+					+					for (int i = start; i < p.point_data.size; i += 1) {+						illustrator_points.point_data.add (p.point_data.get_double (i));+					}+					+					illustrator_points.closed = p.closed;+					illustrator_path_data.add (illustrator_points);+				}+			}+			+			return illustrator_path_data;+			+			/*+			foreach (Points p in path_data) {+				//p.point_data.remove_first (8);+				p.point_data.size -= 8;+				p.point_data.get_double (0)+				p.point_data.get_double (1)+			}+			*/+			+			+			+			/*EditPoint first = path.delete_first_point ();+			EditPoint last = path.get_last_point ();+			handle = last.get_right_handle ();+			+			last.get_right_handle ().independent_x = first.get_left_handle ().x;+			last.get_right_handle ().independent_y = first.get_left_handle ().y;+			+			if (points[0].type == POINT_CUBIC && !handle.is_line ()) {+				handle.set_point_type (PointType.CUBIC);+				handle.move_to_coordinate (points[0].value, points[1].value);+			} else {+				handle.set_point_type (PointType.LINE_CUBIC);+				path.recalculate_linear_handles_for_point (last);+			}+			*/+		} 		 		return path_data; 	}

Contact

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