Clone in a terminal:
Commit 3a907c4
Johan Mattsson - 2017-12-29T16:13:37+00:00
3a907c46f707f3a84799227e0b569d690da6fe18johan.mattsson.m@gmail.com

Add extrema only if necessary

Changed files (3)

Diff

diff --git a/libbirdfont/OpenFontFormat/GlyfData.vala b/libbirdfont/OpenFontFormat/GlyfData.valaindex 667b5ff..d2afc05 100644--- a/libbirdfont/OpenFontFormat/GlyfData.vala+++ b/libbirdfont/OpenFontFormat/GlyfData.vala@@ -1,5 +1,5 @@ /*-	Copyright (C) 2012, 2013, 2014 Johan Mattsson+	Copyright (C) 2012, 2013, 2014 2017 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 @@ -16,20 +16,20 @@ using Math;  namespace BirdFont { -public class CoordinateFlags {+public class CoordinateFlags : GLib.Object { 	/** TTF coordinate flags. */ -	public static const uint8 NONE           = 0;-	public static const uint8 ON_PATH        = 1 << 0;-	public static const uint8 X_SHORT_VECTOR = 1 << 1;-	public static const uint8 Y_SHORT_VECTOR = 1 << 2;-	public static const uint8 REPEAT         = 1 << 3;+	public const uint8 NONE           = 0;+	public const uint8 ON_PATH        = 1 << 0;+	public const uint8 X_SHORT_VECTOR = 1 << 1;+	public const uint8 Y_SHORT_VECTOR = 1 << 2;+	public const uint8 REPEAT         = 1 << 3;  	// same flag or short vector sign flag-	public static const uint8 X_IS_SAME               = 1 << 4; -	public static const uint8 Y_IS_SAME               = 1 << 5;-	public static const uint8 X_SHORT_VECTOR_POSITIVE = 1 << 4;-	public static const uint8 Y_SHORT_VECTOR_POSITIVE = 1 << 5;+	public const uint8 X_IS_SAME               = 1 << 4; +	public const uint8 Y_IS_SAME               = 1 << 5;+	public const uint8 X_SHORT_VECTOR_POSITIVE = 1 << 4;+	public const uint8 Y_SHORT_VECTOR_POSITIVE = 1 << 5;  } @@ -64,17 +64,22 @@ public class GlyfData : GLib.Object { 						 		int i = 0; 		foreach (Path p in all_quadratic.paths) {-			if (p.points.size > 0) {-				if (likely (!is_empty (p))) {-					// Add points at extrema-					p.add_extrema ();-					qp.add (p);-				} else {-					warning (@"Path number $i is empty in $(glyph.get_name ())");-				}-				i++;+			if (p.points.size < 2) {+				warning (@"Missing points, $(points.size) points in path.");+				continue;+			}++			if (likely (!is_empty (p))) {+				qp.add (p);+			} else {+				warning (@"Path number $i is empty in $(glyph.get_name ())"); 			}+			+			i++; 		}++		// Add points at extrema+		add_extrema_to_path (qp); 		 		points.clear (); 		paths.clear ();@@ -94,7 +99,137 @@ public class GlyfData : GLib.Object { 			process_bounding_box (); 		} 	}+	+	public static void add_extrema_to_path (PathList path_list) {+		double x0, y0, x1, y1, x2, y2, x3, y3;+		double minx, maxx, miny, maxy;+		Path path_minx, path_maxx, path_miny, path_maxy;+		+		path_minx = new Path ();+		path_maxx = new Path ();+		path_miny = new Path ();+		path_maxy = new Path ();+		+		minx = Glyph.CANVAS_MAX;+		miny = Glyph.CANVAS_MAX;+		maxx = Glyph.CANVAS_MIN;+		maxy = Glyph.CANVAS_MIN;+		+		x0 = 0;+		y0 = 0;	+		x1 = 0;+		y1 = 0;	+		x2 = 0;+		y2 = 0;+		x3 = 0;+		y3 = 0;+		+		foreach (Path next_path in path_list.paths) {	+			if (next_path.points.size < 2) {+				warning (@"Missing points, $(next_path.points.size) points in path.");+				continue;+			}+		+			next_path.all_of_path ((x, y) => {+				if (x < minx) {+					x0 = x;+					y0 = y;+					minx = x;+					path_minx = next_path;+				}+				+				if (x > maxx) {+					x1 = x;+					y1 = y;+					maxx = x;+					path_maxx = next_path;+				}++				if (y < miny) {+					x2 = x;+					y2 = y;+					miny = y;+					path_miny = next_path;+				}+						+				if (y > maxy) {+					x3 = x;+					y3 = y;+					maxy = y;+					path_maxy = next_path;+				}+				+				return true;+			}, 3000);+		}+		+		if (!has_extrema (path_minx, x0 + 0.001, true, true)) {+			path_minx.insert_new_point_on_path_at (x0 - 0.001, y0);+		}+		+		if (!has_extrema (path_maxx, x1 - 0.001, true, false)) {+			path_maxx.insert_new_point_on_path_at (x1 + 0.001, y1);+		}+		+		if (!has_extrema (path_maxy, y2 + 0.001, false, true)) {+			path_maxy.insert_new_point_on_path_at (x2, y2 - 0.001);+		}+		+		if (!has_extrema (path_miny, y3 - 0.001, false, false)) {+			path_miny.insert_new_point_on_path_at (x3, y3 + 0.001);+		}+	}+	+	public static bool has_extrema (Path path, double coordinate, bool x, bool min) {+		bool has_extrema = false; +		if (x && min) {+			path.all_segments ((start, stop) => {+				if (start.x < coordinate) {+					has_extrema = true;+					return false;+				}+				+				return true;+			});+		}+		+		if (x && !min) {+			path.all_segments ((start, stop) => {+				if (start.x > coordinate) {+					has_extrema = true;+					return false;+				}+				+				return true;+			});+		}+		+		if (!x && min) {+			path.all_segments ((start, stop) => {+				if (start.y < coordinate) {+					has_extrema = true;+					return false;+				}+				+				return true;+			});+		}+		+		if (!x && !min) {+			path.all_segments ((start, stop) => {+				if (start.y > coordinate) {+					has_extrema = true;+					return false;+				}+				+				return true;+			});+		}+		+		return has_extrema;+	}+	 	bool is_empty (Path p) { 		EditPoint? last = null; 		diff --git a/libbirdfont/Path.vala b/libbirdfont/Path.valaindex 7e4650e..3a887a5 100644--- a/libbirdfont/Path.vala+++ b/libbirdfont/Path.vala@@ -2174,63 +2174,6 @@ public class Path : GLib.Object { 		find_intersection (p1.x, p1.y, p2.x, p2.y, q1.x, q1.y, q2.x, q2.y, out point_x, out point_y); 	} 		-	public void add_extrema () {-		double x0, y0, x1, y1, x2, y2, x3, y3;-		double minx, maxx, miny, maxy;-		-		if (unlikely (points.size < 2)) {-			warning (@"Missing points, $(points.size) points in path.");-			return;-		}-		-		minx = Glyph.CANVAS_MAX;-		miny = Glyph.CANVAS_MAX;-		maxx = Glyph.CANVAS_MIN;-		maxy = Glyph.CANVAS_MIN;-		-		x0 = 0;-		y0 = 0;	-		x1 = 0;-		y1 = 0;	-		x2 = 0;-		y2 = 0;-		x3 = 0;-		y3 = 0;-				-		all_of_path ((x, y) => {-			if (x < minx) {-				x0 = x;-				y0 = y;-				minx = x;-			}-			-			if (x > maxx) {-				x1 = x;-				y1 = y;-				maxx = x;-			}--			if (y < miny) {-				x2 = x;-				y2 = y;-				miny = y;-			}-					-			if (y > maxy) {-				x3 = x;-				y3 = y;-				maxy = y;-			}-			-			return true;-		});-		-		insert_new_point_on_path_at (x0 - 0.001, y0);-		insert_new_point_on_path_at (x1 + 0.001, y1);-		insert_new_point_on_path_at (x2, y2 - 0.001);-		insert_new_point_on_path_at (x3, y3 + 0.001);-	}-	 	public EditPoint insert_new_point_on_path_at (double x, double y) { 		EditPoint ep = new EditPoint (); 		EditPoint prev, next;diff --git a/libbirdfont/TestCases.vala b/libbirdfont/TestCases.valaindex b6ae008..0923f6e 100644--- a/libbirdfont/TestCases.vala+++ b/libbirdfont/TestCases.vala@@ -44,7 +44,6 @@ class TestCases { 		add (test_preview, "Preview"); 		add (test_kerning, "Kerning"); 		add (test_boundaries, "Boundaries");-		add (test_extrema, "Extrema"); 		add (test_codepages, "Codepages"); 		add (test_double_quadratic, "Double quadratic"); 		add (test_raster_path, "Raster path");@@ -180,23 +179,6 @@ class TestCases { 		} 	} 	-	public static void test_extrema () {-		Glyph g;-		SvgParser parser = new SvgParser ();-		-		test_open_next_glyph ();-		g = MainWindow.get_current_glyph ();-		-		parser.set_format (SvgFormat.INKSCAPE);-		parser.add_path_to_glyph ("m -163.59375,-250.78125 c -42.43208,51.5679 -78.92929,123.30265 -109.59375,216.03125 l 94.9375,31.375 c 27.9767,-84.600883 60.86301,-146.18598 91.875,-183.875 48.545803,-62.79748 104.513616,-52.47212 139.34375,-5.46875 25.619399,35.30837 51.38402,95.22476 69.625,178.625 l 97.6875,-21.375 c -20.20842,-92.39565 -48.64621,-164.00261 -86.375,-216 -88.811818,-115.9163 -218.868232,-92.82539 -297.5,0.6875 z", g);-		-		Toolbox.select_tool_by_name ("full_glyph");-		-		foreach (Path p in g.get_all_paths ()) {-			p.add_extrema ();-		}-	}-	 	public static void test_freetype () { 		StringBuilder? data; 		int error;

Contact

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