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.
Use other types of graphical objects
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 // FIXME: set guides to ascent & descent 136 } 137 138 public uint32 get_head_checksum () { 139 return directory_table.head_table.get_adjusted_checksum (); 140 } 141 142 public static void append_kerning (StringBuilder bf_data, string file_name) { 143 string s = parse_kerning (file_name); 144 bf_data.append (s); 145 } 146 147 public static string parse_kerning (string file_name) { 148 KernTable kern_table; 149 CmapTable cmap_table; 150 HeadTable head_table; 151 OpenFontFormatReader reader = new OpenFontFormatReader (); 152 StringBuilder bf_kerning = new StringBuilder (); 153 unichar left, right; 154 double kerning, units_per_em; 155 uint npairs = 0; 156 157 try { 158 reader.parse_index (file_name); 159 reader.parse_kern_table (); 160 reader.parse_cmap_table (); 161 reader.parse_head_table (); 162 163 kern_table = reader.directory_table.kern_table; 164 cmap_table = reader.directory_table.cmap_table; 165 head_table = reader.directory_table.head_table; 166 167 npairs = kern_table.kerning.size; 168 169 units_per_em = HeadTable.units_per_em; 170 171 foreach (Kern k in kern_table.kerning) { 172 left = cmap_table.get_char (k.left); 173 right = cmap_table.get_char (k.right); 174 kerning = 100 * (k.kerning / units_per_em); 175 176 if (left <= 0x1F || right <= 0x1F) { 177 warning ("Ignoring kerning of control character."); 178 } else { 179 if (@"$kerning" != "0") { 180 bf_kerning.append ("<kerning left=\""); 181 bf_kerning.append (BirdFontFile.serialize_unichar (left)); 182 bf_kerning.append ("\" "); 183 bf_kerning.append ("right=\""); 184 bf_kerning.append (BirdFontFile.serialize_unichar (right)); 185 bf_kerning.append ("\" "); 186 bf_kerning.append ("hadjustment=\""); 187 bf_kerning.append (@"$kerning".replace (",", ".")); 188 bf_kerning.append ("\" />\n"); 189 } 190 } 191 } 192 } catch (GLib.Error e) { 193 warning (@"Failed to parse font. $(e.message)"); 194 } 195 196 return bf_kerning.str; 197 } 198 } 199 } 200