Clone in a terminal:
Commit 51602ed
Johan Mattsson - 2015-05-08T17:03:45+00:00
51602ed89303cc17e28ddd5680c059b4ed92fa16johan.mattsson.m@gmail.com

Stroke

Changed files (5)

Diff

diff --git a/birdfont/GtkWindow.vala b/birdfont/GtkWindow.valaindex 4195503..5fb3f97 100644--- a/birdfont/GtkWindow.vala+++ b/birdfont/GtkWindow.vala@@ -805,7 +805,9 @@ class ToolboxCanvas : DrawingArea { public class GlyphCanvasArea : DrawingArea  { 	GlyphCanvas glyph_canvas; 	WidgetAllocation alloc = new WidgetAllocation ();-	+	uint32 last_release = 0;+	uint32 last_press = 0;+ 	public GlyphCanvasArea (GlyphCanvas gc) { 		int event_flags; 		@@ -852,17 +854,33 @@ public class GlyphCanvasArea : DrawingArea  { 		button_press_event.connect ((t, e)=> { 			GtkWindow.reset_modifier (e.state); +			if (e.time < last_press) {+				warning ("Discarding event.");+				return true;+			}+			+			last_press = e.time;+			 			if (e.type == EventType.BUTTON_PRESS) { 				TabContent.button_press (e.button, e.x, e.y);	 			} else if (e.type == EventType.2BUTTON_PRESS) { 				TabContent.double_click (e.button, e.x, e.y); 			}-			+			  			return true; 		}); 		 		button_release_event.connect ((t, e)=> {-			TabContent.button_release ((int) e.button, e.x, e.y);+			if (e.time < last_release) {+				warning ("Discarding event.");+				return true;+			}+			+			if (e.type == EventType.BUTTON_RELEASE) {+				TabContent.button_release ((int) e.button, e.x, e.y);+				last_release = e.time;+			}+			 			return true; 		}); 		diff --git a/libbirdfont/BezierTool.vala b/libbirdfont/BezierTool.valaindex 852280e..17ddbe0 100644--- a/libbirdfont/BezierTool.vala+++ b/libbirdfont/BezierTool.vala@@ -40,6 +40,7 @@ public class BezierTool : Tool {  	double last_release_time = 0; 	double last_press_time = 0;+	bool button_down = false; 	 	public BezierTool (string name) { 		base (name, t_ ("Create Beziér curves"));@@ -87,11 +88,18 @@ public class BezierTool : Tool { 		double px, py; 		Path? p; 		Path path;-		++		if (button_down) {+			warning ("Discarding event.");+			return;+		}+				+		button_down = true;+ 		return_if_fail (state != MOVE_HANDLES); 		return_if_fail (state != MOVE_LAST_HANDLE_RIGHT); 		return_if_fail (state != MOVE_LAST_HANDLE_LEFT);-		+				 		if (b == 2) { 			if (g.is_open ()) { 				stop_drawing ();@@ -187,6 +195,13 @@ public class BezierTool : Tool { 		double px, py; 		Glyph g; 		+		if (!button_down) {+			warning ("Discarding event.");+			return;+		}+		+		button_down = false;+		 		return_if_fail (state != MOVE_POINT); 		 		// ignore double clicksdiff --git a/libbirdfont/EditPoint.vala b/libbirdfont/EditPoint.valaindex ac9056a..c5f222d 100644--- a/libbirdfont/EditPoint.vala+++ b/libbirdfont/EditPoint.vala@@ -54,6 +54,8 @@ public class EditPoint : GLib.Object { 	public static uint OVERLAY = 1 << 11; 	public static uint CURVE = 1 << 12; 	public static uint CURVE_KEEP = 1 << 13;+	public static uint SEGMENT_END = 1 << 14;+	 	public static uint ALL = 0xFFFFFF; 	 	public uint flags = NONE;diff --git a/libbirdfont/ResizeTool.vala b/libbirdfont/ResizeTool.valaindex 2aa37e6..135dfcd 100644--- a/libbirdfont/ResizeTool.vala+++ b/libbirdfont/ResizeTool.vala@@ -312,6 +312,7 @@ public class ResizeTool : Tool { 		// resize paths 		foreach (Path selected_path in glyph.active_paths) { 			selected_path.resize (ratio);+			selected_path.reset_stroke (); 		} 		 		// move paths relative to the updated xmin and xmax@@ -319,7 +320,7 @@ public class ResizeTool : Tool { 		dx = resize_pos_x - selection_minx; 		dy = resize_pos_y - selection_miny; 		foreach (Path selected_path in glyph.active_paths) {-			selected_path.move (dx, dy);+			selected_path.move (dx, dy);			 		} 		 		if (glyph.active_paths.size > 0) {@@ -409,6 +410,7 @@ public class ResizeTool : Tool { 		 		foreach (Path p in glyph.active_paths) { 			p.move (dx, 0);+			p.reset_stroke (); 		} 		 		last_skew = skew;diff --git a/libbirdfont/StrokeTool.vala b/libbirdfont/StrokeTool.valaindex 65edbad..c6ffb3e 100644--- a/libbirdfont/StrokeTool.vala+++ b/libbirdfont/StrokeTool.vala@@ -88,16 +88,18 @@ public class StrokeTool : Tool { 	} 	 	public static PathList get_stroke_fast (Path path, double thickness) {-/*		PathList o;+		PathList o; 		Path stroke; 		+		o = get_stroke (path, thickness);+		+		/* // FIXME: 		stroke = path.copy (); 		stroke.remove_points_on_points (0.3); 		o = create_stroke (stroke, thickness, true);-				-		return o; 		*/-		return get_stroke (path, thickness);+			+		return o; 	} 	 	public static PathList get_stroke (Path path, double thickness) {@@ -107,9 +109,22 @@ public class StrokeTool : Tool { 		stroke = path.copy (); 		stroke.remove_points_on_points (0.3); 		o = create_stroke (stroke, thickness, false);++		if (stroke_selected) { // FIXME: DELETE	+			foreach (Path mm in o.paths)+					((!) BirdFont.get_current_font ().get_glyph ("o")).add_path (mm);+		}+ 		o = get_all_parts (o);-		o = merge (o);++		if (stroke_selected) { // FIXME: DELETE	+			foreach (Path mm in o.paths)+					((!) BirdFont.get_current_font ().get_glyph ("p")).add_path (mm);+		} 				+		o = remove_intersection_paths (o);+		o = merge (o);+		 		m = new PathList (); 		foreach (Path p in o.paths) { 			m.add (simplify_stroke (p));@@ -178,59 +193,55 @@ public class StrokeTool : Tool { 				 				if (simplified.points.size > 0) { 					last = simplified.get_last_point ();-					segment_last = added_segment.get_last_point ();-				}--				first = added_segment.get_first_point ();-				-				segment_last.get_right_handle ().convert_to_line ();-				-				if (simplified.points.size > 1) {-					simplified.delete_last_point ();-				}-				-				last.get_right_handle ().x = first.get_right_handle ().x;-				last.get_right_handle ().y = first.get_right_handle ().y;-				-				first.get_left_handle ().convert_to_curve ();-				first.get_left_handle ().x = last.get_left_handle ().x;-				first.get_left_handle ().y = last.get_left_handle ().y;-				-				simplified.append_path (added_segment);-				-				last = added_segment.get_last_point ();-				last.get_right_handle ().convert_to_line ();-				last.recalculate_linear_handles ();+				}	 				-				if (ep_start.get_right_handle ().is_line ()) {+				if (added_segment.points.size > 0) {+					segment_last = added_segment.get_last_point (); 					first = added_segment.get_first_point ();-					first.get_right_handle ().convert_to_line ();-					first.recalculate_linear_handles ();+					segment_last.get_right_handle ().convert_to_line ();+					+					if (simplified.points.size > 1) {+						simplified.delete_last_point ();+					}+					+					last.get_right_handle ().x = first.get_right_handle ().x;+					last.get_right_handle ().y = first.get_right_handle ().y;+					+					first.get_left_handle ().convert_to_curve ();+					first.get_left_handle ().x = last.get_left_handle ().x;+					first.get_left_handle ().y = last.get_left_handle ().y;+	+					last = added_segment.get_last_point ();+					last.get_right_handle ().convert_to_line ();+					last.recalculate_linear_handles ();+						+					simplified.append_path (added_segment);+					+					if (ep_start.get_right_handle ().is_line ()) {+						first = added_segment.get_first_point ();+						first.get_right_handle ().convert_to_line ();+						first.recalculate_linear_handles ();+					}++				} else {+					warning ("No points in segment."); 				}-				+									 				i = stop; 			} else { 				simplified.add_point (ep.copy ()); 			} 		} -		simplified.remove_points_on_points (); 		simplified.recalculate_linear_handles (); 		simplified.close (); 		-		/*-		if (p.get_first_point ().tie_handles) {-			first = simplified.get_first_point ();-			first.convert_to_curve ();-			first.tie_handles = true;-			first.process_tied_handle ();-		}-		*/--		//simplified.remove_points_on_points ();+		simplified.remove_points_on_points (0.01); -		simplified.get_last_point ().color = Color.pink ();-		simplified.get_first_point ().color = Color.green ();+		if (simplified.points.size > 0) {+			simplified.get_last_point ().color = Color.pink ();+			simplified.get_first_point ().color = Color.green ();+		} 		 		return simplified; 	}@@ -278,25 +289,28 @@ public class StrokeTool : Tool { 		return simplified; 	} 	-	static bool segment_is_line (Path p, int start, int stop) {-		EditPoint p0, p1, p2;+	static PathList remove_intersection_paths (PathList pl) {+		PathList r = new PathList (); 		-		if (stop - start < 2) {-			warning ("Too small segment.");-			return true;+		foreach (Path p in pl.paths) {+			if (p.points.size > 7) {+				r.add (p);+			} else {+				has_new_corner (p);+			} 		} 		-		for (int i = start; i <= stop - 2; i++) {-			p0 = p.points.get (i);-			p1 = p.points.get (i + 1);-			p2 = p.points.get (i + 2);-			-			if (!is_line (p0.x, p0.y, p1.x, p1.y, p2.x, p2.y)) {-				return false;+		return r;+	}++	static bool has_new_corner (Path p) {+		foreach (EditPoint ep in p.points) {+			if ((ep.flags & EditPoint.NEW_CORNER) > 0) {+				return true; 			} 		} 		-		return true;+		return false; 	}  	/** Create one stroke from the outline and counter stroke and close the @@ -380,6 +394,7 @@ public class StrokeTool : Tool { 		EditPointHandle next_handle; 		EditPoint cutoff1, cutoff2; 		double adjusted_stroke = (stroke_width * 0.999999) / 2.0;+		bool d1, d2; 		 		previous_handle = previous.get_left_handle (); 		next_handle = next.get_right_handle ();@@ -396,11 +411,27 @@ public class StrokeTool : Tool {  		distance = Path.distance_to_point (corner, original); 		ratio = 1.5 * fabs (adjusted_stroke) / distance;++		double or = original.get_right_handle ().angle;+		double ol = original.get_left_handle ().angle;			++		if (previous.prev == null) { // FIXME: first point +			warning ("Point before corner.");+			d1 = false;+			d2 = false;+		} else {+			d1 = corner.x - previous.x >= 0 == previous.x - previous.get_prev ().x >= 0;+			d2 = corner.y - previous.y >= 0 == previous.y - previous.get_prev ().y >= 0;		+		} 		 		if (ratio > 1) {-			stroked.add_point (corner);+			if (!d1 && !d2) {+				return;+			} else {+				stroked.add_point (corner);+			} 		} else {-+		 			cutoff1 = new EditPoint (); 			cutoff1.set_point_type (previous.type); 			cutoff1.convert_to_line ();@@ -409,11 +440,19 @@ public class StrokeTool : Tool { 			cutoff2.set_point_type (previous.type); 			cutoff2.convert_to_line (); -			cutoff1.x = previous.x + (corner.x - previous.x) * ratio;-			cutoff1.y = previous.y + (corner.y - previous.y) * ratio;+			if (fabs (or - ol) < 0.001) {+				cutoff1.x = previous.x + 1.5 * fabs (adjusted_stroke) * -cos (or);+				cutoff1.y = previous.y + 1.5 * fabs (adjusted_stroke) * -sin (or);++				cutoff2.x = next.x + 1.5 * fabs (adjusted_stroke) * -cos (or);+				cutoff2.y = next.y + 1.5 * fabs (adjusted_stroke) * -sin (or);+			} else {+				cutoff1.x = previous.x + (corner.x - previous.x) * ratio;+				cutoff1.y = previous.y + (corner.y - previous.y) * ratio; -			cutoff2.x = next.x + (corner.x - next.x) * ratio;-			cutoff2.y = next.y + (corner.y - next.y) * ratio;+				cutoff2.x = next.x + (corner.x - next.x) * ratio;+				cutoff2.y = next.y + (corner.y - next.y) * ratio;+			} 			 			if (!cutoff1.is_valid () || cutoff2.is_valid ()) { 				cutoff1 = stroked.add_point (cutoff1);@@ -423,12 +462,8 @@ public class StrokeTool : Tool { 			cutoff1.recalculate_linear_handles (); 			cutoff2.recalculate_linear_handles (); -			return_if_fail (previous.prev != null);-			-			bool d1 = corner.x - previous.x > 0 == previous.x - previous.get_prev ().x > 0;-			bool d2 = corner.y - previous.y > 0 == previous.y - previous.get_prev ().y > 0;-		-			if (!d1 && !d2) { // self intersection+			// self intersection+			if (!d1 && !d2) {  				cutoff1.deleted = true; 				cutoff2.deleted = true; 				@@ -436,7 +471,7 @@ public class StrokeTool : Tool { 				stroked.add (cutoff1.x + (cutoff2.x - cutoff1.x) / 2, cutoff1.y + (cutoff2.y - cutoff1.y) / 2); 				 				return;-			} +			} 			 			if (distance > 4 * stroke_width) { 				previous.flags = EditPoint.NONE;@@ -557,10 +592,17 @@ public class StrokeTool : Tool { 		 		if (add_intersection_points (path1, path2, 2)) { 			i = mark_intersection_as_deleted (path1);-			return_if_fail (i == 2);+			if (i != 2) {+				warning (@"Expecting 2 points, $i points found.");+				return false;+			}  			i = mark_intersection_as_deleted (path2);-			return_if_fail (i == 2);+			if (i != 2) {+				warning (@"Expecting 2 points, $i points found.");+				return false;+			}+ 			 			pl1 = get_remaining_points (path1.copy ()); 			pl2 = get_remaining_points (path2.copy ());@@ -787,7 +829,7 @@ public class StrokeTool : Tool { 		ep1.type = prev.type; 		ep1.x = px; 		ep1.y = py;-		ep1.color = c;+		ep1.color = Color.yellow (); 		n.add (ep1);  		ep2.prev = ep1;@@ -805,7 +847,7 @@ public class StrokeTool : Tool { 		ep3.type = prev.type; 		ep3.x = px; 		ep3.y = py;-		ep3.color = c;+		ep3.color = Color.yellow (); 		n.add (ep3); 		 		next.get_left_handle ().convert_to_line ();			@@ -1189,6 +1231,7 @@ public class StrokeTool : Tool { 				r = get_all_parts (r);				 			} else { 				warning ("Not merged.");+				error = true; 			} 			 			if (error) {@@ -1742,6 +1785,9 @@ public class StrokeTool : Tool { 		bool intersection = false; 		int found = 0; 		+		path1.close (); // FIXME:+		path2.close ();+ 		path1.all_segments ((ep1, ep2) => { 			double ix, iy; 			EditPoint p1, p2;@@ -1761,6 +1807,10 @@ public class StrokeTool : Tool { 			return true; 		}); 		+		if (intersection && found != n) {+			warning (@"Wrong number of points, $found != $n");+		}+		 		return intersection; 	} @@ -1912,9 +1962,9 @@ public class StrokeTool : Tool { 			previous = start.copy (); 			previous_inside = start_inside.copy (); 			-			previous.flags |= EditPoint.CURVE;-			previous_inside.flags |= EditPoint.CURVE;-							+			previous.flags |= EditPoint.CURVE_KEEP;+			previous_inside.flags |= EditPoint.CURVE_KEEP;+			 			side1.add_point (previous); 			side2.add_point (previous_inside); 		}@@ -1937,7 +1987,19 @@ public class StrokeTool : Tool { 				continue; 			} 			-			step = 0;+			get_segment (thickness, 0, 0.00001, p1, p2, out start);+			get_segment (-thickness, 0, 0.00001, p1, p2, out start_inside);++			previous = start.copy ();+			previous_inside = start_inside.copy ();+			+			previous.flags |= EditPoint.CURVE;+			previous_inside.flags |= EditPoint.CURVE;++			side1.add_point (previous);+			side2.add_point (previous_inside);	+		+			step = step_size; 			keep = 0; 			step_size = 0.1; @@ -1965,7 +2027,7 @@ public class StrokeTool : Tool { 					continue; 				} 								-				if (flat && f_bigger && step_size < 0.25) {+				if (flat && f_bigger && step_size < 0.1) { 					step_size *= step_increment; 					continue; 				}@@ -2023,7 +2085,7 @@ public class StrokeTool : Tool {  			previous.flags |= EditPoint.CURVE; 			previous_inside.flags |= EditPoint.CURVE;-							+ 			side1.add_point (previous); 			side2.add_point (previous_inside); 				@@ -2081,9 +2143,6 @@ public class StrokeTool : Tool { 				previous.flags |= EditPoint.CURVE; 				previous_inside.flags |= EditPoint.CURVE; -				side1.add_point (s1);-				side2.add_point (s2);-								 				side1.add_point (previous); 				side2.add_point (previous_inside);		 			}@@ -2111,7 +2170,6 @@ public class StrokeTool : Tool { 	} 	 	static void convert_to_curve (Path path) {-		 		if (path.is_open ()) { 			path.get_first_point ().flags &= EditPoint.ALL ^ EditPoint.CURVE; 			path.get_last_point ().flags &= EditPoint.ALL ^ EditPoint.CURVE;

Contact

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