The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

FontData.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/FontData.vala.
Spelling
1 /* 2 Copyright (C) 2012 2013 2014 2015 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 FontData : Object { 18 19 // Read pointer 20 uint rp = 0; 21 22 // Write pointer 23 uint wp = 0; 24 25 uint32 len = 0; 26 uint32 padding = 0; 27 28 uint32 capacity; 29 30 public uint8* table_data = null; 31 32 public FontData (uint32 size = 1024) { 33 capacity = size; 34 table_data = malloc (size); 35 } 36 37 ~FontData () { 38 if (table_data != null) { 39 delete table_data; 40 table_data = null; 41 } 42 } 43 44 public int get_read_pos () { 45 return (int) rp; 46 } 47 48 public void write_at (uint pos, uint8 new_data) throws GLib.Error 49 requires (pos <= capacity) 50 { 51 if (unlikely (pos >= len)) { 52 warning ("end of table reached"); 53 assert (false); 54 } 55 56 table_data[pos]= new_data; 57 } 58 59 public void write_table (OtfInputStream dis, uint32 offset, uint32 length) throws Error { 60 uint32 l = length + (length % 4); // padding after end of table 61 uint8 b; 62 63 if (length >= l) { 64 expand (l); 65 } 66 67 if (table_data == null) { 68 warning ("Failed to allocate memory for ttf data."); 69 return; 70 } 71 72 seek (0); 73 dis.seek (offset); 74 75 wp = 0; 76 while (wp < l) { 77 b = dis.read_byte (); 78 add (b); 79 } 80 81 rp = 0; 82 } 83 84 public uint length_with_padding () { 85 return len; 86 } 87 88 public uint length () { 89 return len - padding; 90 } 91 92 public void pad () { 93 while (len % 4 != 0) { 94 add (0); 95 padding++; 96 } 97 } 98 99 /** Add additional checksum data to this checksum. */ 100 public void continous_checksum (ref uint32 current_checksum) { 101 uint trp = rp; 102 uint l; 103 104 if (length_with_padding () % 4 != 0) { 105 warning ("OtfTable is not padded to correct size."); 106 } 107 108 seek (0); 109 110 l = (length () % 4 > 0) ? length () / 4 + 1 : length () / 4; 111 112 for (uint32 i = 0; i < l; i++) { 113 current_checksum += read_uint32 (); 114 } 115 116 rp = trp; 117 118 return; 119 } 120 121 public uint32 checksum () { 122 uint32 sum = 0; 123 continous_checksum (ref sum); 124 return sum; 125 } 126 127 public void seek_end () { 128 seek (len); 129 } 130 131 public void seek (uint i) { 132 rp = i; 133 wp = i; 134 } 135 136 public void seek_relative (uint i) { 137 rp += i; 138 wp += i; 139 } 140 141 /** Returns true if next byte is a CFF operator */ 142 public bool next_is_operator () { 143 uint8 o = read (); 144 seek_relative (-1); 145 return (0 <= o <=21); 146 } 147 148 public uint8 read () { 149 if (unlikely (rp >= len)) { 150 warning ("end of table reached"); 151 return 0; 152 } 153 154 return table_data [rp++]; 155 } 156 157 public Fixed read_fixed () { 158 return (Fixed) read_uint32 (); 159 } 160 161 public uint32 read_ulong () { 162 return read_uint32 (); 163 } 164 165 public uint16 read_ushort () { 166 uint16 f; 167 f = read () << 8; 168 f += read (); 169 return f; 170 } 171 172 public int16 read_int16 () { 173 int16 f; 174 f = read () << 8; 175 f += read (); 176 return f; 177 } 178 179 public int16 read_short () throws Error { 180 return read_int16 (); 181 } 182 183 public uint32 read_uint32 () { 184 uint32 f; 185 f = read () << 8 * 3; 186 f += read () << 8 * 2; 187 f += read () << 8 * 1; 188 f += read () << 8 * 0; 189 return f; 190 } 191 192 public uint64 read_uint64 () { 193 uint64 f; 194 f = (uint64) read () << 8 * 7; 195 f += (uint64) read () << 8 * 6; 196 f += (uint64) read () << 8 * 5; 197 f += (uint64) read () << 8 * 4; 198 f += (uint64) read () << 8 * 3; 199 f += (uint64) read () << 8 * 2; 200 f += (uint64) read () << 8 * 1; 201 f += (uint64) read () << 8 * 0; 202 return f; 203 } 204 205 public F2Dot14 read_f2dot14 () throws Error { 206 F2Dot14 f = (F2Dot14) read_int16 (); 207 return f; 208 } 209 210 public uint64 read_udate () throws Error { 211 return read_uint64 (); 212 } 213 214 public uint8 read_byte () throws Error { 215 return read (); 216 } 217 218 public char read_char () throws Error { 219 return (char) read_byte (); 220 } 221 222 public string read_string (uint length) throws Error { 223 StringBuilder str = new StringBuilder (); 224 char c; 225 for (int i = 0; i < length; i++) { 226 c = read_char (); 227 str.append_c (c); 228 } 229 return str.str; 230 } 231 232 public int read_charstring_value () throws Error { 233 uint8 a, b; 234 a = read (); 235 236 if (32 <= a <= 246) { 237 return a - 139; 238 } 239 240 b = read (); 241 242 if (247 <= a <= 250) { 243 return (a - 247) * 256 + b + 108; 244 } 245 246 if (251 <= a <= 254) { 247 return -((a - 251) * 256) - b - 108; 248 } 249 250 if (a == 255) { 251 // Implement it 252 warning ("fractions not implemented yet."); 253 } 254 255 stderr.printf (@"unexpected value: $a\n"); 256 warn_if_reached (); 257 return 0; 258 } 259 260 public void add_fixed (Fixed f) throws Error { 261 add_u32 (f); 262 } 263 264 public void add_short (int16 d) throws Error { 265 add_16 (d); 266 } 267 268 public void add_ushort (uint16 d) throws Error { 269 add_u16 (d); 270 } 271 272 public void add_ulong (uint32 d) throws Error { 273 add_u32 (d); 274 } 275 276 public void add_byte (uint8 b) throws Error { 277 add (b); 278 } 279 280 private void expand (uint extra_bytes = 1024) { 281 capacity += extra_bytes; 282 table_data = (uint8*) try_realloc (table_data, capacity); 283 284 if (table_data == null) { 285 warning ("Out of memory."); 286 capacity = 0; 287 } 288 } 289 290 public void add (uint8 d) { 291 if (unlikely (len == capacity)) { 292 expand (); 293 } 294 295 table_data[wp] = d; 296 297 if (wp == len) { 298 len++; 299 } 300 301 wp++; 302 } 303 304 public void add_littleendian_u16 (uint32 i) { 305 add ((int8) (i & 0x00FF)); 306 add ((int8) ((i & 0xFF00) >> 8)); 307 } 308 309 public void add_u16 (uint16 d) { 310 uint16 n = d >> 8; 311 add ((uint8)n); 312 add ((uint8)(d - (n << 8))); 313 } 314 315 public void add_16 (int16 i) { 316 uint8 s = (uint8) (i >> 8); 317 318 add ((uint8) s); 319 add ((uint8) (i - (s << 8))); 320 } 321 322 public void add_littleendian_u32 (uint32 i) { 323 add ((int8) (i & 0x000000FF)); 324 add ((int8) ((i & 0x0000FF00) >> 8)); 325 add ((int8) ((i & 0x00FF0000) >> 16)); 326 add ((int8) ((i & 0xFF000000) >> 24)); 327 } 328 329 public void add_u32 (uint32 i) { 330 uint32 s = (uint16) (i >> 16); 331 332 add_u16 ((uint16) s); 333 add_u16 ((uint16) (i - (s << 16))); 334 } 335 336 public void add_u64(uint64 i) { 337 uint64 s = (uint32) (i >> 32); 338 339 add_u32 ((uint32) s); 340 add_u32 ((uint32)(i - (s << 32))); 341 } 342 343 public void add_str_littleendian_utf16 (string s) { 344 add_str_utf16 (s, true); 345 } 346 347 public void add_str_utf16 (string s, bool little_endian = false) { 348 int index = 0; 349 unichar c; 350 uint8 c0; 351 uint8 c1; 352 int l = 0; 353 354 while (s.get_next_char (ref index, out c)) { 355 if (c <= 0x7FFF) { 356 c0 = (uint8) (c >> 8); 357 c1 = (uint8) (c - (c0 << 8)); 358 359 if (little_endian) { 360 add (c1); 361 add (c0); 362 } else { 363 add (c0); 364 add (c1); 365 } 366 } else if (c <= 0xFFFFF) { 367 int high = (0xFFC00 & c) >> 10; 368 int low = (0x03FF & c); 369 370 high += 0xD800; 371 low += 0xDC00; 372 373 c0 = (uint8) (high >> 8); 374 c1 = (uint8) (high - (c0 << 8)); 375 376 if (little_endian) { 377 add (c1); 378 add (c0); 379 } else { 380 add (c0); 381 add (c1); 382 } 383 384 c0 = (uint8) (low >> 8); 385 c1 = (uint8) (low - (c0 << 8)); 386 387 if (little_endian) { 388 add (c1); 389 add (c0); 390 } else { 391 add (c0); 392 add (c1); 393 } 394 } else { 395 continue; 396 } 397 398 l += 2; 399 } 400 } 401 402 public static uint utf16_strlen (string s) { 403 FontData fd = new FontData (); 404 fd.add_str_utf16 (s); 405 return fd.length_with_padding (); 406 } 407 408 public void add_macroman_str (string s) { 409 int index = 0; 410 unichar c; 411 412 while (s.get_next_char (ref index, out c)) { 413 if (32 <= c <= 127) { 414 add ((uint8) c); 415 } else { 416 if (c == 196) add ((uint8) 128); 417 if (c == 197) add ((uint8) 129); 418 if (c == 199) add ((uint8) 130); 419 if (c == 201) add ((uint8) 131); 420 if (c == 209) add ((uint8) 132); 421 if (c == 214) add ((uint8) 133); 422 if (c == 220) add ((uint8) 134); 423 if (c == 225) add ((uint8) 135); 424 if (c == 224) add ((uint8) 136); 425 if (c == 226) add ((uint8) 137); 426 if (c == 228) add ((uint8) 138); 427 if (c == 227) add ((uint8) 139); 428 if (c == 229) add ((uint8) 140); 429 if (c == 231) add ((uint8) 141); 430 if (c == 233) add ((uint8) 142); 431 if (c == 232) add ((uint8) 143); 432 if (c == 234) add ((uint8) 144); 433 if (c == 235) add ((uint8) 145); 434 if (c == 237) add ((uint8) 146); 435 if (c == 236) add ((uint8) 147); 436 if (c == 238) add ((uint8) 148); 437 if (c == 239) add ((uint8) 149); 438 if (c == 241) add ((uint8) 150); 439 if (c == 243) add ((uint8) 151); 440 if (c == 242) add ((uint8) 152); 441 if (c == 244) add ((uint8) 153); 442 if (c == 246) add ((uint8) 154); 443 if (c == 245) add ((uint8) 155); 444 if (c == 250) add ((uint8) 156); 445 if (c == 249) add ((uint8) 157); 446 if (c == 251) add ((uint8) 158); 447 if (c == 252) add ((uint8) 159); 448 if (c == 8224) add ((uint8) 160); 449 if (c == 176) add ((uint8) 161); 450 if (c == 162) add ((uint8) 162); 451 if (c == 163) add ((uint8) 163); 452 if (c == 167) add ((uint8) 164); 453 if (c == 8226) add ((uint8) 165); 454 if (c == 182) add ((uint8) 166); 455 if (c == 223) add ((uint8) 167); 456 if (c == 174) add ((uint8) 168); 457 if (c == 169) add ((uint8) 169); 458 if (c == 8482) add ((uint8) 170); 459 if (c == 180) add ((uint8) 171); 460 if (c == 168) add ((uint8) 172); 461 if (c == 8800) add ((uint8) 173); 462 if (c == 198) add ((uint8) 174); 463 if (c == 216) add ((uint8) 175); 464 if (c == 8734) add ((uint8) 176); 465 if (c == 177) add ((uint8) 177); 466 if (c == 8804) add ((uint8) 178); 467 if (c == 8805) add ((uint8) 179); 468 if (c == 165) add ((uint8) 180); 469 if (c == 181) add ((uint8) 181); 470 if (c == 8706) add ((uint8) 182); 471 if (c == 8721) add ((uint8) 183); 472 if (c == 8719) add ((uint8) 184); 473 if (c == 960) add ((uint8) 185); 474 if (c == 8747) add ((uint8) 186); 475 if (c == 170) add ((uint8) 187); 476 if (c == 186) add ((uint8) 188); 477 if (c == 937) add ((uint8) 189); 478 if (c == 230) add ((uint8) 190); 479 if (c == 248) add ((uint8) 191); 480 if (c == 191) add ((uint8) 192); 481 if (c == 161) add ((uint8) 193); 482 if (c == 172) add ((uint8) 194); 483 if (c == 8730) add ((uint8) 195); 484 if (c == 402) add ((uint8) 196); 485 if (c == 8776) add ((uint8) 197); 486 if (c == 8710) add ((uint8) 198); 487 if (c == 171) add ((uint8) 199); 488 if (c == 187) add ((uint8) 200); 489 if (c == 8230) add ((uint8) 201); 490 if (c == 160) add ((uint8) 202); 491 if (c == 192) add ((uint8) 203); 492 if (c == 195) add ((uint8) 204); 493 if (c == 213) add ((uint8) 205); 494 if (c == 338) add ((uint8) 206); 495 if (c == 339) add ((uint8) 207); 496 if (c == 8211) add ((uint8) 208); 497 if (c == 8212) add ((uint8) 209); 498 if (c == 8220) add ((uint8) 210); 499 if (c == 8221) add ((uint8) 211); 500 if (c == 8216) add ((uint8) 212); 501 if (c == 8217) add ((uint8) 213); 502 if (c == 247) add ((uint8) 214); 503 if (c == 9674) add ((uint8) 215); 504 if (c == 255) add ((uint8) 216); 505 if (c == 376) add ((uint8) 217); 506 if (c == 8260) add ((uint8) 218); 507 if (c == 8364) add ((uint8) 219); 508 if (c == 8249) add ((uint8) 220); 509 if (c == 8250) add ((uint8) 221); 510 if (c == 64257) add ((uint8) 222); 511 if (c == 64258) add ((uint8) 223); 512 if (c == 8225) add ((uint8) 224); 513 if (c == 183) add ((uint8) 225); 514 if (c == 8218) add ((uint8) 226); 515 if (c == 8222) add ((uint8) 227); 516 if (c == 8240) add ((uint8) 228); 517 if (c == 194) add ((uint8) 229); 518 if (c == 202) add ((uint8) 230); 519 if (c == 193) add ((uint8) 231); 520 if (c == 203) add ((uint8) 232); 521 if (c == 200) add ((uint8) 233); 522 if (c == 205) add ((uint8) 234); 523 if (c == 206) add ((uint8) 235); 524 if (c == 207) add ((uint8) 236); 525 if (c == 204) add ((uint8) 237); 526 if (c == 211) add ((uint8) 238); 527 if (c == 212) add ((uint8) 239); 528 if (c == 63743) add ((uint8) 240); 529 if (c == 210) add ((uint8) 241); 530 if (c == 218) add ((uint8) 242); 531 if (c == 219) add ((uint8) 243); 532 if (c == 217) add ((uint8) 244); 533 if (c == 305) add ((uint8) 245); 534 if (c == 710) add ((uint8) 246); 535 if (c == 732) add ((uint8) 247); 536 if (c == 175) add ((uint8) 248); 537 if (c == 728) add ((uint8) 249); 538 if (c == 729) add ((uint8) 250); 539 if (c == 730) add ((uint8) 251); 540 if (c == 184) add ((uint8) 252); 541 if (c == 733) add ((uint8) 253); 542 if (c == 731) add ((uint8) 254); 543 if (c == 711) add ((uint8) 255); 544 } 545 } 546 } 547 548 public static uint macroman_strlen (string s) { 549 FontData fd = new FontData (); 550 fd.add_macroman_str (s); 551 return fd.length_with_padding (); 552 } 553 554 public void add_str (string s) { 555 uint8[] data = s.data; 556 for (int n = 0; n < data.length; n++) { 557 add (data[n]); 558 } 559 } 560 561 public void add_tag (string s) 562 requires (s.length == 4 && s.data.length == 4) { 563 add_str (s); 564 } 565 566 public void add_charstring_value (int v) throws Error { 567 int w; 568 uint8 t; 569 570 if (unlikely (!(-1131 <= v <= 1131))) { 571 warning ("charstring value out of range"); 572 v = 0; 573 } 574 575 if (-107 <= v <= 107) { 576 add_byte ((uint8) (v + 139)); 577 } else if (107 < v <= 1131) { 578 // positive value 579 w = v; 580 v -= 108; 581 582 t = 0; 583 while (v >= 256) { 584 v -= 256; 585 t++; 586 } 587 588 add_byte (t + 247); 589 add_byte ((uint8) (w - 108 - (t * 256))); 590 } else if (-1131 <= v < -107) { 591 // negative value 592 v = -v - 108; 593 add_byte ((uint8) ((v >> 8) + 251)); 594 add_byte ((uint8) (v & 0xFF)); 595 } else { 596 // Todo add fraction 597 } 598 } 599 600 public void append (FontData fd) { 601 fd.seek (0); 602 for (int i = 0; i < fd.length (); i++) { 603 add (fd.read ()); 604 } 605 } 606 607 public void dump () { 608 for (uint32 i = 0; i < length_with_padding (); i++) { 609 stdout.printf ("%x " , table_data[i]); 610 } 611 stdout.printf ("\n"); 612 } 613 } 614 615 } 616