Clone in a terminal:
Commit 91b5a8a
Johan Mattsson - 2015-05-11T21:16:49+00:00
91b5a8a76dc451f80f44ed9e1020571c881361edjohan.mattsson.m@gmail.com

Round line cap

Changed files (12)

Diff

diff --git a/libbirdfont/BezierTool.vala b/libbirdfont/BezierTool.valaindex a55a654..830b83c 100644--- a/libbirdfont/BezierTool.vala+++ b/libbirdfont/BezierTool.vala@@ -311,7 +311,7 @@ public class BezierTool : Tool { 		if (state == MOVE_POINT && current_path.points.size > 0) { 			current_path.delete_last_point (); 			current_path.reset_stroke ();-			current_path.get_stroke (); // cache better stroke+			current_path.create_full_stroke (); // cache better stroke 		} 		 		state = NONE;diff --git a/libbirdfont/Color.vala b/libbirdfont/Color.valaindex f04f577..6bbca71 100644--- a/libbirdfont/Color.vala+++ b/libbirdfont/Color.vala@@ -47,9 +47,25 @@ public class Color { 		return new Color (222.0 / 255, 203.0 / 255, 43 / 255.0, 1); 	} +	public static Color brown () {+		return new Color (160.0 / 255, 90.0 / 255, 44.0 / 255, 1);+	}+	 	public static Color pink () { 		return new Color (247.0 / 255, 27.0 / 255, 113 / 255.0, 1); 	}+	+	public static Color white () {+		return new Color (1, 1, 1, 1);+	}+	+	public static Color grey () {+		return new Color (0.5, 0.5, 0.5, 1);+	}+	+	public static Color magenta () {+		return new Color (103.0 / 255, 33.0 / 255, 120.0 / 255, 1);+	} }  }diff --git a/libbirdfont/DrawingTools.vala b/libbirdfont/DrawingTools.valaindex 6903d0d..529bdad 100644--- a/libbirdfont/DrawingTools.vala+++ b/libbirdfont/DrawingTools.vala@@ -1,5 +1,5 @@ /*-    Copyright (C) 2012, 2013, 2014 Johan Mattsson+    Copyright (C) 2012 2013 2014 2015 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 @@ -850,7 +850,41 @@ public class DrawingTools : ToolCollection  { 			outline.set_selected (false); 		}); 		stroke_expander.add_tool (outline);	-				++		// set line cap+		Tool line_cap_round = new Tool ("line_cap_round", t_("Round line cap"));+		line_cap_round.select_action.connect ((self) => {+			Glyph g;+			+			g = MainWindow.get_current_glyph ();+			g.store_undo_state ();+			+			foreach (Path p in g.active_paths) {+				p.line_cap = LineCap.ROUND;+				p.reset_stroke ();+			}+			+			GlyphCanvas.redraw ();+		});+		stroke_expander.add_tool (line_cap_round);	++		Tool line_cap_square = new Tool ("line_cap_square", t_("Square line cap"));+		line_cap_square.select_action.connect ((self) => {+			Glyph g;+			+			g = MainWindow.get_current_glyph ();+			g.store_undo_state ();+			+			foreach (Path p in g.active_paths) {+				p.line_cap = LineCap.SQUARE;+				p.reset_stroke ();+			}+			+			GlyphCanvas.redraw ();+		});+		stroke_expander.add_tool (line_cap_square);	++		// tests 		if (BirdFont.has_argument ("--test")) { 			Tool test_case = new Tool ("test_case"); 			test_case.select_action.connect((self) => {diff --git a/libbirdfont/Glyph.vala b/libbirdfont/Glyph.valaindex 25a9d49..02161bb 100644--- a/libbirdfont/Glyph.vala+++ b/libbirdfont/Glyph.vala@@ -1238,7 +1238,7 @@ public class Glyph : FontDisplay { 				p.convert_path_ending_to_line (); 			} 			-			p.get_stroke (); // cache stroke+			p.create_full_stroke (); // cache stroke 		} 		 		open = false;diff --git a/libbirdfont/MoveTool.vala b/libbirdfont/MoveTool.valaindex 8fb0853..efefd2a 100644--- a/libbirdfont/MoveTool.vala+++ b/libbirdfont/MoveTool.vala@@ -156,7 +156,7 @@ public class MoveTool : Tool { 			DrawingTools.resize_tool.signal_objects_rotated (); 			 			foreach (Path p in glyph.active_paths) {-				p.get_stroke ();+				p.create_full_stroke (); 			} 		} else { 			objects_deselected ();diff --git a/libbirdfont/Path.vala b/libbirdfont/Path.valaindex 7f76655..ca472f0 100644--- a/libbirdfont/Path.vala+++ b/libbirdfont/Path.vala@@ -48,6 +48,7 @@ public class Path {  	/** Stroke width */ 	public double stroke = 0;+	public LineCap line_cap = LineCap.BUTT; 	PathList? full_stroke = null; 	PathList? fast_stroke = null; 	@@ -756,6 +757,7 @@ public class Path { 		new_path.edit = edit; 		new_path.open = open; 		new_path.stroke = stroke;+		new_path.line_cap = line_cap; 		new_path.skew = skew; 		new_path.fill = fill; 		new_path.direction_is_set = direction_is_set;@@ -2320,7 +2322,9 @@ public class Path { 	} 	 	public void create_full_stroke () {-		full_stroke = StrokeTool.get_stroke (this, stroke);+		if (stroke > 0) {+			full_stroke = StrokeTool.get_stroke (this, stroke);+		} 	} 	 	public PathList get_stroke () {diff --git a/libbirdfont/PenTool.vala b/libbirdfont/PenTool.valaindex 5364128..f9c6def 100644--- a/libbirdfont/PenTool.vala+++ b/libbirdfont/PenTool.vala@@ -188,7 +188,7 @@ public class PenTool : Tool { 					p.get_last_point ().set_reflective_handles (false); 				} 				-				p.get_stroke (); // cache good stroke+				p.create_full_stroke (); // cache good stroke 			} 		}); diff --git a/libbirdfont/ResizeTool.vala b/libbirdfont/ResizeTool.valaindex 8d5ff7d..d2ae5c8 100644--- a/libbirdfont/ResizeTool.vala+++ b/libbirdfont/ResizeTool.vala@@ -108,7 +108,7 @@ public class ResizeTool : Tool { 			GlyphCanvas.redraw (); 			 			foreach (Path p in MainWindow.get_current_glyph ().active_paths) {-				p.get_stroke ();+				p.create_full_stroke (); 			} 		}); 		diff --git a/libbirdfont/StrokeTool.vala b/libbirdfont/StrokeTool.valaindex 49980fb..7d097ab 100644--- a/libbirdfont/StrokeTool.vala+++ b/libbirdfont/StrokeTool.vala@@ -17,6 +17,12 @@ using Math;  namespace BirdFont { +public enum LineCap {+	BUTT,+	SQUARE,+	ROUND+}+ public class StrokeTool : Tool { 	 	public static double stroke_width = 0;@@ -283,26 +289,123 @@ public class StrokeTool : Tool { 		return false; 	} -	static void add_line_cap (Path path, Path stroke,-		EditPointHandle last_handle, -		EditPoint start, EditPoint end) {+	static void add_line_cap (Path path, Path stroke1, Path stroke2, bool last_cap) {+		if (path.line_cap == LineCap.SQUARE) {+			add_square_cap (path, stroke1, stroke2, last_cap);+		} else if (path.line_cap == LineCap.ROUND) {+			add_round_cap (path, stroke1, stroke2, last_cap);+		}+	}+	+	static void add_round_cap (Path path, Path stroke1, Path stroke2, bool last_cap) {+		double px, py;+		double step, start_angle, stop_angle;+		double radius;+		EditPoint n, nstart, nend;+		Path cap = new Path ();++		EditPoint start, end;+		EditPointHandle last_handle;+		EditPoint first, last; +		+		stroke1.remove_points_on_points ();+		stroke2.remove_points_on_points ();+		+		last_handle = path.get_first_point ().get_right_handle ();+		start = stroke1.get_last_point ();+		end = stroke2.get_first_point ();+		+		start_angle = last_handle.angle + PI / 2;+		stop_angle = start_angle + PI;	+					+		nstart = cap.add (start.x, start.y);+		radius = Path.distance_to_point (start, end) / 2;+		step = PI / 5;+		+		for (int j = 0; j < 5; j++) {+			double angle = start_angle + step * j;+			px = radius * cos (angle) + last_handle.parent.x;+			py = radius * sin (angle) + last_handle.parent.y;+			n = cap.add (px, py);+			+			n.type = PointType.LINE_CUBIC;+			n.get_right_handle ().type = PointType.LINE_CUBIC;+			n.get_left_handle ().type = PointType.LINE_CUBIC;+		}+		+		nend = cap.add (end.x, end.y);+				+		for (int i = 0; i < cap.points.size; i++) {+			cap.points.get (i).recalculate_linear_handles ();+		}+		+		int size = cap.points.size;++		for (int i = 1; i < size; i++) {+			n = cap.points.get (i);+			n.convert_to_curve ();+			n.set_tie_handle (true);+			n.process_tied_handle ();+		} -		EditPoint n;-		double stroke_width = path.stroke / 2;+		int f = stroke1.points.size - 1;+		+		for (int i = 2; i < cap.points.size - 1; i++) {+			n = cap.points.get (i).copy ();+			stroke1.add_point (n);+		}++		return_if_fail (0 < f < stroke1.points.size);+		+		first = stroke1.points.get (f);+		stroke1.add_point (stroke2.get_first_point ());+		+		last = stroke1.get_last_point ();+		+		double a;+		double l;+		+		return_if_fail (cap.points.size > 1); 		-		double y = sin (last_handle.angle - PI) * stroke_width;-		double x = cos (last_handle.angle - PI) * stroke_width;+		a = (first.get_left_handle ().angle + PI) % (2 * PI);+		l = cap.points.get (1).get_right_handle ().length; 		-		n = stroke.add (start.x + x, start.y + y);-		n.type = start.type;-		n.get_right_handle ().type = start.type;-		n.get_left_handle ().type = start.type;+		first.get_right_handle ().convert_to_curve ();+		first.get_right_handle ().angle = a;+		first.get_right_handle ().length = l;+		+		a = (first.get_left_handle ().angle + PI) % (2 * PI);+		+		last.get_left_handle ().convert_to_curve ();+		last.get_left_handle ().angle = a;+		last.get_left_handle ().length = l;+	}+		+	static void add_square_cap (Path path, Path stroke1, Path stroke2, bool last_cap) {+		EditPointHandle last_handle;+		EditPoint start;+		EditPoint end;+		EditPoint n;+		double x, y;+		double stroke_width = path.stroke / 2;++		last_handle = path.get_first_point ().get_right_handle ();+		start = stroke1.get_last_point ();+		end = stroke2.get_first_point ();++		y = sin (last_handle.angle - PI) * stroke_width;+		x = cos (last_handle.angle - PI) * stroke_width;+						+		n = stroke1.add (start.x + x, start.y + y);+		n.type = PointType.CUBIC;+		n.get_right_handle ().type = PointType.CUBIC;+		n.get_left_handle ().type = PointType.CUBIC; 		n.convert_to_line (); 		-		n = stroke.add (end.x + x, end.y + y);-		n.type = start.type;-		n.get_right_handle ().type = start.type;-		n.get_left_handle ().type = start.type;+		n = stroke1.add (end.x + x, end.y + y);+		n.type = PointType.CUBIC;+		n.get_right_handle ().type = PointType.CUBIC;+		n.get_left_handle ().type = PointType.CUBIC; 		n.convert_to_line (); 	} @@ -317,28 +420,26 @@ public class StrokeTool : Tool { 			 		Path merged; 		EditPoint last_counter, first;-		+ 		merged = stroke.copy ();-		counter.reverse ();-		-		counter.reverse (); 		merged.reverse (); 		 		last_counter = new EditPoint (); 		first = new EditPoint (); 		-		add_line_cap (path, merged, path.get_first_point ().get_right_handle (), -			merged.get_last_point (), counter.get_first_point ());+		add_line_cap (path, merged, counter, true);		+		path.reverse ();		+		+		add_line_cap (path, counter, merged, true);+		path.reverse (); 			 		merged.append_path (counter);-		-		add_line_cap (path, merged, path.get_last_point ().get_left_handle (), -			merged.get_last_point (), merged.get_first_point ());  		merged.close (); 		merged.create_list (); 		merged.recalculate_linear_handles ();-+/*+// BUTT CAP 		if (path.is_open ()) { 			first = merged.get_first_point (); 			last_counter = merged.get_last_point ();@@ -349,7 +450,7 @@ public class StrokeTool : Tool { 			last_counter.get_right_handle ().convert_to_line (); 			last_counter.recalculate_linear_handles (); 		}-+*/ 		return merged; 	} @@ -2094,17 +2195,17 @@ public class StrokeTool : Tool { 				previous_inside.flags |= EditPoint.CURVE;  				side1.add_point (previous);-				side2.add_point (previous_inside);		+				side2.add_point (previous_inside); 			} 		} 		 		if (!fast) { 			side1.remove_points_on_points (); 			side2.remove_points_on_points ();-				+		 			convert_to_curve (side1); 			convert_to_curve (side2);-		+			 			side2.reverse (); 			pl = merge_stroke_parts (path, side1, side2); 		}diff --git a/libbirdfont/SvgArc.vala b/libbirdfont/SvgArc.valaindex c56667d..da62431 100644--- a/libbirdfont/SvgArc.vala+++ b/libbirdfont/SvgArc.vala@@ -159,6 +159,8 @@ static void add_arc_points (BezierPoints[] bezier_points, ref int bi, double x0, 	for (double a = 0; a < fabs (angleExtent); a += step) { 		theta = PI - angleStart - angleExtent + s * a; +		return_if_fail (0 <= bi < bezier_points.length);+ 		bezier_points[bi].type = 'S'; 		bezier_points[bi].svg_type = 'a'; diff --git a/libbirdfont/SvgParser.vala b/libbirdfont/SvgParser.valaindex 25f348d..4fb6eb7 100644--- a/libbirdfont/SvgParser.vala+++ b/libbirdfont/SvgParser.vala@@ -1195,16 +1195,8 @@ public class SvgParser { 			return path_list;	 		} 		-		/* //FIXME: DELETE-		if (bezier_points[bi - 1].type != 'z') {-			bezier_points[bi].type = 'z';-			bezier_points[bi].svg_type = 'z';-			bi++;-		}-		*/-		 		move_and_resize (bezier_points, bi, svg_glyph, units, glyph);-+		 		if (format == SvgFormat.ILLUSTRATOR) { 			path_list = create_paths_illustrator (bezier_points, bi); 		} else {@@ -1578,7 +1570,6 @@ public class SvgParser { 		} 				 		if (path.points.size > 0) {-			warning ("Open path."); 			path_list.add (path); 		} 		diff --git a/libbirdfont/TrackTool.vala b/libbirdfont/TrackTool.valaindex a8105c9..7509f49 100644--- a/libbirdfont/TrackTool.vala+++ b/libbirdfont/TrackTool.vala@@ -122,7 +122,7 @@ public class TrackTool : Tool { 				drawing = true; 				 				foreach (Path path in glyph.active_paths) {-					path.get_stroke (); // cache merged stroke parts+					path.create_full_stroke (); // cache merged stroke parts 				} 			} 		});

Contact

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