Clone in a terminal:
Commit 917c39f
Johan Mattsson - 2012-08-02T14:38:43+00:00
917c39f21a1f0f7f7c346d1ad31c8c5f2ddf944bjohan.mattsson.m@gmail.com

validate headtable, test FontData class and remove some debug code in ttf writer

Changed files (2)

Diff

diff --git a/src/OpenFontFormatWriter.vala b/src/OpenFontFormatWriter.valaindex 3a143e8..9153f2d 100644--- a/src/OpenFontFormatWriter.vala+++ b/src/OpenFontFormatWriter.vala@@ -37,7 +37,6 @@ class OpenFontFormatWriter : Object  { 	}
 	
 	public void write_ttf_font (Font font) throws Error {
-		print (@"Calculate size\n");
 		long dl;
 		uint8* data;
 		uint i = 0;
@@ -67,22 +66,6 @@ class OpenFontFormatWriter : Object  { 				os.put_byte (data[j]);
 			}
 		}
-		
-		/*
-		data = new uint8[dl];
-
-		foreach (Table t in tables) {
-			foreach (uint8 d in t.get_font_data ().data) {
-				data[i] = d;
-				i++;
-			}	
-		}
-		
-		while (written < data.length) {
-			written += os.write (data[written:data.length]);
-		}
-		*/
-		// directory_table.cmap_table.get_font_data ().print ();
 	}
 	
 	public void close () throws Error {
@@ -145,10 +128,10 @@ class OtfInputStream : Object  { class FontData : Object {
 
 	// Read pointer
-	int rp = 0;
+	uint rp = 0;
 
 	// Write pointer
-	int wp = 0;
+	uint wp = 0;
 	
 	// length without pad
 	uint32 len = 0;
@@ -193,9 +176,11 @@ class FontData : Object { 			return;
 		}
 		
+		seek (0);
 		dis.seek (offset);
-	
-		for (wp = 0; wp < l; wp++) {
+		
+		wp = 0;
+		while (wp < l) {
 			b = dis.read_byte ();
 			add (b);
 		}
@@ -203,9 +188,6 @@ class FontData : Object { 		rp = 0;
 	}
 	
-	public void print () {
-	}
-	
 	public uint length_with_padding () {
 		return len;
 	}	
@@ -223,7 +205,7 @@ class FontData : Object { 	
 	/** Add additional checksum data to this checksum. */
 	public void continous_check_sum (ref uint32 current_check_sum) {
-		int trp = rp;
+		uint trp = rp;
 		uint l;
 		
 		if (length_with_padding () % 4 != 0) {
@@ -247,7 +229,7 @@ class FontData : Object { 		return sum;
 	}
 	
-	public void seek (int i) {
+	public void seek (uint i) {
 		rp = i;
 	}
 	
@@ -264,12 +246,23 @@ class FontData : Object { 		return (Fixed) read_uint32 ();
 	}
 
+	public uint32 read_ulong () {
+		return read_uint32 ();
+	}
+
+	public uint32 read_short () {
+		uint32 f;
+		f = read () << 8;
+		f += read ();
+		return f;
+	}
+		
 	public uint32 read_uint32 () {
 		uint32 f;
-		f = read () << 32 - 8 * 1;
-		f += read () << 32 - 8 * 2;
-		f += read () << 32 - 8 * 3;
-		f += read () << 32 - 8 * 4;
+		f = read () << 8 * 3;
+		f += read () << 8 * 2;
+		f += read () << 8 * 1;
+		f += read () << 8 * 0;
 		return f;
 	}
 	
@@ -367,6 +360,24 @@ class FontData : Object { 		add_u32 ((int32)(i - (s << 32)));		
 	}
 	
+	public void add_str_utf16 (string s) {
+		int index = 0;
+		unichar c;
+		uint8 c0;
+		uint8 c1;
+		int l = 0;
+		
+		while (s.get_next_char (ref index, out c)) {
+			c0 = (uint8) (c >> 8);
+			c1 = (uint8) (c - (c0 << 8));
+			add (c0);
+			add (c1);
+			l += 2;
+		}
+		
+		assert (l == 2 * s.char_count ());
+	}
+	
 	public void add_str (string s) {
 		uint8[] data = s.data;
 		for (int n = 0; n < data.length; n++) { 
@@ -535,11 +546,11 @@ class LocaTable : Table { 		
 		dis.seek (offset);
 		
-		print (@"size: $size\n");
-		print (@"length: $length\n");
-		print (@"length/4-1: $(length / 4 - 1)\n");
-		print (@"length/2-1: $(length / 2 - 1)\n");
-		print (@"head_table.loca_offset_size: $(head_table.loca_offset_size)\n");
+		printd (@"size: $size\n");
+		printd (@"length: $length\n");
+		printd (@"length/4-1: $(length / 4 - 1)\n");
+		printd (@"length/2-1: $(length / 2 - 1)\n");
+		printd (@"head_table.loca_offset_size: $(head_table.loca_offset_size)\n");
 		
 		switch (head_table.loca_offset_size) {
 			case 0:
@@ -557,7 +568,7 @@ class LocaTable : Table { 				for (long i = 0; i < size + 1; i++) {
 					glyph_offsets[i] = 	dis.read_ulong ();
 					
-					print (@"glyph_offsets[i]: $(glyph_offsets[i])\n");
+					printd (@"glyph_offsets[i]: $(glyph_offsets[i])\n");
 					
 					if (0 < i < size && glyph_offsets[i - 1] > glyph_offsets[i]) {
 						warning (@"Invalid loca table, it must be sorted. ($(glyph_offsets[i - 1]) > $(glyph_offsets[i]))");
@@ -591,7 +602,7 @@ class LocaTable : Table { 			foreach (uint32 o in glyf_table.location_offsets) {
 				fd.add_u16 ((uint16) (o / 2));
 				
-				print (@"o0: $(o)\n");
+				printd (@"o0: $(o)\n");
 				
 				if (o < last) {
 					warning (@"Loca table must be sorted. ($o < $last)");
@@ -604,7 +615,7 @@ class LocaTable : Table { 			foreach (uint32 o in glyf_table.location_offsets) {
 				fd.add_u32 (o);
 				
-				print (@"o1: $(o)\n");
+				printd (@"o1: $(o)\n");
 				
 				if (o < last) {
 					warning (@"Loca table must be sorted. ($o < $last)");
@@ -658,7 +669,36 @@ class GlyfTable : Table { 		location_offsets = new List<uint32> ();
 		glyphs = new List<Glyph> ();
 	}	
+
+	public uint16 get_first_char () {
+		foreach (Glyph g in glyphs) {
+			if (g.is_unassigned ()) {
+				continue;
+			}
+			
+			return (uint16)g.unichar_code;
+		}
+		
+		return 0;
+	}
 	
+	public uint16 get_last_char () {
+		unowned List<Glyph> gl = glyphs.last ();
+		Glyph g = (!) gl.data;
+		
+		while (gl != glyphs.first ()) {
+			g = (!) gl.data;
+			
+			if (!g.is_unassigned ()) {
+				break;
+			}
+			
+			gl = gl.prev;
+		}
+		
+		return (uint16)g.unichar_code; 
+	}
+			
 	/** Add this glyph from thread safe callback to the running gui. */
 	void add_glyph (Glyph g) {
 		IdleSource idle = new IdleSource ();
@@ -680,7 +720,7 @@ class GlyfTable : Table { 		unichar character = 0;
 		string name;	
 
-		print (@"loca.size: $(loca.size)\n");
+		printd (@"loca.size: $(loca.size)\n");
 		
 		post_table.print_all ();
 		
@@ -713,7 +753,7 @@ class GlyfTable : Table { 					name = name_c.str;
 				}
 				
-				print (@"name: $(name)\n");
+				printd (@"name: $(name)\n");
 				
 				if (!loca.is_empty (i)) {	
 					glyph_offset = loca.get_offset(i);
@@ -724,7 +764,7 @@ class GlyfTable : Table { 					glyph.left_limit = 0;
 					glyph.right_limit = glyph.left_limit + hmtx_table.get_advance (i);
 					
-					print (@"$(glyph.right_limit) = $(glyph.left_limit) + $(hmtx_table.get_advance (i))\n");
+					printd (@"$(glyph.right_limit) = $(glyph.left_limit) + $(hmtx_table.get_advance (i))\n");
 					
 					if (xmin > glyph.right_limit || xmax < glyph.left_limit) {
 						warning (@"Glyph $(name) is outside of it's box.");
@@ -928,10 +968,10 @@ class GlyfTable : Table { 		}
 		// assert (nflags == npoints);
 
-		print (@"npoints: $npoints\n");
-		print (@"ncontours: $ncontours\n");
-		print (@"ninstructions: $ninstructions\n");
-		print (@"nflags: $nflags\n");
+		printd (@"npoints: $npoints\n");
+		printd (@"ncontours: $ncontours\n");
+		printd (@"ninstructions: $ninstructions\n");
+		printd (@"nflags: $nflags\n");
 				
 		int16 last = 0;
 		xcoordinates = new int16[npoints + 1];
@@ -1386,7 +1426,7 @@ class CmapSubtableWindowsUnicode : CmapSubtable { 
 		seg_count = seg_count_x2 / 2;
 		
-		print (@"seg_count: $seg_count\n");
+		printd (@"seg_count: $seg_count\n");
 		
 		end_char = new uint16[seg_count];
 		for (int i = 0; i < seg_count; i++) {
@@ -1420,8 +1460,8 @@ class CmapSubtableWindowsUnicode : CmapSubtable { 		}
 
 		gid_len = (length - 16 - 8 * seg_count) / 2;
-		print (@"length: $length\n");
-		print (@"gid_len: $gid_len\n");
+		printd (@"length: $length\n");
+		printd (@"gid_len: $gid_len\n");
 		glyph_id_array = new uint16[gid_len];
 		for (int i = 0; i < gid_len; i++) {
 			glyph_id_array[i] = dis.read_ushort ();
@@ -1509,7 +1549,7 @@ class CmapSubtableWindowsUnicode : CmapSubtable { 				break;
 			}
 		}
-		print (@"first_assigned $first_assigned\n");
+		printd (@"first_assigned $first_assigned\n");
 		first_assigned = 1;
 		foreach (Glyph g in glyf_table.glyphs) {
 			if (!g.is_unassigned ()) {
@@ -1681,8 +1721,8 @@ class CmapTable : Table { 		version = dis.read_ushort ();
 		nsubtables = dis.read_ushort ();
 
-		print (@"cmap version: $version\n");
-		print (@"cmap subtables: $nsubtables\n");
+		printd (@"cmap version: $version\n");
+		printd (@"cmap subtables: $nsubtables\n");
 				
 		if (version != 0) {
 			warning (@"Bad version for cmap table: $version expecting 0. Number of subtables: $nsubtables");
@@ -1695,7 +1735,7 @@ class CmapTable : Table { 			sub_offset = dis.read_ulong ();	
 			
 			if (platform == 3 && encoding == 1) {
-				print (@"Parsing Unicode BMP (UCS-2) Platform: $platform Encoding: $encoding\n");
+				printd (@"Parsing Unicode BMP (UCS-2) Platform: $platform Encoding: $encoding\n");
 				subtable = new CmapSubtableWindowsUnicode ();
 				subtable.offset = offset + sub_offset;
 				subtables.append (subtable);
@@ -1733,7 +1773,7 @@ class CmapTable : Table { 		fd.add_u16 (1); // encoding (Format Unicode UCS-4)
 
 		subtable_offset = fd.length () + 4;
-		print (@"subtable_offset: $(subtable_offset)\n");
+		printd (@"subtable_offset: $(subtable_offset)\n");
 		
 		fd.add_ulong (subtable_offset);
 		cmap.process (fd, glyf_table);
@@ -1864,7 +1904,7 @@ class HeadTable : Table { 	}
 	
 	public uint32 get_checksum_position () {
-		return offset + 8;
+		return 8;
 	}
 	
 	public void process () {
@@ -1910,7 +1950,7 @@ class HeadTable : Table { 		
 		this.font_data = font_data;
 		
-		print (@"loca_offset_size: $loca_offset_size\n");
+		printd (@"loca_offset_size: $loca_offset_size\n");
 	}
 }
 
@@ -2086,7 +2126,7 @@ class HmtxTable : Table { 			advance_width[i] = dis.read_ushort ();
 			left_side_bearing[i] = dis.read_short ();
 			
-			print (@"advance_width[i] $(advance_width[i])    $(left_side_bearing[i]) \n");
+			// Delete: print (@"advance_width[i] $(advance_width[i])    $(left_side_bearing[i]) \n");
 		}
 		
 		for (int i = 0; i < nmonospaced; i++) {
@@ -2117,7 +2157,7 @@ class HmtxTable : Table { 			extent = (int16) (lsb + (xmax - xmin) + 0.5);
 			rsb = (int16) (advance - extent);
 
-			print (@"$(g.name) advance: $advance  = $((int16) (g.right_limit))  -  $((int16) (g.left_limit))\n");
+			printd (@"$(g.name) advance: $advance  = $((int16) (g.right_limit))  -  $((int16) (g.left_limit))\n");
 						
 			fd.add_u16 (advance);
 			fd.add_16 (lsb);
@@ -2166,7 +2206,7 @@ class MaxpTable : Table { 		dis.seek (offset);
 		
 		format = dis.read_fixed ();
-		print (@"Maxp version: $(format.get_string ())\n");
+		printd (@"Maxp version: $(format.get_string ())\n");
 		
 		num_glyphs = dis.read_ushort ();
 		
@@ -2220,8 +2260,8 @@ class OffsetTable : Table { 		entry_selector = dis.read_ushort ();
 		range_shift = dis.read_ushort ();
 		
-		print (@"Font file version $(version.get_string ())\n");
-		print (@"Number of tables $num_tables\n");		
+		printd (@"Font file version $(version.get_string ())\n");
+		printd (@"Number of tables $num_tables\n");		
 	}
 	
 	public void process () {
@@ -2253,6 +2293,10 @@ class NameTable : Table { 
 	static const uint16 COPYRIGHT_NOTICE = 0;
 	static const uint16 FONT_NAME = 1;
+	static const uint16 SUBFAMILY_NAME = 2;
+	static const uint16 UNIQUE_IDENTIFIER = 3;
+	static const uint16 FULL_FONT_NAME = 4; // name + subfamily
+	static const uint16 VERSION = 5;
 	static const uint16 DESCRIPTION = 10;
 	
 	List<string> text;
@@ -2297,45 +2341,60 @@ class NameTable : Table { 	public void parse_format0 (OtfInputStream dis) throws Error {
 		uint16 count;
 		uint16 storage_offset;
-
-		uint16 platform;
-		uint16 encoding_id;
-		uint16 lang;
 		
 		List<uint16> strlen = new List<uint16> ();
 		List<uint16> off = new List<uint16> ();
 		List<uint16> name_id = new List<uint16> ();
-		
+		List<uint16> encoding_id = new List<uint16> ();
+		List<uint16> platform = new List<uint16> ();
+		List<uint16> lang = new List<uint16> ();
+				
 		count = dis.read_ushort ();
 		storage_offset = dis.read_ushort ();
 		
 		for (int i = 0; i < count; i++) {
-			platform = dis.read_ushort ();
-			encoding_id = dis.read_ushort ();
-			lang = dis.read_ushort ();
+			platform.append (dis.read_ushort ());
+			encoding_id.append (dis.read_ushort ());
+			lang.append (dis.read_ushort ());
 			name_id.append (dis.read_ushort ());
 			strlen.append (dis.read_ushort ());
 			off.append (dis.read_ushort ());
-			
-			print (@"platform $platform\n");
-			print (@"encoding_id $encoding_id\n");
-			print (@"lang $lang\n");
-			print (@"name_id $((!) name_id.last ().data)\n");
-			print (@"strlen $((!) strlen.last ().data)\n");
-			print (@"off $((!) off.last ().data)\n");
 		}
 
+		int plat;
+		StringBuilder str;
 		for (int i = 0; i < count; i++) {
+			plat = platform.nth (i).data;
 			dis.seek (offset + storage_offset + off.nth (i).data);
+			str = new StringBuilder ();
 			
-			StringBuilder str = new StringBuilder ();
-			for (int j = 0; j < strlen.nth (i).data; j++) {
-				char c = dis.read_char ();
-				str.append_c (c);
-			}
+			switch (plat) {
+				case 1:
+					for (int j = 0; j < strlen.nth (i).data; j++) {
+						char c = dis.read_char ();
+						str.append_c (c);
+					}
+					break;
+					
+				case 3:
+					for (int j = 0; j < strlen.nth (i).data; j += 2) {
+						unichar c;
+						char c0 = dis.read_char ();
+						char c1 = dis.read_char ();
+												
+						c = c0 << 8;
+						c += c1;
+						
+						str.append_unichar (c);
+					}
+					break;
+				
+				default:
+					break;
+			} 
 			
 			text.append (str.str);
-			print (@"Name id: $(name_id.nth (i).data) str: \"$(str.str)\"\n");		
+			printd (@"Name id: $(name_id.nth (i).data) platform:  $(platform.nth (i).data) enc: $(encoding_id.nth (i).data) len: $(strlen.nth (i).data) str: \"$(str.str)\"\n");		
 		}
 	}
 	
@@ -2343,46 +2402,76 @@ class NameTable : Table { 		FontData fd = new FontData ();
 		Font font = Supplement.get_current_font ();
 		uint16 len = 0;
-		string text;
-		uint16 num_records = 1;
+		string t;
+		uint16 p;
+		uint16 l;
+		uint16 num_records;
+
+		List<uint16> type = new List<uint16> ();
+		List<string> text = new List<string> ();
+
+		text.append ("Copyright");
+		type.append (COPYRIGHT_NOTICE);
+		
+		text.append (font.get_name ());
+		type.append (FONT_NAME);
+
+		text.append ("Regular");
+		type.append (SUBFAMILY_NAME);
+
+		text.append (font.get_name ()); // TODO: validate
+		type.append (UNIQUE_IDENTIFIER);
+
+		text.append (font.get_name ());
+		type.append (FULL_FONT_NAME);
+
+		text.append ("Version 1.0");
+		type.append (VERSION);
+						
+		num_records = (uint16) text.length ();
 		
 		fd.add_ushort (0); // format 1
-		fd.add_ushort (num_records); // nrecords
-		fd.add_ushort (6 + 12 * num_records); // string storage offset
-
-/*		
-		// name record
-		text = "Copyright";
-		fd.add_ushort (1); // platform
-		fd.add_ushort (0); // encoding id deprecated
-		fd.add_ushort (0); // language
-		fd.add_ushort (COPYRIGHT_NOTICE); // name id 
-		fd.add_ushort ((uint16) text.len ()); // strlen
-		fd.add_ushort (len); // offset from begining of string storage
-		len += (uint16) text.len ();
-		
-		text = "A typeface.";
-		fd.add_ushort (1); // platform
-		fd.add_ushort (0); // encoding id 
-		fd.add_ushort (0); // language
-		fd.add_ushort (DESCRIPTION); // name id 
-		fd.add_ushort ((uint16) text.len ()); // strlen
-		fd.add_ushort (len); // offset from begining of string storage
-		len += (uint16) text.len ();
-*/
-		text = font.get_name ();
-		fd.add_ushort (1); // platform
-		fd.add_ushort (0); // encoding id deprecated
-		fd.add_ushort (0); // language
-		fd.add_ushort (FONT_NAME); // name id 
-		fd.add_ushort ((uint16) text.len ()); // strlen
-		fd.add_ushort (len); // offset from begining of string storage
-		len += (uint16) text.len ();		
-
-//		fd.add_str ("Copyright"); 
-//		fd.add_str ("A typeface.");
-		fd.add_str (font.get_name ());
+		fd.add_ushort (2 * num_records); // nplatforms * nrecords 
+		fd.add_ushort (6 + 12 * 2 * num_records); // string storage offset
+
+		for (int i = 0; i < num_records; i++) {
+			t = (!) text.nth (i).data;
+			p = (!) type.nth (i).data;
+			l = (uint16) t.len ();
+			
+			fd.add_ushort (1); // platform
+			fd.add_ushort (0); // encoding id
+			fd.add_ushort (0); // language
+			fd.add_ushort (p); // name id 
+			fd.add_ushort (l); // strlen
+			fd.add_ushort (len); // offset from begining of string storage
+			len += l;				
+		}	
+
+		for (int i = 0; i < num_records; i++) {
+			t = (!) text.nth (i).data;
+			p = (!) type.nth (i).data;
+			l = (uint16) (2 * t.char_count ());
+
+			fd.add_ushort (3); // platform
+			fd.add_ushort (1); 	// encoding id
+			fd.add_ushort (0x0809); // language
+			fd.add_ushort (p); // name id 
+			fd.add_ushort (l); // strlen
+			fd.add_ushort (len); // offset from begining of string storage
+			len += l;
+		}
+
+		// platform 1
+		foreach (string s in text) {
+			fd.add_str (s); 
+		}
 		
+		// platform 3
+		foreach (string s in text) {
+			fd.add_str_utf16 (s); 
+		}
+
 		fd.pad ();
 		
 		this.font_data = fd;
@@ -2399,7 +2488,7 @@ class Os2Table : Table { 		
 	}
 	
-	public void process () {
+	public void process (GlyfTable glyf_table) {
 		FontData fd = new FontData ();
 		
 		fd.add_u16 (0x0002); // USHORT Version 0x0000, 0x0001, 0x0002, 0x0003, 0x0004
@@ -2442,8 +2531,9 @@ class Os2Table : Table { 		fd.add_tag ("----"); // VendID
 
 		fd.add_u16 (0); // USHORT fsSelection
-		fd.add_u16 (0); // USHORT usFirstCharIndex
-		fd.add_u16 (0); // USHORT usLastCharIndex
+		
+		fd.add_u16 (glyf_table.get_first_char ()); // USHORT usFirstCharIndex
+		fd.add_u16 (glyf_table.get_last_char ()); // USHORT usLastCharIndex
 
 		fd.add_16 (0); // SHORT sTypoAscender
 		fd.add_16 (0); // SHORT sTypoDescender
@@ -2528,18 +2618,18 @@ class PostTable : Table { 			return;
 		}
 		
-		print (@"format: $(format.get_string ())\n");
-		print (@"italic: $(italic.get_string ())\n");
-		print (@"underlie_pos: $(underlie_pos)\n");
-		print (@"underlie_thickness: $(underlie_thickness)\n");
-		print (@"is_fixed_pitch: $(is_fixed_pitch)\n");
-		print (@"mem_min42: $(mem_min42)\n");
-		print (@"mem_max42: $(mem_max42)\n");
-		print (@"mem_min1: $(mem_min1)\n");
-		print (@"mem_max1: $(mem_max1)\n");
-		print (@"\n");
+		printd (@"format: $(format.get_string ())\n");
+		printd (@"italic: $(italic.get_string ())\n");
+		printd (@"underlie_pos: $(underlie_pos)\n");
+		printd (@"underlie_thickness: $(underlie_thickness)\n");
+		printd (@"is_fixed_pitch: $(is_fixed_pitch)\n");
+		printd (@"mem_min42: $(mem_min42)\n");
+		printd (@"mem_max42: $(mem_max42)\n");
+		printd (@"mem_min1: $(mem_min1)\n");
+		printd (@"mem_max1: $(mem_max1)\n");
+		printd (@"\n");
 		
-		print (@"Num names: $(nnames)\n");
+		printd (@"Num names: $(nnames)\n");
 		
 		uint16 k;
 		int non_standard_names = 0;
@@ -3994,7 +4084,7 @@ class DirectoryTable : Table { 		hhea_table.process ();
 		maxp_table.process ();
 		name_table.process ();
-		os_2_table.process ();
+		os_2_table.process (glyf_table);
 		loca_table.process (glyf_table, head_table);
 		post_table.process ();
 		
@@ -4007,9 +4097,9 @@ class DirectoryTable : Table { 			tables.append (offset_table);
 			tables.append (this);
 
-			tables.append (cmap_table);  // The other required tables
-			tables.append (glyf_table);
 			tables.append (head_table);
+			tables.append (cmap_table);
+			tables.append (glyf_table);
 			tables.append (hhea_table);
 			tables.append (hmtx_table);
 			tables.append (loca_table);
@@ -4046,7 +4136,7 @@ class DirectoryTable : Table { 			offset = dis.read_ulong ();
 			length = dis.read_ulong ();
 			
-			print (@"$(tag.str) \toffset: $offset \tlength: $length \tchecksum: $checksum.\n");
+			printd (@"$(tag.str) \toffset: $offset \tlength: $length \tchecksum: $checksum.\n");
 			
 			if (tag.str == "hmtx") {
 				hmtx_table.id = tag.str;
@@ -4109,18 +4199,14 @@ class DirectoryTable : Table { 		fd.print ();
 		*/
 		
-		print (@"fd.write_table (dis, post_table.offset, post_table.length) $(post_table.offset) $(post_table.length)\n");
+		printd (@"fd.write_table (dis, post_table.offset, post_table.length) $(post_table.offset) $(post_table.length)\n");
 		
 		head_table.parse (dis);
-
-		if (!validate_checksum_for_entire_font (dis, file)) {
-			warning ("file has invalid checksum");
-		}
-					
+		
 		if (!validate_tables (dis, file)) {
 			warning ("Missing required table or bad checksum.");
 			// Fixa: stop processing here, if we want to avoid loading bad fonts
-			// return;
+			return;
 		}
 		
 		post_table.parse (dis);
@@ -4136,22 +4222,35 @@ class DirectoryTable : Table { 	
 	public bool validate_tables (OtfInputStream dis, File file) {
 		bool valid = true;
-
+		uint p = head_table.get_checksum_position ();
+		FontData fd = new FontData ();	
+		uint32 checksum;
+		
 		try {
-			
-			if (!glyf_table.validate (dis)) {
-				warning ("glyf_table has invalid checksum");
-				valid = false;
+
+			if (!validate_checksum_for_entire_font (dis, file)) {
+				warning ("file has invalid checksum");
 			}
+							
+			fd.write_table (dis, head_table.offset, head_table.length);
 			
-			// head checksum is calculated without checksum adjustment for entire file 
-			// skip validation for now.
-			/*
-			if (!head_table.validate (dis)) {
+			// zero out checksum entry in head table before validating it
+			fd.write_at (p + 0, 0);
+			fd.write_at (p + 1, 0);
+			fd.write_at (p + 2, 0);
+			fd.write_at (p + 3, 0);	
+
+			checksum = (uint32) fd.check_sum ();	
+			
+			if (checksum != head_table.checksum) {
 				warning ("head_table has is invalid checksum");
+				valid = false;				
+			}
+			
+			if (!glyf_table.validate (dis)) {
+				warning ("glyf_table has invalid checksum");
 				valid = false;
 			}
-			*/
 			
 			if (!maxp_table.validate (dis)) {
 				warning ("maxp_table has is invalid checksum");
@@ -4202,7 +4301,7 @@ class DirectoryTable : Table { 	
 	bool validate_checksum_for_entire_font (OtfInputStream dis, File f) {
 		FontData fd = new FontData ();
-		uint p = head_table.get_checksum_position ();
+		uint p = head_table.offset + head_table.get_checksum_position ();
 		FileInfo file_info = f.query_info ("*", FileQueryInfoFlags.NONE);
 		uint32 checksum_font, checksum_head;
 		uint32 file_size = (uint32) file_info.get_size ();
@@ -4212,17 +4311,13 @@ class DirectoryTable : Table { 			return false;
 		}
 		
-        stdout.printf ("File size: %lld bytes\n", file_info.get_size ());
-        
-        print ("WRITE\n");
         try {
 			fd.write_table (dis, 0, file_size);
 		} catch (GLib.Error e) {
 			warning (@"Failed to compute checksum since $(e.message)");
 		}
-		print ("WRITTEN\n");
 		
-		// zero out checksum entry in head table before calculating it
+		// zero out checksum entry in head table before validating it
 		fd.write_at (p + 0, 0);
 		fd.write_at (p + 1, 0);
 		fd.write_at (p + 2, 0);
@@ -4236,8 +4331,6 @@ class DirectoryTable : Table { 			return false;
 		}
 		
-		print ("Checksum for font is valid.\n");
-		
 		return true;
 	}
 	
@@ -4302,7 +4395,7 @@ class DirectoryTable : Table { 				continue;
 			}
 			
-			print (@"c $(t.id)  offset: $(table_offset)  len with pad  $(t.get_font_data ().length_with_padding ())\n");
+			printd (@"c $(t.id)  offset: $(table_offset)  len with pad  $(t.get_font_data ().length_with_padding ())\n");
 
 			table_length = t.get_font_data ().length (); // without padding
 			
@@ -4326,4 +4419,11 @@ class DirectoryTable : Table { 	
 }
 
+// We could benifit greatly from error detection and validation at a fine grained level in
+// this class. At some later point should this code present meaningfull info to the user but 
+// for now is the approach just to put a lot of info in the console if we need to do some debugging.
+void printd (string s) {
+	print (s);
+}
+
 }
diff --git a/src/TestCases.vala b/src/TestCases.valaindex b498e46..2c2c546 100644--- a/src/TestCases.vala+++ b/src/TestCases.vala@@ -23,6 +23,7 @@ class TestCases { 	public List<Test> test_cases;  	public TestCases () {+		add (test_data_reader, "Font data reader"); 		add (test_argument, "Argument list"); 		add (test_glyph_ranges, "Glyph ranges"); 		add (test_glyph_table, "Glyph table");@@ -37,6 +38,27 @@ class TestCases { 		add (test_save_backup, "Save backup"); 	} +	public static void test_data_reader () {+		FontData fd = new FontData ();+		+		fd.add (7);+		fd.add_ulong (0x5F0F3CF5);+		fd.add_ulong (9);+		+		warn_if_fail (fd.table_data[0] == 7);+		warn_if_fail (fd.read () == 7);+		warn_if_fail (fd.read_ulong () == 0x5F0F3CF5);+		warn_if_fail (fd.read_ulong () == 9);+		+		fd = new FontData ();+		for (int16 i = 0; i < 2048; i++) {+			fd.add_short (i);+		}+		+		fd.seek (2 * 80);+		warn_if_fail (fd.read_short () == 80);+	}+ 	public static void test_argument () { 		Argument arg = new Argument ("supplement -t \"Argument list\" --unknown -unknown --help -s"); 		

Contact

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