1% texfont.w 2% 3% Copyright 2006-2013 Taco Hoekwater <taco@@luatex.org> 4% 5% This file is part of LuaTeX. 6% 7% LuaTeX is free software; you can redistribute it and/or modify it under 8% the terms of the GNU General Public License as published by the Free 9% Software Foundation; either version 2 of the License, or (at your 10% option) any later version. 11% 12% LuaTeX is distributed in the hope that it will be useful, but WITHOUT 13% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15% License for more details. 16% 17% You should have received a copy of the GNU General Public License along 18% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. 19 20@* Main font API implementation for the original pascal parts. 21 22Stuff to watch out for: 23 24\item{} Knuth had a |'null_character'| that was used when a character could 25not be found by the |fetch()| routine, to signal an error. This has 26been deleted, but it may mean that the output of luatex is 27incompatible with TeX after |fetch()| has detected an error condition. 28 29\item{} Knuth also had a |font_glue()| optimization. I've removed that 30because it was a bit of dirty programming and it also was 31problematic |if 0 != null|. 32 33@c 34 35 36#include "ptexlib.h" 37#include "lua/luatex-api.h" 38 39@ @c 40#define noDEBUG 41 42#define proper_char_index(c) (c<=font_ec(f) && c>=font_bc(f)) 43#define do_realloc(a,b,d) a = xrealloc(a,(unsigned)((unsigned)(b)*sizeof(d))) 44 45texfont **font_tables = NULL; 46 47static int font_arr_max = 0; 48static int font_id_maxval = 0; 49 50@ @c 51static void grow_font_table(int id) 52{ 53 int j; 54 if (id >= font_arr_max) { 55 font_bytes += 56 (int) (((id + 8 - font_arr_max) * (int) sizeof(texfont *))); 57 font_tables = 58 xrealloc(font_tables, 59 (unsigned) (((unsigned) id + 8) * sizeof(texfont *))); 60 j = 8; 61 while (j--) { 62 font_tables[id + j] = NULL; 63 } 64 font_arr_max = id + 8; 65 } 66} 67 68int new_font_id(void) 69{ 70 int i; 71 for (i = 0; i < font_arr_max; i++) { 72 if (font_tables[i] == NULL) { 73 break; 74 } 75 } 76 if (i >= font_arr_max) 77 grow_font_table(i); 78 if (i > font_id_maxval) 79 font_id_maxval = i; 80 return i; 81} 82 83int max_font_id(void) 84{ 85 return font_id_maxval; 86} 87 88void set_max_font_id(int i) 89{ 90 font_id_maxval = i; 91} 92 93@ @c 94int new_font(void) 95{ 96 int k; 97 int id; 98 charinfo *ci; 99 id = new_font_id(); 100 font_bytes += (int) sizeof(texfont); 101 /* most stuff is zero */ 102 font_tables[id] = xcalloc(1, sizeof(texfont)); 103 font_tables[id]->_font_name = NULL; 104 font_tables[id]->_font_area = NULL; 105 font_tables[id]->_font_filename = NULL; 106 font_tables[id]->_font_fullname = NULL; 107 font_tables[id]->_font_psname = NULL; 108 font_tables[id]->_font_encodingname = NULL; 109 font_tables[id]->_font_cidregistry = NULL; 110 font_tables[id]->_font_cidordering = NULL; 111 font_tables[id]->_left_boundary = NULL; 112 font_tables[id]->_right_boundary = NULL; 113 font_tables[id]->_param_base = NULL; 114 font_tables[id]->_math_param_base = NULL; 115 116 set_font_bc(id, 1); /* ec = 0 */ 117 set_hyphen_char(id, '-'); 118 set_skew_char(id, -1); 119 font_slant(id) = 0; /* vertical */ 120 font_extend(id) = 1000; /* normal width */ 121 122 /* allocate eight values including 0 */ 123 set_font_params(id, 7); 124 for (k = 0; k <= 7; k++) { 125 set_font_param(id, k, 0); 126 } 127 /* character info zero is reserved for notdef */ 128 font_tables[id]->characters = new_sa_tree(1, 0); /* stack size 1, default item value 0 */ 129 130 ci = xcalloc(1, sizeof(charinfo)); 131 set_charinfo_name(ci, xstrdup(".notdef")); 132 font_tables[id]->charinfo = ci; 133 font_tables[id]->charinfo_size = 1; 134 font_tables[id]->charinfo_cache = NULL; 135 136 return id; 137} 138 139@ @c 140void font_malloc_charinfo(internal_font_number f, int num) 141{ 142 int glyph = font_tables[f]->charinfo_size; 143 font_bytes += (int) (num * (int) sizeof(charinfo)); 144 do_realloc(font_tables[f]->charinfo, (unsigned) (glyph + num), charinfo); 145 memset(&(font_tables[f]->charinfo[glyph]), 0, 146 (size_t) (num * (int) sizeof(charinfo))); 147 font_tables[f]->charinfo_size += num; 148} 149 150@ @c 151#define find_charinfo_id(f,c) get_sa_item(font_tables[f]->characters,c) 152 153charinfo *get_charinfo(internal_font_number f, int c) 154{ 155 sa_tree_item glyph; 156 charinfo *ci; 157 if (proper_char_index(c)) { 158 glyph = get_sa_item(font_tables[f]->characters, c); 159 if (!glyph) { 160 161 int tglyph = ++font_tables[f]->charinfo_count; 162 if (tglyph >= font_tables[f]->charinfo_size) { 163 font_malloc_charinfo(f, 256); 164 } 165 font_tables[f]->charinfo[tglyph].ef = 1000; /* init */ 166 set_sa_item(font_tables[f]->characters, c, (sa_tree_item) tglyph, 1); /* 1= global */ 167 glyph = (sa_tree_item) tglyph; 168 } 169 return &(font_tables[f]->charinfo[glyph]); 170 } else if (c == left_boundarychar) { 171 if (left_boundary(f) == NULL) { 172 ci = xcalloc(1, sizeof(charinfo)); 173 font_bytes += (int) sizeof(charinfo); 174 set_left_boundary(f, ci); 175 } 176 return left_boundary(f); 177 } else if (c == right_boundarychar) { 178 if (right_boundary(f) == NULL) { 179 ci = xcalloc(1, sizeof(charinfo)); 180 font_bytes += (int) sizeof(charinfo); 181 set_right_boundary(f, ci); 182 } 183 return right_boundary(f); 184 } 185 return &(font_tables[f]->charinfo[0]); 186} 187 188@ @c 189static void set_charinfo(internal_font_number f, int c, charinfo * ci) 190{ 191 sa_tree_item glyph; 192 if (proper_char_index(c)) { 193 glyph = get_sa_item(font_tables[f]->characters, c); 194 if (glyph) { 195 font_tables[f]->charinfo[glyph] = *ci; 196 } else { 197 luatex_fail("font: %s", "character insertion failed"); 198 } 199 } else if (c == left_boundarychar) { 200 set_left_boundary(f, ci); 201 } else if (c == right_boundarychar) { 202 set_right_boundary(f, ci); 203 } 204} 205 206@ @c 207charinfo *copy_charinfo(charinfo * ci) 208{ 209 int x, k; 210 kerninfo *kern; 211 liginfo *lig; 212 eight_bits *packet; 213 charinfo *co = NULL; 214 if (ci == NULL) 215 return NULL; 216 co = xmalloc(sizeof(charinfo)); 217 memcpy(co, ci, sizeof(charinfo)); 218 set_charinfo_used(co, false); 219 co->name = NULL; 220 co->tounicode = NULL; 221 co->packets = NULL; 222 co->ligatures = NULL; 223 co->kerns = NULL; 224 co->vert_variants = NULL; 225 co->hor_variants = NULL; 226 if (ci->name != NULL) { 227 co->name = xstrdup(ci->name); 228 } 229 if (ci->tounicode != NULL) { 230 co->tounicode = xstrdup(ci->tounicode); 231 } 232 /* kerns */ 233 if ((kern = get_charinfo_kerns(ci)) != NULL) { 234 x = 0; 235 while (!kern_end(kern[x])) { 236 x++; 237 } 238 x++; 239 co->kerns = xmalloc((unsigned) (x * (int) sizeof(kerninfo))); 240 memcpy(co->kerns, ci->kerns, (size_t) (x * (int) sizeof(kerninfo))); 241 } 242 /* ligs */ 243 if ((lig = get_charinfo_ligatures(ci)) != NULL) { 244 x = 0; 245 while (!lig_end(lig[x])) { 246 x++; 247 } 248 x++; 249 co->ligatures = xmalloc((unsigned) (x * (int) sizeof(liginfo))); 250 memcpy(co->ligatures, ci->ligatures, 251 (size_t) (x * (int) sizeof(liginfo))); 252 } 253 /* packets */ 254 if ((packet = get_charinfo_packets(ci)) != NULL) { 255 x = vf_packet_bytes(ci); 256 co->packets = xmalloc((unsigned) x); 257 memcpy(co->packets, ci->packets, (size_t) x); 258 } 259 260 /* horizontal and vertical extenders */ 261 if (get_charinfo_vert_variants(ci) != NULL) { 262 set_charinfo_vert_variants(co, 263 copy_variants(get_charinfo_vert_variants 264 (ci))); 265 } 266 if (get_charinfo_hor_variants(ci) != NULL) { 267 set_charinfo_hor_variants(co, 268 copy_variants(get_charinfo_hor_variants(ci))); 269 } 270 x = ci->top_left_math_kerns; 271 co->top_left_math_kerns = x; 272 if (x > 0) { 273 co->top_left_math_kern_array = 274 xmalloc((unsigned) (2 * (int) sizeof(scaled) * x)); 275 for (k = 0; k < co->top_left_math_kerns; k++) { 276 co->top_left_math_kern_array[(2 * k)] = 277 ci->top_left_math_kern_array[(2 * k)]; 278 co->top_left_math_kern_array[(2 * k) + 1] = 279 ci->top_left_math_kern_array[(2 * k) + 1]; 280 } 281 } 282 x = ci->top_right_math_kerns; 283 co->top_right_math_kerns = x; 284 if (x > 0) { 285 co->top_right_math_kern_array = 286 xmalloc((unsigned) (2 * (int) sizeof(scaled) * x)); 287 for (k = 0; k < co->top_right_math_kerns; k++) { 288 co->top_right_math_kern_array[(2 * k)] = 289 ci->top_right_math_kern_array[(2 * k)]; 290 co->top_right_math_kern_array[(2 * k) + 1] = 291 ci->top_right_math_kern_array[(2 * k) + 1]; 292 } 293 } 294 x = ci->bottom_right_math_kerns; 295 co->bottom_right_math_kerns = x; 296 if (x > 0) { 297 co->bottom_right_math_kern_array = 298 xmalloc((unsigned) (2 * (int) sizeof(scaled) * x)); 299 for (k = 0; k < co->bottom_right_math_kerns; k++) { 300 co->bottom_right_math_kern_array[(2 * k)] = 301 ci->bottom_right_math_kern_array[(2 * k)]; 302 co->bottom_right_math_kern_array[(2 * k) + 1] = 303 ci->bottom_right_math_kern_array[(2 * k) + 1]; 304 } 305 } 306 x = ci->bottom_left_math_kerns; 307 co->bottom_left_math_kerns = x; 308 if (x > 0) { 309 co->bottom_left_math_kern_array = 310 xmalloc((unsigned) (2 * (int) sizeof(scaled) * x)); 311 for (k = 0; k < co->bottom_left_math_kerns; k++) { 312 co->bottom_left_math_kern_array[(2 * k)] = 313 ci->bottom_left_math_kern_array[(2 * k)]; 314 co->bottom_left_math_kern_array[(2 * k) + 1] = 315 ci->bottom_left_math_kern_array[(2 * k) + 1]; 316 } 317 } 318 319 320 return co; 321} 322 323charinfo *char_info(internal_font_number f, int c) 324{ 325 if (f > font_id_maxval) 326 return 0; 327 if (proper_char_index(c)) { 328 register int glyph = (int) find_charinfo_id(f, c); 329 return &(font_tables[f]->charinfo[glyph]); 330 } else if (c == left_boundarychar && left_boundary(f) != NULL) { 331 return left_boundary(f); 332 } else if (c == right_boundarychar && right_boundary(f) != NULL) { 333 return right_boundary(f); 334 } 335 return &(font_tables[f]->charinfo[0]); 336} 337 338@ @c 339scaled_whd get_charinfo_whd(internal_font_number f, int c) 340{ 341 scaled_whd s; 342 charinfo *i; 343 i = char_info(f, c); 344 s.wd = i->width; 345 s.dp = i->depth; 346 s.ht = i->height; 347 return s; 348} 349 350@ @c 351int char_exists(internal_font_number f, int c) 352{ 353 if (f > font_id_maxval) 354 return 0; 355 if (proper_char_index(c)) { 356 return (int) find_charinfo_id(f, c); 357 } else if ((c == left_boundarychar) && has_left_boundary(f)) { 358 return 1; 359 } else if ((c == right_boundarychar) && has_right_boundary(f)) { 360 return 1; 361 } 362 return 0; 363} 364 365@ @c 366#if 0 367static int lua_char_exists_callback(internal_font_number f, int c) 368{ 369 int callback_id; 370 lua_State *L = Luas; 371 int ret = 0; 372 callback_id = callback_defined(char_exists_callback); 373 if (callback_id != 0) { 374 if (!get_callback(L, callback_id)) { 375 lua_pop(L, 2); 376 return 0; 377 } 378 lua_pushnumber(L, f); 379 lua_pushnumber(L, c); 380 if (lua_pcall(L, 2, 1, 0) != 0) { /* two args, 1 result */ 381 fprintf(stdout, "error: %s\n", lua_tostring(L, -1)); 382 lua_pop(L, 2); 383 error(); 384 } else { 385 ret = lua_toboolean(L, -1); 386 } 387 } 388 return ret; 389} 390#endif 391 392@ @c 393extinfo *new_variant(int glyph, int startconnect, int endconnect, 394 int advance, int repeater) 395{ 396 extinfo *ext; 397 ext = xmalloc(sizeof(extinfo)); 398 ext->next = NULL; 399 ext->glyph = glyph; 400 ext->start_overlap = startconnect; 401 ext->end_overlap = endconnect; 402 ext->advance = advance; 403 ext->extender = repeater; 404 return ext; 405} 406 407 408@ @c 409static extinfo *copy_variant(extinfo * old) 410{ 411 extinfo *ext; 412 ext = xmalloc(sizeof(extinfo)); 413 ext->next = NULL; 414 ext->glyph = old->glyph; 415 ext->start_overlap = old->start_overlap; 416 ext->end_overlap = old->end_overlap; 417 ext->advance = old->advance; 418 ext->extender = old->extender; 419 return ext; 420} 421 422@ @c 423static void dump_variant(extinfo * ext) 424{ 425 dump_int(ext->glyph); 426 dump_int(ext->start_overlap); 427 dump_int(ext->end_overlap); 428 dump_int(ext->advance); 429 dump_int(ext->extender); 430 return; 431} 432 433 434@ @c 435static extinfo *undump_variant(void) 436{ 437 int x; 438 extinfo *ext; 439 undump_int(x); 440 if (x == 0) 441 return NULL; 442 ext = xmalloc(sizeof(extinfo)); 443 ext->next = NULL; 444 ext->glyph = x; 445 undump_int(x); 446 ext->start_overlap = x; 447 undump_int(x); 448 ext->end_overlap = x; 449 undump_int(x); 450 ext->advance = x; 451 undump_int(x); 452 ext->extender = x; 453 return ext; 454} 455 456@ @c 457void add_charinfo_vert_variant(charinfo * ci, extinfo * ext) 458{ 459 if (ci->vert_variants == NULL) { 460 ci->vert_variants = ext; 461 } else { 462 extinfo *lst = ci->vert_variants; 463 while (lst->next != NULL) 464 lst = lst->next; 465 lst->next = ext; 466 } 467 468} 469 470@ @c 471void add_charinfo_hor_variant(charinfo * ci, extinfo * ext) 472{ 473 if (ci->hor_variants == NULL) { 474 ci->hor_variants = ext; 475 } else { 476 extinfo *lst = ci->hor_variants; 477 while (lst->next != NULL) 478 lst = lst->next; 479 lst->next = ext; 480 } 481 482} 483 484@ @c 485extinfo *copy_variants(extinfo * o) 486{ 487 extinfo *c, *t = NULL, *h = NULL; 488 while (o != NULL) { 489 c = copy_variant(o); 490 if (h == null) 491 h = c; 492 else 493 t->next = c; 494 t = c; 495 o = o->next; 496 } 497 498 return h; 499} 500 501 502@ @c 503static void dump_charinfo_variants(extinfo * o) 504{ 505 while (o != NULL) { 506 dump_variant(o); 507 o = o->next; 508 } 509 dump_int(0); 510 return; 511} 512 513@ @c 514static extinfo *undump_charinfo_variants(void) 515{ 516 extinfo *c, *t = NULL, *h = NULL; 517 c = undump_variant(); 518 while (c != NULL) { 519 if (h == null) 520 h = c; 521 else 522 t->next = c; 523 t = c; 524 c = undump_variant(); 525 } 526 return h; 527} 528 529 530@ Note that mant more small things like this are implemented 531as macros in the header file. 532@c 533void set_charinfo_width(charinfo * ci, scaled val) 534{ 535 ci->width = val; 536} 537 538void set_charinfo_height(charinfo * ci, scaled val) 539{ 540 ci->height = val; 541} 542 543void set_charinfo_depth(charinfo * ci, scaled val) 544{ 545 ci->depth = val; 546} 547 548void set_charinfo_italic(charinfo * ci, scaled val) 549{ 550 ci->italic = val; 551} 552 553void set_charinfo_top_accent(charinfo * ci, scaled val) 554{ 555 ci->top_accent = val; 556} 557 558void set_charinfo_bot_accent(charinfo * ci, scaled val) 559{ 560 ci->bot_accent = val; 561} 562 563void set_charinfo_tag(charinfo * ci, scaled val) 564{ 565 ci->tag = (char) val; 566} 567 568void set_charinfo_remainder(charinfo * ci, scaled val) 569{ 570 ci->remainder = val; 571} 572 573void set_charinfo_used(charinfo * ci, scaled val) 574{ 575 ci->used = (char) val; 576} 577 578void set_charinfo_index(charinfo * ci, scaled val) 579{ 580 ci->index = (unsigned short) val; 581} 582 583void set_charinfo_name(charinfo * ci, char *val) 584{ 585 xfree(ci->name); 586 ci->name = val; 587} 588 589void set_charinfo_tounicode(charinfo * ci, char *val) 590{ 591 xfree(ci->tounicode); 592 ci->tounicode = val; 593} 594 595void set_charinfo_ligatures(charinfo * ci, liginfo * val) 596{ 597 dxfree(ci->ligatures, val); 598} 599 600void set_charinfo_kerns(charinfo * ci, kerninfo * val) 601{ 602 dxfree(ci->kerns, val); 603} 604 605void set_charinfo_packets(charinfo * ci, eight_bits * val) 606{ 607 dxfree(ci->packets, val); 608} 609 610void set_charinfo_ef(charinfo * ci, scaled val) 611{ 612 ci->ef = val; 613} 614 615void set_charinfo_lp(charinfo * ci, scaled val) 616{ 617 ci->lp = val; 618} 619 620void set_charinfo_rp(charinfo * ci, scaled val) 621{ 622 ci->rp = val; 623} 624 625@ @c 626void set_charinfo_vert_variants(charinfo * ci, extinfo * ext) 627{ 628 extinfo *c, *lst; 629 if (ci->vert_variants != NULL) { 630 lst = ci->vert_variants; 631 while (lst != NULL) { 632 c = lst->next; 633 free(lst); 634 lst = c; 635 } 636 } 637 ci->vert_variants = ext; 638} 639 640@ @c 641void set_charinfo_hor_variants(charinfo * ci, extinfo * ext) 642{ 643 extinfo *c, *lst; 644 if (ci->hor_variants != NULL) { 645 lst = ci->hor_variants; 646 while (lst != NULL) { 647 c = lst->next; 648 free(lst); 649 lst = c; 650 } 651 } 652 ci->hor_variants = ext; 653 654} 655 656@ @c 657int get_charinfo_math_kerns(charinfo * ci, int id) 658{ 659 660 int k = 0; /* all callers check for |result>0| */ 661 if (id == top_left_kern) { 662 k = ci->top_left_math_kerns; 663 } else if (id == bottom_left_kern) { 664 k = ci->bottom_left_math_kerns; 665 } else if (id == bottom_right_kern) { 666 k = ci->bottom_right_math_kerns; 667 } else if (id == top_right_kern) { 668 k = ci->top_right_math_kerns; 669 } else { 670 confusion("get_charinfo_math_kerns"); 671 } 672 return k; 673} 674 675@ @c 676void add_charinfo_math_kern(charinfo * ci, int id, scaled ht, scaled krn) 677{ 678 int k; 679 if (id == top_left_kern) { 680 k = ci->top_left_math_kerns; 681 do_realloc(ci->top_left_math_kern_array, ((k + 1) * 2), sizeof(scaled)); 682 ci->top_left_math_kern_array[(2 * (k))] = ht; 683 ci->top_left_math_kern_array[((2 * (k)) + 1)] = krn; 684 ci->top_left_math_kerns++; 685 } else if (id == bottom_left_kern) { 686 k = ci->bottom_left_math_kerns; 687 do_realloc(ci->bottom_left_math_kern_array, ((k + 1) * 2), 688 sizeof(scaled)); 689 ci->bottom_left_math_kern_array[(2 * (k))] = ht; 690 ci->bottom_left_math_kern_array[(2 * (k)) + 1] = krn; 691 ci->bottom_left_math_kerns++; 692 } else if (id == bottom_right_kern) { 693 k = ci->bottom_right_math_kerns; 694 do_realloc(ci->bottom_right_math_kern_array, ((k + 1) * 2), 695 sizeof(scaled)); 696 ci->bottom_right_math_kern_array[(2 * (k))] = ht; 697 ci->bottom_right_math_kern_array[(2 * (k)) + 1] = krn; 698 ci->bottom_right_math_kerns++; 699 } else if (id == top_right_kern) { 700 k = ci->top_right_math_kerns; 701 do_realloc(ci->top_right_math_kern_array, ((k + 1) * 2), 702 sizeof(scaled)); 703 ci->top_right_math_kern_array[(2 * (k))] = ht; 704 ci->top_right_math_kern_array[(2 * (k)) + 1] = krn; 705 ci->top_right_math_kerns++; 706 } else { 707 confusion("add_charinfo_math_kern"); 708 } 709} 710 711 712@ @c 713static void dump_math_kerns(charinfo * ci) 714{ 715 int k, l; 716 l = ci->top_left_math_kerns; 717 dump_int(l); 718 for (k = 0; k < l; k++) { 719 dump_int(ci->top_left_math_kern_array[(2 * k)]); 720 dump_int(ci->top_left_math_kern_array[(2 * k) + 1]); 721 } 722 l = ci->bottom_left_math_kerns; 723 dump_int(l); 724 for (k = 0; k < l; k++) { 725 dump_int(ci->bottom_left_math_kern_array[(2 * k)]); 726 dump_int(ci->bottom_left_math_kern_array[(2 * k) + 1]); 727 } 728 l = ci->bottom_right_math_kerns; 729 dump_int(l); 730 for (k = 0; k < l; k++) { 731 dump_int(ci->bottom_right_math_kern_array[(2 * k)]); 732 dump_int(ci->bottom_right_math_kern_array[(2 * k) + 1]); 733 } 734 l = ci->top_right_math_kerns; 735 dump_int(l); 736 for (k = 0; k < l; k++) { 737 dump_int(ci->bottom_left_math_kern_array[(2 * k)]); 738 dump_int(ci->bottom_left_math_kern_array[(2 * k) + 1]); 739 } 740} 741 742@ @c 743static void undump_math_kerns(charinfo * ci) 744{ 745 int k; 746 int x; 747 undump_int(x); 748 ci->top_left_math_kerns = x; 749 if (x > 0) 750 ci->top_left_math_kern_array = 751 xmalloc((unsigned) (2 * (int) sizeof(scaled) * x)); 752 for (k = 0; k < ci->top_left_math_kerns; k++) { 753 undump_int(x); 754 ci->top_left_math_kern_array[(2 * k)] = (scaled) x; 755 undump_int(x); 756 ci->top_left_math_kern_array[(2 * k) + 1] = (scaled) x; 757 } 758 undump_int(x); 759 ci->bottom_left_math_kerns = x; 760 if (x > 0) 761 ci->bottom_left_math_kern_array = 762 xmalloc((unsigned) (2 * (int) sizeof(scaled) * x)); 763 for (k = 0; k < ci->bottom_left_math_kerns; k++) { 764 undump_int(x); 765 ci->bottom_left_math_kern_array[(2 * k)] = (scaled) x; 766 undump_int(x); 767 ci->bottom_left_math_kern_array[(2 * k) + 1] = (scaled) x; 768 } 769 undump_int(x); 770 ci->bottom_right_math_kerns = x; 771 if (x > 0) 772 ci->bottom_right_math_kern_array = 773 xmalloc((unsigned) (2 * (int) sizeof(scaled) * x)); 774 for (k = 0; k < ci->bottom_right_math_kerns; k++) { 775 undump_int(x); 776 ci->bottom_right_math_kern_array[(2 * k)] = (scaled) x; 777 undump_int(x); 778 ci->bottom_right_math_kern_array[(2 * k) + 1] = (scaled) x; 779 } 780 undump_int(x); 781 ci->top_right_math_kerns = x; 782 if (x > 0) 783 ci->top_right_math_kern_array = 784 xmalloc((unsigned) (2 * (int) sizeof(scaled) * x)); 785 for (k = 0; k < ci->top_right_math_kerns; k++) { 786 undump_int(x); 787 ci->top_right_math_kern_array[(2 * k)] = (scaled) x; 788 undump_int(x); 789 ci->top_right_math_kern_array[(2 * k) + 1] = (scaled) x; 790 } 791} 792 793 794@ In TeX, extensibles were fairly simple things. 795 This function squeezes a TFM extensible into the vertical extender structures. 796 |advance==0| is a special case for TFM fonts, because finding the proper 797 advance width during tfm reading can be tricky 798 799 800 a small complication arises if |rep| is the only non-zero: it needs to be 801 doubled as a non-repeatable to avoid mayhem */ 802 803@c 804void set_charinfo_extensible(charinfo * ci, int top, int bot, int mid, int rep) 805{ 806 extinfo *ext; 807 set_charinfo_vert_variants(ci, NULL); /* clear old */ 808 if (bot == 0 && top == 0 && mid == 0 && rep != 0) { 809 ext = new_variant(rep, 0, 0, 0, EXT_NORMAL); 810 add_charinfo_vert_variant(ci, ext); 811 ext = new_variant(rep, 0, 0, 0, EXT_REPEAT); 812 add_charinfo_vert_variant(ci, ext); 813 return; 814 } 815 if (bot != 0) { 816 ext = new_variant(bot, 0, 0, 0, EXT_NORMAL); 817 add_charinfo_vert_variant(ci, ext); 818 } 819 if (rep != 0) { 820 ext = new_variant(rep, 0, 0, 0, EXT_REPEAT); 821 add_charinfo_vert_variant(ci, ext); 822 } 823 if (mid != 0) { 824 ext = new_variant(mid, 0, 0, 0, EXT_NORMAL); 825 add_charinfo_vert_variant(ci, ext); 826 if (rep != 0) { 827 ext = new_variant(rep, 0, 0, 0, EXT_REPEAT); 828 add_charinfo_vert_variant(ci, ext); 829 } 830 } 831 if (top != 0) { 832 ext = new_variant(top, 0, 0, 0, EXT_NORMAL); 833 add_charinfo_vert_variant(ci, ext); 834 } 835} 836 837@ Note that many more simple things like this are implemented as macros 838in the header file. 839 840@c 841scaled get_charinfo_width(charinfo * ci) 842{ 843 return ci->width; 844} 845 846scaled get_charinfo_height(charinfo * ci) 847{ 848 return ci->height; 849} 850 851scaled get_charinfo_depth(charinfo * ci) 852{ 853 return ci->depth; 854} 855 856scaled get_charinfo_italic(charinfo * ci) 857{ 858 return ci->italic; 859} 860 861scaled get_charinfo_top_accent(charinfo * ci) 862{ 863 return ci->top_accent; 864} 865 866scaled get_charinfo_bot_accent(charinfo * ci) 867{ 868 return ci->bot_accent; 869} 870 871char get_charinfo_tag(charinfo * ci) 872{ 873 return ci->tag; 874} 875 876int get_charinfo_remainder(charinfo * ci) 877{ 878 return ci->remainder; 879} 880 881char get_charinfo_used(charinfo * ci) 882{ 883 return ci->used; 884} 885 886int get_charinfo_index(charinfo * ci) 887{ 888 return ci->index; 889} 890 891char *get_charinfo_name(charinfo * ci) 892{ 893 return ci->name; 894} 895 896char *get_charinfo_tounicode(charinfo * ci) 897{ 898 return ci->tounicode; 899} 900 901liginfo *get_charinfo_ligatures(charinfo * ci) 902{ 903 return ci->ligatures; 904} 905 906kerninfo *get_charinfo_kerns(charinfo * ci) 907{ 908 return ci->kerns; 909} 910 911eight_bits *get_charinfo_packets(charinfo * ci) 912{ 913 return ci->packets; 914} 915 916int get_charinfo_ef(charinfo * ci) 917{ 918 return ci->ef; 919} 920 921int get_charinfo_rp(charinfo * ci) 922{ 923 return ci->rp; 924} 925 926int get_charinfo_lp(charinfo * ci) 927{ 928 return ci->lp; 929} 930 931extinfo *get_charinfo_vert_variants(charinfo * ci) 932{ 933 extinfo *w = NULL; 934 if (ci->vert_variants != NULL) 935 w = ci->vert_variants; 936 return w; 937} 938 939extinfo *get_charinfo_hor_variants(charinfo * ci) 940{ 941 extinfo *w = NULL; 942 if (ci->hor_variants != NULL) 943 w = ci->hor_variants; 944 return w; 945} 946 947 948scaled char_width(internal_font_number f, int c) 949{ 950 charinfo *ci = char_info(f, c); 951 scaled w = get_charinfo_width(ci); 952 return w; 953} 954 955scaled calc_char_width(internal_font_number f, int c, int ex) 956{ 957 charinfo *ci = char_info(f, c); 958 scaled w = get_charinfo_width(ci); 959 //printf("ex=%d\n",ex); 960 if (ex != 0) 961 w = round_xn_over_d(w, 1000 + ex, 1000); 962 return w; 963} 964 965scaled char_depth(internal_font_number f, int c) 966{ 967 charinfo *ci = char_info(f, c); 968 scaled w = get_charinfo_depth(ci); 969 return w; 970} 971 972scaled char_height(internal_font_number f, int c) 973{ 974 charinfo *ci = char_info(f, c); 975 scaled w = get_charinfo_height(ci); 976 return w; 977} 978 979scaled char_italic(internal_font_number f, int c) 980{ 981 charinfo *ci = char_info(f, c); 982 return get_charinfo_italic(ci); 983} 984 985scaled char_top_accent(internal_font_number f, int c) 986{ 987 charinfo *ci = char_info(f, c); 988 return get_charinfo_top_accent(ci); 989} 990 991scaled char_bot_accent(internal_font_number f, int c) 992{ 993 charinfo *ci = char_info(f, c); 994 return get_charinfo_bot_accent(ci); 995} 996 997 998int char_remainder(internal_font_number f, int c) 999{ 1000 charinfo *ci = char_info(f, c); 1001 return get_charinfo_remainder(ci); 1002} 1003 1004char char_tag(internal_font_number f, int c) 1005{ 1006 charinfo *ci = char_info(f, c); 1007 return get_charinfo_tag(ci); 1008} 1009 1010char char_used(internal_font_number f, int c) 1011{ 1012 charinfo *ci = char_info(f, c); 1013 return get_charinfo_used(ci); 1014} 1015 1016char *char_name(internal_font_number f, int c) 1017{ 1018 charinfo *ci = char_info(f, c); 1019 return get_charinfo_name(ci); 1020} 1021 1022int char_index(internal_font_number f, int c) 1023{ 1024 charinfo *ci = char_info(f, c); 1025 return get_charinfo_index(ci); 1026} 1027 1028liginfo *char_ligatures(internal_font_number f, int c) 1029{ 1030 charinfo *ci = char_info(f, c); 1031 return get_charinfo_ligatures(ci); 1032} 1033 1034kerninfo *char_kerns(internal_font_number f, int c) 1035{ 1036 charinfo *ci = char_info(f, c); 1037 return get_charinfo_kerns(ci); 1038} 1039 1040eight_bits *char_packets(internal_font_number f, int c) 1041{ 1042 charinfo *ci = char_info(f, c); 1043 return get_charinfo_packets(ci); 1044} 1045 1046@ @c 1047void set_font_params(internal_font_number f, int b) 1048{ 1049 int i; 1050 i = font_params(f); 1051 if (i != b) { 1052 font_bytes += 1053 (int) ((b - (int) font_params(f) + 1) * (int) sizeof(scaled)); 1054 do_realloc(param_base(f), (b + 2), int); 1055 font_params(f) = b; 1056 if (b > i) { 1057 while (i < b) { 1058 i++; 1059 set_font_param(f, i, 0); 1060 } 1061 } 1062 } 1063} 1064 1065@ @c 1066void set_font_math_params(internal_font_number f, int b) 1067{ 1068 int i; 1069 i = font_math_params(f); 1070 if (i != b) { 1071 font_bytes += 1072 ((b - (int) font_math_params(f) + 1) * (int) sizeof(scaled)); 1073 do_realloc(math_param_base(f), (b + 2), int); 1074 font_math_params(f) = b; 1075 if (b > i) { 1076 while (i < b) { 1077 i++; 1078 set_font_math_param(f, i, undefined_math_parameter); 1079 } 1080 } 1081 } 1082} 1083 1084 1085@ @c 1086int copy_font(int f) 1087{ 1088 int i, ci_cnt, ci_size; 1089 charinfo *ci; 1090 int k = new_font(); 1091 1092 { 1093 ci = font_tables[k]->charinfo; 1094 ci_cnt = font_tables[k]->charinfo_count; 1095 ci_size = font_tables[k]->charinfo_size; 1096 memcpy(font_tables[k], font_tables[f], sizeof(texfont)); 1097 font_tables[k]->charinfo = ci; 1098 font_tables[k]->charinfo_count = ci_cnt; 1099 font_tables[k]->charinfo_size = ci_size; 1100 } 1101 1102 font_malloc_charinfo(k, font_tables[f]->charinfo_count); 1103 set_font_cache_id(k, 0); 1104 set_font_used(k, 0); 1105 set_font_touched(k, 0); 1106 1107 font_tables[k]->_font_name = NULL; 1108 font_tables[k]->_font_filename = NULL; 1109 font_tables[k]->_font_fullname = NULL; 1110 font_tables[k]->_font_psname = NULL; 1111 font_tables[k]->_font_encodingname = NULL; 1112 font_tables[k]->_font_area = NULL; 1113 font_tables[k]->_font_cidregistry = NULL; 1114 font_tables[k]->_font_cidordering = NULL; 1115 font_tables[k]->_left_boundary = NULL; 1116 font_tables[k]->_right_boundary = NULL; 1117 1118 set_font_name(k, xstrdup(font_name(f))); 1119 if (font_filename(f) != NULL) 1120 set_font_filename(k, xstrdup(font_filename(f))); 1121 if (font_fullname(f) != NULL) 1122 set_font_fullname(k, xstrdup(font_fullname(f))); 1123 if (font_psname(f) != NULL) 1124 set_font_psname(k, xstrdup(font_psname(f))); 1125 if (font_encodingname(f) != NULL) 1126 set_font_encodingname(k, xstrdup(font_encodingname(f))); 1127 if (font_area(f) != NULL) 1128 set_font_area(k, xstrdup(font_area(f))); 1129 if (font_cidregistry(f) != NULL) 1130 set_font_cidregistry(k, xstrdup(font_cidregistry(f))); 1131 if (font_cidordering(f) != NULL) 1132 set_font_cidordering(k, xstrdup(font_cidordering(f))); 1133 1134 i = (int) (sizeof(*param_base(f)) * (unsigned) (font_params(f)+1)); 1135 font_bytes += i; 1136 param_base(k) = xmalloc((unsigned) (i+1)); 1137 memcpy(param_base(k), param_base(f), (size_t) (i)); 1138 1139 if (font_math_params(f) > 0) { 1140 i = (int) (sizeof(*math_param_base(f)) * 1141 (unsigned) font_math_params(f)); 1142 font_bytes += i; 1143 math_param_base(k) = xmalloc((unsigned) i); 1144 memcpy(math_param_base(k), math_param_base(f), (size_t) i); 1145 } 1146 1147 for (i = 0; i <= font_tables[f]->charinfo_count; i++) { 1148 ci = copy_charinfo(&font_tables[f]->charinfo[i]); 1149 font_tables[k]->charinfo[i] = *ci; 1150 } 1151 1152 if (left_boundary(f) != NULL) { 1153 ci = copy_charinfo(left_boundary(f)); 1154 set_charinfo(k, left_boundarychar, ci); 1155 } 1156 1157 if (right_boundary(f) != NULL) { 1158 ci = copy_charinfo(right_boundary(f)); 1159 set_charinfo(k, right_boundarychar, ci); 1160 } 1161 /* not updated yet: */ 1162 font_tables[k]->charinfo_count = font_tables[f]->charinfo_count; 1163 return k; 1164} 1165 1166@ @c 1167void delete_font(int f) 1168{ 1169 int i; 1170 charinfo *co; 1171 assert(f > 0); 1172 if (font_tables[f] != NULL) { 1173 set_font_name(f, NULL); 1174 set_font_filename(f, NULL); 1175 set_font_fullname(f, NULL); 1176 set_font_psname(f, NULL); 1177 set_font_encodingname(f, NULL); 1178 set_font_area(f, NULL); 1179 set_font_cidregistry(f, NULL); 1180 set_font_cidordering(f, NULL); 1181 set_left_boundary(f, NULL); 1182 set_right_boundary(f, NULL); 1183 1184 for (i = font_bc(f); i <= font_ec(f); i++) { 1185 if (quick_char_exists(f, i)) { 1186 co = char_info(f, i); 1187 set_charinfo_name(co, NULL); 1188 set_charinfo_tounicode(co, NULL); 1189 set_charinfo_packets(co, NULL); 1190 set_charinfo_ligatures(co, NULL); 1191 set_charinfo_kerns(co, NULL); 1192 set_charinfo_vert_variants(co, NULL); 1193 set_charinfo_hor_variants(co, NULL); 1194 } 1195 } 1196 /* free .notdef */ 1197 set_charinfo_name(font_tables[f]->charinfo + 0, NULL); 1198 free(font_tables[f]->charinfo); 1199 destroy_sa_tree(font_tables[f]->characters); 1200 1201 free(param_base(f)); 1202 if (math_param_base(f) != NULL) 1203 free(math_param_base(f)); 1204 free(font_tables[f]); 1205 font_tables[f] = NULL; 1206 1207 if (font_id_maxval == f) { 1208 font_id_maxval--; 1209 } 1210 } 1211} 1212 1213@ @c 1214void create_null_font(void) 1215{ 1216 int i = new_font(); 1217 assert(i == 0); 1218 set_font_name(i, xstrdup("nullfont")); 1219 set_font_area(i, xstrdup("")); 1220 set_font_touched(i, 1); 1221} 1222 1223@ @c 1224boolean is_valid_font(int id) 1225{ 1226 int ret = 0; 1227 if (id >= 0 && id <= font_id_maxval && font_tables[id] != NULL) 1228 ret = 1; 1229 return ret; 1230} 1231 1232@ @c 1233boolean cmp_font_area(int id, str_number t) 1234{ 1235 char *tt = NULL; 1236 char *tid = font_area(id); 1237 if (t == 0) { 1238 if (tid == NULL || strlen(tid) == 0) 1239 return 1; 1240 else 1241 return 0; 1242 } 1243 tt = makecstring(t); 1244 if ((tt == NULL || strlen(tt) == 0) && (tid == NULL || strlen(tid) == 0)) 1245 return 1; 1246 if (tt == NULL || strcmp(tid, tt) != 0) 1247 return 0; 1248 free(tt); 1249 return 1; 1250} 1251 1252@ @c 1253int test_no_ligatures(internal_font_number f) 1254{ 1255 int c; 1256 for (c = font_bc(f); c <= font_ec(f); c++) { 1257 if (has_lig(f, c)) /* |char_exists(f,c)| */ 1258 return 0; 1259 } 1260 return 1; 1261} 1262 1263@ @c 1264int get_tag_code(internal_font_number f, int c) 1265{ 1266 small_number i; 1267 if (char_exists(f, c)) { 1268 i = char_tag(f, c); 1269 if (i == lig_tag) 1270 return 1; 1271 else if (i == list_tag) 1272 return 2; 1273 else if (i == ext_tag) 1274 return 4; 1275 else 1276 return 0; 1277 } 1278 return -1; 1279} 1280 1281@ @c 1282int get_lp_code(internal_font_number f, int c) 1283{ 1284 charinfo *ci = char_info(f, c); 1285 return get_charinfo_lp(ci); 1286} 1287 1288int get_rp_code(internal_font_number f, int c) 1289{ 1290 charinfo *ci = char_info(f, c); 1291 return get_charinfo_rp(ci); 1292} 1293 1294int get_ef_code(internal_font_number f, int c) 1295{ 1296 charinfo *ci = char_info(f, c); 1297 return get_charinfo_ef(ci); 1298} 1299 1300@ @c 1301void set_tag_code(internal_font_number f, int c, int i) 1302{ 1303 int fixedi; 1304 charinfo *co; 1305 if (char_exists(f, c)) { 1306 /* |abs(fix_int(i-7,0))| */ 1307 fixedi = -(i < -7 ? -7 : (i > 0 ? 0 : i)); 1308 co = char_info(f, c); 1309 if (fixedi >= 4) { 1310 if (char_tag(f, c) == ext_tag) 1311 set_charinfo_tag(co, (char_tag(f, c) - ext_tag)); 1312 fixedi = fixedi - 4; 1313 } 1314 if (fixedi >= 2) { 1315 if (char_tag(f, c) == list_tag) 1316 set_charinfo_tag(co, (char_tag(f, c) - list_tag)); 1317 fixedi = fixedi - 2; 1318 }; 1319 if (fixedi >= 1) { 1320 if (has_lig(f, c)) 1321 set_charinfo_ligatures(co, NULL); 1322 if (has_kern(f, c)) 1323 set_charinfo_kerns(co, NULL); 1324 } 1325 } 1326} 1327 1328 1329@ @c 1330void set_lp_code(internal_font_number f, int c, int i) 1331{ 1332 charinfo *co; 1333 if (char_exists(f, c)) { 1334 co = char_info(f, c); 1335 set_charinfo_lp(co, i); 1336 } 1337} 1338 1339void set_rp_code(internal_font_number f, int c, int i) 1340{ 1341 charinfo *co; 1342 if (char_exists(f, c)) { 1343 co = char_info(f, c); 1344 set_charinfo_rp(co, i); 1345 } 1346} 1347 1348void set_ef_code(internal_font_number f, int c, int i) 1349{ 1350 charinfo *co; 1351 if (char_exists(f, c)) { 1352 co = char_info(f, c); 1353 set_charinfo_ef(co, i); 1354 } 1355} 1356 1357@ @c 1358void set_no_ligatures(internal_font_number f) 1359{ 1360 int c; 1361 charinfo *co; 1362 1363 if (font_tables[f]->ligatures_disabled) 1364 return; 1365 1366 co = char_info(f, left_boundarychar); 1367 set_charinfo_ligatures(co, NULL); 1368 co = char_info(f, right_boundarychar); /* this is weird */ 1369 set_charinfo_ligatures(co, NULL); 1370 for (c = 0; c < font_tables[f]->charinfo_count; c++) { 1371 co = font_tables[f]->charinfo + c; 1372 set_charinfo_ligatures(co, NULL); 1373 } 1374 font_tables[f]->ligatures_disabled = 1; 1375} 1376 1377@ @c 1378liginfo get_ligature(internal_font_number f, int lc, int rc) 1379{ 1380 int k; 1381 liginfo t, u; 1382 charinfo *co; 1383 t.lig = 0; 1384 t.type = 0; 1385 t.adj = 0; 1386 if (lc == non_boundarychar || rc == non_boundarychar || (!has_lig(f, lc))) 1387 return t; 1388 k = 0; 1389 co = char_info(f, lc); 1390 while (1) { 1391 u = charinfo_ligature(co, k); 1392 if (lig_end(u)) 1393 break; 1394 if (lig_char(u) == rc) { 1395 if (lig_disabled(u)) { 1396 return t; 1397 } else { 1398 return u; 1399 } 1400 } 1401 k++; 1402 } 1403 return t; 1404} 1405 1406 1407@ @c 1408scaled raw_get_kern(internal_font_number f, int lc, int rc) 1409{ 1410 int k; 1411 kerninfo u; 1412 charinfo *co; 1413 if (lc == non_boundarychar || rc == non_boundarychar) 1414 return 0; 1415 k = 0; 1416 co = char_info(f, lc); 1417 while (1) { 1418 u = charinfo_kern(co, k); 1419 if (kern_end(u)) 1420 break; 1421 if (kern_char(u) == rc) { 1422 if (kern_disabled(u)) 1423 return 0; 1424 else 1425 return kern_kern(u); 1426 } 1427 k++; 1428 } 1429 return 0; 1430} 1431 1432 1433@ @c 1434scaled get_kern(internal_font_number f, int lc, int rc) 1435{ 1436 if (lc == non_boundarychar || rc == non_boundarychar || (!has_kern(f, lc))) 1437 return 0; 1438 return raw_get_kern(f, lc, rc); 1439} 1440 1441 1442@ dumping and undumping fonts 1443 1444@c 1445#define dump_string(a) \ 1446 if (a!=NULL) { \ 1447 x = (int)(strlen(a)+1); \ 1448 dump_int(x); dump_things(*a, x); \ 1449 } else { \ 1450 x = 0; dump_int(x); \ 1451 } 1452 1453static void dump_charinfo(int f, int c) 1454{ 1455 charinfo *co; 1456 int x; 1457 liginfo *lig; 1458 kerninfo *kern; 1459 dump_int(c); 1460 co = char_info(f, c); 1461 set_charinfo_used(co, 0); 1462 dump_int(get_charinfo_width(co)); 1463 dump_int(get_charinfo_height(co)); 1464 dump_int(get_charinfo_depth(co)); 1465 dump_int(get_charinfo_italic(co)); 1466 dump_int(get_charinfo_top_accent(co)); 1467 dump_int(get_charinfo_bot_accent(co)); 1468 dump_int(get_charinfo_tag(co)); 1469 dump_int(get_charinfo_ef(co)); 1470 dump_int(get_charinfo_rp(co)); 1471 dump_int(get_charinfo_lp(co)); 1472 dump_int(get_charinfo_remainder(co)); 1473 dump_int(get_charinfo_used(co)); 1474 dump_int(get_charinfo_index(co)); 1475 dump_string(get_charinfo_name(co)); 1476 dump_string(get_charinfo_tounicode(co)); 1477 1478 /* ligatures */ 1479 x = 0; 1480 if ((lig = get_charinfo_ligatures(co)) != NULL) { 1481 while (!lig_end(lig[x])) { 1482 x++; 1483 } 1484 x++; 1485 dump_int(x); 1486 dump_things(*lig, x); 1487 } else { 1488 dump_int(x); 1489 } 1490 /* kerns */ 1491 x = 0; 1492 if ((kern = get_charinfo_kerns(co)) != NULL) { 1493 while (!kern_end(kern[x])) { 1494 x++; 1495 } 1496 x++; 1497 dump_int(x); 1498 dump_things(*kern, x); 1499 } else { 1500 dump_int(x); 1501 } 1502 /* packets */ 1503 x = vf_packet_bytes(co); 1504 dump_int(x); 1505 if (x > 0) { 1506 dump_things(*get_charinfo_packets(co), x); 1507 } 1508 1509 if (get_charinfo_tag(co) == ext_tag) { 1510 dump_charinfo_variants(get_charinfo_vert_variants(co)); 1511 dump_charinfo_variants(get_charinfo_hor_variants(co)); 1512 } 1513 dump_math_kerns(co); 1514} 1515 1516static void dump_font_entry(texfont * f) 1517{ 1518 int x; 1519 dump_int(f->_font_size); 1520 dump_int(f->_font_dsize); 1521 dump_int(f->_font_cidversion); 1522 dump_int(f->_font_cidsupplement); 1523 dump_int(f->_font_ec); 1524 x = (int) f->_font_checksum; 1525 dump_int(x); 1526 dump_int(f->_font_used); 1527 dump_int(f->_font_touched); 1528 dump_int(f->_font_cache_id); 1529 dump_int(f->_font_encodingbytes); 1530 dump_int(f->_font_slant); 1531 dump_int(f->_font_extend); 1532 dump_int(f->font_max_shrink); 1533 dump_int(f->font_max_stretch); 1534 dump_int(f->_font_step); 1535 dump_int(f->_font_auto_expand); 1536 dump_int(f->_font_tounicode); 1537 dump_int(f->_font_type); 1538 dump_int(f->_font_format); 1539 dump_int(f->_font_embedding); 1540 dump_int(f->_font_bc); 1541 dump_int(f->_hyphen_char); 1542 dump_int(f->_skew_char); 1543 dump_int(f->_font_natural_dir); 1544 dump_int(f->_font_params); 1545 dump_int(f->_font_math_params); 1546 dump_int(f->ligatures_disabled); 1547 dump_int(f->_pdf_font_num); 1548 dump_int(f->_pdf_font_attr); 1549} 1550 1551void dump_font(int f) 1552{ 1553 int i, x; 1554 1555 set_font_used(f, 0); 1556 font_tables[f]->charinfo_cache = NULL; 1557 dump_font_entry(font_tables[f]); 1558 dump_string(font_name(f)); 1559 dump_string(font_area(f)); 1560 dump_string(font_filename(f)); 1561 dump_string(font_fullname(f)); 1562 dump_string(font_psname(f)); 1563 dump_string(font_encodingname(f)); 1564 dump_string(font_cidregistry(f)); 1565 dump_string(font_cidordering(f)); 1566 1567 dump_things(*param_base(f), (font_params(f) + 1)); 1568 1569 if (font_math_params(f) > 0) { 1570 dump_things(*math_param_base(f), (font_math_params(f) + 1 )); 1571 } 1572 if (has_left_boundary(f)) { 1573 dump_int(1); 1574 dump_charinfo(f, left_boundarychar); 1575 } else { 1576 dump_int(0); 1577 } 1578 if (has_right_boundary(f)) { 1579 dump_int(1); 1580 dump_charinfo(f, right_boundarychar); 1581 } else { 1582 dump_int(0); 1583 } 1584 1585 for (i = font_bc(f); i <= font_ec(f); i++) { 1586 if (quick_char_exists(f, i)) { 1587 dump_charinfo(f, i); 1588 } 1589 } 1590} 1591 1592@ @c 1593static int undump_charinfo(int f) 1594{ 1595 charinfo *co; 1596 int x, i; 1597 char *s = NULL; 1598 liginfo *lig = NULL; 1599 kerninfo *kern = NULL; 1600 eight_bits *packet = NULL; 1601 1602 undump_int(i); 1603 co = get_charinfo(f, i); 1604 undump_int(x); 1605 set_charinfo_width(co, x); 1606 undump_int(x); 1607 set_charinfo_height(co, x); 1608 undump_int(x); 1609 set_charinfo_depth(co, x); 1610 undump_int(x); 1611 set_charinfo_italic(co, x); 1612 undump_int(x); 1613 set_charinfo_top_accent(co, x); 1614 undump_int(x); 1615 set_charinfo_bot_accent(co, x); 1616 undump_int(x); 1617 set_charinfo_tag(co, x); 1618 undump_int(x); 1619 set_charinfo_ef(co, x); 1620 undump_int(x); 1621 set_charinfo_rp(co, x); 1622 undump_int(x); 1623 set_charinfo_lp(co, x); 1624 undump_int(x); 1625 set_charinfo_remainder(co, x); 1626 undump_int(x); 1627 set_charinfo_used(co, x); 1628 undump_int(x); 1629 set_charinfo_index(co, x); 1630 1631 /* name */ 1632 undump_int(x); 1633 if (x > 0) { 1634 font_bytes += x; 1635 s = xmalloc((unsigned) x); 1636 undump_things(*s, x); 1637 } 1638 set_charinfo_name(co, s); 1639 /* tounicode */ 1640 undump_int(x); 1641 if (x > 0) { 1642 font_bytes += x; 1643 s = xmalloc((unsigned) x); 1644 undump_things(*s, x); 1645 } 1646 set_charinfo_tounicode(co, s); 1647 /* ligatures */ 1648 undump_int(x); 1649 if (x > 0) { 1650 font_bytes += (int) ((unsigned) x * sizeof(liginfo)); 1651 lig = xmalloc((unsigned) ((unsigned) x * sizeof(liginfo))); 1652 undump_things(*lig, x); 1653 } 1654 set_charinfo_ligatures(co, lig); 1655 /* kerns */ 1656 undump_int(x); 1657 if (x > 0) { 1658 font_bytes += (int) ((unsigned) x * sizeof(kerninfo)); 1659 kern = xmalloc((unsigned) ((unsigned) x * sizeof(kerninfo))); 1660 undump_things(*kern, x); 1661 } 1662 set_charinfo_kerns(co, kern); 1663 1664 /* packets */ 1665 undump_int(x); 1666 if (x > 0) { 1667 font_bytes += x; 1668 packet = xmalloc((unsigned) x); 1669 undump_things(*packet, x); 1670 } 1671 set_charinfo_packets(co, packet); 1672 1673 if (get_charinfo_tag(co) == ext_tag) { 1674 set_charinfo_vert_variants(co, undump_charinfo_variants()); 1675 set_charinfo_hor_variants(co, undump_charinfo_variants()); 1676 } 1677 undump_math_kerns(co); 1678 return i; 1679} 1680 1681#define undump_font_string(a) undump_int (x); \ 1682 if (x>0) { \ 1683 font_bytes += x; \ 1684 s = xmalloc((unsigned)x); undump_things(*s,x); \ 1685 a(f,s); } 1686 1687 1688static void undump_font_entry(texfont * f) 1689{ 1690 int x = 0; 1691 /* *INDENT-OFF* */ 1692 undump_int(x); f->_font_size = x; 1693 undump_int(x); f->_font_dsize = x; 1694 undump_int(x); f->_font_cidversion = x; 1695 undump_int(x); f->_font_cidsupplement = x; 1696 undump_int(x); f->_font_ec = x; 1697 undump_int(x); f->_font_checksum = (unsigned)x; 1698 undump_int(x); f->_font_used = (char)x; 1699 undump_int(x); f->_font_touched = (char)x; 1700 undump_int(x); f->_font_cache_id = x; 1701 undump_int(x); f->_font_encodingbytes = (char)x; 1702 undump_int(x); f->_font_slant = x; 1703 undump_int(x); f->_font_extend = x; 1704 undump_int(x); f->font_max_shrink = x; 1705 undump_int(x); f->font_max_stretch = x; 1706 undump_int(x); f->_font_step = x; 1707 undump_int(x); f->_font_auto_expand = x; 1708 undump_int(x); f->_font_tounicode = (char)x; 1709 undump_int(x); f->_font_type = x; 1710 undump_int(x); f->_font_format = x; 1711 undump_int(x); f->_font_embedding = x; 1712 undump_int(x); f->_font_bc = x; 1713 undump_int(x); f->_hyphen_char = x; 1714 undump_int(x); f->_skew_char = x; 1715 undump_int(x); f->_font_natural_dir = x; 1716 undump_int(x); f->_font_params = x; 1717 undump_int(x); f->_font_math_params = x; 1718 undump_int(x); f->ligatures_disabled = x; 1719 undump_int(x); f->_pdf_font_num = x; 1720 undump_int(x); f->_pdf_font_attr = x; 1721 /* *INDENT-ON* */ 1722} 1723 1724 1725 1726void undump_font(int f) 1727{ 1728 int x, i; 1729 texfont *tt; 1730 charinfo *ci; 1731 char *s; 1732 grow_font_table(f); 1733 tt = xmalloc(sizeof(texfont)); 1734 memset(tt, 0, sizeof(texfont)); 1735 font_bytes += (int) sizeof(texfont); 1736 undump_font_entry(tt); 1737 font_tables[f] = tt; 1738 1739 undump_font_string(set_font_name); 1740 undump_font_string(set_font_area); 1741 undump_font_string(set_font_filename); 1742 undump_font_string(set_font_fullname); 1743 undump_font_string(set_font_psname); 1744 undump_font_string(set_font_encodingname); 1745 undump_font_string(set_font_cidregistry); 1746 undump_font_string(set_font_cidordering); 1747 1748 i = (int) (sizeof(*param_base(f)) * ((unsigned) font_params(f) + 1)); 1749 font_bytes += i; 1750 param_base(f) = xmalloc((unsigned) i); 1751 undump_things(*param_base(f), (font_params(f) + 1)); 1752 1753 if (font_math_params(f) > 0) { 1754 i = (int) (sizeof(*math_param_base(f)) * 1755 ((unsigned) font_math_params(f) + 1)); 1756 font_bytes += i; 1757 math_param_base(f) = xmalloc((unsigned) i); 1758 undump_things(*math_param_base(f), (font_math_params(f) + 1)); 1759 } 1760 1761 font_tables[f]->characters = new_sa_tree(1, 0); /* stack size 1, default item value 0 */ 1762 ci = xcalloc(1, sizeof(charinfo)); 1763 set_charinfo_name(ci, xstrdup(".notdef")); 1764 font_tables[f]->charinfo = ci; 1765 undump_int(x); 1766 if (x) { 1767 i = undump_charinfo(f); 1768 } /* left boundary */ 1769 undump_int(x); 1770 if (x) { 1771 i = undump_charinfo(f); 1772 } /* right boundary */ 1773 1774 i = font_bc(f); 1775 while (i < font_ec(f)) { 1776 i = undump_charinfo(f); 1777 } 1778} 1779