The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

HeadTable.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/HeadTable.vala.
Spelling
1 /* 2 Copyright (C) 2012, 2013, 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 namespace BirdFont { 16 17 public class HeadTable : OtfTable { 18 19 public int16 xmin = int16.MIN; 20 public int16 ymin = int16.MIN; 21 public int16 xmax = int16.MAX; 22 public int16 ymax = int16.MAX; 23 24 uint32 adjusted_checksum = 0; 25 26 uint16 mac_style; 27 uint16 lowest_PPEM; 28 int16 font_direction_hint; 29 30 public int16 loca_offset_size = 1; // 0 for int16 1 for int32 31 int16 glyph_data_format; 32 33 Fixed version; 34 Fixed font_revision; 35 36 uint32 magic_number; 37 38 uint16 flags; 39 40 uint64 created; 41 uint64 modified; 42 43 public static uint16 units_per_em; 44 public static double UNITS; 45 46 const uint8 BASELINE_AT_ZERO = 1 << 0; 47 const uint8 LSB_AT_ZERO = 1 << 1; 48 const uint8 SIZE_SPECIFIC_INSTRUCTIONS = 1 << 2; 49 const uint8 FORCE_PPEM_INTEGER_VALUES = 1 << 3; 50 51 GlyfTable glyf_table; 52 53 public HeadTable (GlyfTable gt) { 54 glyf_table = gt; 55 id = "head"; 56 } 57 58 /** Set default value for unit. */ 59 public static void init (int units_per_em) { 60 if (units_per_em <= 0 || units_per_em > uint16.MAX) { 61 HeadTable.units_per_em = 1024; 62 } else { 63 HeadTable.units_per_em = (uint16) units_per_em; 64 } 65 66 UNITS = 10 * (HeadTable.units_per_em / 1000.0); 67 } 68 69 public uint32 get_adjusted_checksum () { 70 return adjusted_checksum; 71 } 72 73 /** Get the units per em for generated fonts, not for fonts parsed 74 * with this library. 75 */ 76 public double get_units_per_em () { 77 return units_per_em * 10; 78 } 79 80 public override void parse (FontData dis) throws GLib.Error { 81 return_if_fail (offset > 0 && length > 0); 82 83 dis.seek (offset); 84 85 font_data = new FontData (); 86 87 version = dis.read_fixed (); 88 89 if (!version.equals (1, 0)) { 90 warning (@"Expecting head version 1.0 got $(version.get_string ())\n"); 91 } 92 93 font_revision = dis.read_fixed (); 94 adjusted_checksum = dis.read_ulong (); 95 magic_number = dis.read_ulong (); 96 97 if (magic_number != 0x5F0F3CF5) { 98 warning (@"Magic number is invalid ($(magic_number))."); 99 return; 100 } 101 102 flags = dis.read_ushort (); 103 104 if ((flags & BASELINE_AT_ZERO) > 0) { 105 printd ("Flag BASELINE_AT_ZERO has been set.\n"); 106 } 107 108 if ((flags & LSB_AT_ZERO) > 0) { 109 printd ("Flags LSB_AT_ZERO has been set.\n"); 110 } 111 112 units_per_em = dis.read_ushort (); 113 114 created = dis.read_udate (); 115 modified = dis.read_udate (); 116 117 xmin = dis.read_short (); 118 ymin = dis.read_short (); 119 120 xmax = dis.read_short (); 121 ymax = dis.read_short (); 122 123 printd (@"font boundaries:\n"); 124 printd (@"xmin: $xmin\n"); 125 printd (@"ymin: $ymin\n"); 126 printd (@"xmax: $xmax\n"); 127 printd (@"ymax: $ymax\n"); 128 129 mac_style = dis.read_ushort (); 130 lowest_PPEM = dis.read_ushort (); 131 font_direction_hint = dis.read_short (); 132 133 loca_offset_size = dis.read_short (); 134 glyph_data_format = dis.read_short (); 135 136 if (glyph_data_format != 0) { 137 warning (@"Unknown glyph data format. Expecting 0 got $glyph_data_format."); 138 } 139 140 printd (@"Version: $(version.get_string ())\n"); 141 printd (@"flags: $flags\n"); 142 printd (@"font_revision: $(font_revision.get_string ())\n"); 143 printd (@"flags: $flags\n"); 144 printd (@"Units per em: $units_per_em\n"); 145 printd (@"lowest_PPEM: $lowest_PPEM\n"); 146 printd (@"font_direction_hint: $font_direction_hint\n"); 147 printd (@"loca_offset_size: $loca_offset_size\n"); 148 printd (@"glyph_data_format: $glyph_data_format\n"); 149 150 // Some deprecated values follow here ... 151 } 152 153 public uint32 get_font_checksum () { 154 return adjusted_checksum; 155 } 156 157 public void set_check_sum_adjustment (uint32 csa) { 158 this.adjusted_checksum = csa; 159 } 160 161 public uint32 get_checksum_position () { 162 return 8; 163 } 164 165 public void process () throws GLib.Error { 166 FontData font_data = new FontData (); 167 Fixed version = 1 << 16; 168 Fixed font_revision = 1 << 16; 169 uint64 time = (uint64) Math.rint (GLib.get_real_time () / 1000000.0); 170 const uint64 time_diff = 60 * 60 * 24 * (365 * (1970 - 1904) + 17); // FIXME: add leap seconds 171 172 font_data.add_fixed (version); 173 font_data.add_fixed (font_revision); 174 175 // Zero on the first run and updated by directory tables checksum calculation 176 // for the entire font. 177 font_data.add_u32 (adjusted_checksum); 178 179 font_data.add_u32 (0x5F0F3CF5); // magic number 180 181 // FIXME: delete LSB_AT_ZERO? 182 183 // flags 184 font_data.add_u16 (BASELINE_AT_ZERO | LSB_AT_ZERO | FORCE_PPEM_INTEGER_VALUES); 185 186 font_data.add_u16 (units_per_em); // units per em (should be a power of two for ttf fonts) 187 188 font_data.add_u64 (time + time_diff); // creation time since 1901-01-01 189 font_data.add_u64 (time + time_diff); // modified time since 1901-01-01 190 191 xmin = glyf_table.xmin; 192 ymin = glyf_table.ymin; 193 xmax = glyf_table.xmax; 194 ymax = glyf_table.ymax; 195 196 printd (@"font boundaries:\n"); 197 printd (@"xmin: $xmin\n"); 198 printd (@"ymin: $ymin\n"); 199 printd (@"xmax: $xmax\n"); 200 printd (@"ymax: $ymax\n"); 201 202 font_data.add_short (xmin); 203 font_data.add_short (ymin); 204 font_data.add_short (xmax); 205 font_data.add_short (ymax); 206 207 font_data.add_u16 (0); // mac style 208 font_data.add_u16 (8); // smallest recommended size in pixels, ppem 209 font_data.add_16 (2); // deprecated direction hint 210 font_data.add_16 (loca_offset_size); // long offset 211 font_data.add_16 (0); // Use current glyph data format 212 213 font_data.pad (); 214 215 this.font_data = font_data; 216 } 217 } 218 219 } 220