The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

OpenFontFormatReader.vala in libbirdfont/OpenFontFormat

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git

Revisions

View the latest version of libbirdfont/OpenFontFormat/OpenFontFormatReader.vala.
Fix compile time error
1 /* 2 Copyright (C) 2012, 2014 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 15 [SimpleType] 16 [CCode (cname = "FontFace")] 17 public extern class FontFace { 18 } 19 20 [CCode (cname = "load_freetype_font")] 21 public extern static StringBuilder? load_freetype_font (string file, out int error); 22 23 [CCode (cname = "validate_freetype_font")] 24 public extern static bool validate_freetype_font (string file); 25 26 [CCode (cname = "load_glyph")] 27 public extern static StringBuilder? load_glyph (FontFace font, uint unicode); 28 29 [CCode (cname = "open_font")] 30 public extern static FontFace* open_font (string font_file); 31 32 [CCode (cname = "close_ft_font")] 33 public extern static void close_font (FontFace* font); 34 35 namespace BirdFont { 36 37 [SimpleType] 38 [CCode (has_type_id = false)] // Vala bug 39 public struct Fixed : uint32 { 40 41 public bool @equals (uint16 upper, uint16 lower) { 42 uint32 t = (upper << 16) + lower; 43 return (t == this); 44 } 45 46 public string get_string () { 47 uint a = this >> 16; 48 return @"$(a).$(this - (a << 16))"; 49 } 50 } 51 52 [SimpleType] 53 [CCode (has_type_id = false)] // same as above 54 public struct F2Dot14 : uint32 { 55 } 56 57 errordomain BadFormat { 58 PARSE 59 } 60 61 public class OpenFontFormatReader : Object { 62 63 public DirectoryTable directory_table; 64 public FontData font_data = new FontData (); 65 66 OtfInputStream dis; 67 File file; 68 69 public OpenFontFormatReader () { 70 directory_table = new DirectoryTable (); 71 } 72 73 public void close () { 74 dis.close (); 75 } 76 77 public void parse_index (string file_name) throws Error { 78 file = File.new_for_path (file_name); 79 if (!file.query_exists ()) { 80 throw new FileError.EXIST(@"OpenFontFormatReader: file does not exist. $((!) file.get_path ())"); 81 } 82 83 dis = new OtfInputStream (file.read ()); 84 85 parse_index_tables (); 86 } 87 88 void parse_index_tables () throws Error { 89 OffsetTable offset_table; 90 91 FileInfo file_info = file.query_info ("*", FileQueryInfoFlags.NONE); 92 uint32 file_size = (uint32) file_info.get_size (); 93 94 try { 95 font_data.write_table (dis, 0, file_size); 96 } catch (GLib.Error e) { 97 warning (@"Failed to read font data. $(e.message)"); 98 } 99 100 offset_table = new OffsetTable (directory_table); 101 offset_table.parse (font_data); 102 103 directory_table = new DirectoryTable (); 104 directory_table.set_offset_table (offset_table); 105 directory_table.parse (font_data, this); 106 } 107 108 public void parse_all_tables () throws Error { 109 directory_table.parse_all_tables (font_data, this); 110 111 if (!directory_table.validate_tables (font_data, file)) { 112 warning ("Missing required table or bad checksum."); 113 } 114 } 115 116 public void parse_kern_table () throws Error { 117 directory_table.parse_kern_table (font_data); 118 } 119 120 public void parse_cmap_table () throws Error { 121 directory_table.parse_cmap_table (font_data); 122 } 123 124 public void parse_head_table () throws Error { 125 directory_table.parse_head_table (font_data); 126 } 127 128 public void set_limits () { 129 Font f = OpenFontFormatWriter.font; 130 131 if (is_null (f)) { 132 f = BirdFont.get_current_font (); 133 } 134 135 f.top_position = get_ascender (); 136 f.top_limit = f.top_position + 5; 137 f.xheight_position = f.top_position + 5; 138 f.bottom_position = get_descender (); 139 f.bottom_limit = f.bottom_position - 5; 140 } 141 142 public double get_ascender () { 143 return directory_table.hhea_table.get_ascender (); 144 } 145 146 public double get_descender () { 147 return directory_table.hhea_table.get_descender (); 148 } 149 150 public uint32 get_head_checksum () { 151 return directory_table.head_table.get_adjusted_checksum (); 152 } 153 154 public static void append_kerning (StringBuilder bf_data, string file_name) { 155 string s = parse_kerning (file_name); 156 bf_data.append (s); 157 } 158 159 public static string parse_kerning (string file_name) { 160 KernTable kern_table; 161 CmapTable cmap_table; 162 HeadTable head_table; 163 OpenFontFormatReader reader = new OpenFontFormatReader (); 164 StringBuilder bf_kerning = new StringBuilder (); 165 unichar left, right; 166 double kerning, units_per_em; 167 uint npairs = 0; 168 169 try { 170 reader.parse_index (file_name); 171 reader.parse_kern_table (); 172 reader.parse_cmap_table (); 173 reader.parse_head_table (); 174 175 kern_table = reader.directory_table.kern_table; 176 cmap_table = reader.directory_table.cmap_table; 177 head_table = reader.directory_table.head_table; 178 179 npairs = kern_table.kerning.size; 180 181 units_per_em = HeadTable.units_per_em; 182 183 foreach (Kern k in kern_table.kerning) { 184 left = cmap_table.get_char (k.left); 185 right = cmap_table.get_char (k.right); 186 kerning = 100 * (k.kerning / units_per_em); 187 188 if (left <= 0x1F || right <= 0x1F) { 189 warning ("Ignoring kerning of control character."); 190 } else { 191 if (@"$kerning" != "0") { 192 bf_kerning.append ("<kerning left=\""); 193 bf_kerning.append (BirdFontFile.serialize_unichar (left)); 194 bf_kerning.append ("\" "); 195 bf_kerning.append ("right=\""); 196 bf_kerning.append (BirdFontFile.serialize_unichar (right)); 197 bf_kerning.append ("\" "); 198 bf_kerning.append ("hadjustment=\""); 199 bf_kerning.append (@"$kerning".replace (",", ".")); 200 bf_kerning.append ("\" />\n"); 201 } 202 } 203 } 204 } catch (GLib.Error e) { 205 warning (@"Failed to parse font. $(e.message)"); 206 } 207 208 return bf_kerning.str; 209 } 210 } 211 } 212