Clone in a terminal:
Commit ec89776
Johan Mattsson - 2015-03-20T12:51:56+00:00
ec89776d0bb79e20ad4d3bb6f4a8beafd9fbd115johan.mattsson.m@gmail.com

Merge branch 'master' of https://github.com/johanmattssonm/birdfont into HEAD

Changed files (19)

Diff

diff --git a/libbirdfont/BirdFontFile.vala b/libbirdfont/BirdFontFile.valaindex 37c8c62..303b5a3 100644--- a/libbirdfont/BirdFontFile.vala+++ b/libbirdfont/BirdFontFile.vala@@ -923,13 +923,13 @@ class BirdFontFile : GLib.Object { 			} 			 			if (range_left.get_length () > 1) {-				kerning_range = new KerningRange ();+				kerning_range = new KerningRange (font); 				kerning_range.set_ranges (range_left.get_all_ranges ()); 				KerningTools.add_unique_class (kerning_range); 			}  			if (range_right.get_length () > 1) {-				kerning_range = new KerningRange ();+				kerning_range = new KerningRange (font); 				kerning_range.set_ranges (range_right.get_all_ranges ()); 				KerningTools.add_unique_class (kerning_range); 			}diff --git a/libbirdfont/ClickMap.vala b/libbirdfont/ClickMap.valaindex 1dcce99..01e1b3c 100644--- a/libbirdfont/ClickMap.vala+++ b/libbirdfont/ClickMap.vala@@ -1,5 +1,5 @@ /*-    Copyright (C) 2014 Johan Mattsson+    Copyright (C) 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 @@ -12,177 +12,57 @@     Lesser General Public License for more details. */ +using Cairo;+ namespace BirdFont { -// This is a refcounted container in order to avoid double free -// corruption in lambda functions. public class ClickMap : GLib.Object {-	char* map;+	ImageSurface map; 	int width;-	int margin;-	int map_size;-+	 	public ClickMap (int width) { 		this.width = width;-		margin = 10;-		map_size = width + margin;-		map = malloc (map_size * map_size);+		map = new Cairo.ImageSurface (Cairo.Format.ARGB32, width, width); 	}-	-	~ClickMap () {-		delete map;-	}-	-	public char get_value (int x, int y) { 		-		if (unlikely (!(0 <= x < map_size && 0 <= y < map_size))) {-			warning ("Array index out of bounds.");-			return '\0';-		}+	public bool get_value (int x, int y) {+		unowned uchar[] d = map.get_data ();+		bool transparent; 		-		return map[y * width + x];-	}-	-	public void set_value (int x, int y, char val) {-		if (unlikely (!(0 <= x < map_size && 0 <= y < map_size))) {+		if (unlikely (!(0 <= x < width && 0 <= y < width))) { 			warning ("Array index out of bounds.");-			return;+			return true; 		} 		-		map[y * width + x] = val;+		transparent = d[y * map.get_stride () + 4 * x + 3] == 0;+				+		return !transparent; 	}+		+	public void create_click_map (Path path) {+		double w, h;+		Context c;+				+		c = new Context (map);+		+		c.save ();+		+		c.set_source_rgba (0, 0, 0, 1);+		c.new_path (); -	private void map_outline (Path path) { 		path.all_of_path ((cx, cy, ct) => { 			int px = (int) (width * ((cx - path.xmin) / (path.xmax - path.xmin))); 			int py = (int) (width * ((cy - path.ymin) / (path.ymax - path.ymin))); 			-			set_value (px, py, '#');+			c.line_to (px, py); 			 			return true; 		}, 2 * width);-	}--	private void close_outline (Path path) {-		// first to last point in case the path is open-		Path.all_of (path.get_last_point (), path.get_first_point (), (cx, cy, ct) => {-			int px = (int) (width * ((cx - path.xmin) / (path.xmax - path.xmin)));-			int py = (int) (width * ((cy - path.ymin) / (path.ymax - path.ymin)));-			-			set_value (px, py, '#');-			-			return true;-		}, 2 * width);-	}-	-	public void create_click_map (Path path) {-		// Clear the map-		for (int i = 0; i < map_size; i++) {-			for (int j = 0; j < map_size; j++) {-				set_value (i, j, '\0');-			}-		} 		-		// Create outline-		map_outline (path);-		close_outline (path);+		c.close_path ();+		c.fill (); 		-		// Fill the map-		for (int j = 0; j < width; j++) {-			for (int k = 0; k < width; k++) {-				if (get_value (k, j) == '#') {-					-					k++;-					while (k < width && get_value (k, j) == '#') {-						k++;-					}--					while (k < width && get_value (k, j) == '\0') {-						set_value (k, j, 'o');-						k++;-					}--					k++;-					while (k < width && get_value (k, j) == '#') {-						k++;-					}-				}-			}-		}--		// Remove fill from the out side-		for (int k = 0; k < width; k++) {-			-			if (get_value (k, 0) == 'o') {-				set_value (k, 0, '\0'); -			}-			-			for (int l = width - 1; l >= 0; l--) {-				if (get_value (k, l) != '#') {-					if (get_value (k, l + 1) == '\0') {-						set_value (k, l, '\0');-					}-					-					if (get_value (k, l + 1) == 'o') {-						set_value (k, l, 'o');-					}-				}-			}-		} --		for (int k = 0; k < width; k++) {-			if (get_value (0, k) == 'o') {-				set_value (0, k,'\0'); -			}-			-			for (int l = width - 1; l >= 0; l--) {-				if (get_value (l, k) != '#') {-					if (get_value (l + 1, k) == '\0') {-						set_value (l, k, '\0');-					}-					-					if (get_value (l + 1, k) == 'o') {-						set_value (l, k, 'o');-					}-				}-			}-		}--		for (int k = width - 1; k > 0; k--) {-			if (get_value (k, 0) == 'o') {-				set_value (k, 0,'\0'); -			}-			-			for (int l = width - 1; l >= 0; l--) {-				if (get_value (k, l) != '#') {				-					if (get_value (k, l + 1) == 'o') {-						set_value (k, l, 'o');-					}-				}-			}-		}-	}-	-	public void print () {-		char c;-		for (int i = width - 1; i >= 0; i--) {-			for (int j = 0; j < width; j++) {-				c = get_value (j, i);-				if (c == '\0') {-					stdout.printf (" ");-				} else if (c == '#') {-					stdout.printf ("#");-				} else if (c == 'o') {-					stdout.printf ("o");-				} else if (c == 'X') {-					stdout.printf ("X");-				} else {-					stdout.printf ("?");-				}-			}-			-			stdout.printf ("\n");-		}+		c.restore (); 	} } diff --git a/libbirdfont/Font.vala b/libbirdfont/Font.valaindex 4493703..01b9f50 100644--- a/libbirdfont/Font.vala+++ b/libbirdfont/Font.vala@@ -87,7 +87,7 @@ public class Font : GLib.Object { 	/** File format. */ 	public FontFormat format = FontFormat.BIRDFONT; 	-	SpacingData spacing;+	public SpacingData spacing; 	 	bool read_only = false; 	diff --git a/libbirdfont/ForesightTool.vala b/libbirdfont/ForesightTool.valaindex 1b53cb9..751f38b 100644--- a/libbirdfont/ForesightTool.vala+++ b/libbirdfont/ForesightTool.vala@@ -94,11 +94,9 @@ public class ForesightTool : Tool {  						ps = new PointSelection (PenTool.active_path.points.get (PenTool.active_path.points.size - 1), PenTool.active_path); 						ps.point.set_tie_handle (false);-						ps.point.convert_to_curve (); 						 						ps = new PointSelection (PenTool.active_path.points.get (0), PenTool.active_path); 						ps.point.set_tie_handle (false);-						ps.point.convert_to_curve (); 						 						first_point = PenTool.active_path.points.get (0); 						clockwise = PenTool.active_path.is_clockwise ();@@ -197,6 +195,7 @@ public class ForesightTool : Tool { 						return; 					} 					last = PenTool.selected_points.get (PenTool.selected_points.size - 1);+					last.point.convert_to_curve (); 				} 				 				PenTool.move_selected_handle = true;diff --git a/libbirdfont/Glyph.vala b/libbirdfont/Glyph.valaindex 63e6b0b..e588608 100644--- a/libbirdfont/Glyph.vala+++ b/libbirdfont/Glyph.vala@@ -186,13 +186,13 @@ public class Glyph : FontDisplay { 		return active_paths.get (active_paths.size - 1); 	} 	-	public void boundaries (out double x1, out double y1, out double x2, out double y2) {+	public bool boundaries (out double x1, out double y1, out double x2, out double y2) { 		if (path_list.size == 0) { 			x1 = 0; 			y1 = 0; 			x2 = 0; 			y2 = 0;-			return;+			return false; 		}  		x1 = double.MAX;@@ -221,6 +221,8 @@ public class Glyph : FontDisplay { 				} 			} 		}+		+		return x1 != double.MAX; 	} 	 	public void selection_boundaries (out double x, out double y, out double w, out double h) {@@ -484,8 +486,7 @@ public class Glyph : FontDisplay { 	public double get_left_side_bearing () { 		double x1, y1, x2, y2; 		-		if (path_list.size > 0 && path_list.get (0).points.size > 0) {-			boundaries (out x1, out y1, out x2, out y2);+		if (boundaries (out x1, out y1, out x2, out y2)) { 			return x1 - left_limit; 		} else { 			return right_limit - left_limit;@@ -495,8 +496,7 @@ public class Glyph : FontDisplay { 	public double get_right_side_bearing () { 		double x1, y1, x2, y2; 		-		if (path_list.size > 0 && path_list.get (0).points.size > 0) {-			boundaries (out x1, out y1, out x2, out y2);+		if (boundaries (out x1, out y1, out x2, out y2)) { 			return right_limit - x2; 		} else { 			return right_limit - left_limit;diff --git a/libbirdfont/KerningClasses.vala b/libbirdfont/KerningClasses.valaindex 60df354..f355149 100644--- a/libbirdfont/KerningClasses.vala+++ b/libbirdfont/KerningClasses.vala@@ -52,6 +52,30 @@ public class KerningClasses : GLib.Object { 		single_kerning = new HashMap<string, double?> (); 	} +	public void update_range (GlyphRange old, GlyphRange new_range) {+		string o = old.get_all_ranges ();+		+		foreach (GlyphRange gr in classes_first) {+			try {+				if (gr.get_all_ranges () == o) {+					gr.parse_ranges (new_range.get_all_ranges ());+				}+			} catch (GLib.MarkupError e) {+				warning (e.message);+			}+		}+		+		foreach (GlyphRange gr in classes_last) {+			try {+				if (gr.get_all_ranges () == o) {+					gr.parse_ranges (new_range.get_all_ranges ());+				}+			} catch (GLib.MarkupError e) {+				warning (e.message);+			}+		}+	}+ 	/** Class based gpos kerning. */ 	public double get_kerning_for_pair (string a, string b, GlyphRange? gr_left, GlyphRange? gr_right) { 		double k = 0;@@ -492,7 +516,6 @@ public class KerningClasses : GLib.Object { 		// add the right hand glyph and the kerning value 		foreach (Glyph character in left_glyphs) { 			KerningPair kl = new KerningPair (character);-			pairs.add (kl);  			foreach (GlyphRange r in classes_last) { 				foreach (UniRange u in r.ranges) {@@ -523,6 +546,15 @@ public class KerningClasses : GLib.Object { 				} 			} 			+			if (kl.kerning.size > 0) {+				pairs.add (kl);+			}+			+			if (kl.kerning.size == 0) {+				warning (@"No kerning pairs for character: $((kl.character.get_name ()))");+			}+			+						 			kl.sort (); 		} 		diff --git a/libbirdfont/KerningRange.vala b/libbirdfont/KerningRange.valaindex 0bf11c9..82c6b6f 100644--- a/libbirdfont/KerningRange.vala+++ b/libbirdfont/KerningRange.vala@@ -22,9 +22,13 @@ public class KerningRange : Tool { 	public string ranges = ""; 	public GlyphRange glyph_range;  	bool malformed = false;+	Font font; 	-	public KerningRange (string? name = null, string tip = "") {+	public KerningRange (Font f, string? name = null, string tip = "") { 		base (null , tip);++		font = f;+		 		glyph_range = new GlyphRange ();  		 		if (name != null) {@@ -57,7 +61,6 @@ public class KerningRange : Tool { 	 	public void set_ranges (string r) { 		GlyphRange glyph_range = new GlyphRange ();-		Font font = BirdFont.get_current_font (); 		SpacingData spacing = font.get_spacing (); 		string new_range; 		string ch;@@ -90,12 +93,19 @@ public class KerningRange : Tool { 	} 		 	private void set_one_range (string r) throws MarkupError {+		GlyphRange old = new GlyphRange ();+		+		old.parse_ranges (ranges);+		old.set_class (true);+		 		ranges = r; 		name = r;  		glyph_range.empty (); 		glyph_range.parse_ranges (r); 		glyph_range.set_class (true);++		font.spacing.kerning_classes.update_range (old, glyph_range); 	} 	 	public void update_kerning_classes () {@@ -124,19 +134,21 @@ public class KerningRange : Tool { 	 	public override void draw (Context cr) { 		double xt, yt;+		Text label_text;  		xt = x + 5; 		yt = y + 10; 		 		cr.save (); 	-		// FIXME: use color to indicate error-		Theme.color (cr, "Foreground 1");+		label_text = new Text ();+		label_text.set_text (name);+		Theme.text_color (label_text, "Foreground 2");+		label_text.set_font_size (18);+		label_text.widget_x = x;+		label_text.widget_y = y;+		label_text.draw (cr); 		-		cr.set_font_size (10);-		cr.select_font_face ("Cantarell", FontSlant.NORMAL, FontWeight.NORMAL);-		cr.move_to (xt, yt);-		cr.show_text (name); 		cr.restore (); 	} }diff --git a/libbirdfont/KerningTools.vala b/libbirdfont/KerningTools.valaindex 5690e9d..1006225 100644--- a/libbirdfont/KerningTools.vala+++ b/libbirdfont/KerningTools.vala@@ -54,7 +54,10 @@ public class KerningTools : ToolCollection  { 		 		Tool new_kerning_class = new Tool ("kerning_class", t_("Create new kerning class.")); 		new_kerning_class.select_action.connect ((self) => {-			classes.add_tool (new KerningRange (@"Kerning class $(++next_class)"));+			Font font = BirdFont.get_current_font ();+			string label = t_("Kerning class");+			KerningRange kr = new KerningRange (font, @"$label $(++next_class)");+			classes.add_tool (kr); 			Toolbox.redraw_tool_box (); 		}); 		kerning_tools.add_tool (new_kerning_class);@@ -131,7 +134,8 @@ public class KerningTools : ToolCollection  { 	} 	 	public static void update_kerning_classes () {-		KerningClasses k = BirdFont.get_current_font ().get_kerning_classes ();+		Font font = BirdFont.get_current_font ();+		KerningClasses k = font.get_kerning_classes (); 		KerningRange kr; 		GlyphRange r; 		int i;@@ -141,14 +145,14 @@ public class KerningTools : ToolCollection  { 		for (i = 0; i < k.classes_first.size; i++) { 			r = k.classes_first.get (i); 			if (r.is_class ()) {-				kr = new KerningRange ();+				kr = new KerningRange (font); 				kr.set_ranges (r.get_all_ranges ()); 				add_unique_class (kr); 			} 			 			r = k.classes_last.get (i); 			if (r.is_class ()) {-				kr = new KerningRange ();+				kr = new KerningRange (font); 				kr.set_ranges (r.get_all_ranges ()); 				add_unique_class (kr); 			}diff --git a/libbirdfont/Line.vala b/libbirdfont/Line.valaindex 668674b..4ce9dbd 100644--- a/libbirdfont/Line.vala+++ b/libbirdfont/Line.vala@@ -172,16 +172,7 @@ public class Line : GLib.Object { 	}  	void redraw_line () {-		double p;-		Glyph g = MainWindow.get_current_glyph ();--		if (vertical) {-			p = Glyph.reverse_path_coordinate_x (pos);-			queue_draw_area ((int)p - 100, 0, 200, g.allocation.height);-		} else {-			p = Glyph.reverse_path_coordinate_y (pos);-			queue_draw_area (0, (int)p - 100, g.allocation.width, 300);-		}+		GlyphCanvas.redraw (); 	}	 	 	public void move_line_to (int x, int y, WidgetAllocation allocation) {diff --git a/libbirdfont/Menu.vala b/libbirdfont/Menu.valaindex 6cb3469..d23473a 100644--- a/libbirdfont/Menu.vala+++ b/libbirdfont/Menu.vala@@ -441,7 +441,7 @@ public class Menu : GLib.Object { 			show_menu = false; 		}); 		menu.items.add (description);-																																														+																						 		current_menu = menu; 		top_menu = menu; 		allocation = new WidgetAllocation ();@@ -465,7 +465,7 @@ public class Menu : GLib.Object { 				 				display = current_display.get_name (); 				-				if (!(display == "Kerning" && item.modifiers == NONE)) {+				if (!(display == "Kerning" && display == "Spacing" && display != "Preview" && item.modifiers == NONE)) { 					if (!SettingsDisplay.update_key_bindings  						&& (item.display == "" || item.display == display)) { 						item.action ();@@ -476,8 +476,10 @@ public class Menu : GLib.Object { 						 						if (!tm.tool.is_tool_modifier) { 							MainWindow.get_toolbox ().set_current_tool (tm.tool);+							return; 						} else { 							tm.tool.select_action (tm.tool);+							return; 						} 					} 				}diff --git a/libbirdfont/MenuTab.vala b/libbirdfont/MenuTab.valaindex 73c5c8d..cce3539 100644--- a/libbirdfont/MenuTab.vala+++ b/libbirdfont/MenuTab.vala@@ -360,6 +360,7 @@ public class MenuTab : FontDisplay { 		}	 			 		dialog.overwrite_signal.connect (() => {+			KeyBindings.set_modifier (NONE); 			tab_bar.add_unique_tab (new Preview (), true); 			PreviewTools.update_preview (); 		});@@ -465,6 +466,11 @@ public class MenuTab : FontDisplay { 	} 	 	public static void simplify_path () {+		if (suppress_event) {+			warn_if_test ("Event suppressed");+			return;+		}+		 		Task t = new Task (); 		t.task.connect (simplify); 		MainWindow.native_window.run_background_thread (t);diff --git a/libbirdfont/OpenFontFormat/GsubTable.vala b/libbirdfont/OpenFontFormat/GsubTable.valaindex b55b30c..fbfba53 100644--- a/libbirdfont/OpenFontFormat/GsubTable.vala+++ b/libbirdfont/OpenFontFormat/GsubTable.vala@@ -79,7 +79,7 @@ public class GsubTable : OtfTable { 		 		// lookup table 		fd.add_ushort (1); // number of lookups FIXME: should be 3-		fd.add_ushort (8); // offset to lookup 1+		fd.add_ushort (4); // offset to lookup 1 FIXME: should be 8 		//fd.add_ushort (16); // offset to lookup 2 		//fd.add_ushort (24); // offset to lookup 3 @@ -87,7 +87,7 @@ public class GsubTable : OtfTable { 		fd.add_ushort (4); // lookup type  		fd.add_ushort (0); // lookup flags 		fd.add_ushort (1); // number of subtables-		fd.add_ushort (24 + length); // array of offsets to subtable+		fd.add_ushort (8 + length); // array of offsets to subtable FIXME: should be 24 		length += (uint16) clig_subtable.length_with_padding ();  /*diff --git a/libbirdfont/OpenFontFormat/KernList.vala b/libbirdfont/OpenFontFormat/KernList.valaindex dc4bb13..e375622 100644--- a/libbirdfont/OpenFontFormat/KernList.vala+++ b/libbirdfont/OpenFontFormat/KernList.vala@@ -57,7 +57,7 @@ public class KernList : GLib.Object { 			pairs.add (current_pairs); 			 			if (unlikely (kerning_pair.kerning.size == 0)) {-				warning ("No pairs.");+				warning (@"No kerning pairs for character: $((kerning_pair.character.get_name ()))"); 			} 			 			i = 0;diff --git a/libbirdfont/Path.vala b/libbirdfont/Path.valaindex ed7e570..cb8b5ea 100644--- a/libbirdfont/Path.vala+++ b/libbirdfont/Path.vala@@ -736,7 +736,6 @@ public class Path { 	/** Variable precision */ 	public bool is_over_coordinate_var (double x, double y) { 		PathList pathlist;-		bool in_path = false; 		int width; 		ClickMap click_map; 		int px, py;@@ -774,11 +773,7 @@ public class Path { 		click_x = (int) (width * ((x - xmin) / (xmax - xmin))); 		click_y = (int) (width * ((y - ymin) / (ymax - ymin))); -		in_path = click_map.get_value (click_x, click_y) != '\0';-		-		click_map.set_value (click_x, click_y, 'X');-		-		return in_path;+		return click_map.get_value (click_x, click_y); 	} 	 	public bool is_over_boundry (double x, double y) {diff --git a/libbirdfont/PenTool.vala b/libbirdfont/PenTool.valaindex 785613f..10b1cd7 100644--- a/libbirdfont/PenTool.vala+++ b/libbirdfont/PenTool.vala@@ -125,7 +125,9 @@ public class PenTool : Tool { 		 			move_action (this, x, y); -			press (b, x, y, false);+			if (!has_join_icon ()) {+				press (b, x, y, false);+			}  			if (BirdFont.android) { 				point_selection_image = true;@@ -157,7 +159,7 @@ public class PenTool : Tool { 			 			x = Glyph.path_coordinate_x (ix); 			y = Glyph.path_coordinate_y (iy);-						+ 			if (has_join_icon ()) { 				join_paths (x, y); 			}@@ -195,7 +197,7 @@ public class PenTool : Tool { 		move_action.connect ((self, x, y) => { 			selection_box_last_x = x; 			selection_box_last_y = y;-			+ 			if (Path.distance (begin_action_x, x, begin_action_y, y) > 10 * MainWindow.units) { 				point_selection_image = false; 			}@@ -1013,7 +1015,9 @@ public class PenTool : Tool { 		Path union, second_path; 		EditPoint first_point; 		int px, py;-		+		bool last_segment_is_line;+		bool first_segment_is_line;+ 		if (glyph.path_list.size == 0) { 			return; 		}@@ -1024,12 +1028,14 @@ public class PenTool : Tool { 			return; 		} 		path = (!) p;-		+ 		if (!path.is_open ()) { 			warning ("Path is closed."); 			return; 		} 		+		return_if_fail (path.points.size > 1);+		 		if (active_edit_point == path.points.get (0)) { 			path.reverse (); 			update_selection ();@@ -1049,6 +1055,10 @@ public class PenTool : Tool { 		py = Glyph.reverse_path_coordinate_y (((!) active_edit_point).y); 		if (is_endpoint ((!) active_edit_point) 			&& is_close_to_point (path.points.get (0), px, py)) {+			+			last_segment_is_line = path.get_last_point ().get_left_handle ().is_line ();+			first_segment_is_line = path.get_first_point ().get_right_handle ().is_line ();+			 			// TODO: set point type 			path.points.get (0).left_handle.move_to_coordinate ( 				path.points.get (path.points.size - 1).left_handle.x,@@ -1068,6 +1078,16 @@ public class PenTool : Tool { 			 			path.close (); 			glyph.close_path ();++			if (last_segment_is_line) {+				path.get_first_point ().get_left_handle ().convert_to_line ();+				path.get_first_point ().recalculate_linear_handles ();+			}++			if (first_segment_is_line) {+				path.get_first_point ().get_right_handle ().convert_to_line ();+				path.get_first_point ().recalculate_linear_handles ();+			} 			  			force_direction (); @@ -1077,6 +1097,7 @@ public class PenTool : Tool { 			} 			 			remove_all_selected_points ();+ 			return; 		} 		diff --git a/libbirdfont/Renderer/TextArea.vala b/libbirdfont/Renderer/TextArea.valaindex f0cbe83..0091337 100644--- a/libbirdfont/Renderer/TextArea.vala+++ b/libbirdfont/Renderer/TextArea.vala@@ -130,21 +130,21 @@ public class TextArea : Widget { 				add_character (keyval); 				break; 			case 'a':-				if (KeyBindings.has_ctrl ()) {+				if (KeyBindings.has_ctrl () || KeyBindings.has_logo ()) { 					select_all (); 				} else { 					add_character (keyval); 				} 				break; 			case 'c':-				if (KeyBindings.has_ctrl ()) {+				if (KeyBindings.has_ctrl () || KeyBindings.has_logo ()) { 					ClipTool.copy_text (this); 				} else { 					add_character (keyval); 				} 				break; 			case 'v':-				if (KeyBindings.has_ctrl ()) {+				if (KeyBindings.has_ctrl () || KeyBindings.has_logo ()) { 					ClipTool.paste_text (this); 					store_undo_state_at_next_event = true; 				} else {@@ -152,14 +152,14 @@ public class TextArea : Widget { 				} 				break; 			case 'y':-				if (KeyBindings.has_ctrl ()) {+				if (KeyBindings.has_ctrl () || KeyBindings.has_logo ()) { 					redo (); 				} else { 					add_character (keyval); 				} 				break; 			case 'z':-				if (KeyBindings.has_ctrl ()) {+				if (KeyBindings.has_ctrl () || KeyBindings.has_logo ()) { 					undo (); 				} else { 					add_character (keyval);@@ -811,8 +811,8 @@ public class TextArea : Widget { 		} 		 		if (unlikely (c.paragraph < 0)) {-			c.paragraph = 0;-			c.character_index = 0;+			c.paragraph = paragraphs.size > 0 ? paragraphs.size - 1 : 0;+			c.character_index = paragraphs.size > 0 ? paragraphs.get (c.paragraph).text.length : 0; 		} 		 		store_undo_state_at_next_event = true;diff --git a/libbirdfont/Row.vala b/libbirdfont/Row.valaindex db59b51..e010aa0 100644--- a/libbirdfont/Row.vala+++ b/libbirdfont/Row.vala@@ -20,7 +20,7 @@ public class Row : GLib.Object {  	int index = 0; 	bool delete_button = true;-	Gee.ArrayList<string> columns_labels = new Gee.ArrayList<string> ();+	public Gee.ArrayList<string> columns_labels = new Gee.ArrayList<string> (); 	GLib.Object? row_data = null; 	 	public int columns {diff --git a/libbirdfont/SpacingData.vala b/libbirdfont/SpacingData.valaindex 549428b..28ce3c0 100644--- a/libbirdfont/SpacingData.vala+++ b/libbirdfont/SpacingData.vala@@ -21,7 +21,7 @@ public class SpacingData : GLib.Object { 	public KerningClasses kerning_classes; 	 	public Gee.ArrayList<SpacingClass> classes = new Gee.ArrayList<SpacingClass> ();-	Gee.ArrayList<String> connections = new Gee.ArrayList<String> ();+	Gee.ArrayList<string> connections = new Gee.ArrayList<string> ();  	public SpacingData (KerningClasses kerning) { 		kerning_classes = kerning;@@ -32,15 +32,14 @@ public class SpacingData : GLib.Object { 	}  	public Gee.ArrayList<string> get_all_connections (string glyph) {-		String s; 		Gee.ArrayList<string> c = new Gee.ArrayList<string> (); 		 		connections.clear (); 		 		add_connections (glyph); 		-		foreach (String t in connections) {-			c.add (t.data.dup ());+		foreach (string t in connections) {+			c.add (t.dup ()); 		} 		 		connections.clear ();@@ -49,8 +48,8 @@ public class SpacingData : GLib.Object { 	} 	 	bool has_connection (string s) {-		foreach (String t in connections) {-			if (t.data == s) {+		foreach (string t in connections) {+			if (t == s) { 				return true; 			} 		}@@ -59,7 +58,7 @@ public class SpacingData : GLib.Object { 	} 	 	public void add_connections (string glyph) {-		String sb = new String (glyph);+		string sb = glyph; 		 		connections.add (sb); 		@@ -119,15 +118,6 @@ public class SpacingData : GLib.Object { 		 		KerningTools.update_spacing_classes (); 	}-	-	class String : GLib.Object {-		-		public string data;-		-		public String (string s) {-			data = s.dup ();-		}	-	} }  }diff --git a/libbirdfont/TabContent.vala b/libbirdfont/TabContent.valaindex c149333..84590ec 100644--- a/libbirdfont/TabContent.vala+++ b/libbirdfont/TabContent.vala@@ -23,6 +23,7 @@ public class TabContent : GLib.Object { 	static LineTextArea text_input; 	static Button text_input_button; 	static bool text_input_visible = false;+	static TextListener text_callback;  	static const int TEXT_INPUT_HEIGHT = 51; @@ -319,6 +320,8 @@ public class TabContent : GLib.Object { 	} 	 	public static void show_text_input (TextListener tl) {+		text_callback = tl;+		 		text_input_label = new Text (tl.label); 		text_input = new LineTextArea (20 * MainWindow.units); 		text_input_button = new Button (tl.button_label);

Contact

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