The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

LocaTable.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/LocaTable.vala.
Fix zero length handles in Beziér tool
1 /* 2 Copyright (C) 2012, 2013 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 LocaTable : OtfTable { 18 19 uint32* glyph_offsets = null; 20 public uint32 size = 0; 21 22 public LocaTable () { 23 id = "loca"; 24 } 25 26 ~LocaTable () { 27 if (glyph_offsets != null) { 28 delete glyph_offsets; 29 } 30 } 31 32 public uint32 get_offset (uint32 i) { 33 return_val_if_fail (glyph_offsets != null, 0); 34 35 if (size == 0) { 36 warning ("No glyphs in loca table"); 37 } 38 39 if (!(0 <= i < size + 1)) { 40 warning (@"No offset for glyph $i. Requires (0 <= $i < $(size + 1)"); 41 } 42 43 return glyph_offsets [i]; 44 } 45 46 /** Returns true if glyph at index i is empty and have no body to parse. */ 47 public bool is_empty (uint32 i) { 48 return_val_if_fail (glyph_offsets != null, true); 49 50 if (size == 0) { 51 warning ("No glyphs in loca table"); 52 } 53 54 if (!(0 <= i < size + 1)) { 55 warning (@"No offset for glyph $i. Requires (0 <= $i < $(size + 1)"); 56 } 57 58 return glyph_offsets[i] == glyph_offsets[i + 1]; 59 } 60 61 public new void parse (FontData dis, HeadTable head_table, MaxpTable maxp_table) throws GLib.Error { 62 size = maxp_table.num_glyphs; 63 glyph_offsets = new uint32[size + 1]; 64 65 dis.seek (offset); 66 67 printd (@"size: $size\n"); 68 printd (@"length: $length\n"); 69 printd (@"length/4-1: $(length / 4 - 1)\n"); 70 printd (@"length/2-1: $(length / 2 - 1)\n"); 71 printd (@"head_table.loca_offset_size: $(head_table.loca_offset_size)\n"); 72 73 switch (head_table.loca_offset_size) { 74 case 0: 75 for (long i = 0; i < size + 1; i++) { 76 glyph_offsets[i] = 2 * dis.read_ushort (); 77 78 if (0 < i < size && glyph_offsets[i - 1] > glyph_offsets[i]) { 79 warning (@"Invalid loca table, it must be sorted. ($(glyph_offsets[i - 1]) > $(glyph_offsets[i]))"); 80 } 81 } 82 break; 83 84 case 1: 85 for (long i = 0; i < size + 1; i++) { 86 glyph_offsets[i] = dis.read_ulong (); 87 88 if (0 < i < size && glyph_offsets[i - 1] > glyph_offsets[i]) { 89 warning (@"Invalid loca table, it must be sorted. ($(glyph_offsets[i - 1]) > $(glyph_offsets[i]))"); 90 } 91 } 92 93 break; 94 95 default: 96 warning ("unknown size for offset in loca table"); 97 break; 98 } 99 } 100 101 public void process (GlyfTable glyf_table, HeadTable head_table) { 102 FontData fd = new FontData (); 103 uint32 last = 0; 104 uint32 prev = 0; 105 int i = 0; 106 107 foreach (uint32 o in glyf_table.location_offsets) { 108 if (i != 0 && (o - prev) % 4 != 0) { 109 warning (@"glyph length is not a multiple of four in gid $i"); 110 } 111 112 if (o % 4 != 0) { 113 warning ("glyph is not on a four byte boundary"); 114 assert_not_reached (); 115 } 116 117 prev = o; 118 i++; 119 } 120 121 if (head_table.loca_offset_size == 0) { 122 foreach (uint32 o in glyf_table.location_offsets) { 123 fd.add_u16 ((uint16) (o / 2)); 124 125 if (o < last) { 126 warning (@"Loca table must be sorted. ($o < $last)"); 127 } 128 129 last = o; 130 } 131 } else if (head_table.loca_offset_size == 1) { 132 foreach (uint32 o in glyf_table.location_offsets) { 133 fd.add_u32 (o); 134 135 if (o < last) { 136 warning (@"Loca table must be sorted. ($o < $last)"); 137 } 138 139 last = o; 140 } 141 } else { 142 warn_if_reached (); 143 } 144 145 if (!(glyf_table.location_offsets.size == glyf_table.glyphs.size + 1)) { 146 warning ("Bad location offset."); 147 } 148 149 fd.pad (); 150 font_data = fd; 151 } 152 } 153 154 } 155