Clone in a terminal:
Commit b09d1af
Johan Mattsson - 2012-08-04T12:38:59+00:00
b09d1af003ae361938de4bfd52ecef1fb9683596johan.mattsson.m@gmail.com

fix path is clockwise

Changed files (5)

Diff

diff --git a/src/EditPoint.vala b/src/EditPoint.valaindex 2fc3d30..e6e9776 100644--- a/src/EditPoint.vala+++ b/src/EditPoint.vala@@ -32,6 +32,7 @@ enum PointType { }  class EditPoint {+	 	public double x; 	public double y; 	public PointType type;@@ -161,10 +162,67 @@ class EditPoint { 		tie_handles = t; 	} +	public void process_tied_handle () {+		double a, b, c, length, angle;+		EditPointHandle eh;+		+		eh = right_handle;+		+		a = left_handle.x () - right_handle.x ();+		b = left_handle.y () - right_handle.y ();+		c = a * a + b * b;+		+		if (c == 0) {+			return;+		}+		+		length = sqrt (fabs (c));+		+		if (right_handle.y () < left_handle.y ()) {+			angle = acos (a / length) + PI;+		} else {+			angle = -acos (a / length) + PI;+		}+		+		left_handle.type = PointType.CURVE;+		right_handle.type = PointType.CURVE;+		+		right_handle.angle = angle;+		left_handle.angle = angle;++		set_tie_handle (true);+		eh.move_to_coordinate (right_handle.x (), right_handle.y ());+	}+ 	public void set_point_type (PointType point_type) { 		type = point_type; 	} +	public double get_average_angle () {+		double a, b, c, length, angle;++		recalculate_linear_handles ();+		+		a = left_handle.x () - right_handle.x ();+		b = left_handle.y () - right_handle.y ();+		c = a * a + b * b;+		+		if (c == 0) {+			warning ("Can't calculate average length");+			return 0;+		}+		+		length = sqrt (fabs (c));+		+		if (right_handle.y () < left_handle.y ()) {+			angle = acos (a / length) + PI;		+		} else {+			angle = -acos (a / length) + PI;+		}	+		+		return angle;+	}+ 	public EditPoint copy () { 		EditPoint new_point = new EditPoint (); 		diff --git a/src/Glyph.vala b/src/Glyph.valaindex 8d07ee9..98956bb 100644--- a/src/Glyph.vala+++ b/src/Glyph.vala@@ -769,7 +769,8 @@ class Glyph : FontDisplay { 		}  		if (unlikely (min_distance == double.MAX)) {-			warning (@"No path found in path_list. Length: $(path_list.length ())");+			// put back important warning:+			// warning (@"No path found in path_list. Length: $(path_list.length ())"); 			 			if (path_list.length () > 0) { 				stderr.printf (@"p.points.length () $(path_list.first ().data.points.length ()) \n");diff --git a/src/Path.vala b/src/Path.valaindex 2635457..d4e11a2 100644--- a/src/Path.vala+++ b/src/Path.vala@@ -604,31 +604,77 @@ class Path { 		} 	} 	-	private bool is_clockwise_top () {-		EditPoint top_point = new EditPoint (1000, 1000);+	private bool validate_list () {+		unowned List<EditPoint> ep = points.first (); 		-		return_if_fail (points.length () >= 3);-		-		create_list ();+		if (points.length () < 3) {+			warning ("points.length () < 3");+		} 		-		foreach (EditPoint ep in points) {-			if (ep.y < top_point.y) {-				top_point = ep;+		if (!is_open ()) {+			for (int i = 0; i < points.length (); i++) {+				if (ep.data.next == null) {+					return false;+				}++				if (ep.data.prev == null) {+					return false;+				}+								+				ep = (!) ep.data.next;+			}+		}++		if (is_open ()) {+			for (int i = 1; i < points.length () - 1; i++) {+				if (ep.data.next == null) {+					return false;+				}++				if (ep.data.prev == null) {+					return false;+				}+								+				ep = (!) ep.data.next;+			}+			+			if (ep.data.next != null) {+				return false; 			} 		} 		-		return_if_fail (top_point.next != null && top_point.prev != null);+		return true;+	}+	+	private double clockwise_sum () {+		return_if_fail (points.length () >= 3);+		+		double sum = 0;+		EditPoint prev = points.last ().data;+		foreach (EditPoint e in points) {+			sum += (e.x - prev.x) * (e.y + prev.y);+			prev = e;+		} 		-		return (top_point.get_prev ().data.x < top_point.get_next ().data.x);+		return sum; 	} 	 	public bool is_clockwise () {+		double s;+		 		if (unlikely (points.length () <= 2)) { 			no_derived_direction = true; 			return clockwise_direction; 		} 		-		return is_clockwise_top ();+		s = clockwise_sum ();+		+		if (s == 0) {+			no_derived_direction = true;+			return clockwise_direction;	+		}+		+		return s > 0; 	} 	 	public bool is_editable () {@@ -853,14 +899,6 @@ class Path { 		return np; 		 	}-	-	/*// FIXA: DELETE-	public void add_point_on_path (double x, double y) {-		EditPoint e = new EditPoint (0, 0);-		get_closest_point_on_path (e, x, y);-		add_after (x, y, e.prev);-	}-	*/  	public void close () { 		open = false;@@ -1228,7 +1266,8 @@ class Path { 	} 	 	public void create_list () {-		unowned List<EditPoint> ep = points;+		unowned List<EditPoint> ep = points.first ();+		unowned List<EditPoint> prev = ep; 		 		if (points.length () == 0) { 			return;@@ -1241,21 +1280,32 @@ class Path { 		} 		 		ep.data.next = ep.next;-		ep.data.prev = ep.last ();+		ep.data.prev = points.last ();+		prev = ep;+		+		assert (ep.data.next != null);+		assert (ep.data.prev != null); 		 		while (ep != ep.last ()) { 			ep.data.next = ep.next;-			ep.data.prev = ep.prev;+			ep.data.prev = prev;+			prev = ep;+			+			assert (ep.data.next != null);+			assert (ep.data.prev != null);+		 			ep = ep.next; 		} 		 		if (is_open ()) {-			ep.data.next = null;+			ep.data.next = points.first (); 		} else {-			ep.data.next = ep.first ();+			ep.data.next = points.first ();+			assert (ep.data.next != null); 		} 		-		ep.data.prev = ep.prev;+		ep.data.prev = prev;+		assert (ep.data.prev != null); 	}  	public void delete_edit_point (EditPoint ep) diff --git a/src/PenTool.vala b/src/PenTool.valaindex 4dd2b89..c32a99b 100644--- a/src/PenTool.vala+++ b/src/PenTool.vala@@ -840,8 +840,7 @@ class PenTool : Tool { 		test_open_next_glyph (); 		pen = select_pen (); -		int skip = 0;-		for (int i = 0; i < 10; i++) {+		for (int i = 0; i < 30; i++) { 			this.yield (); 			 			ax = Random.int_range (0, 300);@@ -869,10 +868,7 @@ class PenTool : Tool { 				return false; 			} 			-			if (++skip == 5) {-				test_open_next_glyph ();-				skip = 0;-			}+			test_open_next_glyph (); 		} 		 		if (r) test_open_next_glyph ();diff --git a/src/Toolbox.vala b/src/Toolbox.valaindex 9b2a0d1..8bcd432 100644--- a/src/Toolbox.vala+++ b/src/Toolbox.vala@@ -152,8 +152,6 @@ class Toolbox : DrawingArea { 		Tool tie_editpoint_tool = new Tool ("tie_point", "Tie curve handles for selected edit point", 'w'); 		tie_editpoint_tool.select_action.connect((self) => { 				EditPoint ep;-				EditPointHandle eh;-				double a, b, c, length, angle; 				bool tie; 				 				select_draw_tool ();@@ -161,33 +159,8 @@ class Toolbox : DrawingArea { 				ep = pen_tool.selected_corner; 				tie = !ep.tie_handles; -				eh = ep.right_handle;-				 				if (tie) {-					a = ep.left_handle.x () - ep.right_handle.x ();-					b = ep.left_handle.y () - ep.right_handle.y ();-					c = a * a + b * b;-					-					if (c == 0) {-						return;-					}-					-					length = sqrt (fabs (c));-					-					if (ep.right_handle.y () < ep.left_handle.y ()) {-						angle = acos (a / length) + PI;-					} else {-						angle = -acos (a / length) + PI;-					}-					-					ep.left_handle.type = PointType.CURVE;-					ep.right_handle.type = PointType.CURVE;-					-					ep.right_handle.angle = angle;-					ep.left_handle.angle = angle;--					ep.set_tie_handle (true);-					eh.move_to_coordinate (ep.right_handle.x (), ep.right_handle.y ());+					ep.process_tied_handle (); 				} 				 				ep.set_tie_handle (tie);

Contact

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