Clone in a terminal:
Commit 0ffc4bc
Johan Mattsson - 2015-03-09T11:57:31+00:00
0ffc4bc53b59cddf2f6f06df8ae8ae6c79d7c490johan.mattsson.m@gmail.com

Thread safety in text rendering

Changed files (10)

Diff

diff --git a/dodo.py b/dodo.pyindex 5d6bca4..d094b73 100644--- a/dodo.py+++ b/dodo.py@@ -88,6 +88,7 @@ def task_pkg_flags():   valac_options = [+	'--thread', 	'--enable-experimental-non-null', 	'--enable-experimental', 	'--target-glib=2.34', # see bug 0000004diff --git a/libbirdfont/Font.vala b/libbirdfont/Font.valaindex 911403d..9d8b297 100644--- a/libbirdfont/Font.vala+++ b/libbirdfont/Font.vala@@ -132,7 +132,7 @@ public class Font : GLib.Object { 		bfp_file = new BirdFontPart (this); 		 		deleted_glyphs = new Gee.ArrayList<Glyph> ();-		ligatures_substitution = new Ligatures ();+		ligatures_substitution = new Ligatures (this); 		 		background_images = new Gee.ArrayList<BackgroundImage> (); 	}diff --git a/libbirdfont/GlyphRange.vala b/libbirdfont/GlyphRange.valaindex defa020..a390c62 100644--- a/libbirdfont/GlyphRange.vala+++ b/libbirdfont/GlyphRange.vala@@ -399,7 +399,7 @@ public class GlyphRange { 		string chr; 		UniRange r; 		StringBuilder sb;-		unichar c;+		unichar c;		 		 		if (index > len + unassigned.size) { 			return "\0".dup();@@ -428,8 +428,14 @@ public class GlyphRange { 				 		sb = new StringBuilder (); 		c = r.get_char ((unichar) (ti + r.length ()));+		+		if (unlikely (!c.validate ())) {+			warning ("Not a valid unicode character.");+			return "";+		}+		 		sb.append_unichar (c);-+		 		return sb.str; 	} 	diff --git a/libbirdfont/GlyphSequence.vala b/libbirdfont/GlyphSequence.valaindex c442e9a..5cc032c 100644--- a/libbirdfont/GlyphSequence.vala+++ b/libbirdfont/GlyphSequence.vala@@ -13,7 +13,7 @@ */ namespace BirdFont { -public class GlyphSequence {+public class GlyphSequence : GLib.Object { 	 	/** A list of all glyphs */ 	public Gee.ArrayList<Glyph?> glyph;@@ -33,10 +33,9 @@ public class GlyphSequence { 	/** Do ligature substitution. 	 * @return a new sequence with ligatures 	 */-	public GlyphSequence process_ligatures () {+	public GlyphSequence process_ligatures (Font font) { 		// FIXME add range to ligature 		GlyphSequence ligature_sequence = new GlyphSequence ();-		Font font = BirdFont.get_current_font (); 		bool has_range = false; 		Ligatures ligatures; 		diff --git a/libbirdfont/KerningClasses.vala b/libbirdfont/KerningClasses.valaindex 7b78174..60df354 100644--- a/libbirdfont/KerningClasses.vala+++ b/libbirdfont/KerningClasses.vala@@ -37,7 +37,7 @@ public class KerningClasses : GLib.Object { 	/** Ensure that map iterator is not invalidated because of inserts. */ 	bool protect_map = false; -	Font font;+	public Font font;  	public KerningClasses (Font font) { 		this.font = font;diff --git a/libbirdfont/KerningDisplay.vala b/libbirdfont/KerningDisplay.valaindex 81b41f1..a83afe9 100644--- a/libbirdfont/KerningDisplay.vala+++ b/libbirdfont/KerningDisplay.vala@@ -122,7 +122,7 @@ public class KerningDisplay : FontDisplay { 		 		foreach (GlyphSequence word in row) { 			wi = 0;-			word_with_ligatures = word.process_ligatures ();+			word_with_ligatures = word.process_ligatures (font); 			gr_left = null; 			gr_right = null; 			foreach (Glyph? g in word_with_ligatures.glyph) {@@ -311,7 +311,7 @@ public class KerningDisplay : FontDisplay { 		} 		 		foreach (GlyphSequence word in row) {-			word_with_ligatures = word.process_ligatures ();+			word_with_ligatures = word.process_ligatures (font); 			ranges_index = 0; 			foreach (Glyph? g in word_with_ligatures.glyph) { 				@@ -503,8 +503,9 @@ public class KerningDisplay : FontDisplay { 		Glyph? g; 		selected_handle = handle; 		GlyphSequence sequence_with_ligatures;+		Font font = BirdFont.get_current_font (); -		sequence_with_ligatures = row.get (0).process_ligatures ();+		sequence_with_ligatures = row.get (0).process_ligatures (font); 		 		if (selected_handle <= 0) { 			selected_handle = 1;@@ -724,6 +725,7 @@ public class KerningDisplay : FontDisplay { 		int col_index = 0; 		double fs = KerningTools.font_size; 		Glyph glyph = new Glyph.no_lines ("");+		Font font = BirdFont.get_current_font (); 		 		GlyphRange? gr_left, gr_right; 		@@ -734,7 +736,7 @@ public class KerningDisplay : FontDisplay { 		foreach (GlyphSequence word in row) { 			col_index = 0; 			-			word_with_ligatures = word.process_ligatures ();+			word_with_ligatures = word.process_ligatures (font); 			foreach (Glyph? g in word_with_ligatures.glyph) { 				if (g == null) { 					w = 50;diff --git a/libbirdfont/Ligatures.vala b/libbirdfont/Ligatures.valaindex dcd8364..a475daa 100644--- a/libbirdfont/Ligatures.vala+++ b/libbirdfont/Ligatures.vala@@ -27,7 +27,10 @@ public class Ligatures : GLib.Object {  	public delegate void ContextualLigatureIterator (ContextualLigature lig); -	public Ligatures () {+	Font font;++	public Ligatures (Font font) {+		this.font = font; 	} 	 	public void get_ligatures (LigatureIterator iter) {@@ -44,7 +47,6 @@ public class Ligatures : GLib.Object {  	public void get_single_substitution_ligatures (SingleLigatureIterator iter) { 		get_ligatures ((substitution, ligature) => {-			Font font = BirdFont.get_current_font (); 			GlyphCollection? gc; 			GlyphCollection li; 			GlyphSequence gs;diff --git a/libbirdfont/Renderer/Text.vala b/libbirdfont/Renderer/Text.valaindex c61c682..8012824 100644--- a/libbirdfont/Renderer/Text.vala+++ b/libbirdfont/Renderer/Text.vala@@ -130,6 +130,12 @@ public class Text : Widget { 		GlyphSequence word; 		Glyph? g; 		KerningClasses kc;++		// FIXME: Create a thread safe implementation of the bf text rendering+		// The problem is (probably) in the spacing and kerning code.+		if (MenuTab.suppress_event) {+			return;+		} 		 		glyph = new Glyph ("", '\0'); @@ -140,11 +146,12 @@ public class Text : Widget { 		word = glyph_sequence; 		wi = 0; -		word_with_ligatures = word.process_ligatures ();+		return_if_fail (current_font != null);+		word_with_ligatures = word.process_ligatures ((!) current_font); 		 		gr_left = null; 		gr_right = null;-		kc = font.get_kerning_classes ();+		kc = ((!) current_font).get_kerning_classes (); 		for (int i = 0; i < word_with_ligatures.glyph.size; i++) {  			g = word_with_ligatures.glyph.get (i);@@ -324,7 +331,9 @@ public class Text : Widget { 		double x, y; 		double ratio; 		double cc_y;-		int64 cache_id = (cacheid < 0) ? get_cache_id () : cacheid;+		int64 cache_id;+		+		cache_id = (cacheid < 0) ? get_cache_id () : cacheid; 			 		ratio = get_scale (); 		cc_y = (font.top_limit - font.base_line) * ratio;diff --git a/libbirdfont/SpacingData.vala b/libbirdfont/SpacingData.valaindex 0550495..549428b 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,13 +32,15 @@ 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);+		foreach (String t in connections) {+			c.add (t.data.dup ()); 		} 		 		connections.clear ();@@ -46,18 +48,30 @@ public class SpacingData : GLib.Object { 		return c; 	} 	+	bool has_connection (string s) {+		foreach (String t in connections) {+			if (t.data == s) {+				return true;+			}+		}+		+		return false;+	}+	 	public void add_connections (string glyph) {-		connections.add (glyph);+		String sb = new String (glyph);+		+		connections.add (sb); 		 		foreach (SpacingClass s in classes) { 			if (s.first == glyph) {-				if (connections.index_of (s.next) == -1) {+				if (has_connection (s.next)) { 					add_connections (s.next); 				} 			}  			if (s.next == glyph) {-				if (connections.index_of (s.first) == -1) {+				if (has_connection (s.first)) { 					add_connections (s.first); 				} 			}@@ -81,7 +95,7 @@ public class SpacingData : GLib.Object { 	}  	public void update_kerning (SpacingClass s) {-		Font font = BirdFont.get_current_font ();+		Font font = kerning_classes.font; 		GlyphCollection? g; 		GlyphCollection gc; 		@@ -105,6 +119,15 @@ 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/SpacingTab.vala b/libbirdfont/SpacingTab.valaindex 3e060ad..ba21fad 100644--- a/libbirdfont/SpacingTab.vala+++ b/libbirdfont/SpacingTab.vala@@ -47,6 +47,7 @@ public class SpacingTab : KerningDisplay { 	void draw_spacing_metrix (WidgetAllocation allocation, Context cr) { 		GlyphSequence row; 		int index;+		Font font = BirdFont.get_current_font ();  		// background 		cr.save ();@@ -69,7 +70,7 @@ public class SpacingTab : KerningDisplay { 		cr.restore (); 		 		// TODO: add button for processing ligatures-		row = get_first_row ().process_ligatures ();+		row = get_first_row ().process_ligatures (font); 		index = 0; 		foreach (Glyph? g in row.glyph) { 			draw_glyph_spacing (allocation, cr, g, index);@@ -163,10 +164,11 @@ public class SpacingTab : KerningDisplay { 	public override void button_press (uint button, double ex, double ey) { 		GlyphSequence row; 		double p;+		Font font = BirdFont.get_current_font (); 		 		if (ey >= allocation.height - height) { 			// TODO: add button for processing ligatures-			row = get_first_row ().process_ligatures ();+			row = get_first_row ().process_ligatures (font); 			p = 0; 			foreach (Glyph? g in row.glyph) { 				if (p < ex < p + box_size / 2.0) {

Contact

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