Clone in a terminal:
Commit 9b3c1ae
Johan Mattsson - 2014-06-26T20:03:05+00:00
9b3c1ae4716e9cd9a51f485b4ec104b570152e70johan.mattsson.m@gmail.com

Ligatures and a fix for the kerning bug

Changed files (12)

Diff

diff --git a/birdfont/GtkWindow.vala b/birdfont/GtkWindow.valaindex a269973..f40a0ee 100644--- a/birdfont/GtkWindow.vala+++ b/birdfont/GtkWindow.vala@@ -415,6 +415,7 @@ public class GtkWindow : Gtk.Window, NativeWindow { 		Gtk.Menu tool_menu = new Gtk.Menu (); 		Gtk.Menu kerning_menu = new Gtk.Menu (); 		Gtk.Menu git_menu = new Gtk.Menu ();+		Gtk.Menu ligature_menu = new Gtk.Menu ();  		AccelGroup accel_group = new Gtk.AccelGroup(); 		add_accel_group (accel_group);@@ -709,6 +710,13 @@ public class GtkWindow : Gtk.Window, NativeWindow { 		save_as_bfp.activate.connect (() => {  			 MenuTab.save_as_bfp (); 		});++		// Ligatures+		Gtk.MenuItem show_ligatures = new Gtk.MenuItem.with_mnemonic (t_("_Show Ligatures"));+		ligature_menu.append (show_ligatures);+		show_ligatures.activate.connect (() => { +			 MenuTab.show_ligature_tab ();+		}); 		 		// Add menus 		Gtk.MenuItem file_launcher = new Gtk.MenuItem.with_mnemonic (t_("_File"));@@ -728,7 +736,10 @@ public class GtkWindow : Gtk.Window, NativeWindow {  		Gtk.MenuItem git_launcher = new Gtk.MenuItem.with_mnemonic ("_Git"); 		git_launcher.set_submenu (git_menu);-	++		Gtk.MenuItem ligature_launcher = new Gtk.MenuItem.with_mnemonic ("_Ligatures");+		ligature_launcher.set_submenu (ligature_menu);+ 		menubar.append (file_launcher); 		menubar.append (edit_launcher); 		menubar.append (tab_launcher);@@ -737,6 +748,7 @@ public class GtkWindow : Gtk.Window, NativeWindow { 		 		if (BirdFont.has_argument ("--test")) { 			menubar.append (git_launcher);+			menubar.append (ligature_launcher); 		} 		 		return menubar;	diff --git a/libbirdfont/KerningDisplay.vala b/libbirdfont/KerningDisplay.valaindex da68764..978de3d 100644--- a/libbirdfont/KerningDisplay.vala+++ b/libbirdfont/KerningDisplay.vala@@ -443,7 +443,6 @@ public class KerningDisplay : FontDisplay { 	public override void selected_canvas () { 		Glyph g; 		GlyphSequence w;-		unowned List<GlyphSequence>? r; 		StringBuilder s = new StringBuilder (); 		bool append_char = false; 		Font font = BirdFont.get_current_font ();diff --git a/libbirdfont/KerningPair.vala b/libbirdfont/KerningPair.valadeleted file mode 100644index 3d13b97..0000000--- a/libbirdfont/KerningPair.vala+++ /dev/null@@ -1,50 +0,0 @@-/*-    Copyright (C) 2014 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 -    published by the Free Software Foundation; either version 3 of the -    License, or (at your option) any later version.--    This library is distributed in the hope that it will be useful, but -    WITHOUT ANY WARRANTY; without even the implied warranty of -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -    Lesser General Public License for more details.-*/--using Cairo;-using Xml;--namespace BirdFont {--/** A list of all kerning pairs for one glyph. */-public class KerningPair : GLib.Object {-	public Glyph character;-	public Gee.ArrayList<Kerning> kerning;--	Gee.ArrayList<Glyph> right; // FIXME: should be fast and sorted-	-	public KerningPair (Glyph left) {-		character = left;-		right = new Gee.ArrayList<Glyph> ();-		kerning = new Gee.ArrayList<Kerning> ();-	}-	-	public void add_unique (Glyph g, double k) {-		if (right.contains ((!) g)) {-			right.add ((!) g);-			kerning.add (new Kerning.for_glyph (g, k));-		}-	}-	-	public void sort () {-		kerning.sort ((a, b) => {-			Kerning first, next;-			first = (Kerning) a;-			next = (Kerning) b;-			return strcmp (((!)first.glyph).get_unichar_string (), ((!)next.glyph).get_unichar_string ());-		});		-	}-}-	-}diff --git a/libbirdfont/LigatureList.vala b/libbirdfont/LigatureList.valanew file mode 100644index 0000000..ad9c0c1--- /dev/null+++ b/libbirdfont/LigatureList.vala@@ -0,0 +1,149 @@+/*+    Copyright (C) 2014 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 +    published by the Free Software Foundation; either version 3 of the +    License, or (at your option) any later version.++    This library is distributed in the hope that it will be useful, but +    WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +    Lesser General Public License for more details.+*/++using Cairo;+using Math;++namespace BirdFont {++public class LigatureList : FontDisplay {+	+	Ligatures ligatures;+	+	int scroll = 0;+	int visible_rows = 0;+	WidgetAllocation allocation;+	+	public LigatureList () {+		allocation = new WidgetAllocation ();+		ligatures = new Ligatures ();+	}++	public override void draw (WidgetAllocation allocation, Context cr) {+		int y = 20;+		int s = 0;+		bool color = (scroll % 2) == 0;+		+		this.allocation = allocation;+		+		visible_rows = (int) (allocation.height / 18.0);+		+		cr.save ();+		cr.set_source_rgba (1, 1, 1, 1);+		cr.rectangle (0, 0, allocation.width, allocation.height);+		cr.fill ();+		cr.restore ();+		+		cr.save ();+		cr.set_source_rgba (0.3, 0.3, 0.3, 1);+		cr.set_font_size (12);++		ligatures.get_ligatures ((substitution, ligature) => {+			if (s++ >= scroll) {+				draw_row (allocation, cr, substitution, ligature, y, color);+				y += 18;+				color = !color;+			}+		});+		+		cr.restore ();+	}	++	private static void draw_row (WidgetAllocation allocation, Context cr,+		string substitution, string ligature, int y, bool color) {++		if (color) {+			cr.save ();+			cr.set_source_rgba (224/255.0, 224/255.0, 224/255.0, 1);+			cr.rectangle (0, y - 14, allocation.width, 18);+			cr.fill ();+			cr.restore ();+		}+		+		cr.move_to (30, y);+		cr.show_text (substitution);+		cr.move_to (230, y);+		cr.show_text (ligature);+	}++	public override string get_label () {+		return t_("Ligatures");+	}++	public override string get_name () {+		return "Ligatures";+	}++	public override bool has_scrollbar () {+		return true;+	}+	+	public override void scroll_wheel_down (double x, double y) {+		uint liga = ligatures.count ();+		scroll += 3;++		if (scroll > liga - visible_rows) {+			scroll = (int) (liga - visible_rows);+		}+		+		if (visible_rows > liga) {+			scroll = 0;+		} +		+		update_scrollbar ();+		redraw_area (0, 0, allocation.width, allocation.height);+	}+	+	public override void scroll_wheel_up (double x, double y) {+		scroll -= 3;+		+		if (scroll < 0) {+			scroll = 0;+		}+		+		update_scrollbar ();+		redraw_area (0, 0, allocation.width, allocation.height);+	}++	public override void selected_canvas () {+		update_scrollbar ();+		redraw_area (0, 0, allocation.width, allocation.height);+	}+	+	public void update_scrollbar () {+		uint rows = ligatures.count ();++		if (rows == 0 || visible_rows == 0) {+			MainWindow.set_scrollbar_size (0);+			MainWindow.set_scrollbar_position (0);+		} else {+			MainWindow.set_scrollbar_size ((double) visible_rows / rows);+			MainWindow.set_scrollbar_position ((double) scroll /  rows);+		}+	}++	public override void scroll_to (double percent) {+		uint liga = ligatures.count ();+		scroll = (int) (percent * liga);+		+		if (scroll > liga - visible_rows) {+			scroll = (int) (liga - visible_rows);+		}+		+		redraw_area (0, 0, allocation.width, allocation.height);+	}+}++}+diff --git a/libbirdfont/Ligatures.vala b/libbirdfont/Ligatures.valanew file mode 100644index 0000000..1f6c282--- /dev/null+++ b/libbirdfont/Ligatures.vala@@ -0,0 +1,36 @@+/*+    Copyright (C) 2014 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 +    published by the Free Software Foundation; either version 3 of the +    License, or (at your option) any later version.++    This library is distributed in the hope that it will be useful, but +    WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +    Lesser General Public License for more details.+*/++using Cairo;+using Math;++namespace BirdFont {++public class Ligatures : GLib.Object {+	+	public delegate void LigatureIterator (string substitution, string ligature);++	public Ligatures () {+	}++	public void get_ligatures (LigatureIterator iter) {+		iter ("f i", "fi");+	}+	+	public int count () {+		return 1;+	}+}++}diff --git a/libbirdfont/MainWindow.vala b/libbirdfont/MainWindow.valaindex a928782..7b444d8 100644--- a/libbirdfont/MainWindow.vala+++ b/libbirdfont/MainWindow.vala@@ -27,6 +27,7 @@ public class MainWindow { 	public static NativeWindow native_window;
 	public static KerningDisplay kerning_display;
 	public static CharDatabase character_database;
+	public static LigatureList ligature_display;
 
 	public MainWindow () {
 		singleton = this;
@@ -40,6 +41,7 @@ public class MainWindow { 		over_view = new OverView();
 		kerning_display = new KerningDisplay ();
 		character_database = new CharDatabase ();
+		ligature_display = new LigatureList ();
 	}
  	public static FileTab get_recent_files_tab () {@@ -198,6 +200,10 @@ public class MainWindow { 	public static KerningDisplay get_kerning_display () {
 		return kerning_display;
 	}
+	
+	public static LigatureList get_ligature_display () {
+		return ligature_display;
+	}
 }
 
 }
diff --git a/libbirdfont/MenuTab.vala b/libbirdfont/MenuTab.valaindex 3b98fb4..da0d7e7 100644--- a/libbirdfont/MenuTab.vala+++ b/libbirdfont/MenuTab.vala@@ -333,6 +333,16 @@ public class MenuTab : FontDisplay { 		KerningDisplay kd = MainWindow.get_kerning_display (); 		MainWindow.get_tab_bar ().add_unique_tab (kd); 	}++	public static void show_ligature_tab () {+		if (suppress_event) {+			warn_if_test ("Event suppressed");+			return;+		}+		+		LigatureList d = MainWindow.get_ligature_display ();+		MainWindow.get_tab_bar ().add_unique_tab (d);+	} 	 	public static void preview ()  { 		Font font = BirdFont.get_current_font ();diff --git a/libbirdfont/OpenFontFormat/DirectoryTable.vala b/libbirdfont/OpenFontFormat/DirectoryTable.valaindex a15c4a5..1bdc73c 100644--- a/libbirdfont/OpenFontFormat/DirectoryTable.vala+++ b/libbirdfont/OpenFontFormat/DirectoryTable.vala@@ -23,6 +23,7 @@ public class DirectoryTable : Table { 	public GdefTable gdef_table; 	public GlyfTable glyf_table; 	public GposTable gpos_table;+	public GsubTable gsub_table; 	public HeadTable head_table; 	public HheaTable hhea_table; 	public HmtxTable hmtx_table;@@ -44,6 +45,7 @@ public class DirectoryTable : Table { 		gasp_table = new GaspTable (); 		gdef_table = new GdefTable (); 		glyf_table = new GlyfTable (loca_table);+		gsub_table = new GsubTable (glyf_table); 		cmap_table = new CmapTable (glyf_table); 		cvt_table  = new CvtTable (); 		head_table = new HeadTable (glyf_table);@@ -64,6 +66,7 @@ public class DirectoryTable : Table { 		glyf_table.process (); 		gasp_table.process (); 		gdef_table.process ();+		gsub_table.process (); 		cmap_table.process (glyf_table); 		cvt_table.process (); 		hmtx_table.process ();@@ -87,6 +90,10 @@ public class DirectoryTable : Table { 			tables.append (this); 			 			tables.append (gpos_table);+			+			// FIXME: implement it+			// tables.append (gsub_table);+			 			tables.append (os_2_table);  			// tables.append (gdef_table); // invalid tablediff --git a/libbirdfont/OpenFontFormat/GposTable.vala b/libbirdfont/OpenFontFormat/GposTable.valaindex 4623862..625bc6a 100644--- a/libbirdfont/OpenFontFormat/GposTable.vala+++ b/libbirdfont/OpenFontFormat/GposTable.vala@@ -258,7 +258,7 @@ public class GposTable : Table { 	} 	 	public uint pairs_offset_length () {-		return 2 * pairs.pairs.length ();+		return 2 * pairs.pairs.size; 	} } diff --git a/libbirdfont/OpenFontFormat/Gsub.vala b/libbirdfont/OpenFontFormat/Gsub.valaindex ca0f162..0bd7d22 100644--- a/libbirdfont/OpenFontFormat/Gsub.vala+++ b/libbirdfont/OpenFontFormat/Gsub.vala@@ -1,5 +1,5 @@ /*-    Copyright (C) 2012, 2013 Johan Mattsson+    Copyright (C) 2012, 2013, 2014 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 @@ -17,8 +17,10 @@ namespace BirdFont {  public class GsubTable : Table { 	-	public GsubTable () {-		id = "GPOS";+	GlyfTable glyf_table;+	+	public GsubTable (GlyfTable glyf_table) {+		this.glyf_table = glyf_table; 	} 	 	public override void parse (FontData dis) throws Error {@@ -35,7 +37,7 @@ public class GsubTable : Table { 		// script list 		fd.add_ushort (1);   // number of items in script list 		fd.add_tag ("DFLT"); // default script-		fd.add_ushort (8);	 // offset to script table from script list+		fd.add_ushort (8); // offset to script table from script list 		 		// script table 		fd.add_ushort (4); // offset to default language system@@ -61,14 +63,27 @@ public class GsubTable : Table { 		fd.add_ushort (1); // number of lookups 		fd.add_ushort (4); // offset to lookup 1 		-		fd.add_ushort (2); // lookup type // FIXME	-		fd.add_ushort (0); // lookup flags-		fd.add_ushort (1); // number of subtables-		fd.add_ushort (8); // array of offsets to subtables+		// ligature substitution+		fd.add_ushort (1); // lookup type, format identifier+		fd.add_ushort (20); // offset to coverage+		fd.add_ushort (1); // number of ligature set tables+		fd.add_ushort (10); // array of offsets to ligature sets+		+		// ligature sets+		fd.add_ushort (1); // number of offsets+		fd.add_ushort (4); // offset to ligature table+		+		// ligatures+		fd.add_ushort ((uint16) glyf_table.get_gid ("fi")); // gid of ligature+		fd.add_ushort (2); // number of components+		fd.add_ushort ((uint16) glyf_table.get_gid ("f")); // gid to component +		fd.add_ushort ((uint16) glyf_table.get_gid ("i")); // gid to component +		+		// coverage+		fd.add_ushort (1); // format+		fd.add_ushort (1); // num glyphs+		fd.add_ushort ((uint16) glyf_table.get_gid ("f")); // gid 		-		// MarkFilteringSet --		//fd.append (get_clig_data ()); 		 		fd.pad ();	 		this.font_data = fd;diff --git a/libbirdfont/OpenFontFormat/KernList.vala b/libbirdfont/OpenFontFormat/KernList.valaindex 614fe4c..89afb77 100644--- a/libbirdfont/OpenFontFormat/KernList.vala+++ b/libbirdfont/OpenFontFormat/KernList.vala@@ -15,7 +15,7 @@ namespace BirdFont {  public class KernList : GLib.Object {-	public List<PairFormat1> pairs;+	public Gee.ArrayList<PairFormat1> pairs;  	public delegate void KernIterator (Kern k); 	public delegate void PairFormat1Iterator (PairFormat1 k);@@ -26,20 +26,19 @@ public class KernList : GLib.Object { 	public KernList (GlyfTable glyf_table) { 		this.glyf_table = glyf_table; 		num_pairs = 0;+		pairs = new Gee.ArrayList<PairFormat1> ();  	} 	 	/** @return number of pairs. */ 	public uint fetch_all_pairs () { 		PairFormat1 current_pairs = new PairFormat1 (); 		-		if (pairs.length () > 0 || num_pairs > 0) {+		if (pairs.size > 0 || num_pairs > 0) { 			warning ("Pairs already loaded."); 		} 		 		num_pairs = 0;-		while (pairs.length () > 0) {-			pairs.remove_link (pairs.first ());-		}+		pairs.clear (); 		 		KerningClasses.get_instance ().all_pairs ((kp) => { 			uint16 gid_left, gid_right;@@ -54,7 +53,7 @@ public class KernList : GLib.Object { 			current_pairs = new PairFormat1 (); 			gid_left = (uint16) glyf_table.get_gid (kerning_pair.character.get_name ()); 			current_pairs.left = gid_left;-			pairs.append (current_pairs);+			pairs.add (current_pairs); 			 			if (unlikely (kerning_pair.kerning.size == 0)) { 				warning ("No pairs.");@@ -76,7 +75,7 @@ public class KernList : GLib.Object { 	 * pair pos format 1. 	 */ 	public uint get_length_left () {-		return pairs.length ();+		return pairs.size; 	} 		 	/** @return the total number of pairs. */diff --git a/libbirdfont/OpenFontFormat/KerningPair.vala b/libbirdfont/OpenFontFormat/KerningPair.valanew file mode 100644index 0000000..d3f635b--- /dev/null+++ b/libbirdfont/OpenFontFormat/KerningPair.vala@@ -0,0 +1,50 @@+/*+    Copyright (C) 2014 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 +    published by the Free Software Foundation; either version 3 of the +    License, or (at your option) any later version.++    This library is distributed in the hope that it will be useful, but +    WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +    Lesser General Public License for more details.+*/++using Cairo;+using Xml;++namespace BirdFont {++/** A list of all kerning pairs for one glyph. */+public class KerningPair : GLib.Object {+	public Glyph character;+	public Gee.ArrayList<Kerning> kerning;++	Gee.ArrayList<Glyph> right;+	+	public KerningPair (Glyph left) {+		character = left;+		right = new Gee.ArrayList<Glyph> ();+		kerning = new Gee.ArrayList<Kerning> ();+	}+	+	public void add_unique (Glyph g, double k) {+		if (!right.contains ((!) g)) {+			right.add ((!) g);+			kerning.add (new Kerning.for_glyph (g, k));+		}+	}+	+	public void sort () {+		kerning.sort ((a, b) => {+			Kerning first, next;+			first = (Kerning) a;+			next = (Kerning) b;+			return strcmp (((!)first.glyph).get_unichar_string (), ((!)next.glyph).get_unichar_string ());+		});		+	}+}+	+}

Contact

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