dvi-init.c (20200B)
1 /*========================================================================*\ 2 3 Copyright (c) 1990-2013 Paul Vojta 4 5 Permission is hereby granted, free of charge, to any person obtaining a copy 6 of this software and associated documentation files (the "Software"), to 7 deal in the Software without restriction, including without limitation the 8 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 sell copies of the Software, and to permit persons to whom the Software is 10 furnished to do so, subject to the following conditions: 11 12 The above copyright notice and this permission notice shall be included in 13 all copies or substantial portions of the Software. 14 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 IN NO EVENT SHALL PAUL VOJTA OR ANY OTHER AUTHOR OF OR CONTRIBUTOR TO 19 THIS SOFTWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 IN THE SOFTWARE. 23 24 NOTE: 25 xdvi is based on prior work, as noted in the modification history 26 in xdvi.c. 27 28 \*========================================================================*/ 29 30 #include <err.h> 31 32 #include <X11/Shell.h> /* defines XtNtitle and XtNiconName */ 33 34 #include "dvi-init.h" 35 #include "dvi-draw.h" /* spell_conv() */ 36 #include "events.h" /* mane */ 37 #include "font.h" /* struct font, struct glyph */ 38 #include "special.h" /* init_prescan() */ 39 #include "xdvi.h" 40 #include "dvi.h" 41 #include "util.h" /* xmalloc() */ 42 43 44 #define PK_PRE 247 45 #define PK_ID 89 46 #define PK_MAGIC ((PK_PRE << 8) | PK_ID) 47 #define GF_PRE 247 48 #define GF_ID 131 49 #define GF_MAGIC ((GF_PRE << 8) | GF_ID) 50 #define VF_PRE 247 51 #define VF_ID_BYTE 202 52 #define VF_MAGIC ((VF_PRE << 8) | VF_ID_BYTE) 53 54 55 /* 56 * DVI preamble and postamble information. 57 */ 58 static unsigned int dvi_unshrunk_page_w, dvi_unshrunk_page_h; 59 60 /* 61 * free_vf_chain frees the vf_chain structure. 62 */ 63 64 static void 65 free_vf_chain(struct tn *tnp) 66 { 67 while (tnp != NULL) { 68 struct tn *tnp1 = tnp->next; 69 free((char *) tnp); 70 tnp = tnp1; 71 } 72 } 73 74 75 /* 76 * Release all shrunken bitmaps for all fonts. 77 */ 78 79 void 80 reset_fonts(void) 81 { 82 struct font *f; 83 struct glyph *g; 84 85 for (f = font_head; f != NULL; f = f->next) { 86 if (!(f->flags & FONT_LOADED) || (f->flags & FONT_VIRTUAL)) 87 continue; 88 89 for (g = f->glyph; g <= f->glyph + f->maxchar; ++g) { 90 if (g->bitmap2.bits) { 91 free(g->bitmap2.bits); 92 g->bitmap2.bits = NULL; 93 } 94 if (g->pixmap2) { 95 XDestroyImage(g->image2); 96 g->pixmap2 = NULL; 97 if (g->pixmap2_t != NULL) { 98 free(g->pixmap2_t); 99 g->pixmap2_t = NULL; 100 } 101 } 102 g->fg = NULL; 103 } 104 } 105 } 106 107 108 109 /* 110 * Release all allocated pixels, and (in greyscale mode) invalidate 111 * all shrunken glyphs. 112 */ 113 114 void 115 reset_colors(void) 116 { 117 struct font *f; 118 struct glyph *g; 119 120 while (bg_head != NULL) { 121 struct bgrec *bgp; 122 struct fgrec *fgp; 123 124 for (fgp = bg_head->fg_head; fgp != NULL;) { 125 struct fgrec *fgp1 = fgp->next; 126 free(fgp); 127 fgp = fgp1; 128 } 129 bgp = bg_head->next; 130 free(bg_head); 131 bg_head = bgp; 132 } 133 134 /* use_grey */ 135 for (f = font_head; f != NULL; f = f->next) { 136 if (!(f->flags & FONT_LOADED) || (f->flags & FONT_VIRTUAL)) 137 continue; 138 139 for (g = f->glyph; g <= f->glyph + f->maxchar; ++g) 140 g->fg = NULL; 141 } 142 143 bg_current = NULL; 144 fg_active = NULL; 145 } 146 147 /* 148 * All of the above, plus discard all scanned information. 149 */ 150 151 void 152 full_reset_colors(void) 153 { 154 if (page_colors != NULL) { 155 int i; 156 const struct rgb *last_freed = &fg_initial; 157 158 for (i = 0; i < total_pages; ++i) { 159 if (page_colors[i].colorstack != last_freed) { 160 last_freed = page_colors[i].colorstack; 161 if (last_freed != NULL) 162 free((char *) last_freed); 163 } 164 } 165 free((char *) page_colors); 166 page_colors = NULL; 167 } 168 reset_colors(); 169 } 170 171 172 173 /* 174 * realloc_font allocates the font structure to contain (newsize + 1) 175 * characters. 176 */ 177 178 void 179 realloc_font(struct font *fontp, unsigned char newsize) 180 { 181 struct glyph *glyph; 182 183 glyph = fontp->glyph = xrealloc(fontp->glyph, 184 (unsigned int) (newsize + 1) * sizeof(struct glyph)); 185 if (newsize > fontp->maxchar) 186 bzero((char *) (glyph + fontp->maxchar + 1), 187 (int) (newsize - fontp->maxchar) * sizeof(struct glyph)); 188 maxchar = fontp->maxchar = newsize; 189 } 190 191 192 /* 193 * realloc_virtual_font does the same thing for virtual fonts. 194 */ 195 196 void 197 realloc_virtual_font(struct font *fontp, unsigned char newsize) 198 { 199 struct macro *macro; 200 201 macro = fontp->macro = xrealloc(fontp->macro, 202 (unsigned int) (newsize + 1) * sizeof(struct macro)); 203 if (newsize > fontp->maxchar) 204 bzero((char *) (macro + fontp->maxchar + 1), 205 (int) (newsize - fontp->maxchar) * sizeof(struct macro)); 206 maxchar = fontp->maxchar = newsize; 207 } 208 209 210 /* 211 * load_font locates the raster file and reads the index of characters, 212 * plus whatever other preprocessing is done (depending on the format). 213 * Returns True if successful; False if not. 214 */ 215 216 Boolean 217 load_font(struct font *fontp) 218 { 219 double fsize = fontp->fsize; 220 int dpi = fsize + 0.5; 221 char *font_found; 222 int size_found; 223 int magic; 224 Boolean hushcs = False; 225 226 if (!font_open(fontp, &font_found, &size_found)) { 227 if (ev_flags & EV_GE_NEWDOC) 228 return False; 229 fontp->flags |= FONT_LOADED; /* as loaded as it'll get */ 230 warnx("can't find font '%s'.", fontp->fontname); 231 return False; 232 } 233 fontp->flags |= FONT_LOADED; 234 if (font_found != NULL) { 235 warnx("can't find font '%s'; using '%s' instead at %d dpi.", 236 fontp->fontname, font_found, dpi); 237 free(fontp->fontname); 238 fontp->fontname = font_found; 239 hushcs = True; 240 } 241 else if (size_found > (int) (1.002 * fsize + 0.5) || 242 size_found < (int) (0.998 * fsize + 0.5)) 243 warnx("can't find font %s at %d dpi; using %d dpi instead.", 244 fontp->fontname, dpi, size_found); 245 fontp->timestamp = ++current_timestamp; 246 fontp->maxchar = maxchar = 255; 247 fontp->set_char_p = set_char; 248 if (fontp->ft != NULL) { /* if freetype font */ 249 fontp->set_char_p = set_ft_char; 250 fontp->glyph = xmalloc(256 * sizeof(struct glyph)); 251 bzero((char *) fontp->glyph, 256 * sizeof(struct glyph)); 252 return True; 253 } 254 fontp->fsize = size_found; 255 magic = two(fontp->file); 256 if (magic == PK_MAGIC) read_PK_index(fontp, hushcs); 257 else 258 if (magic == VF_MAGIC) read_VF_index(fontp, hushcs); 259 else 260 errx(1, "Cannot recognize format for font file '%s'", 261 fontp->filename); 262 263 if (fontp->flags & FONT_VIRTUAL) { 264 while (maxchar > 0 && fontp->macro[maxchar].pos == NULL) --maxchar; 265 if (maxchar < 255) 266 realloc_virtual_font(fontp, maxchar); 267 } 268 else { 269 while (maxchar > 0 && fontp->glyph[maxchar].addr == 0) --maxchar; 270 if (maxchar < 255) 271 realloc_font(fontp, maxchar); 272 } 273 return True; 274 } 275 276 277 /* 278 * MAGSTEPVALUE - If the given magnification is close to a \magstep 279 * or a \magstephalf, then return twice the number of \magsteps. 280 * Otherwise return NOMAGSTP. 281 */ 282 283 #define NOMAGSTP (-29999) 284 #define NOBUILD 29999 285 286 static int 287 magstepvalue(float *mag) 288 { 289 int m = 0; 290 double fmag = *mag; 291 double xmag = pixels_per_inch; 292 float margin = fmag * 0.002; 293 294 if (fmag < pixels_per_inch) 295 for (;;) { 296 if (xmag - fmag < margin && -(xmag - fmag) < margin) { 297 *mag = xmag; 298 return m; 299 } 300 if (xmag < fmag) break; 301 xmag *= 0.9128709292; 302 --m; 303 } 304 else 305 for (;;) { 306 if (xmag - fmag < margin && -(xmag - fmag) < margin) { 307 *mag = xmag; 308 return m; 309 } 310 if (xmag > fmag) break; 311 xmag *= 1.095445115; 312 ++m; 313 } 314 return NOMAGSTP; 315 } 316 317 318 /* 319 * reuse_font recursively sets the flags for font structures being reused. 320 */ 321 322 static void 323 reuse_font(struct font *fontp) 324 { 325 struct font **fp; 326 struct tn *tnp; 327 328 if (fontp->flags & FONT_IN_USE) return; 329 330 fontp->flags |= FONT_IN_USE; 331 if (resource._list_fonts) 332 printf("(reusing) %s at %d dpi\n", fontp->fontname, 333 (int) (fontp->fsize + 0.5)); 334 if (fontp->flags & FONT_VIRTUAL) { 335 for (fp = fontp->vf_table; fp < fontp->vf_table + VFTABLELEN; ++fp) 336 if (*fp != NULL) reuse_font(*fp); 337 for (tnp = fontp->vf_chain; tnp != NULL; tnp = tnp->next) 338 reuse_font(tnp->fontp); 339 } 340 } 341 342 343 /* 344 * define_font reads the rest of the fntdef command and then reads in 345 * the specified pixel file, adding it to the global linked-list holding 346 * all of the fonts used in the job. 347 * 348 * vfparent; vf parent of this font, or NULL 349 * tntable; table for low TeXnumbers 350 * tn_table_len; length of table for TeXnumbers 351 * tn_headpp; addr of head of list of TeXnumbers 352 * m; magnification 353 * 354 * returns NULL when a font cannot be loaded, non NULL otherwise. 355 */ 356 struct font * 357 define_font(FILE *file, unsigned char cmnd, struct font *vfparent, 358 struct font **tntable, unsigned int tn_table_len, 359 struct tn **tn_headpp, long m) 360 { 361 long k, c, s, d; 362 size_t a, l; 363 struct font *fontp; 364 float fsize; 365 double scale_dimconv; 366 int magstepval; 367 char *n; 368 int size; 369 370 k = num(file, (int) cmnd - FNTDEF1 + 1); 371 c = four(file); /* checksum */ 372 s = four(file); /* scale */ 373 d = four(file); /* design */ 374 a = one(file); /* area (directory) length */ 375 l = one(file); /* font name length */ 376 n = xmalloc(a + l + 1); 377 fread(n, sizeof(*n), a + l, file); 378 n[a + l] = '\0'; /* font name */ 379 380 if (debug & DBG_PK) 381 printf("Define font '%s' scale=%ld design=%ld\n", n, s, d); 382 383 if (vfparent == NULL) { 384 fsize = 0.001 * s / d * m * pixels_per_inch; 385 scale_dimconv = dimconv; 386 } 387 else { 388 /* 389 * The scaled size is given in units of vfparent->scale * 2 ** -20 390 * SPELL units, so we convert it into SPELL units by multiplying by 391 * vfparent->dimconv. 392 * The design size is given in units of 2 ** -20 pt, so we convert 393 * into SPELL units by multiplying by 394 * (pixels_per_inch * 2**16) / (72.27 * 2**20). 395 */ 396 fsize = (72.27 * (1<<4)) * vfparent->dimconv * s / d; 397 scale_dimconv = vfparent->dimconv; 398 } 399 400 magstepval = magstepvalue(&fsize); 401 size = fsize + 0.5; 402 403 /* 404 * reuse font if possible 405 */ 406 for (fontp = font_head; fontp != NULL; fontp = fontp->next) { 407 if (strcmp(n, fontp->fontname) != 0 || 408 size != (int) (fontp->fsize + 0.5)) 409 continue; 410 411 /* font already in use */ 412 reuse_font(fontp); 413 free(n); 414 break; 415 } 416 417 if (fontp == NULL) { 418 /* font doesn't exist yet */ 419 if (resource._list_fonts) 420 printf("%s at %d dpi\n", n, size); 421 fontp = xmalloc(sizeof(struct font)); 422 fontp->fontname = n; 423 fontp->fsize = fsize; 424 fontp->magstepval = magstepval; 425 fontp->file = NULL; /* needed for virtual/freetype fonts */ 426 fontp->filename = NULL; /* needed for freetype fonts */ 427 fontp->checksum = c; 428 fontp->flags = FONT_IN_USE; 429 fontp->dimconv = s * scale_dimconv / (1 << 20); 430 fontp->set_char_p = load_n_set_char; 431 fontp->ft = NULL; 432 /* spsize = scaled size of the font in spell units, 433 * = scale * [vfparent->]dimconv. 434 */ 435 fontp->spsize = (vfparent != NULL ? vfparent->dimconv : dimconv) * s; 436 if (vfparent == NULL) 437 if (!load_font(fontp)) { 438 free(n); 439 free(fontp); 440 return NULL; 441 } 442 fontp->next = font_head; 443 font_head = fontp; 444 } 445 446 if (k < tn_table_len) 447 tntable[k] = fontp; 448 else { 449 struct tn *tnp; 450 tnp = xmalloc(sizeof(struct tn)); 451 tnp->next = *tn_headpp; 452 *tn_headpp = tnp; 453 tnp->TeXnumber = k; 454 tnp->fontp = fontp; 455 } 456 return fontp; 457 } 458 459 Boolean 460 dvi_magic_ok(FILE *dvi) 461 { 462 if (one(dvi) != PRE) 463 /* Not a DVI file */ 464 return False; 465 if (one(dvi) != 2) 466 /* Wrong version of DVI output for this program */ 467 return False; 468 469 return True; 470 } 471 472 473 /* 474 * process_preamble reads the information in the preamble and stores 475 * it into global variables for later use. 476 */ 477 static Boolean 478 process_preamble(long *n, long *d, long *m) 479 { 480 char comment[256 + 1]; 481 size_t k; 482 483 if (dvi_magic_ok(dvi_file) == False) 484 return False; 485 *n = four(dvi_file); /* numerator */ 486 *d = four(dvi_file); /* denominator */ 487 *m = four(dvi_file); /* magnification */ 488 dimconv = (((double) (*n) * (*m)) / ((double) (*d) * 1000.)); 489 dimconv = dimconv * (((long) pixels_per_inch)<<16) / 254000; 490 tpic_conv = pixels_per_inch * (*m) / 1000000.0; 491 k = one(dvi_file); 492 fread(comment, sizeof(char), k, dvi_file); 493 comment[k] = '\0'; 494 495 if (debug & DBG_DVI) 496 printf("Preamble comment '%s'\n", comment); 497 498 return True; 499 } 500 501 /* 502 * find_postamble locates the beginning of the postamble 503 * and leaves the file ready to start reading at that location. 504 */ 505 #define TMPSIZ 516 /* 4 trailer bytes + 512 junk bytes allowed */ 506 static Boolean 507 find_postamble(void) 508 { 509 long pos; 510 unsigned char temp[TMPSIZ]; 511 unsigned char *p; 512 unsigned char *p1; 513 unsigned char byte; 514 515 if (fseek(dvi_file, 0, SEEK_END) != 0) 516 err(1, "fseek"); 517 pos = ftell(dvi_file) - TMPSIZ; 518 if (pos < 0) pos = 0; 519 if (fseek(dvi_file, pos, SEEK_SET) != 0) 520 err(1, "fseek"); 521 p = temp + fread((char *) temp, sizeof(char), TMPSIZ, dvi_file); 522 for (;;) { 523 p1 = p; 524 while (p1 > temp && *(--p1) != TRAILER) ; 525 p = p1; 526 while (p > temp && *(--p) == TRAILER) ; 527 if (p <= p1 - 4) break; /* found 4 TRAILER bytes */ 528 if (p <= temp) 529 /* DVI file corrupted */ 530 return False; 531 } 532 pos += p - temp; 533 byte = *p; 534 while (byte == TRAILER) { 535 if (fseek(dvi_file, --pos, SEEK_SET) != 0) 536 err(1, "fseek"); 537 byte = one(dvi_file); 538 } 539 if (byte != 2) 540 /* Wrong version of DVI output for this program */ 541 return False; 542 if (fseek(dvi_file, pos - 4, SEEK_SET) != 0) 543 err(1, "fseek"); 544 if (fseek(dvi_file, sfour(dvi_file), SEEK_SET) != 0) 545 err(1, "fseek"); 546 547 return True; 548 } 549 550 551 /* 552 * read_postamble reads the information in the postamble, 553 * storing it into global variables. 554 * It also takes care of reading in all of the pixel files for the fonts 555 * used in the job. 556 */ 557 static Boolean 558 read_postamble(long *p, long n, long d, long m) 559 { 560 unsigned char cmnd; 561 Boolean font_not_found; 562 struct font *fontp; 563 struct font **fontpp; 564 565 if (one(dvi_file) != POST) 566 /* Postamble doesn't begin with POST */ 567 return False; 568 *p = four(dvi_file); /* pointer to final bop (last page) */ 569 570 /* Check postamble duplicates match preamble. */ 571 if (n != four(dvi_file)) 572 return False; 573 if (d != four(dvi_file)) 574 return False; 575 if (m != four(dvi_file)) 576 return False; 577 578 /* read largest box height and width */ 579 dvi_unshrunk_page_h = (spell_conv(sfour(dvi_file)) >> 16) + offset_y; 580 if (dvi_unshrunk_page_h < unshrunk_paper_h) 581 dvi_unshrunk_page_h = unshrunk_paper_h; 582 dvi_unshrunk_page_w = (spell_conv(sfour(dvi_file)) >> 16) + offset_x; 583 if (dvi_unshrunk_page_w < unshrunk_paper_w) 584 dvi_unshrunk_page_w = unshrunk_paper_w; 585 (void) two(dvi_file); /* max stack size */ 586 total_pages = two(dvi_file); 587 588 /* 589 * Attempt to load all fonts for the file. If one is not found, 590 * keep searching such that we can show all fonts that are missing. 591 */ 592 font_not_found = False; 593 while (1) { 594 cmnd = one(dvi_file); 595 if (cmnd < FNTDEF1 || cmnd > FNTDEF4) 596 break; 597 if (define_font(dvi_file, cmnd, NULL, tn_table, TNTABLELEN, 598 &tn_head, m) == NULL) 599 font_not_found = True; 600 } 601 if (font_not_found == True) 602 return False; 603 if (cmnd != POSTPOST) 604 /* Non-fntdef command found in postamble */ 605 return False; 606 /* 607 * free up fonts no longer in use 608 */ 609 fontpp = &font_head; 610 while ((fontp = *fontpp) != NULL) { 611 if (fontp->flags & FONT_IN_USE) { 612 fontpp = &fontp->next; 613 continue; 614 } 615 if (debug & DBG_PK) 616 printf("Discarding font \"%s\" at %d dpi\n", 617 fontp->fontname, (int) (fontp->fsize + 0.5)); 618 *fontpp = fontp->next; /* remove from list */ 619 free(fontp->fontname); 620 if (fontp->flags & FONT_LOADED) { 621 if (fontp->ft != NULL) { /* if FreeType font */ 622 struct ftfont *ft; 623 624 ft = fontp->ft; 625 if (fontp->size != NULL) 626 FT_Done_Size(fontp->size); 627 if (fontp == ft->first_size) { 628 if (fontp->next_size == NULL) { 629 /* if this is the only size of this font face */ 630 FT_Done_Face(ft->face); 631 ft->t1->ft = NULL; 632 free(ft); 633 } 634 else { 635 struct font *fp2; 636 637 ft->first_size = fp2 = fontp->next_size; 638 fp2->file = fontp->file; 639 fontp->file = NULL; 640 fp2->filename = fontp->filename; 641 fontp->filename = NULL; 642 fp2->timestamp = fontp->timestamp; 643 } 644 } 645 else { 646 struct font *fp2; 647 648 fp2 = ft->first_size; 649 while (fp2->next_size != fontp) 650 fp2 = fp2->next_size; 651 fp2->next_size = fontp->next_size; 652 } 653 } 654 if (fontp->file != NULL) 655 fclose(fontp->file); 656 if (fontp->filename != NULL) 657 free((void *) fontp->filename); 658 659 if (fontp->flags & FONT_VIRTUAL) { 660 struct macro *m; 661 662 for (m = fontp->macro; 663 m <= fontp->macro + fontp->maxchar; ++m) 664 if (m->free_me) free((char *) m->pos); 665 free((char *) fontp->macro); 666 free((char *) fontp->vf_table); 667 free_vf_chain(fontp->vf_chain); 668 } 669 else { 670 struct glyph *g; 671 672 for (g = fontp->glyph; 673 g <= fontp->glyph + fontp->maxchar; ++g) { 674 if (g->bitmap.bits != NULL) free(g->bitmap.bits); 675 if (g->bitmap2.bits != NULL) free(g->bitmap2.bits); 676 if (g->pixmap2 != NULL) { 677 XDestroyImage(g->image2); 678 if (g->pixmap2_t != NULL) 679 free(g->pixmap2_t); 680 } 681 } 682 free((char *) fontp->glyph); 683 } 684 free((char *) fontp); 685 } 686 } 687 return True; 688 } 689 690 static void 691 prepare_pages(long p) 692 { 693 int i; 694 695 page_info = xmalloc((unsigned) (total_pages + 1) * sizeof(*page_info)); 696 page_info->pw = unshrunk_paper_w; 697 page_info->ph = unshrunk_paper_h; 698 page_info->ww = dvi_unshrunk_page_w; 699 page_info->wh = dvi_unshrunk_page_h; 700 ++page_info; /* this is indexed starting with -1 */ 701 702 i = total_pages; 703 page_info[--i].offset = p; 704 if (fseek(dvi_file, p, SEEK_SET) != 0) 705 err(1, "fseek"); 706 /* 707 * Follow back pointers through pages in the DVI file, 708 * storing the offsets in the page_info[].offset table. 709 */ 710 while (i > 0) { 711 if (fseek(dvi_file, (long) (1+4+(9*4)), SEEK_CUR) != 0) 712 err(1, "fseek"); 713 if (fseek(dvi_file, page_info[--i].offset = four(dvi_file), 714 SEEK_SET) != 0) 715 err(1, "fseek"); 716 } 717 } 718 719 void 720 init_page(void) 721 { 722 unshrunk_page_w = page_info[current_page].ww; 723 page_w = ROUNDUP(unshrunk_page_w, mane.shrinkfactor) + 2; 724 unshrunk_page_h = page_info[current_page].wh; 725 page_h = ROUNDUP(unshrunk_page_h, mane.shrinkfactor) + 2; 726 } 727 728 /* For non-toolkit compiles, this code appears in xdvi.c. */ 729 730 static void 731 set_titles(void) 732 { 733 char *title_name; 734 char *icon_name; 735 size_t baselen; 736 Boolean icon_name_malloced = False; 737 738 icon_name = rindex(dvi_name, '/'); 739 if (icon_name != NULL) ++icon_name; 740 else icon_name = dvi_name; 741 baselen = strlen(icon_name); 742 if (baselen > 4 && memcmp(icon_name + baselen - 4, ".dvi", 4) == 0) { 743 /* remove the .dvi */ 744 char *p; 745 746 baselen -= 4; 747 p = xmalloc(baselen + 1); 748 memcpy(p, icon_name, baselen); 749 p[baselen] = '\0'; 750 icon_name = p; 751 icon_name_malloced = True; 752 } 753 754 title_name = xmalloc(baselen + 8); 755 memcpy(title_name, "Xdvi: ", 7); 756 memcpy(title_name + 7, icon_name, baselen + 1); 757 758 XtVaSetValues(top_level, 759 XtNtitle, title_name, 760 XtNiconName, icon_name, 761 NULL); 762 763 free(title_name); 764 if (icon_name_malloced) 765 free(icon_name); 766 } 767 768 /* 769 * init_dvi_file is the main subroutine for reading the startup 770 * information from the dvi file. 771 */ 772 773 Boolean 774 init_dvi_file(void) 775 { 776 long n, d, m, p; 777 778 if (!process_preamble(&n, &d, &m)) 779 goto err; 780 if (!find_postamble()) 781 goto err; 782 if (!read_postamble(&p, n, d, m)) 783 goto err; 784 785 prepare_pages(p); 786 if (current_page >= total_pages) 787 current_page = total_pages - 1; 788 init_prescan(); 789 set_titles(); 790 791 return True; 792 793 err: 794 fclose(dvi_file); 795 dvi_file = NULL; 796 return False; 797 } 798 799 800 /** 801 ** Reload the dvi file (unconditionally). Called only from do_pages(). 802 **/ 803 804 Boolean 805 reload_dvi_file(void) 806 { 807 struct font *fontp; 808 809 if (page_info != NULL) { 810 free(page_info - 1); 811 page_info = NULL; 812 full_reset_colors(); 813 } 814 bzero(tn_table, sizeof(tn_table)); 815 free_vf_chain(tn_head); 816 tn_head = NULL; 817 for (fontp = font_head; fontp != NULL; fontp = fontp->next) 818 fontp->flags &= ~FONT_IN_USE; 819 820 if (fseek(dvi_file, 0, SEEK_SET) != 0) 821 err(1, "fseek"); 822 if (!init_dvi_file()) 823 return False; 824 if (resource._list_fonts) 825 putchar('\n'); 826 827 return True; 828 }