Clone in a terminal:
Commit ebfec3a
Johan Mattsson - 2015-11-16T16:09:36+00:00
ebfec3aeefa6bac6ad8389899fa01168a53e5cc7johan.mattsson.m@gmail.com

Generate outline for new masters from stroked paths

Changed files (7)

Diff

diff --git a/libbirdfont/EditPointHandle.vala b/libbirdfont/EditPointHandle.valaindex 1d2b779..63bdc7c 100644--- a/libbirdfont/EditPointHandle.vala+++ b/libbirdfont/EditPointHandle.vala@@ -219,7 +219,7 @@ public class EditPointHandle : GLib.Object { 		 		process_connected_handle (); 	}-		+ 	public void move_to_coordinate_internal (double x, double y) { 		double a, b, c; @@ -308,6 +308,15 @@ public class EditPointHandle : GLib.Object { 	public bool is_line () { 		return PenTool.is_line (type); 	}++	public static double average_angle (double angle1, double angle2) {+		EditPointHandle handle = new EditPointHandle (new EditPoint (0, 0), 0, 1);+		double x = (cos (angle1) + cos (angle2)) / 2;+		double y = (sin (angle1) + sin (angle2)) / 2;+		handle.move_to_coordinate (x, y);+		return handle.angle;+	}+ }  }diff --git a/libbirdfont/Glyph.vala b/libbirdfont/Glyph.valaindex 920c79c..d983f00 100644--- a/libbirdfont/Glyph.vala+++ b/libbirdfont/Glyph.vala@@ -2444,10 +2444,36 @@ public class Glyph : FontDisplay { 		GlyphCanvas.redraw (); 	} 	-	public void self_interpolate (double weight) {+	public Glyph self_interpolate (double weight) {+		Glyph g = copy ();+		g.fix_curve_orientation ();+		g.layers = new Layer (); // remove all paths+		+		foreach (Path p in get_visible_paths ()) {+			bool counter = !p.is_clockwise ();+			+			g.add_path (p.copy ());+			Path master = p.get_self_interpolated_master (counter);+			g.add_path (master);+			+			g.add_path (p.interpolate_estimated_path (master, weight));+		}+		+		return g;+	}+	+	public Glyph self_interpolate_fast (double weight) {+		Glyph g = copy ();+		g.fix_curve_orientation ();+		g.layers = new Layer (); // remove all paths+		 		foreach (Path p in get_visible_paths ()) {-			p.self_interpolate (weight);+			bool counter = !p.is_clockwise ();+			Path path = p.self_interpolate_fast (weight, counter);+			g.add_path (path); 		}+		+		return g; 	} } diff --git a/libbirdfont/GlyphCollection.vala b/libbirdfont/GlyphCollection.valaindex 5ba7f2d..79d3afb 100644--- a/libbirdfont/GlyphCollection.vala+++ b/libbirdfont/GlyphCollection.vala@@ -21,10 +21,8 @@ public class GlyphCollection : GLib.Object { 	unichar unicode_character; 	string name; 	bool unassigned;-	public Gee.ArrayList<GlyphMaster> glyph_masters;-	-	// FIXME: move this somewhere-	static int current_master = 0;+	public Gee.ArrayList<GlyphMaster> glyph_masters;	+	int current_master = 0; 	 	public GlyphCollection (unichar unicode_character, string name) { 		this.unicode_character = unicode_character;@@ -66,7 +64,7 @@ public class GlyphCollection : GLib.Object { 			add_master (m); 			return m; 		} else if (unlikely (i >= glyph_masters.size)) {-			warning(@"No master at index $i.");+			warning(@"No master at index $i. ($(glyph_masters.size)) in $(name)"); 			i = glyph_masters.size - 1; 		} 		@@ -146,16 +144,28 @@ public class GlyphCollection : GLib.Object { 		} 		 		if (glyph_masters.size == 1) {-			Glyph master1 = get_current ().copy ();-			master1.self_interpolate (weight);-			return master1;+			return get_current ().self_interpolate (weight); 		} else { 			warning("Not implemented."); 		} 		 		return get_current (); 	}-	++	public Glyph get_interpolated_fast (double weight) {+		if (weight == 0) { // FIXME: compare to master weight+			return get_current (); +		}+		+		if (glyph_masters.size == 1) {+			return get_current ().self_interpolate_fast (weight);+		} else {+			warning("Not implemented.");+		}+		+		return get_current ();+	}+		 	public void insert_glyph (Glyph g, bool selected_glyph) { 		get_current_master ().insert_glyph (g, selected_glyph); 	}diff --git a/libbirdfont/OverViewItem.vala b/libbirdfont/OverViewItem.valaindex 61f2a36..ed3458d 100644--- a/libbirdfont/OverViewItem.vala+++ b/libbirdfont/OverViewItem.vala@@ -211,7 +211,7 @@ public class OverViewItem : GLib.Object { 		 		if (gl != null) { 			font = BirdFont.get_current_font ();-			g = ((!) gl).get_interpolated (OverviewTools.current_master_size);+			g = ((!) gl).get_interpolated_fast (OverviewTools.current_master_size);  			c.save (); 			g.boundaries (out x1, out y1, out x2, out y2);diff --git a/libbirdfont/OverviewTools.vala b/libbirdfont/OverviewTools.valaindex a0c7470..1050818 100644--- a/libbirdfont/OverviewTools.vala+++ b/libbirdfont/OverviewTools.vala@@ -199,7 +199,6 @@ public class OverviewTools : ToolCollection  { 			master.add_glyph(g); 			glyph_collection.add_master (master); 			glyph_collection.set_selected_master (master);-			print(@"$(glyph_collection.get_name ())\n"); 			 			i++; 			gc = font.get_glyph_collection_indice (i);diff --git a/libbirdfont/Path.vala b/libbirdfont/Path.valaindex c430788..0bb47d4 100644--- a/libbirdfont/Path.vala+++ b/libbirdfont/Path.vala@@ -2640,8 +2640,8 @@ public class Path : GLib.Object { 		EditPoint p = new EditPoint (Glyph.CANVAS_MAX, Glyph.CANVAS_MAX); 		 		foreach (EditPoint ep in points) {-			d = distance (x, ep.x, y, ep.y);-			+			d = distance (x, ep.x, y, ep.y);	+ 			if (d < min) { 				min = d; 				p = ep;@@ -2651,69 +2651,78 @@ public class Path : GLib.Object { 		return p; 	} 	-	public void self_interpolate (double weight) {+	public Path self_interpolate (double weight, bool counter) { 		Path master;+		Path p = new Path (); 		 		if (stroke > 0) {-			stroke += 5 * weight * 2;+			p = copy ();+			p.stroke += 5 * weight * 2; 			-			if (stroke < 0.002) {-				stroke = 0.002;+			if (p.stroke < 0.002) {+				p.stroke = 0.002; 			} 		} else { 			remove_points_on_points ();-			master = get_self_interpolated_master ();-			interpolate_path (master, weight);+			master = get_self_interpolated_master (counter);+			p = interpolate_estimated_path (master, weight); 			recalculate_linear_handles ();-		}	-	}-	-	Path get_self_interpolated_master () {-		Path master = new Path ();-		EditPoint ep1, ep2, none;-		-		none = new EditPoint ();-		for (int i = 0; i < points.size; i++) {-			ep1 = points.get (i).copy ();-			ep2 = ep1.copy ();-			-			StrokeTool.move_segment (ep1, none, 5);-			StrokeTool.move_segment (none, ep2, 5);-			-			ep1.x = (ep2.x + ep1.x) / 2;-			ep1.y = (ep2.y + ep1.y) / 2;-			-			master.add_point (ep1.copy ()); 		} 		-		return master;	+		return p;+	}+	+	public Path self_interpolate_fast (double weight, bool counter) {+		return StrokeTool.change_weight_fast (this,  5 * weight, counter); 	} 	-	void interpolate_path (Path master, double weight) {+	static double abs_max (double a, double b) {+		return fabs (a) > fabs (b) ? a : b;+	}+		+	public Path interpolate_estimated_path (Path master, double weight) {+		Path p = copy (); 		EditPoint ep, master_point; 		EditPointHandle h; 		double length;-		-		if (unlikely (points.size != master.points.size)) {-			warning ("Master and path must have the same number of points.");-			return;-		}-	-		for (int i = 0; i < points.size; i++) {-			ep = points.get (i);-			master_point = master.points.get (i);-						+		double x, y;++		master_point = new EditPoint ();++		for (int i = 0; i < p.points.size; i++) {+			ep = p.points.get (i);++			double right_angle = ep.get_right_handle ().angle;+			double left_angle = ep.get_left_handle ().angle;+			double angle = EditPointHandle.average_angle (right_angle, left_angle);+			angle += PI;+			angle %= 2 * PI;+			+			x = ep.x + 5 * cos (angle);+			y = ep.y + 5 * sin (angle);+			+			master_point = new EditPoint ();+			master.get_closest_point_on_path (master_point, x, y);+			master_point.color = Color.red ();+			master.insert_new_point_on_path (master_point);+			 			ep.x += (master_point.x - ep.x) * weight; 			ep.y += (master_point.y - ep.y) * weight; +/* 			h = ep.get_right_handle ();-			length = master_point.get_right_handle ().length;-			h.length = length * weight + h.length * (1 - weight);+			h.length += 5 * weight; 			 			h = ep.get_left_handle ();-			length = master_point.get_left_handle ().length;-			h.length = length * weight + h.length * (1 - weight) ;+			h.length += 5 * weight;+			*/ 		}+		+		return p;+	}++	public Path get_self_interpolated_master (bool counter) {+		return StrokeTool.change_weight (this, counter);	 	} } diff --git a/libbirdfont/StrokeTool.vala b/libbirdfont/StrokeTool.valaindex 0fef9ee..f0d135e 100644--- a/libbirdfont/StrokeTool.vala+++ b/libbirdfont/StrokeTool.vala@@ -2799,8 +2799,7 @@ public class StrokeTool : GLib.Object { 		return sum > 0; 	}	 -	public PathList create_stroke (Path original_path, double thickness) {-			+	public PathList create_stroke (Path original_path, double thickness) {	 		PathList pl; 		EditPoint p1, p2, p3; 		EditPoint previous, previous_inside, start, start_inside;@@ -3115,6 +3114,56 @@ public class StrokeTool : GLib.Object {  		return paths; 	}+	+	public static Path change_weight_fast (Path path, double weight, bool counter) {+		StrokeTool tool = new StrokeTool ();+		PathList pl;+		+		pl = tool.get_stroke_fast (path, fabs(weight));+		+		return_val_if_fail (pl.paths.size == 2, new Path ());+		+		if (counter == !pl.paths.get (0).is_clockwise ()) {+			return pl.paths.get (0);+		}+		+		return pl.paths.get (1);+	}+	+	public static Path change_weight (Path path, bool counter) {+		StrokeTool tool = new StrokeTool ();+		Path o = path.copy ();+		Path interpolated = new Path();+		o.force_direction (Direction.CLOCKWISE);+		+		PathList pl = tool.get_stroke (o, 5);+		Gee.ArrayList<PointSelection> deleted;+		+		deleted = new Gee.ArrayList<PointSelection> (); ++		return_val_if_fail (pl.paths.size > 0, new Path ());+		+		foreach (Path sp in pl.paths) {+			if (sp.points.size > interpolated.points.size+				&& counter == !sp.is_clockwise ()) {+				interpolated = sp;+			}+		}+		+		/*+		foreach (EditPoint ep in interpolated.points) {+			if ((ep.flags & EditPoint.SEGMENT_END) != 0) {+				deleted.add (new PointSelection (ep, interpolated));+			}+		}+	+		foreach (PointSelection ps in deleted) {+			PenTool.remove_point_simplify_path (ps);+		}+		*/+		+		return interpolated; // FIXME: split paths in interpolation?+	}  }  }

Contact

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