Clone in a terminal:
Commit 0eae353
Johan Mattsson - 2012-07-28T22:03:09+00:00
0eae353f1f1ce3aa616eb799c9659efd56e6ac9fjohan.mattsson.m@gmail.com

expand and connect unicode ranges

Changed files (5)

Diff

diff --git a/src/GlyphRange.vala b/src/GlyphRange.valaindex c99680c..c135925 100644--- a/src/GlyphRange.vala+++ b/src/GlyphRange.vala@@ -26,8 +26,6 @@ class GlyphRange { 	 	unichar len = 0; 	-	public bool is_fill_unicode = false;-	 	public GlyphRange () { 	} 	@@ -80,7 +78,6 @@ class GlyphRange { 	} 	 	public void use_full_unicode_range () {-		is_fill_unicode = true; 		add_range ('\0', (unichar) 0xA868FE00); 	} 	@@ -110,26 +107,74 @@ class GlyphRange { 	} 	 	public void add_range (unichar start, unichar stop) {+		unichar b, s; 		if (unique (start, stop)) {-			insert_range(start, stop);+			append_range (start, stop); 		} else { 			-			unichar b = start;-			unichar s = b;-			while (b < stop) {-				if (unique (b, b)) {-					b++;-				} else {-					if (s != b) {-						insert_range(s, b - 1);+			// make sure this range does not overlap existing ranges+			b = start;+			s = b;+			if (!unique (b, b)) {			+				while (b < stop) {+					if (!unique (b, b)) {+						b++;+					} else {+						if (s != b) {+							add_range (b, stop);+						}+						+						b++;+						s = b; 					}-					-					b++;-					s = b; 				}+			} else {+				while (b < stop) {+					if (unique (b, b)) {+						b++;+					} else {+						if (s != b) {+							add_range (start, b - 1);+						}+						+						b++;+						s = b;+					}+				}				 			} 		}+	}+	+	private void append_range (unichar start, unichar stop) {+		UniRange r;+		+		StringBuilder s = new StringBuilder ();+		StringBuilder e = new StringBuilder ();+		s.append_unichar (start);+		e.append_unichar (stop); 		+		r = insert_range (start, stop); // insert a unique range+		merge_range (r); // join connecting ranges+	}+	+	private void merge_range (UniRange r) {+		foreach (UniRange u in ranges) {+			if (u == r) {+				continue;+			}			+			+			if (u.start == r.stop + 1) {+				u.start = r.start;+				ranges.remove_all (r);+				merge_range (u);+			}+			+			if (u.stop == r.start - 1) {+				u.stop = r.stop;+				ranges.remove_all (r);+				merge_range (u);+			}+		} 	}  	public string get_char (unichar index) {@@ -183,7 +228,7 @@ class GlyphRange { 			if (inside (stop, u.start, u.stop)) return false; 			if (inside (u.start, start, stop)) return false; 			if (inside (u.stop, start, stop)) return false;-+			 		}  		return true;@@ -193,18 +238,33 @@ class GlyphRange { 		return (u_start <= start <= u_stop); 	} 	-	private void insert_range (unichar start, unichar stop) {+	private UniRange insert_range (unichar start, unichar stop) { 		if (unlikely (start > stop)) { 			warning ("start > stop");-			return;+			stop = start; 		} 		 		UniRange ur = new UniRange (start, stop); 		len += ur.length (); 		index_start.append (len); 		ranges.append (ur);+		+		return ur; 	} +	public void print_all () {+		StringBuilder s;+		+		stdout.printf ("Ranges:\n");+		foreach (UniRange u in ranges) {+			s = new StringBuilder ();+			s.append_unichar (u.start);+			s.append (" - ");+			s.append_unichar (u.stop);+			s.append ("\n");+			stdout.printf (s.str);+		}+	} }  }diff --git a/src/OpenFontFormatReader.vala b/src/OpenFontFormatReader.valanew file mode 100644index 0000000..38de966--- /dev/null+++ b/src/OpenFontFormatReader.vala@@ -0,0 +1,127 @@+/*+    Copyright (C) 2012 Johan Mattsson++    This program is free software: you can redistribute it and/or modify+    it under the terms of the GNU General Public License as published by+    the Free Software Foundation, either version 3 of the License, or+    (at your option) any later version.++    This program 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 General Public License for more details.++    You should have received a copy of the GNU General Public License+    along with this program.  If not, see <http://www.gnu.org/licenses/>.+*/++namespace Supplement {++[SimpleType]+[CCode (has_type_id = false)] // Vala bug+public struct Fixed : uint32 {++	public void @set (uint16 upper, uint16 lower) {+		uint32* p = &this;+		*p = (upper << 16) + lower;+	}++	public bool @equals (uint16 upper, uint16 lower) {+		uint32 t = (upper << 16) + lower;+		return (t == this);		+	}++	public string get_string () {+		uint a = this >> 16;+		return @"$(a).$(this - (a << 16))";+	}+}++[SimpleType]+[CCode (has_type_id = false)] // same as above+public struct F2Dot14 : uint32 {+}++errordomain BadFormat {+	PARSE+}++class OpenFontFormatReader : Object {+	+	OtfInputStream dis;+	DirectoryTable directory_table;+	+	public OpenFontFormatReader (string file_name) {+		try {+			parse (file_name);+		} catch (Error e) {+			stderr.printf (e.message);+		}+	}+	+	void parse (string file_name) throws Error {+		File f = File.new_for_path (file_name);+		if (!f.query_exists ()) {+			throw new FileError.EXIST(@"OpenFontFormatReader: file does not exist. $((!) f.get_path ())");+		}+			+		dis = new OtfInputStream (f.read ());+		+		parse_index ();+		done ();+	}+	+	void done () {+		IdleSource idle = new IdleSource ();++		idle.set_callback (() => {+			Font f = Supplement.get_current_font ();+			f.loading_finished_callback ();+			return false;+		});++		idle.attach (null);		+	}+	+	void parse_index () throws Error {+		OffsetTable offset_table;+		+		directory_table = new DirectoryTable ();+		+		offset_table = new OffsetTable (directory_table);+		offset_table.parse (dis);+		+		directory_table = new DirectoryTable ();+		directory_table.set_offset_table (offset_table);+		directory_table.parse (dis);+		+		set_limits ();+	}++	public void set_limits () {+		IdleSource idle = new IdleSource ();++		idle.set_callback (() => {+			Font f = Supplement.get_current_font ();+			+			f.base_line = 0;+			f.top_position = -get_ascender ();+			f.top_limit = f.top_position - 5;+			f.bottom_position = -get_descender ();+			f.bottom_limit = f.bottom_position + 5;	++			return false;+		});++		idle.attach (null);+	}++	public double get_ascender () {+		return directory_table.hhea_table.get_ascender ();+	}+	+	public double get_descender () {+		return directory_table.hhea_table.get_descender ();+	}}++}diff --git a/src/OpenFontFormatWriter.vala b/src/OpenFontFormatWriter.valaindex aa37f6f..ea694cc 100644--- a/src/OpenFontFormatWriter.vala+++ b/src/OpenFontFormatWriter.vala@@ -1403,6 +1403,8 @@ class CmapSubtableWindowsUnicode : CmapSubtable { 			}
 		}
 		
+		glyph_range.print_all ();
+		
 		ranges = glyph_range.get_ranges ();
 		seg_count = (uint16) ranges.length () + 1;
 		seg_count_2 =  seg_count * 2;
diff --git a/src/TestSupplement.vala b/src/TestSupplement.valaindex 3b76b20..bff63df 100644--- a/src/TestSupplement.vala+++ b/src/TestSupplement.vala@@ -33,6 +33,7 @@ class TestCases { 	public List<Test> test_cases;
 
 	public TestCases () {
+		add (test_glyph_ranges, "Glyph ranges");
 		add (test_glyph_table, "Glyph table");
 		add (test_active_edit_point, "Active edit point");
 		add (test_hex, "Unicode hex values");
@@ -45,6 +46,23 @@ class TestCases { 		add (test_save_backup, "Save backup");
 	}
 
+	public static void test_glyph_ranges () {
+		GlyphRange gr = new GlyphRange ();
+		
+		gr.add_range ('b', 'c');
+		gr.add_single ('d');
+		gr.add_range ('e', 'h');
+		gr.add_range ('k', 'm');
+		gr.add_range ('o', 'u');
+		gr.add_range ('a', 'd');
+		gr.add_range ('f', 'z');
+		gr.add_range ('b', 'd');
+			
+		return_if_fail (gr.length () == 'z' - 'a' + 1);
+		return_if_fail (gr.get_ranges ().length () == 1);
+		return_if_fail (gr.get_ranges ().first ().data.length () == 'z' - 'a' + 1);
+	}
+
 	public static void test_glyph_table () {
 		GlyphTable table = new GlyphTable ();
 		List<GlyphCollection> gc = new List<GlyphCollection> ();
diff --git a/src/UniRange.vala b/src/UniRange.valanew file mode 100644index 0000000..f097bd9--- /dev/null+++ b/src/UniRange.vala@@ -0,0 +1,47 @@+/*+    Copyright (C) 2012 Johan Mattsson++    This program is free software: you can redistribute it and/or modify+    it under the terms of the GNU General Public License as published by+    the Free Software Foundation, either version 3 of the License, or+    (at your option) any later version.++    This program 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 General Public License for more details.++    You should have received a copy of the GNU General Public License+    along with this program.  If not, see <http://www.gnu.org/licenses/>.+*/++namespace Supplement {	+	class UniRange : GLib.Object {+		+		public unichar start;+		public unichar stop;+		+		public UniRange (unichar start, unichar stop) {+			this.start = start;+			this.stop = stop;+		}+		+		public unichar length () {+			return stop - start + 1;+		}++		public unichar get_char (unichar index) {+			unichar result = start + index;+			+			if (unlikely (index < 0)) {+				warning ("Index is negative in UniRange.");+			}+			+			if (unlikely (!(start <= result <= stop))) {+				warning ("Index out of range in UniRange (%u <= %u <= %u) (index: %u)\n", start, result, stop, index);+			}+			+			return result;+		}+	}+}

Contact

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