Clone in a terminal:
Commit f111418
Johan Mattsson - 2015-05-05T19:46:52+00:00
f111418d36925a9fe42b5c8d8e4b43faee3f67bajohan.mattsson.m@gmail.com

Simplify stroke

Changed files (7)

Diff

diff --git a/libbirdfont/EditPoint.vala b/libbirdfont/EditPoint.valaindex 21c5b02..ac9056a 100644--- a/libbirdfont/EditPoint.vala+++ b/libbirdfont/EditPoint.vala@@ -53,6 +53,7 @@ public class EditPoint : GLib.Object { 	public static uint REMOVE_PART = 1 << 10; 	public static uint OVERLAY = 1 << 11; 	public static uint CURVE = 1 << 12;+	public static uint CURVE_KEEP = 1 << 13; 	public static uint ALL = 0xFFFFFF; 	 	public uint flags = NONE;diff --git a/libbirdfont/Glyph.vala b/libbirdfont/Glyph.valaindex 33e248c..72762ce 100644--- a/libbirdfont/Glyph.vala+++ b/libbirdfont/Glyph.vala@@ -145,7 +145,7 @@ public class Glyph : FontDisplay { 		pl = new PathList (); 		foreach (Path p in path_list) { 			if (p.stroke > 0) {-				stroke = p.get_stroke_fast ();+				stroke = p.get_stroke (); 				foreach (Path stroke_part in stroke.paths) { 					pc = new PointConverter (stroke_part); 					pl.add (pc.get_quadratic_path ());diff --git a/libbirdfont/Path.vala b/libbirdfont/Path.valaindex 9aa1e63..7cdd87f 100644--- a/libbirdfont/Path.vala+++ b/libbirdfont/Path.vala@@ -1455,7 +1455,6 @@ public class Path { 		PointType left =  PenTool.to_curve (stop.type); 		 		if (right == PointType.DOUBLE_CURVE || left == PointType.DOUBLE_CURVE) {-			warning ("FIX the double curve in stroke."); 			x = double_bezier_path (step, start.x, start.get_right_handle ().x, stop.get_left_handle ().x, stop.x); 			y = double_bezier_path (step, start.y, start.get_right_handle ().y, stop.get_left_handle ().y, stop.y); 		} else if (right == PointType.QUADRATIC && left == PointType.QUADRATIC) {diff --git a/libbirdfont/PenTool.vala b/libbirdfont/PenTool.valaindex 83a0d2c..af8d73a 100644--- a/libbirdfont/PenTool.vala+++ b/libbirdfont/PenTool.vala@@ -423,9 +423,21 @@ public class PenTool : Tool { 		active_edit_point = null; 		selected_point = new EditPoint (); 	}-	+ 	/** @return path distortion. */ 	public static double remove_point_simplify (PointSelection p, double tolerance = 0.6) {+		double e;++		e = remove_point_simplify_path (p, tolerance, Glyph.CANVAS_MAX);+		p.path.update_region_boundaries ();+		+		return e;+	}	+	+	/** @return path distortion. */+	public static double remove_point_simplify_path (PointSelection p,+		double tolerance = 0.6, double keep_tolerance = 10000) {+			 		double start_length, stop_length; 		double start_distortion, start_min_distortion, start_previous_length; 		double stop_distortion, stop_min_distortion, stop_previous_length;@@ -508,7 +520,7 @@ public class PenTool : Tool { 							 					ep1.get_right_handle ().length = start_length + a; 					ep2.get_left_handle ().length = stop_length + b;-					+ 					get_path_distortion (prev, p.point, next,  						ep1, ep2,  						out start_distortion, out stop_distortion);@@ -519,33 +531,34 @@ public class PenTool : Tool { 							&& start_length + a > 0 							&& stop_length + b > 0) { 						min_distortion = distortion;-						 						prev_length_adjustment_reverse = a; 						next_length_adjustment = b; 					} 				} 			}-						+				 			start_length += prev_length_adjustment_reverse; 			stop_length += next_length_adjustment; 		} 		-		prev.get_right_handle ().length = start_length;-		-		if (prev.get_right_handle ().type != PointType.QUADRATIC) {-			next.get_left_handle ().length = stop_length;-		} else {-			next.get_left_handle ().move_to_coordinate (-				prev.get_right_handle ().x, prev.get_right_handle ().y);-		} 		-		p.point.deleted = true;-		p.path.remove_deleted_points ();-		p.path.update_region_boundaries ();+		if (min_distortion < keep_tolerance || keep_tolerance >= Glyph.CANVAS_MAX) {+			prev.get_right_handle ().length = start_length;+			+			if (prev.get_right_handle ().type != PointType.QUADRATIC) {+				next.get_left_handle ().length = stop_length;+			} else {+				next.get_left_handle ().move_to_coordinate (+					prev.get_right_handle ().x, prev.get_right_handle ().y);+			} 		+			p.point.deleted = true;+			p.path.remove_deleted_points ();+		}+ 		return min_distortion; 	}-	+ 	/** Retain selected points even if path is copied after running reverse. */ 	public static void update_selection () { 		Glyph g = MainWindow.get_current_glyph ();@@ -2208,7 +2221,7 @@ public class PenTool : Tool { 		} else { 			first.get_right_handle ().type = to_line (point_type); 		}-+		 		if (!line) { 			next.get_left_handle ().type = point_type; 		} else {diff --git a/libbirdfont/PointConverter.vala b/libbirdfont/PointConverter.valaindex 858160e..278c266 100644--- a/libbirdfont/PointConverter.vala+++ b/libbirdfont/PointConverter.vala@@ -69,9 +69,6 @@ public class PointConverter { 		int points_in_segment = 0; 		int size; -		if (quadratic_path.points.size <= 1) {-		}- 		foreach (EditPoint ep in quadratic_path.points) { 			ep.set_tie_handle (false); 			ep.set_reflective_handles (false);diff --git a/libbirdfont/StrokeTool.vala b/libbirdfont/StrokeTool.valaindex a8ebe46..7133010 100644--- a/libbirdfont/StrokeTool.vala+++ b/libbirdfont/StrokeTool.vala@@ -32,6 +32,8 @@ public class StrokeTool : Tool { 	public static void stroke_selected_paths () { 		Glyph g = MainWindow.get_current_glyph (); 		PathList paths = new PathList ();+		+		// FIXME: use background thread  		stroke_selected = true; // FIXME: delete 			@@ -92,10 +94,6 @@ public class StrokeTool : Tool { 		stroke = path.copy (); 		stroke.remove_points_on_points (0.3); 		o = create_stroke (stroke, thickness);--		// FIXME: remove-		//o = get_all_parts (o);-		//o = merge (o); 				 		return o; 	}@@ -107,9 +105,38 @@ public class StrokeTool : Tool { 		o = get_all_parts (o); // FIXME: keep. 		o = merge (o); 		+		foreach (Path p in o.paths) {+			simplify_stroke (p);+		}+		 		return o; 	} 	+	static void simplify_stroke (Path p) {+		Gee.ArrayList<PointSelection> points = new Gee.ArrayList<PointSelection> ();+		double error;+		+		p.remove_points_on_points (0.1);+		+		foreach (EditPoint ep in p.points) {+			if ((ep.flags & EditPoint.CURVE) > 0) {+				points.add (new PointSelection (ep, p));+			}+		}+		+		foreach (PointSelection ps in points) {+			error = PenTool.remove_point_simplify_path (ps, 1, 2);+			+			if (error > 0.2) {+				ps.point.deleted = false;+				ps.point.flags ^= EditPoint.CURVE;+				ps.point.flags |= EditPoint.CURVE_KEEP;+			}+		}+		+		p.update_region_boundaries ();+	}+	 	/** Create one stroke from the outline and counter stroke and close the  	 * open endings. 	 * @@ -1663,7 +1690,12 @@ public class StrokeTool : Tool { 		EditPointHandle l, r;  		Path path = original_path.copy ();+		+		int keep;+		bool on_curve; +		// FIXME: DELETE+/* 		if (path.points.size > 1) { 			path.add_hidden_double_points (); // FIXME: 		}@@ -1673,7 +1705,7 @@ public class StrokeTool : Tool { 				PenTool.convert_point_type (ep, PointType.QUADRATIC); 			} 		}-+*/ 		pl = new PathList (); 		size = path.is_open () ? path.points.size - 1 : path.points.size; 		@@ -1711,8 +1743,7 @@ public class StrokeTool : Tool { 			p2 = path.points.get ((i + 1) % path.points.size); 			p3 = path.points.get ((i + 2) % path.points.size); -			//tolerance = 0.13 / sqrt (stroke_width);-			tolerance = 1.6 / sqrt (stroke_width);+			tolerance = 0.13 / sqrt (stroke_width); 			step_increment = 1.05; 			step_size = 0.039 / stroke_width; @@ -1724,6 +1755,7 @@ public class StrokeTool : Tool { 			} 			 			step = 0;+			keep = 0; 			while (step < 1 - 2 * step_size) { 				Path.get_point_for_step (p1, p2, step, out x, out y); 				Path.get_point_for_step (p1, p2, step + step_size, out x2, out y2);@@ -1761,22 +1793,30 @@ public class StrokeTool : Tool { 				previous_inside.get_right_handle ().length *= step_size; 				corner1_inside.get_left_handle ().length *= step_size; -				adjust_right_handle (x, y, x2, y2, previous, corner1);-				adjust_right_handle (x, y, x2, y2, previous_inside, corner1_inside);-				 				previous = corner1.copy (); 				previous_inside = corner1_inside.copy (); 				-				previous.flags |= EditPoint.CURVE;-				previous_inside.flags |= EditPoint.CURVE;-												+				if (keep == 0 && step > 0.3) { // keep two points per segment+					on_curve = true;+					keep++;+				} else if (keep == 1 && step > 0.6) {+					on_curve = true;+					keep++;+				} else {+					on_curve = false;+				}+				+				if (!on_curve) {+					previous.flags |= EditPoint.CURVE;+					previous_inside.flags |= EditPoint.CURVE;+				} else {+					previous.flags |= EditPoint.CURVE_KEEP;+					previous_inside.flags |= EditPoint.CURVE_KEEP;+				}+				 				side1.add_point (previous); 				side2.add_point (previous_inside); 				-				// FIXME: DELETE-				//adjust_left_handle (x2, y2, x3, y3, previous);-				//adjust_left_handle (x2, y2, x3, y3, previous_inside);-				 				step += step_size; 			} @@ -1813,13 +1853,12 @@ public class StrokeTool : Tool { 					get_segment (-thickness, 0, 0.00001, p2, p3, out start); 					add_corner (side2, previous_inside, start, p2.copy (), thickness); 				}-			} else {-				// FIXME: DELETE-				//previous.flags |= EditPoint.CURVE;-				//previous_inside.flags |= EditPoint.CURVE; 			} 		} 		+		side1.remove_points_on_points ();+		side2.remove_points_on_points ();+		 		convert_to_curve (side1); 		convert_to_curve (side2); 		@@ -1841,59 +1880,23 @@ public class StrokeTool : Tool { 		path.remove_points_on_points ();  		foreach (EditPoint ep in path.points) {-			if ((ep.flags & EditPoint.CURVE) > 0) {+			if ((ep.flags & EditPoint.CURVE) > 0 || (ep.flags & EditPoint.CURVE_KEEP) > 0) { 				ep.convert_to_curve ();  			} 		} 			 		foreach (EditPoint ep in path.points) {-			if ((ep.flags & EditPoint.CURVE) > 0) {+			if ((ep.flags & EditPoint.CURVE) > 0 || (ep.flags & EditPoint.CURVE_KEEP) > 0) { 				ep.set_tie_handle (true); 			} 		} 			 		foreach (EditPoint ep in path.points) {-			if ((ep.flags & EditPoint.CURVE) > 0) {+			if ((ep.flags & EditPoint.CURVE) > 0 || (ep.flags & EditPoint.CURVE_KEEP) > 0) { 				ep.process_tied_handle (); 			} 		}			 	}-	-	public static void adjust_left_handle (double x0, double y0, double x1, double y1, EditPoint ep) {-		return_if_fail (ep.prev != null);-	-		double dp = Path.distance_to_point (ep.get_prev (), ep);-		double op = Path.distance (x0, x1, y0, y1);-		double rp = dp / op;-		EditPointHandle l = ep.get_left_handle ();-		-		if (l.type == PointType.CUBIC  && dp > 0 && op > 0) {-			//l.length *= rp * rp;  -		} -	}-	-	public static void adjust_right_handle (double x0, double y0, double x1, double y1,-		EditPoint ep, EditPoint next) {-				-		double dp = Path.distance_to_point (ep, next);-		double op = Path.distance (x0, x1, y0, y1);-		double rp = dp / op;-		EditPointHandle r = ep.get_right_handle ();-		-		if (r.type == PointType.CUBIC && dp > 0 && op > 0) {-			//r.length *= rp * rp; -		} -		-		// FIXME: DELETE-		/*-		ep.convert_to_line ();-		ep.recalculate_linear_handles ();-		ep.convert_to_curve ();-		ep.set_tie_handle (true);-		ep.process_tied_handle ();-		ep.set_tie_handle (false);-		*/-	} 		 	public static void get_segment (double stroke_thickness, double step, double step_size, 		EditPoint p1, EditPoint p2, out EditPoint ep1) {@@ -1916,7 +1919,6 @@ public class StrokeTool : Tool { 		corner2 = new EditPoint (x2, y2, type); 		corner3 = new EditPoint (x3, y3, type); 		-		//corner2.convert_to_curve (); 		corner2.convert_to_line (); // FIXME: delete 		 		overlay.add_point (corner1);@@ -1926,15 +1928,6 @@ public class StrokeTool : Tool { 		overlay.close (); 		overlay.recalculate_linear_handles (); 		-		// FIXME: DELETE-		/*-		Path.get_handles_for_step (p1, p2, step + step_size, -			out handle1_x, out handle1_y, out handle2_x, out handle2_y);-		-		corner2.get_left_handle ().move_to_coordinate (handle1_x, handle1_y);-		corner2.get_right_handle ().move_to_coordinate (handle2_x, handle2_y);-		*/-		 		move_segment (corner1, corner2, thickness);  		ep1 = corner2;diff --git a/resources/icons.bf b/resources/icons.bfindex 3f43855..dfa568f 100644--- a/resources/icons.bf+++ b/resources/icons.bf@@ -1063,92 +1063,91 @@ GNU Lesser General Public License</copyright> <ligature sequence="i n s e r t _ g l y p h _ f r o m _ o v e r v i e w" replacement="insert_glyph_from_overview"/> <ligature sequence="h i g h _ c o n t r a s t _ b a c k g r o u n d" replacement="high_contrast_background"/> <ligature sequence="p r e v i o u s _ k e r n i n g _ s t r i n g" replacement="previous_kerning_string"/>-<ligature sequence="s h o w _ x h e i g h t _ h e l p l i n e s" replacement="show_xheight_helplines"/> <ligature sequence="g e n e r a t e _ h t m l _ d o c u m e n t" replacement="generate_html_document"/>-<ligature sequence="s h o w _ a l l _ l i n e _ h a n d l e s" replacement="show_all_line_handles"/>-<ligature sequence="b a c k g r o u n d _ h e l p _ l i n e s" replacement="background_help_lines"/>-<ligature sequence="a u t o _ t r a c e _ r e s o l u t i o n" replacement="auto_trace_resolution"/>-<ligature sequence="z o o m _ b a c k g r o u n d _ i m a g e" replacement="zoom_background_image"/>+<ligature sequence="s h o w _ x h e i g h t _ h e l p l i n e s" replacement="show_xheight_helplines"/> <ligature sequence="o r i e n t a t i o n _ c l o c k w i s e" replacement="orientation_clockwise"/>-<ligature sequence="a u t o _ t r a c e _ s i m p l i f y" replacement="auto_trace_simplify"/>+<ligature sequence="z o o m _ b a c k g r o u n d _ i m a g e" replacement="zoom_background_image"/>+<ligature sequence="a u t o _ t r a c e _ r e s o l u t i o n" replacement="auto_trace_resolution"/>+<ligature sequence="b a c k g r o u n d _ h e l p _ l i n e s" replacement="background_help_lines"/>+<ligature sequence="s h o w _ a l l _ l i n e _ h a n d l e s" replacement="show_all_line_handles"/> <ligature sequence="n e x t _ k e r n i n g _ s t r i n g" replacement="next_kerning_string"/>-<ligature sequence="k e r n i n g _ t e x t _ i n p u t" replacement="kerning_text_input"/>+<ligature sequence="a u t o _ t r a c e _ s i m p l i f y" replacement="auto_trace_simplify"/> <ligature sequence="c o n t r a s t _ t h r e s h o l d" replacement="contrast_threshold"/>-<ligature sequence="o r i e n t a t i o n _ a r r o w" replacement="orientation_arrow"/>-<ligature sequence="d e l e t e _ b a c k g r o u n d" replacement="delete_background"/>-<ligature sequence="n e w _ p o i n t _ o n _ p a t h" replacement="new_point_on_path"/>-<ligature sequence="i n s e r t _ b a c k g r o u n d" replacement="insert_background"/>-<ligature sequence="s e l e c t _ b a c k g r o u n d" replacement="select_background"/>+<ligature sequence="k e r n i n g _ t e x t _ i n p u t" replacement="kerning_text_input"/> <ligature sequence="s t r o k e _ t o _ o u t l i n e" replacement="stroke_to_outline"/>-<ligature sequence="s c a l e _ b a c k g r o u n d" replacement="scale_background"/>-<ligature sequence="q u a d r a t i c _ p o i n t s" replacement="quadratic_points"/>+<ligature sequence="s e l e c t _ b a c k g r o u n d" replacement="select_background"/>+<ligature sequence="i n s e r t _ b a c k g r o u n d" replacement="insert_background"/>+<ligature sequence="n e w _ p o i n t _ o n _ p a t h" replacement="new_point_on_path"/>+<ligature sequence="d e l e t e _ b a c k g r o u n d" replacement="delete_background"/>+<ligature sequence="o r i e n t a t i o n _ a r r o w" replacement="orientation_arrow"/> <ligature sequence="o r i e n t a t i o n _ b o t h" replacement="orientation_both"/>-<ligature sequence="m o v e _ b a c k g r o u n d" replacement="move_background"/>-<ligature sequence="f l i p _ h o r i z o n t a l" replacement="flip_horizontal"/>-<ligature sequence="s h o w _ b a c k g r o u n d" replacement="show_background"/>+<ligature sequence="q u a d r a t i c _ p o i n t s" replacement="quadratic_points"/>+<ligature sequence="s c a l e _ b a c k g r o u n d" replacement="scale_background"/> <ligature sequence="z o o m _ b o u n d a r i e s" replacement="zoom_boundaries"/>-<ligature sequence="i n s e r t _ u n i c h a r" replacement="insert_unichar"/>-<ligature sequence="c u t _ b a c k g r o u n d" replacement="cut_background"/>-<ligature sequence="u p d a t e _ w e b v i e w" replacement="update_webview"/>+<ligature sequence="s h o w _ b a c k g r o u n d" replacement="show_background"/>+<ligature sequence="f l i p _ h o r i z o n t a l" replacement="flip_horizontal"/>+<ligature sequence="m o v e _ b a c k g r o u n d" replacement="move_background"/> <ligature sequence="f i l l _ o p e n _ p a t h" replacement="fill_open_path"/>-<ligature sequence="r e s i z e _ h a n d l e" replacement="resize_handle"/>-<ligature sequence="d r o p d o w n _ m e n u" replacement="dropdown_menu"/>-<ligature sequence="f l i p _ v e r t i c a l" replacement="flip_vertical"/>-<ligature sequence="d e l e t e _ b u t t o n" replacement="delete_button"/>-<ligature sequence="c o n v e r t _ p o i n t" replacement="convert_point"/>-<ligature sequence="d o u b l e _ p o i n t s" replacement="double_points"/>-<ligature sequence="k e r n i n g _ c l a s s" replacement="kerning_class"/>+<ligature sequence="u p d a t e _ w e b v i e w" replacement="update_webview"/>+<ligature sequence="c u t _ b a c k g r o u n d" replacement="cut_background"/>+<ligature sequence="i n s e r t _ u n i c h a r" replacement="insert_unichar"/> <ligature sequence="a d d _ n e w _ t h e m e" replacement="add_new_theme"/>-<ligature sequence="y _ c o o r d i n a t e" replacement="y_coordinate"/>-<ligature sequence="x _ c o o r d i n a t e" replacement="x_coordinate"/>-<ligature sequence="c u b i c _ p o i n t s" replacement="cubic_points"/>-<ligature sequence="r e v e r s e _ p a t h" replacement="reverse_path"/>-<ligature sequence="e x p o r t _ f o n t s" replacement="export_fonts"/>+<ligature sequence="k e r n i n g _ c l a s s" replacement="kerning_class"/>+<ligature sequence="d o u b l e _ p o i n t s" replacement="double_points"/>+<ligature sequence="c o n v e r t _ p o i n t" replacement="convert_point"/>+<ligature sequence="d e l e t e _ b u t t o n" replacement="delete_button"/>+<ligature sequence="f l i p _ v e r t i c a l" replacement="flip_vertical"/>+<ligature sequence="d r o p d o w n _ m e n u" replacement="dropdown_menu"/>+<ligature sequence="r e s i z e _ h a n d l e" replacement="resize_handle"/> <ligature sequence="a p p l y _ s t r o k e" replacement="apply_stroke"/>-<ligature sequence="b e z i e r _ t o o l" replacement="bezier_tool"/>-<ligature sequence="r i g h t _ a r r o w" replacement="right_arrow"/>-<ligature sequence="b e z i e r _ l i n e" replacement="bezier_line"/>-<ligature sequence="c r e a t e _ l i n e" replacement="create_line"/>-<ligature sequence="s p i n _ b u t t o n" replacement="spin_button"/>+<ligature sequence="e x p o r t _ f o n t s" replacement="export_fonts"/>+<ligature sequence="r e v e r s e _ p a t h" replacement="reverse_path"/>+<ligature sequence="c u b i c _ p o i n t s" replacement="cubic_points"/>+<ligature sequence="x _ c o o r d i n a t e" replacement="x_coordinate"/>+<ligature sequence="y _ c o o r d i n a t e" replacement="y_coordinate"/> <ligature sequence="m o v e _ c a n v a s" replacement="move_canvas"/>-<ligature sequence="c l o s e _ p a t h" replacement="close_path"/>-<ligature sequence="l e f t _ a r r o w" replacement="left_arrow"/>-<ligature sequence="h e l p _ l i n e s" replacement="help_lines"/>-<ligature sequence="m o v e _ l a y e r" replacement="move_layer"/>-<ligature sequence="s e l e c t _ a l l" replacement="select_all"/>-<ligature sequence="p o i n t _ t o o l" replacement="point_tool"/>+<ligature sequence="s p i n _ b u t t o n" replacement="spin_button"/>+<ligature sequence="c r e a t e _ l i n e" replacement="create_line"/>+<ligature sequence="b e z i e r _ l i n e" replacement="bezier_line"/>+<ligature sequence="r i g h t _ a r r o w" replacement="right_arrow"/>+<ligature sequence="b e z i e r _ t o o l" replacement="bezier_tool"/> <ligature sequence="f u l l _ g l y p h" replacement="full_glyph"/>-<ligature sequence="s a v e _ f o n t" replacement="save_font"/>-<ligature sequence="i n f o _ i c o n" replacement="info_icon"/>-<ligature sequence="s h o w _ g r i d" replacement="show_grid"/>-<ligature sequence="a u t o t r a c e" replacement="autotrace"/>-<ligature sequence="u n d o _ t o o l" replacement="undo_tool"/>-<ligature sequence="t i e _ p o i n t" replacement="tie_point"/>-<ligature sequence="s y m m e t r i c" replacement="symmetric"/>-<ligature sequence="f o r e s i g h t" replacement="foresight"/>-<ligature sequence="z o o m _ t o o l" replacement="zoom_tool"/>-<ligature sequence="r e c t a n g l e" replacement="rectangle"/>-<ligature sequence="t t f _ u n i t s" replacement="ttf_units"/>-<ligature sequence="m e n u _ i c o n" replacement="menu_icon"/>+<ligature sequence="p o i n t _ t o o l" replacement="point_tool"/>+<ligature sequence="s e l e c t _ a l l" replacement="select_all"/>+<ligature sequence="m o v e _ l a y e r" replacement="move_layer"/>+<ligature sequence="h e l p _ l i n e s" replacement="help_lines"/>+<ligature sequence="l e f t _ a r r o w" replacement="left_arrow"/>+<ligature sequence="c l o s e _ p a t h" replacement="close_path"/> <ligature sequence="o p e n _ f o n t" replacement="open_font"/>-<ligature sequence="s e t t i n g s" replacement="settings"/>-<ligature sequence="z o o m _ o u t" replacement="zoom_out"/>-<ligature sequence="r o t a t i o n" replacement="rotation"/>-<ligature sequence="p e n _ t o o l" replacement="pen_tool"/>-<ligature sequence="z o o m _ 1 _ 1" replacement="zoom_1_1"/>-<ligature sequence="p r o g r e s s" replacement="progress"/>+<ligature sequence="m e n u _ i c o n" replacement="menu_icon"/>+<ligature sequence="t t f _ u n i t s" replacement="ttf_units"/>+<ligature sequence="r e c t a n g l e" replacement="rectangle"/>+<ligature sequence="z o o m _ t o o l" replacement="zoom_tool"/>+<ligature sequence="s y m m e t r i c" replacement="symmetric"/>+<ligature sequence="t i e _ p o i n t" replacement="tie_point"/>+<ligature sequence="u n d o _ t o o l" replacement="undo_tool"/>+<ligature sequence="a u t o t r a c e" replacement="autotrace"/>+<ligature sequence="s h o w _ g r i d" replacement="show_grid"/>+<ligature sequence="i n f o _ i c o n" replacement="info_icon"/>+<ligature sequence="s a v e _ f o n t" replacement="save_font"/> <ligature sequence="n e w _ f o n t" replacement="new_font"/>+<ligature sequence="p r o g r e s s" replacement="progress"/>+<ligature sequence="z o o m _ 1 _ 1" replacement="zoom_1_1"/>+<ligature sequence="p e n _ t o o l" replacement="pen_tool"/>+<ligature sequence="r o t a t i o n" replacement="rotation"/>+<ligature sequence="z o o m _ o u t" replacement="zoom_out"/>+<ligature sequence="s e t t i n g s" replacement="settings"/> <ligature sequence="z o o m _ i n" replacement="zoom_in"/>-<ligature sequence="h e i g h t" replacement="height"/>-<ligature sequence="r e s i z e" replacement="resize"/> <ligature sequence="c i r c l e" replacement="circle"/>-<ligature sequence="t h e m e" replacement="theme"/>-<ligature sequence="w i d t h" replacement="width"/>+<ligature sequence="r e s i z e" replacement="resize"/>+<ligature sequence="h e i g h t" replacement="height"/> <ligature sequence="t r a c k" replacement="track"/>-<ligature sequence="s k e w" replacement="skew"/>-<ligature sequence="m o v e" replacement="move"/>-<ligature sequence="p r e v" replacement="prev"/>+<ligature sequence="w i d t h" replacement="width"/>+<ligature sequence="t h e m e" replacement="theme"/> <ligature sequence="n e x t" replacement="next"/>+<ligature sequence="p r e v" replacement="prev"/>+<ligature sequence="m o v e" replacement="move"/>+<ligature sequence="s k e w" replacement="skew"/>  <kerning left="settings" right="l" hadjustment="3.8289794922" /> </font>

Contact

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