Clone in a terminal:
OpenFontFormatReader.vala
/*
    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
internal 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
internal struct F2Dot14 : uint32 {
}

errordomain BadFormat {
	PARSE
}

class OpenFontFormatReader : Object {
	
	public DirectoryTable directory_table;
	
	OtfInputStream dis;
	File file;
	
	public OpenFontFormatReader () {
		directory_table = new DirectoryTable ();
	}
	
	public void close () {
		dis.close ();
	}
	
	public Glyph? read_glyph (string name) {
		try {
			return directory_table.glyf_table.read_glyph (name);
		} catch (GLib.Error e) {
			warning (e.message);
		}
		
		return null;
	}
	
	public void parse_index (string file_name) throws Error {
		file = File.new_for_path (file_name);
		if (!file.query_exists ()) {
			throw new FileError.EXIST(@"OpenFontFormatReader: file does not exist. $((!) file.get_path ())");
		}
			
		dis = new OtfInputStream (file.read ());
		
		parse_index_tables ();
	}
	
	void parse_index_tables () throws Error {
		OffsetTable offset_table;
		FontData fd = new FontData ();
		
		FileInfo file_info = file.query_info ("*", FileQueryInfoFlags.NONE);
		uint32 file_size = (uint32) file_info.get_size ();

        try {
			fd.write_table (dis, 0, file_size);
		} catch (GLib.Error e) {
			warning (@"Failed to read font data. $(e.message)");
		}

		offset_table = new OffsetTable (directory_table);
		offset_table.parse (fd);
		
		directory_table = new DirectoryTable ();
		directory_table.set_offset_table (offset_table);
		directory_table.parse (fd, file, this);
	}

	public void set_limits () {
		Font f = OpenFontFormatWriter.font;
		
		if (is_null (f)) {
			f = Supplement.get_current_font ();
		}
		
		f.top_position = -get_ascender ();
		f.top_limit = f.top_position - 5;
		f.xheight_position = f.top_position - 5;
		f.bottom_position = -get_descender ();
		f.bottom_limit = f.bottom_position + 5;	
	}

	public double get_ascender () {
		return directory_table.hhea_table.get_ascender ();
	}
	
	public double get_descender () {
		return directory_table.hhea_table.get_descender ();
	}

	public unowned List<string> get_all_names () {
		return directory_table.post_table.get_all_names ();
	}
	
	public uint32 get_head_checksum () {
		return directory_table.head_table.get_adjusted_checksum ();
	}
}
}

Contact

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