Clone in a terminal:
Commit a85374e
Johan Mattsson - 2013-09-01T16:30:58+00:00
a85374e4cee8473a3c4757ef5eacdca43d56fe3fjohan.mattsson.m@gmail.com

copy and paste selected points and add new points to pasted paths

Changed files (12)

Diff

diff --git a/libbirdfont/BirdFontFile.vala b/libbirdfont/BirdFontFile.valaindex c2977cb..e2c5603 100644--- a/libbirdfont/BirdFontFile.vala+++ b/libbirdfont/BirdFontFile.vala@@ -274,6 +274,8 @@ class BirdFontFile { 	 * C - Cubic Bézier path 	 *  	 * T - Tie handles for previous curve+	 * +	 * O - Keep open (do not close path) 	 */ 	public static string get_point_data (Path pl) { 		StringBuilder data = new StringBuilder ();@@ -281,20 +283,39 @@ class BirdFontFile { 		EditPoint m; 		int i = 0; 		-		if (pl.points.length () < 2) {-			return "";+		if (pl.points.length () == 0) {+			return data.str;+		}+		+		if (pl.points.length () == 1) {+			add_start_point (pl.points.first ().data, data);+			data.append (" ");+			add_next_point (pl.points.first ().data, pl.points.first ().data, data);++			if (pl.is_open ()) {+				data.append (" O");+			}+			return data.str;+		}+		+		if (pl.points.length () == 2) {+			add_start_point (pl.points.first ().data, data);+			data.append (" ");+			add_next_point (pl.points.first ().data, pl.points.last ().data, data);+			data.append (" ");+			add_next_point (pl.points.last ().data, pl.points.first ().data, data);+			+			if (pl.is_open ()) {+				data.append (" O");+			}+			return data.str; 		} 		 		pl.create_list (); 			 		foreach (EditPoint e in pl.points) { 			if (i == 0) {-				if (e.type == PointType.CUBIC || e.type == PointType.LINE_CUBIC) {-					add_cubic_start (e, data);-				} else {-					add_quadratic_start (e, data);-				}-				+				add_start_point (e, data); 				i++; 				n = e; 				continue;@@ -303,28 +324,30 @@ class BirdFontFile { 			m = (!) n; 			data.append (" "); 			add_next_point (m, e, data);-			n = e;-			-			if (e.tie_handles) {-				data.append (" ");-				data.append (@"T");-			}-			++			n = e;			 			i++; 		}  		data.append (" "); 		m = pl.points.first ().data;	 		add_next_point ((!) n, m, data);--		if (m.tie_handles) {-			data.append (" ");-			data.append (@"T");+		+		if (pl.is_open ()) {+			data.append (" O"); 		} 		 		return data.str; 	} 	+	private static void add_start_point (EditPoint e, StringBuilder data) {+		if (e.type == PointType.CUBIC || e.type == PointType.LINE_CUBIC) {+			add_cubic_start (e, data);+		} else {+			add_quadratic_start (e, data);+		}+	}+	 	private static void add_quadratic_start (EditPoint p, StringBuilder data) { 		data.append (@"S $(p.x),$(p.y)"); 	}@@ -378,7 +401,12 @@ class BirdFontFile { 		} else { 			warning (@"Unknown point type. \nStart handle: $(start.right_handle.type) \nStop handle: $(end.left_handle.type)"); 			add_cubic (start, end, data);-		}		+		}++		if (end.tie_handles) {+			data.append (" ");+			data.append (@"T");+		}	 	}  	private void write_glyph_collection (GlyphCollection gc, DataOutputStream os)  throws GLib.Error {@@ -1024,6 +1052,8 @@ class BirdFontFile { 		ep2.left_handle.angle = ep1.left_handle.angle; 		ep2.left_handle.length = ep1.left_handle.length; 		ep2.left_handle.type = ep1.left_handle.type;+		+		path.close (); 	} 	 	public static Path parse_path_data (string data) {@@ -1032,6 +1062,7 @@ class BirdFontFile { 		int i = 0; 		Path path = new Path (); 		string instruction = "";+		bool open = false;  		if (data == "") { 			return path;@@ -1112,13 +1143,20 @@ class BirdFontFile { 				cubic (path, p[0], p[1], p1[0], p1[1], p2[0], p2[1]); 			} else if (instruction == "T") { 				path.points.last ().data.tie_handles = true;+			} else if (instruction == "O") {+				open = true; 			} else { 				warning (@"invalid instruction $instruction"); 				return path; 			} 		} -		close (path);+		if (!open) {+			close (path);+		} else {+			path.points.remove_link (path.points.last ());+		}+		 		path.update_region_boundries (); 		 		return path;	diff --git a/libbirdfont/ClipTool.vala b/libbirdfont/ClipTool.valaindex 1e1b64b..21e2e95 100644--- a/libbirdfont/ClipTool.vala+++ b/libbirdfont/ClipTool.vala@@ -96,14 +96,59 @@ public class ClipTool : Tool { 	static string export_selected_paths_to_birdfont_clipboard () { 		Glyph glyph = MainWindow.get_current_glyph (); 		StringBuilder s = new StringBuilder ();+		Path new_path;+		List<Path> paths = new List<Path> (); 		 		s.append ("\n"); 		s.append ("<!-- BirdFontClipboard\n"); 		-		foreach (Path path in glyph.active_paths) {-			s.append ("BF path: ");-			s.append (BirdFontFile.get_point_data (path));-			s.append ("\n");+		if (glyph.path_list.length () > 0 && !glyph.path_list.first ().data.is_editable ()) {+			foreach (Path path in glyph.active_paths) {+				s.append ("BF path: ");+				s.append (BirdFontFile.get_point_data (path));+				s.append ("\n");+			}+		} else {+			+			new_path = new Path ();+			foreach (Path path in glyph.path_list) {+				if (path.points.length () > 0+					&& path.points.first ().data.is_selected ()+					&& path.points.last ().data.is_selected ()) {+					+					foreach (EditPoint ep in path.points) {+						if (!ep.is_selected ()) {+							path.set_new_start (ep);+							break;+						}	+					}+				}+				+				foreach (EditPoint ep in path.points) {+					if (!ep.is_selected ()) {+						if (path.points.length () > 0) {+							paths.append (new_path);+							new_path = new Path ();+						}+					} else {+						new_path.add_point (ep);+					}+				}++				if (all_points_selected (path)) {+					new_path.close ();+				}+			}+			+			paths.append (new_path);+			+			foreach (Path path in paths) {+				if (path.points.length () > 0) {+					s.append ("BF path: ");+					s.append (BirdFontFile.get_point_data (path));+					s.append ("\n");+				}+			} 		} 		 		s.append ("-->");@@ -111,6 +156,15 @@ public class ClipTool : Tool { 		return s.str; 	} 	+	static bool all_points_selected (Path p) {+		foreach (EditPoint ep in p.points) {+			if (!ep.is_selected ()) {+				return false;+			}+		}+		return true;+	}+	 	static void import_birdfont_clipboard (string data) { 		string[] paths = data.split ("\nBF "); 		string d;@@ -131,9 +185,24 @@ public class ClipTool : Tool { 	static void import_birdfont_path (string data) { 		Glyph glyph = MainWindow.get_current_glyph (); 		Path path = BirdFontFile.parse_path_data (data);-		path.close ();-		glyph.add_path (path);-		glyph.active_paths.append (path);++		if (path.points.length () > 0) {+			glyph.add_path (path);+			glyph.active_paths.append (path);+			path.update_region_boundries ();+		}+		+		PenTool.remove_all_selected_points ();+		+		foreach (Path p in glyph.active_paths) {+			if (p.is_open ()) {+				foreach (EditPoint e in p.points) {+					e.set_selected (true);+				}+			}+		}+		+		PenTool.update_selection (); 	} } diff --git a/libbirdfont/DrawingTools.vala b/libbirdfont/DrawingTools.valaindex db73cef..38b5ba7 100644--- a/libbirdfont/DrawingTools.vala+++ b/libbirdfont/DrawingTools.vala@@ -123,22 +123,22 @@ public class DrawingTools : ToolCollection  { 				} 				 				p.set_tie_handle (tie);-				p.get_path ().update_region_boundries_for_point (p);+				+				PenTool.handle_selection.path.update_region_boundries (); 			} else {-				foreach (EditPoint ep in PenTool.selected_points) {-					tie = !ep.tie_handles;+				foreach (PointSelection ep in PenTool.selected_points) {+					tie = !ep.point.tie_handles; 					 					if (tie) {-						ep.process_tied_handle ();-						ep.set_reflective_handles (false);+						ep.point.process_tied_handle ();+						ep.point.set_reflective_handles (false); 					} 				-					ep.set_tie_handle (tie);-					ep.get_path ().update_region_boundries_for_point (ep);+					ep.point.set_tie_handle (tie);+					ep.path.update_region_boundries (); 				} 			} 			-			 			MainWindow.get_current_glyph ().update_view (); 		}); 		edit_point_modifiers.add_tool (tie_handles);@@ -147,20 +147,20 @@ public class DrawingTools : ToolCollection  { 		Tool reflect_handle = new Tool ("symmetric", _("Symmetrical handles"), 'r'); 		reflect_handle.select_action.connect ((self) => { 			bool symmetrical;-			EditPoint ep;+			PointSelection ep; 			if (PenTool.selected_points.length () > 0) { 				ep = PenTool.selected_points.first ().data;-				symmetrical = ep.reflective_handles;-				foreach (EditPoint p in PenTool.selected_points) {-					p.set_reflective_handles (!symmetrical);-					p.process_symmetrical_handles ();+				symmetrical = ep.point.reflective_handles;+				foreach (PointSelection p in PenTool.selected_points) {+					p.point.set_reflective_handles (!symmetrical);+					p.point.process_symmetrical_handles (); 					 					if (symmetrical) {-						ep.set_tie_handle (false);+						ep.point.set_tie_handle (false); 					}+					+					p.path.update_region_boundries (); 				}-				-				ep.get_path ().update_region_boundries_for_point (ep); 				MainWindow.get_current_glyph ().update_view (); 			} 		});diff --git a/libbirdfont/EditPoint.vala b/libbirdfont/EditPoint.valaindex f315a86..4130581 100644--- a/libbirdfont/EditPoint.vala+++ b/libbirdfont/EditPoint.vala@@ -49,8 +49,6 @@ public class EditPoint { 	public bool tie_handles = false; 	public bool reflective_handles = false; 	-	Path? path = null;-	 	public EditPoint (double nx = 0, double ny = 0, PointType nt = PointType.NONE) { 		x = nx; 		y = ny;@@ -73,18 +71,6 @@ public class EditPoint { 		} 	} -	public void set_path (Path p) {-		path = p;-	}--	public Path get_path () {-		if (unlikely (path == null)) {-			warning ("path is null");-			return new Path ();-		}	-		return (!) path;-	}- 	public bool equals (EditPoint e) { 		return e.x == x  			&& e.y == y @@ -337,7 +323,7 @@ public class EditPoint { 		new_point.left_handle.angle = left_handle.angle; 		new_point.left_handle.length = left_handle.length;		 		new_point.left_handle.type = left_handle.type;-+		 		return new_point; 	} diff --git a/libbirdfont/Glyph.vala b/libbirdfont/Glyph.valaindex 2e207ea..9c36dc6 100644--- a/libbirdfont/Glyph.vala+++ b/libbirdfont/Glyph.vala@@ -144,7 +144,9 @@ public class Glyph : FontDisplay { 		clear_active_paths (); 		 		foreach (Path p in path_list) {-			active_paths.append (p);+			if (p.points.length () > 0) {+				active_paths.append (p);+			} 		} 	} 	@@ -159,6 +161,7 @@ public class Glyph : FontDisplay { 			 			foreach (Path pi in active_paths) { 				if (pi == p) {+					print ("Exists\n"); 					return; 				} 			}@@ -689,6 +692,23 @@ public class Glyph : FontDisplay { 		} 	} +	/** Add new points to this path. */+	public void set_active_path (Path p) {+		unowned List<Path> pl;+		for (int i = 0; i < path_list.length (); i++) {+			pl = path_list.nth (i);+			if (pl.data == p) {+				path_list.remove_link (pl);+				break;+			}+		}+		+		path_list.append (p);+		p.reopen ();+		+		warn_if_fail (path_list.last ().data == p);+	}+ 	/** Insert new edit point for current path on the appropriate zoom 	 * level. 	 */@@ -927,7 +947,7 @@ public class Glyph : FontDisplay { 	 		added = false; -		// FIXME: what about removeing this feature+		// FIXME: remove this feature 		if (new_point_on_path != null) { 			return_val_if_fail (active_paths.length () > 0, new EditPoint ()); @@ -951,48 +971,21 @@ public class Glyph : FontDisplay { 		} 		 		if (!added) {-			foreach (Path p in paths) {-				if (p.is_open ()) {-					p.add (xt, yt);-					clear_active_paths ();-					add_active_path (p);-					added = true;-					break;-				}-			}-		}--		if (!added) {-			foreach (Path p in paths) {-				if (p.is_over (xt, yt)) {-					p.add (xt, yt);-					paths.append (p);-					added = true;-					redraw_area (0, 0, allocation.width, allocation.height);-					break;-				}-			}-		}-		-		if (!added) { 			if (paths.length () > 0 && paths.last ().data.is_open ()) { 				paths.last().data.add (xt, yt);-			}-			-			foreach (var p in path_list) {-				p.close ();-			}-			-			np = new Path ();-			paths.append (np);-			np.add (xt, yt);-			-			clear_active_paths ();-			add_active_path (np);+				add_active_path (paths.last().data);+			} else {+				np = new Path ();+				paths.append (np);+				np.add (xt, yt);+				+				clear_active_paths ();+				add_active_path (np);+			}	 		} 	-		assert (active_paths.length () > 0);-		assert (active_paths.last ().data.points.length () > 0);+		warn_if_fail (active_paths.length () > 0);+		warn_if_fail (active_paths.last ().data.points.length () > 0); 		 		inserted = active_paths.last ().data.points.data; 		@@ -1590,6 +1583,7 @@ public class Glyph : FontDisplay { 		 		foreach (Path p in g.path_list) { 			add_path (p);+			p.update_region_boundries (); 		}  		remove_lines ();diff --git a/libbirdfont/MainWindow.vala b/libbirdfont/MainWindow.valaindex 0c4b0c6..2111582 100644--- a/libbirdfont/MainWindow.vala+++ b/libbirdfont/MainWindow.vala@@ -1,18 +1,15 @@ /*
     Copyright (C) 2012 Johan Mattsson
 
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+    This library is free software; you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as 
+    published by the Free Software Foundation; either version 3 of the 
+    License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful, but 
+    WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
+    Lesser General Public License for more details.
 */
 
 namespace BirdFont {
diff --git a/libbirdfont/MoveTool.vala b/libbirdfont/MoveTool.valaindex 8306a75..e797f2a 100644--- a/libbirdfont/MoveTool.vala+++ b/libbirdfont/MoveTool.vala@@ -123,6 +123,7 @@ class MoveTool : Tool { 			}  			if (!rotate_path) {+				update_boundries_for_selection (); 				get_selection_box_boundries (out selection_box_center_x, 					out selection_box_center_y, out selection_box_width, 					out selection_box_height);	@@ -233,7 +234,7 @@ class MoveTool : Tool { 		cr.restore ();				 	} 	-	static void get_selection_box_boundries (out double x, out double y, out double w, out double h) {+	public static void get_selection_box_boundries (out double x, out double y, out double w, out double h) { 		double px, py, px2, py2; 		Glyph glyph = MainWindow.get_current_glyph (); 		@@ -322,12 +323,19 @@ class MoveTool : Tool { 		}		 	} 	+	public static void update_boundries_for_selection () {+		Glyph glyph = MainWindow.get_current_glyph ();+		foreach (Path p in glyph.active_paths) {+			p.update_region_boundries ();+		}+	}+	 	/** Move rotate handle to pixel x,y. */ 	void rotate (double x, double y) { 		double cx, cy, xc, yc, xc2, yc2, a, b, w, h;		 		Glyph glyph = MainWindow.get_current_glyph ();   		double dx, dy;-+		 		cx = Glyph.reverse_path_coordinate_x (selection_box_center_x); 		cy = Glyph.reverse_path_coordinate_y (selection_box_center_y); 		xc = selection_box_center_x;@@ -390,7 +398,7 @@ class MoveTool : Tool { 		double xc, yc, xc2, yc2, w, h;		 		double dx, dy; 		Glyph glyph = MainWindow.get_current_glyph ();  -+		 		xc = selection_box_center_x; 		yc = selection_box_center_y; diff --git a/libbirdfont/Path.vala b/libbirdfont/Path.valaindex 6c0d0b3..2609282 100644--- a/libbirdfont/Path.vala+++ b/libbirdfont/Path.vala@@ -667,9 +667,11 @@ public class Path { 	 	public Path copy () { 		Path new_path = new Path ();+		EditPoint p; 		 		foreach (var ep in points) {-			new_path.add_point (ep.copy ());+			p = ep.copy ();+			new_path.add_point (p); 		} 		 		new_path.edit = edit;@@ -886,8 +888,6 @@ public class Path { 		 		second_last_point = last_point; 		last_point = p;--		p.set_path (this); 		 		return np; 	}@@ -988,7 +988,9 @@ public class Path { 			xmax = 0; 			xmin = 0; 			ymax = 0;-			ymin = 0;		+			ymin = 0;+			+			warning ("No points in region.\n");	 		}  		foreach (EditPoint p in points) {@@ -1651,7 +1653,7 @@ public class Path { 		stderr.printf (@"ymin $ymin \n");		 	} 	-	public bool got_region_boundries () {+	public bool has_region_boundries () { 		return !(xmax == -10000 || xmin ==  10000 || ymax == -10000 || ymin ==  10000); 	} 	@@ -1822,6 +1824,10 @@ public class Path { 			} 		} 		+		foreach (Path path in path_list.paths) {+			path.update_region_boundries ();+		}+		 		return path_list; 	} 		@@ -2156,7 +2162,7 @@ public class Path { 	}  	public void append_path (Path path) {-		if (points.length () == 0) {+		if (points.length () == 0 || path.points.length () == 0) { 			warning ("No points"); 			return; 		}diff --git a/libbirdfont/PenTool.vala b/libbirdfont/PenTool.valaindex 1d0202c..2f7e49f 100644--- a/libbirdfont/PenTool.vala+++ b/libbirdfont/PenTool.vala@@ -27,12 +27,15 @@ public class PenTool : Tool {  	public static bool edit_active_corner = false; 	-	public static List<EditPoint> selected_points = new List<EditPoint> (); +	public static List<PointSelection> selected_points = new List<PointSelection> ();   	public static EditPointHandle active_handle = new EditPointHandle.empty (); 	public static EditPointHandle selected_handle = new EditPointHandle.empty ();+	public static PointSelection handle_selection = new PointSelection.empty (); 	 	public static EditPoint? active_edit_point = new EditPoint ();+	public static Path active_path = new Path ();+	 	public static EditPoint selected_point = new EditPoint ();  	public static bool move_selected_handle = false;@@ -180,13 +183,13 @@ public class PenTool : Tool { 	public static void delete_selected_points () { 		Glyph g = MainWindow.get_current_glyph (); -		foreach (EditPoint p in selected_points) {-			p.deleted = true;+		foreach (PointSelection p in selected_points) {+			p.point.deleted = true; 		} 		 		process_deleted (); -		foreach (var p in g.path_list) {+		foreach (Path p in g.path_list) { 			if (p.has_deleted_point ()) { 				process_deleted (); 			}@@ -214,11 +217,11 @@ public class PenTool : Tool { 		while (selected_points.length () > 0) { 			selected_points.remove_link (selected_points.first ()); 		}-		//remove_all_selected_points ();+ 		foreach (Path p in g.path_list) { 			foreach (EditPoint e in p.points) { 				if (e.is_selected ()) {-					selected_points.append (e);+					selected_points.append (new PointSelection (e, p)); 				} 			} 		}@@ -248,6 +251,7 @@ public class PenTool : Tool { 		double coordinate_x, coordinate_y; 		double px = 0; 		double py = 0;+		EditPoint p; 		 		control_point_event (x, y); 		curve_active_corner_event (x, y);@@ -273,10 +277,9 @@ public class PenTool : Tool { 				selected_handle.move_delta ((x - last_point_x) * precision, (y - last_point_y) * precision); 			} 			-			selected_handle.parent.recalculate_linear_handles ();-			selected_handle.parent.get_path ().update_region_boundries_for_handle (selected_handle);+			handle_selection.path.update_region_boundries (); 			-			// Fixa: redraw line only+			// FIXME: redraw line only 			glyph.redraw_area (0, 0, glyph.allocation.width, glyph.allocation.height); 			 			if (GridTool.is_visible ()) {@@ -292,7 +295,8 @@ public class PenTool : Tool {  		// move edit point 		if (move_selected) {-			foreach (EditPoint p in selected_points) {+			foreach (PointSelection ps in selected_points) {+				p = ps.point; 				if (GridTool.is_visible ()) { 					coordinate_x = Glyph.path_coordinate_x (x); 					coordinate_y = Glyph.path_coordinate_y (y);@@ -304,7 +308,7 @@ public class PenTool : Tool { 					glyph.move_selected_edit_point_delta (p, (x - last_point_x) * precision, (y - last_point_y) * precision); 				} 				p.recalculate_linear_handles ();-				p.get_path ().update_region_boundries_for_point (p);+				ps.path.update_region_boundries_for_point (p); 			} 		} 		@@ -434,9 +438,9 @@ public class PenTool : Tool { 	 	public void remove_from_selected (EditPoint ep)  		requires (selected_points.length () > 0) {-		for (unowned List<EditPoint> e = selected_points.first (); !is_null (e.next); e = e.next) {-			if (ep.equals (e.data)) {-				ep.set_selected (false);+		for (unowned List<PointSelection> e = selected_points.first (); !is_null (e.next); e = e.next) {+			if (e.data.point.equals (e.data.point)) {+				e.data.point.set_selected (false); 				selected_points.remove_link (e); 				return; 			}@@ -450,14 +454,32 @@ public class PenTool : Tool { 		 		control_point_event (x, y); -		// continue adding points from the other end+		// continue adding points from the other end of the selected path 		reverse = false;-		foreach (Path p in glyph.active_paths) {++		foreach (Path p in glyph.path_list) {+			+			if (p.is_open () && p.points.length () >= 1 +				&& (active_edit_point == p.points.first ().data +				|| active_edit_point == p.points.last ().data)) {+				active_path = p;+				glyph.set_active_path (p);+				+				update_selection ();+				reverse = true;+				control_point_event (x, y);+				break;+			}+				+		}+			+		foreach (Path p in glyph.path_list) { 			if (p.is_open () && p.points.length () > 1 && active_edit_point == p.points.first ().data) { 				p.reverse (); 				update_selection (); 				reverse = true; 				control_point_event (x, y);+				break; 			} 		} 				@@ -481,7 +503,7 @@ public class PenTool : Tool { 				} else { 					((!)active_edit_point).set_selected (true); 					selected_point = (!)active_edit_point;-					add_selected_point (selected_point);+					add_selected_point (selected_point, active_path); 					last_selected_is_handle = false; 				} 			} else {@@ -491,7 +513,7 @@ public class PenTool : Tool { 					remove_all_selected_points (); 					((!)active_edit_point).set_selected (true); 					selected_point = (!)active_edit_point;-					add_selected_point (selected_point);+					add_selected_point (selected_point, active_path); // FIXME: double check active path 					last_selected_is_handle = false; 				} 			}@@ -562,6 +584,7 @@ public class PenTool : Tool { 			path.recalculate_linear_handles (); 			direction_changed = true; 			active_edit_point = path.points.last ().data;+			active_path = path; 		} 		 		// join path with it self@@ -822,7 +845,7 @@ public class PenTool : Tool { 		move_current_point_on_path (x, y); 	} 		-	public static void set_active_edit_point (EditPoint? e) {+	public static void set_active_edit_point (EditPoint? e, Path path) { 		Glyph g = MainWindow.get_current_glyph (); 		foreach (var p in g.path_list) { 			foreach (var ep in p.points) {@@ -831,6 +854,7 @@ public class PenTool : Tool { 		} 		 		active_edit_point = e;+		active_path = path; 		 		if (e != null) { 			((!)e).set_active (true);@@ -839,12 +863,12 @@ public class PenTool : Tool { 		g.redraw_area (0, 0, g.allocation.width, g.allocation.height); 	} -	EditPoint? get_closest_point (double ex, double ey, out Path? path) {+	PointSelection? get_closest_point (double ex, double ey, out Path? path) { 		double x = Glyph.path_coordinate_x (ex); 		double y = Glyph.path_coordinate_y (ey); 		double d = double.MAX; 		double nd;-		EditPoint? ep = null;+		PointSelection? ep = null; 		Glyph g = MainWindow.get_current_glyph (); 		 		path = null;@@ -856,7 +880,7 @@ public class PenTool : Tool { 					 					if (nd < d) { 						d = nd;-						ep = e;+						ep = new PointSelection (e, current_path); 						path = current_path; 					} 				}@@ -868,8 +892,8 @@ public class PenTool : Tool {  	public double get_distance_to_closest_edit_point (double event_x, double event_y) { 		Path? p;-		EditPoint e;-		EditPoint? ep = get_closest_point (event_x, event_y, out p);+		PointSelection e;+		PointSelection? ep = get_closest_point (event_x, event_y, out p);  		double x = Glyph.path_coordinate_x (event_x); 		double y = Glyph.path_coordinate_y (event_y);@@ -880,39 +904,39 @@ public class PenTool : Tool { 		 		e = (!) ep; 		-		return e.get_distance (x, y);+		return e.point.get_distance (x, y); 	}  	public void control_point_event (double event_x, double event_y) { 		Path? p;-		EditPoint? ep = get_closest_point (event_x, event_y, out p);+		PointSelection? ep = get_closest_point (event_x, event_y, out p); 		Glyph g = MainWindow.get_current_glyph (); 		double x = Glyph.path_coordinate_x (event_x); 		double y = Glyph.path_coordinate_y (event_y); 		double distance;-		EditPoint e;+		PointSelection e; 		-		set_active_edit_point (null);+		set_active_edit_point (null, new Path ()); 		 		if (ep == null) { 			return;	 		} 		 		e = (!) ep;-		distance = e.get_distance (x, y) * g.view_zoom;+		distance = e.point.get_distance (x, y) * g.view_zoom;  		if (distance < CONTACT_SURFACE) {-			set_active_edit_point (ep);+			set_active_edit_point (e.point, e.path); 			 			if (first_move_action && GridTool.is_visible () && move_selected) {-				double coordinate_x = e.x;-				double coordinate_y = e.y;+				double coordinate_x = e.point.x;+				double coordinate_y = e.point.y; 				GridTool.tie_coordinate (ref coordinate_x, ref coordinate_y); 				int px = Glyph.reverse_path_coordinate_x (coordinate_x); 				int py = Glyph.reverse_path_coordinate_y (coordinate_y); 				-				last_point_x += Glyph.reverse_path_coordinate_x (e.x) - px;-				last_point_y += Glyph.reverse_path_coordinate_y (e.y) - py;+				last_point_x += Glyph.reverse_path_coordinate_x (e.point.x) - px;+				last_point_y += Glyph.reverse_path_coordinate_y (e.point.y) - py; 				 				first_move_action = false; 			}@@ -927,14 +951,16 @@ public class PenTool : Tool { 		 		new_point = glyph.add_new_edit_point (x, y); 		new_point.set_selected (true);+		glyph.active_paths.last ().data.update_region_boundries_for_point (new_point); 		 		if (KeyBindings.modifier != SHIFT) { 			remove_all_selected_points (); 		} 		-		add_selected_point (new_point); 		selected_point = new_point;-		add_selected_point (selected_point);+		active_edit_point = new_point;+		+		add_selected_point (selected_point, glyph.active_paths.last ().data); 		 		move_selected = true; 		@@ -1031,8 +1057,8 @@ public class PenTool : Tool { 		double distance_to_edit_point = g.view_zoom * get_distance_to_closest_edit_point (event_x, event_y); 		 		if (!Path.show_all_line_handles) {-			foreach (EditPoint selected_corner in selected_points) {-				if (is_close_to_handle (selected_corner, event_x, event_y, distance_to_edit_point)) {+			foreach (PointSelection selected_corner in selected_points) {+				if (is_close_to_handle (selected_corner.point, event_x, event_y, distance_to_edit_point)) { 					return true; 				} 			}@@ -1056,7 +1082,7 @@ public class PenTool : Tool { 		double x = Glyph.path_coordinate_x (event_x); 		double y = Glyph.path_coordinate_y (event_y); 		-		if (unlikely (p.xmin == 10000)) {+		if (unlikely (!p.has_region_boundries ())) { 			if (p.points.length () > 0) { 				warning (@"No bounding box. $(p.points.length ())"); 				p.update_region_boundries ();@@ -1087,18 +1113,18 @@ public class PenTool : Tool { 		return false; 	}  -	EditPointHandle get_closest_handle (double event_x, double event_y) {+	PointSelection get_closest_handle (double event_x, double event_y) { 		EditPointHandle left, right; 		double x = Glyph.path_coordinate_x (event_x); 		double y = Glyph.path_coordinate_y (event_y);		 		EditPointHandle eh = new EditPointHandle.empty();-		Glyph g = MainWindow.get_current_glyph (); -+		Glyph g = MainWindow.get_current_glyph (); 		double d = double.MAX; 		double dn;-+		Path path = new Path ();+		 		foreach (Path p in g.path_list) {-			if (is_close_to_path (p, event_x, event_y)) {+			if (is_close_to_path (p, event_x, event_y) || p == active_path) { 				foreach (EditPoint ep in p.points) { 					if (ep.is_selected () || Path.show_all_line_handles) { 						left = ep.get_left_handle ();@@ -1109,6 +1135,7 @@ public class PenTool : Tool { 						if (dn < d) { 							eh = left; 							d = dn;+							path = p; 						}  						dn = right.get_point ().get_distance (x, y);@@ -1116,16 +1143,18 @@ public class PenTool : Tool { 						if (dn < d) { 							eh = right; 							d = dn;+							path = p; 						} 					} 				} 			} 		}-		return eh;+		+		return new PointSelection.handle_selection (eh, path); 	}  	private void curve_active_corner_event (double event_x, double event_y) {-		EditPointHandle eh;+		PointSelection eh; 		 		active_handle.active = false; 		@@ -1134,13 +1163,15 @@ public class PenTool : Tool { 		}		 		 		eh = get_closest_handle (event_x, event_y);-		eh.active = true;-		active_handle = eh;+		eh.handle.active = true;+		active_handle = eh.handle;+		active_path = eh.path; 	}  	private void curve_corner_event (double event_x, double event_y) { 		MainWindow.get_current_glyph ().open_path ();-+		PointSelection p;+		 		if (!is_over_handle (event_x, event_y)) { 			return; 		}@@ -1148,18 +1179,21 @@ public class PenTool : Tool { 		move_selected_handle = true; 		last_selected_is_handle = true; 		selected_handle.selected = false;-		selected_handle = get_closest_handle (event_x, event_y);+		p = get_closest_handle (event_x, event_y);+		selected_handle = p.handle;+		handle_selection = p;+		active_path = p.path; 		selected_handle.selected = true; 	} -	public static void add_selected_point (EditPoint p) {-		foreach (EditPoint ep in selected_points) {-			if (p == ep) {+	public static void add_selected_point (EditPoint p, Path path) {+		foreach (PointSelection ep in selected_points) {+			if (p == ep.point) { 				return; 			} 		} 		-		selected_points.append (p);+		selected_points.append (new PointSelection (p, path)); 	} 	 	public static void remove_all_selected_points () {@@ -1170,9 +1204,9 @@ public class PenTool : Tool { 		selected_point = new EditPoint (); 			 		while (selected_points.length () > 0) {-			EditPoint ep = selected_points.first ().data;-			ep.set_active (false);-			ep.set_selected (false);+			PointSelection ep = selected_points.first ().data;+			ep.point.set_active (false);+			ep.point.set_selected (false); 			selected_points.remove_link (selected_points.first ()); 		} 		@@ -1185,7 +1219,7 @@ public class PenTool : Tool { 	}  	static void move_select_next_point (uint keyval) {-		EditPoint next = new EditPoint ();+		PointSelection next = new PointSelection.empty (); 		Glyph g = MainWindow.get_current_glyph(); 		 		if (selected_points.length () == 0) {@@ -1209,20 +1243,20 @@ public class PenTool : Tool { 				break; 		} -		set_selected_point (next);		+		set_selected_point (next.point, next.path);		 		g.redraw_area (0, 0, g.allocation.width, g.allocation.height);	 	} -	private static EditPoint get_next_point (double angle) +	private static PointSelection get_next_point (double angle)  		requires (selected_points.length () != 0) {-		EditPoint e = selected_points.last ().data;		-		double right_angle = e.right_handle.angle;-		double left_angle = e.left_handle.angle;+		PointSelection e = selected_points.last ().data;		+		double right_angle = e.point.right_handle.angle;+		double left_angle = e.point.left_handle.angle; 		double min_right, min_left; 		double min; 		-		return_val_if_fail (e.next != null, new EditPoint ());-		return_val_if_fail (e.prev != null, new EditPoint ());+		return_val_if_fail (e.point.next != null, new EditPoint ());+		return_val_if_fail (e.point.prev != null, new EditPoint ()); 			 		// angle might be greater than 2 PI or less than 0 		min_right = double.MAX;@@ -1240,32 +1274,32 @@ public class PenTool : Tool { 		} 		 		if (min_right < min_left) {-			return e.get_next ().data;+			return new PointSelection (e.point.get_next ().data, e.path); 		} 		-		return e.get_prev ().data;+		return new PointSelection (e.point.get_prev ().data, e.path); 	} 	-	private static EditPoint get_next_point_up () {+	private static PointSelection get_next_point_up () { 		return get_next_point (PI / 2); 	} -	private static EditPoint get_next_point_down () {+	private static PointSelection get_next_point_down () { 		return get_next_point (PI + PI / 2); 	} -	private static EditPoint get_next_point_left () {+	private static PointSelection get_next_point_left () { 		return get_next_point (PI); 	} -	private static EditPoint get_next_point_right () {+	private static PointSelection get_next_point_right () { 		return get_next_point (0); 	} -	private static void set_selected_point (EditPoint ep) {+	private static void set_selected_point (EditPoint ep, Path p) { 		remove_all_selected_points ();-		add_selected_point (ep);-		set_active_edit_point (ep);+		add_selected_point (ep, p);+		set_active_edit_point (ep, p); 		edit_active_corner = true; 		ep.set_selected (true); 		set_default_handle_positions ();		@@ -1296,30 +1330,30 @@ public class PenTool : Tool { 		 		if (!last_selected_is_handle) { 			if (keyval == Key.UP) {-				foreach (EditPoint e in selected_points) {-					e.set_position (e.x, e.y + Glyph.ivz ());-					e.recalculate_linear_handles ();+				foreach (PointSelection e in selected_points) {+					e.point.set_position (e.point.x, e.point.y + Glyph.ivz ());+					e.point.recalculate_linear_handles (); 				} 			} 			 			if (keyval == Key.DOWN) {-				foreach (EditPoint e in selected_points) {-					e.set_position (e.x, e.y - Glyph.ivz ());-					e.recalculate_linear_handles ();+				foreach (PointSelection e in selected_points) {+					e.point.set_position (e.point.x, e.point.y - Glyph.ivz ());+					e.point.recalculate_linear_handles (); 				} 			}  			if (keyval == Key.LEFT) {-				foreach (EditPoint e in selected_points) {-					e.set_position (e.x - Glyph.ivz (), e.y);-					e.recalculate_linear_handles ();+				foreach (PointSelection e in selected_points) {+					e.point.set_position (e.point.x - Glyph.ivz (), e.point.y);+					e.point.recalculate_linear_handles (); 				} 			}  			if (keyval == Key.RIGHT) {-				foreach (EditPoint e in selected_points) {-					e.set_position (e.x + Glyph.ivz (), e.y);-					e.recalculate_linear_handles ();+				foreach (PointSelection e in selected_points) {+					e.point.set_position (e.point.x + Glyph.ivz (), e.point.y);+					e.point.recalculate_linear_handles (); 				} 			} 			@@ -1432,10 +1466,10 @@ public class PenTool : Tool { 		} 		 		if (selected_points.length () == 1) {-			convert_point_to_line (selected_points.first ().data, true);+			convert_point_to_line (selected_points.first ().data.point, true); 		} else {-			foreach (EditPoint p in selected_points) {-				convert_point_to_line (p, false);+			foreach (PointSelection p in selected_points) {+				convert_point_to_line (p.point, false); 			} 		} 	}@@ -1509,26 +1543,27 @@ public class PenTool : Tool { 	public static void convert_point_types () { 		Glyph glyph = MainWindow.get_current_glyph (); 		glyph.store_undo_state ();-		EditPoint selected = new EditPoint ();+		PointSelection selected = new PointSelection.empty (); 		bool reset_selected = false;+		EditPoint e; 		 		if (selected_points.length () == 1) { 			selected = selected_points.first ().data;-			if (selected.next != null) {-				selected_points.append (selected.get_next ().data);-				selected.get_next ().data.set_selected (true);+			if (selected.point.next != null) {+				selected_points.append (new PointSelection (selected.point.get_next ().data, selected.path));+				selected.point.get_next ().data.set_selected (true); 			} 			-			if (selected.prev != null) {-				selected_points.append (selected.get_prev ().data);-				selected.get_next ().data.set_selected (true);+			if (selected.point.prev != null) {+				selected_points.append (new PointSelection (selected.point.get_prev ().data, selected.path));+				selected.point.get_next ().data.set_selected (true); 			} 			 			reset_selected = true; 		} 		-		foreach (EditPoint e in selected_points) {-			+		foreach (PointSelection ps in selected_points) {+			e = ps.point; 			// convert segments not control points 			if (e.next == null || !e.get_next ().data.is_selected ()) { 				continue;@@ -1563,7 +1598,7 @@ public class PenTool : Tool { 		if (reset_selected) { 			remove_all_selected_points (); 			selected_points.append (selected);-			selected.set_selected (true);+			selected.point.set_selected (true); 		} 	} 	@@ -1576,7 +1611,7 @@ public class PenTool : Tool { 		foreach (Path p in g.path_list) { 			foreach (EditPoint ep in p.points) { 				if (ep.is_selected ()) {-					selected_points.append (ep);+					selected_points.append (new PointSelection (ep, p)); 				} 			} 		}diff --git a/libbirdfont/PointSelection.vala b/libbirdfont/PointSelection.valanew file mode 100644index 0000000..2febc86--- /dev/null+++ b/libbirdfont/PointSelection.vala@@ -0,0 +1,45 @@+/*+    Copyright (C) 2013 Johan Mattsson++    This library is free software; you can redistribute it and/or modify +    it under the terms of the GNU Lesser General Public License as +    published by the Free Software Foundation; either version 3 of the +    License, or (at your option) any later version.++    This library is distributed in the hope that it will be useful, but +    WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +    Lesser General Public License for more details.+*/++using Math;+using Cairo;++namespace BirdFont {++public class PointSelection : GLib.Object {++	public EditPointHandle handle;+	public EditPoint point;+	public Path path;++	public PointSelection (EditPoint ep, Path p) {+		path = p;+		point = ep;+		handle = new EditPointHandle.empty ();+	}++	public PointSelection.handle_selection (EditPointHandle h, Path p) {+		path = p;+		point = new EditPoint ();+		handle = h;+	}+	+	public PointSelection.empty () {+		path = new Path ();+		point = new EditPoint ();+		handle = new EditPointHandle.empty ();+	}+}++}diff --git a/libbirdfont/Preferences.vala b/libbirdfont/Preferences.valaindex 365ffb4..60063ec 100644--- a/libbirdfont/Preferences.vala+++ b/libbirdfont/Preferences.vala@@ -11,6 +11,7 @@     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      Lesser General Public License for more details. */+ namespace BirdFont {  using Gee;@@ -18,7 +19,7 @@ using Gee; public class Preferences { 		 	static Gee.HashMap<string, string> data;-	public static bool draw_boundries = false; +	public static bool draw_boundries = true;   	public Preferences () { 		data = new HashMap<string, string> ();diff --git a/libbirdfont/ResizeTool.vala b/libbirdfont/ResizeTool.valaindex 2b1f516..4ccb6fb 100644--- a/libbirdfont/ResizeTool.vala+++ b/libbirdfont/ResizeTool.vala@@ -102,43 +102,11 @@ class ResizeTool : Tool { 	}  	static void update_selection_boundries () {-		get_selection_box_boundries (out selection_box_center_x,+		MoveTool.update_boundries_for_selection ();+		MoveTool.get_selection_box_boundries (out selection_box_center_x, 			out selection_box_center_y, out selection_box_width, 			out selection_box_height);	 	}--	static void get_selection_box_boundries (out double x, out double y, out double w, out double h) {-		double px, py, px2, py2;-		Glyph glyph = MainWindow.get_current_glyph ();-		-		px = 10000;-		py = 10000;-		px2 = -10000;-		py2 = -10000;-		-		foreach (Path p in glyph.active_paths) {-			if (px > p.xmin) {-				px = p.xmin;-			} --			if (py > p.ymin) {-				py = p.ymin;-			}--			if (px2 < p.xmax) {-				px2 = p.xmax;-			}-			-			if (py2 < p.ymax) {-				py2 = p.ymax;-			}-		}-		-		w = px2 - px;-		h = py2 - py;-		x = px + (w / 2);-		y = py + (h / 2);-	} 	 	void move_selected_paths (uint key) { 		Glyph glyph = MainWindow.get_current_glyph ();

Contact

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