Clone in a terminal:
Commit c51d71c
Johan Mattsson - 2013-08-31T20:53:20+00:00
c51d71c79358c98bab69be25c39811d4bd9b3d6bjohan.mattsson.m@gmail.com

optimizations of justaposed glyphs and object boundries

Changed files (7)

Diff

diff --git a/libbirdfont/DrawingTools.vala b/libbirdfont/DrawingTools.valaindex c6ff3ad..db73cef 100644--- a/libbirdfont/DrawingTools.vala+++ b/libbirdfont/DrawingTools.vala@@ -123,6 +123,7 @@ public class DrawingTools : ToolCollection  { 				} 				 				p.set_tie_handle (tie);+				p.get_path ().update_region_boundries_for_point (p); 			} else { 				foreach (EditPoint ep in PenTool.selected_points) { 					tie = !ep.tie_handles;@@ -133,9 +134,11 @@ public class DrawingTools : ToolCollection  { 					} 				 					ep.set_tie_handle (tie);+					ep.get_path ().update_region_boundries_for_point (ep); 				} 			} 			+			 			MainWindow.get_current_glyph ().update_view (); 		}); 		edit_point_modifiers.add_tool (tie_handles);@@ -157,6 +160,7 @@ public class DrawingTools : ToolCollection  { 					} 				} 				+				ep.get_path ().update_region_boundries_for_point (ep); 				MainWindow.get_current_glyph ().update_view (); 			} 		});diff --git a/libbirdfont/EditPoint.vala b/libbirdfont/EditPoint.valaindex 430d924..f315a86 100644--- a/libbirdfont/EditPoint.vala+++ b/libbirdfont/EditPoint.vala@@ -49,6 +49,8 @@ public class EditPoint { 	public bool tie_handles = false; 	public bool reflective_handles = false; 	+	Path? path = null;+	 	public EditPoint (double nx = 0, double ny = 0, PointType nt = PointType.NONE) { 		x = nx; 		y = ny;@@ -71,6 +73,18 @@ public class EditPoint { 		} 	} +	public void set_path (Path p) {+		path = p;+	}++	public Path get_path () {+		if (unlikely (path == null)) {+			warning ("path is null");+			return new Path ();+		}	+		return (!) path;+	}+ 	public bool equals (EditPoint e) { 		return e.x == x  			&& e.y == y diff --git a/libbirdfont/Glyph.vala b/libbirdfont/Glyph.valaindex 6322435..2e207ea 100644--- a/libbirdfont/Glyph.vala+++ b/libbirdfont/Glyph.vala@@ -1361,7 +1361,7 @@ public class Glyph : FontDisplay { 	 	public void draw_path (Context cr) { 		double left, baseline;-			+		 		baseline = get_line ("baseline").pos; 		left = get_line ("left").pos; 		@@ -1380,7 +1380,7 @@ public class Glyph : FontDisplay { 				cr.restore (); 			} 		}-				+						 		if (is_open ()) { 			foreach (unowned Path p in path_list) { 				p.draw_outline (cr, allocation, view_zoom);@@ -1443,6 +1443,12 @@ public class Glyph : FontDisplay { 		if (background_image != null && background_image_visible) { 			((!)background_image).draw (cr, allocation, view_offset_x, view_offset_y, view_zoom); 		}++		if (unlikely (Preferences.draw_boundries)) {+			foreach (unowned Path p in path_list) {+				p.draw_boundries (cr, allocation, view_zoom);+			}+		} 		 		draw_background_glyph (allocation, cr); 		juxtapose (allocation, cr);@@ -1734,6 +1740,10 @@ public class Glyph : FontDisplay { 		return false; 	} 	+	static bool in_range (double offset_x, double coordinate_x1, double coordinate_x2) {+		return coordinate_x1 <= offset_x <= coordinate_x2;+	}+	 	public void juxtapose (WidgetAllocation allocation, Context cr) { 		string glyph_sequence = Preferences.get ("glyph_sequence"); 		unichar c;@@ -1746,9 +1756,17 @@ public class Glyph : FontDisplay { 		double x, kern; 		double left, baseline; 		string last_name;-				+		+		double box_x1, box_x2, box_y1, box_y2;+		double marker_x, marker_y;+		 		x = 0; 		+		box_x1 = path_coordinate_x (0);+		box_y1 = path_coordinate_y (0);+		box_x2 = path_coordinate_x (allocation.width);+		box_y2 = path_coordinate_y (allocation.height);+		 		current.append_unichar (glyph.unichar_code); 		pos = glyph_sequence.index_of (current.str); 		@@ -1767,20 +1785,27 @@ public class Glyph : FontDisplay { 			} else { 				kern = 0; 			}+			+			if (!juxtaposed.is_empty ()+				&& (in_range (left + x + kern, box_x1, box_x2) // the letter is visible+				|| in_range (left + x + kern + juxtaposed.get_width (), box_x1, box_x2))) { -			if (!juxtaposed.is_empty ()) {+				marker_x = Glyph.xc () + left + x + kern - glyph.view_offset_x;+				marker_y = Glyph.yc () + baseline - glyph.view_offset_y;+				 				cr.save (); 				cr.scale (glyph.view_zoom, glyph.view_zoom);-				cr.translate (-glyph.view_offset_x, -glyph.view_offset_y); 				cr.set_source_rgba (0, 0, 0, 1);-				Svg.draw_svg_path (cr, juxtaposed.get_svg_data (), Glyph.xc () + left + x + kern, Glyph.yc () + baseline);++				Svg.draw_svg_path (cr, juxtaposed.get_svg_data (), marker_x, marker_y); 				cr.restore (); 			} 			-			x += juxtaposed.get_width () + KerningClasses.get_instance ().get_kerning (glyph.name, name) + kern;+			x += juxtaposed.get_width () + kern;+ 			last_name = name; 		}-		+ 		x = 0; 		last_name = glyph.name; 		for (int i = pos - 1; i >= 0; i--) {@@ -1797,17 +1822,21 @@ public class Glyph : FontDisplay { 			x -= juxtaposed.get_width (); 			x -= kern; 			-			if (!juxtaposed.is_empty ()) {+			marker_x = Glyph.xc () + left + x;+			marker_y = Glyph.yc () + baseline;+			if (!juxtaposed.is_empty () +				&&(in_range (left + x, box_x1, box_x2)+				|| in_range (left + x + juxtaposed.get_width (), box_x1, box_x2))) { 				cr.save (); 				cr.scale (glyph.view_zoom, glyph.view_zoom); 				cr.translate (-glyph.view_offset_x, -glyph.view_offset_y); 				cr.set_source_rgba (0, 0, 0, 1);-				Svg.draw_svg_path (cr, juxtaposed.get_svg_data (), Glyph.xc () + left + x, Glyph.yc () + baseline);+				Svg.draw_svg_path (cr, juxtaposed.get_svg_data (), marker_x, marker_y); 				cr.restore (); 			} 			 			last_name = name;-		}	+		} 	} 	 	void draw_background_glyph (WidgetAllocation allocation, Context cr) {diff --git a/libbirdfont/OpenFontFormat/load_font.c b/libbirdfont/OpenFontFormat/load_font.cindex ea4cf0f..c42a0a1 100644--- a/libbirdfont/OpenFontFormat/load_font.c+++ b/libbirdfont/OpenFontFormat/load_font.c@@ -748,6 +748,7 @@ GString* get_bf_font (FT_Face face, char* file, int* err) { 		g_string_append (bf, "</version>\n"); 	} +	// FIXME: for some fonts will this return entry 0 (copyright) 	if (FT_Get_Sfnt_Name (face, 10, &name_table_data) == 0) { // description 		g_string_append (bf, "<description>"); 		append_description (bf, &name_table_data);diff --git a/libbirdfont/Path.vala b/libbirdfont/Path.valaindex fa0671c..6c0d0b3 100644--- a/libbirdfont/Path.vala+++ b/libbirdfont/Path.vala@@ -129,6 +129,22 @@ public class Path { 		return points.length () == 0; 	} +	public void draw_boundries  (Context cr, WidgetAllocation allocation, double view_zoom) {+		double x = Glyph.reverse_path_coordinate_x (xmin); +		double y = Glyph.reverse_path_coordinate_y (ymin);+		double x2 = Glyph.reverse_path_coordinate_x (xmax);+		double y2 = Glyph.reverse_path_coordinate_y (ymax);+		+		cr.save ();+		+		cr.set_source_rgba (0, 0, 0.3, 1);+		cr.set_line_width (2);+		cr.rectangle (x, y, x2 - x, y2 - y);+		cr.stroke ();+		+		cr.restore ();+	}+ 	public void draw_outline (Context cr, WidgetAllocation allocation, double view_zoom) { 		unowned List<EditPoint> ep = points; 		@@ -871,6 +887,8 @@ public class Path { 		second_last_point = last_point; 		last_point = p; +		p.set_path (this);+		 		return np; 	} @@ -915,141 +933,66 @@ public class Path { 		update_region_boundries (); 	} -	public void update_region_boundries () {-		double txmax = -10000;-		double txmin = 10000;-		double tymax = -10000;-		double tymin = 10000;-		-		EditPoint top = new EditPoint ();-		EditPoint bottom = new EditPoint ();-		EditPoint left = new EditPoint ();-		EditPoint right = new EditPoint ();+	public void update_region_boundries_for_point (EditPoint p) {+		EditPointHandle left_handle;+		EditPointHandle right_handle; 		-		if (points.length () == 0) {-			xmax = 0;-			xmin = 0;-			ymax = 0;-			ymin = 0;			-		}--		// on curve points-		foreach (EditPoint p in points) {-			if (p.x > txmax) {-				txmax = p.x;-				right = p;-			}-			-			if (p.x < txmin) {-				txmin = p.x;-				left = p;-			}--			if (p.y > tymax) {-				tymax = p.y;-				top = p;-			}+		left_handle = p.get_left_handle ();+		right_handle = p.get_right_handle (); 	-			if (p.y < tymin) {-				tymin = p.y;-				bottom = p;-			}+		if (p.x > xmax) {+			xmax = p.x; 		}--		xmax = -10000;-		xmin = 10000;-		ymax = -10000;-		ymin = 10000;--		bool new_val = false; 		-		// TODO: optimize (iterate over only x or y)-		-		if (top.prev != null) {-			all_of (top.get_prev ().data, top, (cx, cy) => {-				if (cy > tymax) {-					tymax = cy;-				}-				return true;-			});+		if (p.x < xmin) {+			xmin = p.x; 		} -		if (top.next != null) {-			all_of (top, top.get_next ().data, (cx, cy) => {-				if (cy > tymax) {-					tymax = cy;-				}-				return true;-			});+		if (p.y > ymax) {+			ymax = p.y; 		}-		-		if (bottom.prev != null) {-			all_of (bottom.get_prev ().data, bottom, (cx, cy) => {-				if (cy < tymin) {-					tymin = cy;-				}-				return true;-			});-		}-		-		if (bottom.next != null) {-			all_of (bottom, bottom.get_next ().data, (cx, cy) => {-				if (cy < tymin) {-					tymin = cy;-				}-				return true;-			});++		if (p.y < ymin) {+			ymin = p.y; 		} 		-		if (right.prev != null) {-			all_of (right.get_prev ().data, right, (cx, cy) => {-				if (cx > txmax) {-					txmax = cx;-				}-				return true;-			});+		update_region_boundries_for_handle (left_handle);+		update_region_boundries_for_handle (right_handle);+	}++	public void update_region_boundries_for_handle (EditPointHandle h) {+		if (h.x () > xmax) {+			xmax = h.x (); 		} -		if (right.next != null) {-			all_of (right, right.get_next ().data, (cx, cy) => {-				if (cx > txmax) {-					txmax = cx;-				}-				return true;-			});+		if (h.x () < xmin) {+			xmin = h.x (); 		} -		if (left.prev != null) {-			all_of (left.get_prev ().data, left, (cx, cy) => {-				if (cx < txmin) {-					txmin = cx;-				}-				return true;-			});+		if (h.y () > ymax) {+			ymax = h.y (); 		} -		if (left.next != null) {-			all_of (left, left.get_next ().data, (cx, cy) => {-				if (cx < txmin) {-					txmin = cx;-				}-				return true;-			});+		if (h.y () < ymin) {+			ymin = h.y (); 		}-		-		xmax = txmax;-		xmin = txmin;-		ymax = tymax;-		ymin = tymin;+	} +	public void update_region_boundries () {+		xmax = -10000;+		xmin = 10000;+		ymax = -10000;+		ymin = 10000;+		 		if (points.length () == 0) { 			xmax = 0; 			xmin = 0; 			ymax = 0;-			ymin = 0;-		} else if (unlikely (!got_region_boundries ())) {-			warning (@"No new region boundries.\nPoints.length: $(points.length ())");-			print_boundries ();+			ymin = 0;		+		}++		foreach (EditPoint p in points) {+			update_region_boundries_for_point (p); 		} 	} 		diff --git a/libbirdfont/PenTool.vala b/libbirdfont/PenTool.valaindex 28c68ca..1d0202c 100644--- a/libbirdfont/PenTool.vala+++ b/libbirdfont/PenTool.vala@@ -274,6 +274,7 @@ public class PenTool : Tool { 			} 			 			selected_handle.parent.recalculate_linear_handles ();+			selected_handle.parent.get_path ().update_region_boundries_for_handle (selected_handle); 			 			// Fixa: redraw line only 			glyph.redraw_area (0, 0, glyph.allocation.width, glyph.allocation.height);@@ -302,8 +303,8 @@ public class PenTool : Tool { 				} else { 					glyph.move_selected_edit_point_delta (p, (x - last_point_x) * precision, (y - last_point_y) * precision); 				}-				 				p.recalculate_linear_handles ();+				p.get_path ().update_region_boundries_for_point (p); 			} 		} 		diff --git a/libbirdfont/Preferences.vala b/libbirdfont/Preferences.valaindex af7dbad..365ffb4 100644--- a/libbirdfont/Preferences.vala+++ b/libbirdfont/Preferences.vala@@ -18,6 +18,7 @@ using Gee; public class Preferences { 		 	static Gee.HashMap<string, string> data;+	public static bool draw_boundries = false;   	public Preferences () { 		data = new HashMap<string, string> ();

Contact

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