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