Back to index

tetex-bin  3.0
vf.c
Go to the documentation of this file.
00001 /*  $Header$
00002 
00003     This is dvipdfm, a DVI to PDF translator.
00004     Copyright (C) 1998, 1999 by Mark A. Wicks
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019     
00020     The author may be contacted via the e-mail address
00021 
00022        mwicks@kettering.edu
00023 */
00024 
00025 #include <stdio.h>
00026 #include <ctype.h>
00027 #include "system.h"
00028 #include "mfileio.h"
00029 #include "pdflimits.h"
00030 #include "numbers.h"
00031 #include "mem.h"
00032 #include "error.h"
00033 #include "tfm.h"
00034 #include "pdfdev.h"
00035 #include "dvi.h"
00036 #include "vf.h"
00037 #include "config.h"
00038 
00039 #include "dvicodes.h"
00040 
00041 #define VF_ID 202
00042 #define FIX_WORD_BASE 1048576.0
00043 #define TEXPT2PT (72.0/72.27)
00044 #define FW2PT (TEXPT2PT/((double)(FIX_WORD_BASE)))
00045 
00046 static unsigned char verbose = 0, debug = 0;
00047 
00048 void vf_set_verbose(void)
00049 {
00050   if (verbose < 255) {
00051     verbose += 1;
00052   }
00053 }
00054 
00055 
00056 struct font_def {
00057   signed long font_id /* id used internally in vf file */;
00058   unsigned long checksum, size, design_size;
00059   char *directory, *name;
00060   int tfm_id;  /* id returned by TFM module */
00061   int dev_id;  /* id returned by DEV module */
00062 };
00063 
00064 
00065 typedef struct font_def dev_font;
00066 
00067 struct vf 
00068 {
00069   char *tex_name;
00070   spt_t ptsize;
00071   unsigned long design_size; /* A fixword-pts quantity */
00072   int num_dev_fonts, max_dev_fonts;
00073   dev_font *dev_fonts;
00074   unsigned char **ch_pkt;
00075   unsigned long *pkt_len;
00076   unsigned num_chars;
00077 };
00078 
00079 struct vf *vf_fonts = NULL;
00080 int num_vf_fonts = 0, max_vf_fonts = 0;
00081 
00082 static int read_header(FILE *vf_file, int thisfont) 
00083 {
00084   int i, result = 1, ch;
00085 
00086   /* Check for usual signature */
00087   if ((ch = get_unsigned_byte (vf_file)) == PRE &&
00088       (ch = get_unsigned_byte (vf_file)) == VF_ID) {
00089 
00090     /* If here, assume it's a legitimate vf file */
00091     ch = get_unsigned_byte (vf_file);
00092 
00093     /* skip comment */
00094     for (i=0; i<ch; i++)
00095       get_unsigned_byte (vf_file);
00096 
00097     /* Skip checksum */
00098     get_unsigned_quad(vf_file);
00099     
00100     vf_fonts[thisfont].design_size =
00101       get_unsigned_quad(vf_file);
00102   } else { /* Try to fail gracefully and return an error to caller */
00103     fprintf (stderr, "VF file may be corrupt\n");
00104     result = 0;
00105   }
00106   return result;
00107 }
00108 
00109 
00110 static void resize_vf_fonts(int size)
00111 {
00112   int i;
00113   if (size > max_vf_fonts) {
00114     vf_fonts = RENEW (vf_fonts, size, struct vf);
00115     for (i=max_vf_fonts; i<size; i++) {
00116       vf_fonts[i].num_dev_fonts = 0;
00117       vf_fonts[i].max_dev_fonts = 0;
00118       vf_fonts[i].dev_fonts = NULL;
00119     }
00120     max_vf_fonts = size;
00121   }
00122   return;
00123 }
00124 
00125 static void resize_one_vf_font (struct vf *a_vf, unsigned size) 
00126 {
00127   unsigned i;
00128   if (size > (a_vf->num_chars)) {
00129     size = MAX (size, a_vf->num_chars+256);
00130     a_vf->ch_pkt = RENEW (a_vf->ch_pkt, size, unsigned char *);
00131     a_vf->pkt_len = RENEW (a_vf->pkt_len, size, unsigned long);
00132     for (i=a_vf->num_chars; i<size; i++) {
00133       (a_vf->ch_pkt)[i] = NULL;
00134       (a_vf->pkt_len)[i] = 0;
00135     }
00136     a_vf->num_chars = size;
00137   }
00138 }
00139 
00140 static void read_a_char_def(FILE *vf_file, int thisfont, unsigned long pkt_len,
00141                          unsigned ch)
00142 {
00143   unsigned char *pkt;
00144   if (debug)
00145     fprintf (stderr, "read_a_char_def: len=%ld, ch=%d\n", pkt_len, ch);
00146   /* Resize and initialize character arrays if necessary */
00147   if (ch >= vf_fonts[thisfont].num_chars) {
00148     resize_one_vf_font (vf_fonts+thisfont, ch+1);
00149   }
00150   if (pkt_len > 0) {
00151     pkt = NEW (pkt_len, unsigned char);
00152     if (fread (pkt, 1, pkt_len, vf_file) != pkt_len)
00153       ERROR ("VF file ended prematurely.");
00154     (vf_fonts[thisfont].ch_pkt)[ch] = pkt;
00155   }
00156   (vf_fonts[thisfont].pkt_len)[ch] = pkt_len;
00157   return;
00158 }
00159 
00160 static void read_a_font_def(FILE *vf_file, signed long font_id, int thisfont)
00161 {
00162   dev_font *dev_font;
00163   int dir_length, name_length;
00164   if (debug) {
00165     fprintf (stderr, "read_a_font_def: font_id = %ld\n", font_id);
00166   }
00167   if (vf_fonts[thisfont].num_dev_fonts >=
00168       vf_fonts[thisfont].max_dev_fonts) {
00169     vf_fonts[thisfont].max_dev_fonts += VF_ALLOC_SIZE;
00170     vf_fonts[thisfont].dev_fonts = RENEW
00171       (vf_fonts[thisfont].dev_fonts,
00172        vf_fonts[thisfont].max_dev_fonts,
00173        struct font_def);
00174   }
00175   dev_font = vf_fonts[thisfont].dev_fonts+
00176     vf_fonts[thisfont].num_dev_fonts;
00177   dev_font -> font_id = font_id;
00178   dev_font -> checksum = get_unsigned_quad (vf_file);
00179   dev_font -> size = get_unsigned_quad (vf_file);
00180   dev_font -> design_size = get_unsigned_quad (vf_file);
00181   dir_length = get_unsigned_byte (vf_file);
00182   name_length = get_unsigned_byte (vf_file);
00183   dev_font -> directory = NEW (dir_length+1, char);
00184   dev_font -> name = NEW (name_length+1, char);
00185   fread (dev_font -> directory, 1, dir_length, vf_file);
00186   fread (dev_font -> name, 1, name_length, vf_file);
00187   (dev_font -> directory)[dir_length] = 0;
00188   (dev_font -> name)[name_length] = 0;
00189   vf_fonts[thisfont].num_dev_fonts += 1;
00190   dev_font->tfm_id = tfm_open (dev_font -> name);
00191   dev_font->dev_id =
00192     dvi_locate_font (dev_font->name, 
00193                    sqxfw (vf_fonts[thisfont].ptsize,
00194                          dev_font->size));
00195   if (debug) {
00196     fprintf (stderr, "[%s/%s]\n", dev_font -> directory, dev_font -> name);
00197   }
00198   return;
00199 }
00200 
00201 
00202 void process_vf_file (FILE *vf_file, int thisfont)
00203 {
00204   int eof = 0, code;
00205   unsigned long font_id;
00206   while (!eof) {
00207     code = get_unsigned_byte (vf_file);
00208     switch (code) {
00209     case FNT_DEF1:
00210       font_id = get_unsigned_byte (vf_file);
00211       read_a_font_def (vf_file, font_id, thisfont);
00212       break;
00213     case FNT_DEF2:
00214       font_id = get_unsigned_pair (vf_file);
00215       read_a_font_def (vf_file, font_id, thisfont);
00216       break;
00217     case FNT_DEF3:
00218       font_id = get_unsigned_triple(vf_file);
00219       read_a_font_def (vf_file, font_id, thisfont);
00220       break;
00221     case FNT_DEF4:
00222       font_id = get_signed_quad(vf_file);
00223       read_a_font_def (vf_file, font_id, thisfont);
00224       break;
00225     default:
00226       if (code < 242) {
00227        long ch;
00228        /* For a short packet, code is the pkt_len */
00229        ch = get_unsigned_byte (vf_file);
00230        /* Skip over TFM width since we already know it */
00231        get_unsigned_triple (vf_file);
00232        read_a_char_def (vf_file, thisfont, code, ch);
00233        break;
00234       }
00235       if (code == 242) {
00236        unsigned long pkt_len, ch;
00237        pkt_len = get_unsigned_quad(vf_file);
00238        ch = get_unsigned_quad (vf_file);
00239        /* Skip over TFM width since we already know it */
00240        get_unsigned_quad (vf_file);
00241        if (ch < 65536L) 
00242          read_a_char_def (vf_file, thisfont, pkt_len, ch);
00243        else {
00244          fprintf (stderr, "char=%ld\n", ch);
00245          ERROR ("Long character (>16 bits) in VF file.\nI can't handle long characters!\n");
00246        }
00247        break;
00248       }
00249       if (code == POST) {
00250        eof = 1;
00251        break;
00252       }
00253       fprintf (stderr, "Quitting on code=%d\n", code);
00254       eof = 1;
00255       break;
00256     }
00257   }
00258   return;
00259 }
00260 
00261 /* Unfortunately, the following code isn't smart enough
00262    to load the vf only once for multiple point sizes. 
00263    You will get a separate copy of each VF in memory (and a separate
00264    opening and reading of the file) for
00265    each point size.  Since VFs are pretty small, I guess
00266    this is tolerable for now.  In any case, 
00267    the PDF file will never repeat a physical font name */
00268 /* Note: This code needs to be able to recurse */
00269 /* Global variables such as num_vf_fonts require careful attention */
00270 int vf_locate_font (char *tex_name, spt_t ptsize)
00271 {
00272   int thisfont = -1, i;
00273   char *full_vf_file_name;
00274   FILE *vf_file;
00275   /* Has this name and ptsize already been loaded as a VF? */
00276   for (i=0; i<num_vf_fonts; i++) {
00277     if (!strcmp (vf_fonts[i].tex_name, tex_name) &&
00278        vf_fonts[i].ptsize == ptsize) 
00279       break;
00280   }
00281   if (i != num_vf_fonts) {
00282     thisfont = i;
00283   } else {
00284     /* It's hasn't already been loaded as a VF, so try to load it */
00285     full_vf_file_name = kpse_find_file (tex_name, 
00286                                    kpse_vf_format,
00287                                    1);
00288 #ifdef HAVE_OMEGA_FORMATS
00289     if (!full_vf_file_name) {
00290       full_vf_file_name = kpse_find_file (tex_name, 
00291                                      kpse_ovf_format,
00292                                      1);
00293     }
00294 #endif
00295     if (full_vf_file_name &&
00296        (vf_file = MFOPEN (full_vf_file_name, FOPEN_RBIN_MODE)) != NULL) {
00297       if (verbose == 1)
00298        fprintf (stderr, "(VF:%s", tex_name);
00299       if (verbose > 1)
00300        fprintf (stderr, "(VF:%s", full_vf_file_name);
00301       if (num_vf_fonts >= max_vf_fonts) {
00302        resize_vf_fonts (max_vf_fonts + VF_ALLOC_SIZE);
00303       }
00304       thisfont = num_vf_fonts++;
00305       { /* Initialize some pointers and such */
00306        vf_fonts[thisfont].tex_name = NEW (strlen(tex_name)+1, char);
00307        strcpy (vf_fonts[thisfont].tex_name, tex_name);
00308        vf_fonts[thisfont].ptsize = ptsize;
00309        vf_fonts[thisfont].num_chars = 0;
00310        vf_fonts[thisfont].ch_pkt = NULL;
00311        vf_fonts[thisfont].pkt_len = NULL;
00312       }
00313       read_header(vf_file, thisfont);
00314       process_vf_file (vf_file, thisfont);
00315       if (verbose)
00316        fprintf (stderr, ")");
00317       MFCLOSE (vf_file);
00318     }
00319   }
00320   return thisfont;
00321 }
00322 
00323 #define next_byte() (*((*start)++))
00324 static UNSIGNED_BYTE unsigned_byte (unsigned char **start, unsigned char *end)
00325 {
00326   UNSIGNED_BYTE byte = 0;
00327   if (*start < end)
00328     byte = next_byte();
00329   else
00330     ERROR ("Premature end of DVI byte stream in VF font\n");
00331   return byte;
00332 }
00333 
00334 static SIGNED_BYTE signed_byte (unsigned char **start, unsigned char *end)
00335 {
00336   int byte = 0;
00337   if (*start < end) {
00338     byte = next_byte();
00339     if (byte >= 0x80) 
00340       byte -= 0x100;
00341   }
00342   else
00343     ERROR ("Premature end of DVI byte stream in VF font\n");
00344   return (SIGNED_BYTE) byte;
00345 }
00346 
00347 static UNSIGNED_PAIR unsigned_pair (unsigned char **start, unsigned char *end)
00348 {
00349   int i;
00350   UNSIGNED_BYTE byte;
00351   UNSIGNED_PAIR pair = 0;
00352   if (end-*start > 1) {
00353     for (i=0; i<2; i++) {
00354       byte = next_byte();
00355       pair = pair*0x100u + byte;
00356     }
00357   }
00358   else
00359     ERROR ("Premature end of DVI byte stream in VF font\n");
00360   return pair;
00361 }
00362 
00363 static SIGNED_PAIR signed_pair (unsigned char **start, unsigned char *end)
00364 {
00365   int i;
00366   long pair = 0;
00367   if (end - *start > 1) {
00368     for (i=0; i<2; i++) {
00369       pair = pair*0x100 + next_byte();
00370     }
00371     if (pair >= 0x8000) {
00372       pair -= 0x10000l;
00373     }
00374   } else
00375     ERROR ("Premature end of DVI byte stream in VF font\n");
00376   return (SIGNED_PAIR) pair;
00377 }
00378 
00379 static UNSIGNED_TRIPLE unsigned_triple(unsigned char **start, unsigned
00380                                 char *end)
00381 {
00382   int i;
00383   long triple = 0;
00384   if (end-*start > 2) {
00385     for (i=0; i<3; i++) {
00386       triple = triple*0x100u + next_byte();
00387     }
00388   } else
00389     ERROR ("Premature end of DVI byte stream in VF font\n");
00390   return (UNSIGNED_TRIPLE) triple;
00391 }
00392 
00393 static SIGNED_TRIPLE signed_triple(unsigned char **start, unsigned char *end)
00394 {
00395   int i;
00396   long triple = 0;
00397   if (end-*start > 2) {
00398     for (i=0; i<3; i++) {
00399       triple = triple*0x100 + next_byte();
00400     }
00401     if (triple >= 0x800000l) 
00402        triple -= 0x1000000l;
00403   } else
00404     ERROR ("Premature end of DVI byte stream in VF font\n");
00405   return (SIGNED_TRIPLE) triple;
00406 }
00407 
00408 static SIGNED_QUAD signed_quad(unsigned char **start, unsigned char *end)
00409 {
00410   int byte, i;
00411   long quad = 0;
00412   /* Check sign on first byte before reading others */
00413   if (end-*start > 3) {
00414     byte = next_byte();
00415     quad = byte;
00416     if (quad >= 0x80) 
00417       quad = byte - 0x100;
00418     for (i=0; i<3; i++) {
00419       quad = quad*0x100 + next_byte();
00420     }
00421   } else
00422     ERROR ("Premature end of DVI byte stream in VF font\n");
00423   return (SIGNED_QUAD) quad;
00424 }
00425 
00426 static UNSIGNED_QUAD unsigned_quad(unsigned char **start, unsigned char *end)
00427 {
00428   int i;
00429   unsigned long quad = 0;
00430   if (end-*start > 3) {
00431     for (i=0; i<4; i++) {
00432       quad = quad*0x100u + next_byte();
00433     }
00434   } else
00435     ERROR ("Premature end of DVI byte stream in VF font\n");
00436   return (UNSIGNED_QUAD) quad;
00437 }
00438 
00439 static void vf_set (SIGNED_QUAD ch)
00440 {
00441   /* Defer to the dvi_set() defined in dvi.c */
00442   dvi_set (ch);
00443   return;
00444 }
00445 
00446 static void vf_set1(unsigned char **start, unsigned char *end) 
00447 {
00448   vf_set (unsigned_byte(start, end));
00449   return;
00450 }
00451 
00452 static void vf_set2(unsigned char **start, unsigned char *end) 
00453 {
00454   vf_set (unsigned_pair(start, end));
00455   return;
00456 }
00457 
00458 static void vf_putrule(unsigned char **start, unsigned char *end, spt_t ptsize)
00459 {
00460   SIGNED_QUAD width, height;
00461   height = signed_quad (start, end);
00462   width = signed_quad (start, end);
00463   if (width > 0 && height > 0) {
00464     dvi_rule (sqxfw(ptsize,width), sqxfw(ptsize, height));
00465   }
00466   return;
00467 }
00468 
00469 static void vf_setrule(unsigned char **start, unsigned char *end, spt_t ptsize)
00470 {
00471   SIGNED_QUAD width, height, s_width;
00472   height = signed_quad (start, end);
00473   width = signed_quad (start, end);
00474   s_width = sqxfw(ptsize, width);
00475   if (width > 0 && height > 0) {
00476     dvi_rule (s_width, sqxfw(ptsize, height));
00477   }
00478   dvi_right (s_width);
00479   return;
00480 }
00481 
00482 static void vf_put1(unsigned char **start, unsigned char *end)
00483 {
00484   dvi_put (unsigned_byte(start, end));
00485   return;
00486 }
00487 
00488 static void vf_put2(unsigned char **start, unsigned char *end)
00489 {
00490   dvi_put (unsigned_pair(start, end));
00491   return;
00492 }
00493 
00494 static void vf_push(void)
00495 {
00496   dvi_push();
00497   return;
00498 }
00499 
00500 static void vf_pop(void)
00501 {
00502   dvi_pop();
00503   return;
00504 }
00505 
00506 static void vf_right (SIGNED_QUAD x, spt_t ptsize)
00507 {
00508   dvi_right ((SIGNED_QUAD) (sqxfw(ptsize, x)));
00509   return;
00510 }
00511 
00512 
00513 static void vf_right1(unsigned char **start, unsigned char *end, spt_t ptsize)
00514 {
00515   vf_right (signed_byte (start, end), ptsize);
00516   return;
00517 }
00518 
00519 static void vf_right2(unsigned char **start, unsigned char *end, spt_t ptsize)
00520 {
00521   vf_right (signed_pair (start, end), ptsize);
00522   return;
00523 }
00524 
00525 static void vf_right3(unsigned char **start, unsigned char *end, spt_t ptsize)
00526 {
00527   vf_right (signed_triple (start, end), ptsize);
00528   return;
00529 }
00530 
00531 static void vf_right4(unsigned char **start, unsigned char *end, spt_t ptsize)
00532 {
00533   vf_right (signed_quad (start, end), ptsize);
00534   return;
00535 }
00536 
00537 static void vf_w0(void)
00538 {
00539   dvi_w0();
00540   return;
00541 }
00542 
00543 static void vf_w (SIGNED_QUAD w, spt_t ptsize)
00544 {
00545   dvi_w ((SIGNED_QUAD) (sqxfw(ptsize, w)));
00546   return;
00547 }
00548 
00549 static void vf_w1(unsigned char **start, unsigned char *end, spt_t ptsize)
00550 {
00551   vf_w (signed_byte(start, end), ptsize);
00552   return;
00553 }
00554 
00555 static void vf_w2(unsigned char **start, unsigned char *end, spt_t ptsize)
00556 {
00557   vf_w (signed_pair(start, end), ptsize);
00558   return;
00559 }
00560 
00561 static void vf_w3(unsigned char **start, unsigned char *end, spt_t ptsize)
00562 {
00563   vf_w (signed_triple(start, end), ptsize);
00564   return;
00565 }
00566 
00567 static void vf_w4(unsigned char **start, unsigned char *end, spt_t ptsize)
00568 {
00569   vf_w (signed_quad(start, end), ptsize);
00570   return;
00571 }
00572 
00573 static void vf_x0(void)
00574 {
00575   dvi_x0();
00576   return;
00577 }
00578 
00579 static void vf_x (SIGNED_QUAD x, spt_t ptsize)
00580 {
00581   dvi_x ((SIGNED_QUAD) (sqxfw(ptsize, x)));
00582   return;
00583 }
00584 
00585 static void vf_x1(unsigned char **start, unsigned char *end, spt_t ptsize)
00586 {
00587   vf_x (signed_byte(start, end), ptsize);
00588   return;
00589 }
00590 
00591 static void vf_x2(unsigned char **start, unsigned char *end, spt_t ptsize)
00592 {
00593   vf_x (signed_pair(start, end), ptsize);
00594   return;
00595 }
00596 
00597 static void vf_x3(unsigned char **start, unsigned char *end, spt_t ptsize)
00598 {
00599   vf_x (signed_triple(start, end), ptsize);
00600   return;
00601 }
00602 
00603 static void vf_x4(unsigned char **start, unsigned char *end, spt_t ptsize)
00604 {
00605   vf_x (signed_quad(start, end), ptsize);
00606   return;
00607 }
00608 
00609 static void vf_down (SIGNED_QUAD y, spt_t ptsize)
00610 {
00611   dvi_down ((SIGNED_QUAD) (sqxfw(ptsize, y)));
00612   return;
00613 }
00614 
00615 static void vf_down1(unsigned char **start, unsigned char *end, spt_t ptsize)
00616 {
00617   vf_down (signed_byte(start, end), ptsize);
00618   return;
00619 }
00620 
00621 static void vf_down2(unsigned char **start, unsigned char *end, spt_t ptsize)
00622 {
00623   vf_down (signed_pair(start, end), ptsize);
00624   return;
00625 }
00626 
00627 static void vf_down3(unsigned char **start, unsigned char *end, spt_t ptsize)
00628 {
00629   vf_down (signed_triple(start, end), ptsize);
00630   return;
00631 }
00632 
00633 static void vf_down4(unsigned char **start, unsigned char *end, spt_t ptsize)
00634 {
00635   vf_down (signed_quad(start, end), ptsize);
00636   return;
00637 }
00638 
00639 static void vf_y0(void)
00640 {
00641   dvi_y0();
00642   return;
00643 }
00644 
00645 static void vf_y (SIGNED_QUAD y, spt_t ptsize)
00646 {
00647   dvi_y ((SIGNED_QUAD) (sqxfw(ptsize, y)));
00648   return;
00649 }
00650 
00651 
00652 static void vf_y1(unsigned char **start, unsigned char *end, spt_t ptsize)
00653 {
00654   vf_y (signed_byte(start, end), ptsize);
00655   return;
00656 }
00657 
00658 static void vf_y2(unsigned char **start, unsigned char *end, spt_t ptsize)
00659 {
00660   vf_y (signed_pair(start, end), ptsize);
00661   return;
00662 }
00663 
00664 static void vf_y3(unsigned char **start, unsigned char *end, spt_t ptsize)
00665 {
00666   vf_y (signed_triple(start, end), ptsize);
00667   return;
00668 }
00669 
00670 static void vf_y4(unsigned char **start, unsigned char *end, spt_t ptsize)
00671 {
00672   vf_y (signed_quad(start, end), ptsize);
00673   return;
00674 }
00675 
00676 static void vf_z0(void)
00677 {
00678   dvi_z0();
00679   return;
00680 }
00681 
00682 static void vf_z (SIGNED_QUAD z, spt_t ptsize)
00683 {
00684   dvi_z ((SIGNED_QUAD) (sqxfw(ptsize, z)));
00685   return;
00686 }
00687 
00688 static void vf_z1(unsigned char **start, unsigned char *end, spt_t ptsize)
00689 {
00690   vf_z (signed_byte(start, end), ptsize);
00691   return;
00692 }
00693 
00694 static void vf_z2(unsigned char **start, unsigned char *end, spt_t ptsize)
00695 {
00696   vf_z (signed_pair(start, end), ptsize);
00697   return;
00698 }
00699 
00700 static void vf_z3(unsigned char **start, unsigned char *end, spt_t ptsize)
00701 {
00702   vf_z (signed_triple(start, end), ptsize);
00703   return;
00704 }
00705 
00706 static void vf_z4(unsigned char **start, unsigned char *end, spt_t ptsize)
00707 {
00708   vf_z (signed_quad(start, end), ptsize);
00709   return;
00710 }
00711 
00712 static void vf_fnt (SIGNED_QUAD font_id, unsigned long vf_font)
00713 {
00714   int i;
00715   for (i=0; i<vf_fonts[vf_font].num_dev_fonts; i++) {
00716     if (font_id == ((vf_fonts[vf_font].dev_fonts)[i]).font_id) {
00717       break;
00718     }
00719   }
00720   if (i < vf_fonts[vf_font].num_dev_fonts) { /* Font was found */
00721     dvi_set_font ((vf_fonts[vf_font].dev_fonts[i]).dev_id);
00722   } else {
00723     fprintf (stderr, "Font_id: %ld not found in VF\n", font_id);
00724   }
00725   return;
00726 }
00727 
00728 static void vf_fnt1(unsigned char **start, unsigned char *end,
00729                   unsigned long vf_font)
00730 {
00731   vf_fnt (unsigned_byte(start, end), vf_font);
00732   return;
00733 }
00734 
00735 static void vf_fnt2(unsigned char **start, unsigned char *end,
00736                   unsigned long vf_font)
00737 {
00738   vf_fnt (unsigned_pair(start, end), vf_font);
00739   return;
00740 }
00741 
00742 static void vf_fnt3(unsigned char **start, unsigned char *end,
00743                   unsigned long vf_font)
00744 {
00745   vf_fnt (unsigned_triple(start, end), vf_font);
00746   return;
00747 }
00748 
00749 static void vf_fnt4(unsigned char **start, unsigned char *end,
00750                   unsigned long vf_font)
00751 {
00752   vf_fnt (signed_quad(start, end), vf_font);
00753   return;
00754 }
00755 
00756 static void vf_xxx (SIGNED_QUAD len, unsigned char **start, unsigned
00757                   char *end)
00758 {
00759   /* For now, skip specials */
00760   if (end-*start >= len)
00761     *start += len;
00762   else 
00763     ERROR ("Premature end of DVI byte stream in VF font\n");
00764   return;
00765 }
00766 
00767 static void vf_xxx1(unsigned char **start, unsigned char *end)
00768 {
00769   vf_xxx (unsigned_byte(start, end), start, end);
00770   return;
00771 }
00772 
00773 static void vf_xxx2(unsigned char **start, unsigned char *end)
00774 {
00775   vf_xxx (unsigned_pair(start, end), start, end);
00776   return;
00777 }
00778 
00779 static void vf_xxx3(unsigned char **start, unsigned char *end)
00780 {
00781   vf_xxx (unsigned_triple(start, end), start, end);
00782   return;
00783 }
00784 
00785 static void vf_xxx4(unsigned char **start, unsigned char *end)
00786 {
00787   vf_xxx (unsigned_quad(start, end), start, end);
00788   return;
00789 }
00790 
00791 void vf_set_char(SIGNED_QUAD ch, int vf_font)
00792 {
00793   unsigned char opcode;
00794   unsigned char *start, *end;
00795   spt_t ptsize;
00796   int default_font = -1;
00797   if (vf_font < num_vf_fonts) {
00798     /* Initialize to the first font or -1 if undefined */
00799     ptsize = vf_fonts[vf_font].ptsize;
00800     if (vf_fonts[vf_font].num_dev_fonts > 0)
00801       default_font = ((vf_fonts[vf_font].dev_fonts)[0]).dev_id;
00802     dvi_vf_init (default_font);
00803     if (ch >= vf_fonts[vf_font].num_chars ||
00804        !(start = (vf_fonts[vf_font].ch_pkt)[ch])) {
00805       fprintf (stderr, "\nchar=0x%lx(%ld)\n", ch, ch);
00806       fprintf (stderr, "Tried to set a nonexistent character in a virtual font");
00807       start = end = NULL;
00808     } else {
00809       end = start + (vf_fonts[vf_font].pkt_len)[ch];
00810     }
00811     while (start && start < end) {
00812       opcode = *(start++);
00813       if (debug) {
00814        fprintf (stderr, "VF opcode: %d", opcode);
00815        if (isprint (opcode)) fprintf (stderr, " (\'%c\')\n", opcode);
00816        else  fprintf (stderr, "\n");
00817       }
00818       switch (opcode)
00819        {
00820        case SET1:
00821          vf_set1(&start, end);
00822          break;
00823        case SET2:
00824          vf_set2(&start, end);
00825          break;
00826        case SET3:
00827        case SET4:
00828          ERROR ("Multibyte (>16 bits) character in VF packet.\nI can't handle this!");
00829          break;
00830        case SET_RULE:
00831          vf_setrule(&start, end, ptsize);
00832          break;
00833        case PUT1:
00834          vf_put1(&start, end);
00835          break;
00836        case PUT2:
00837          vf_put2(&start, end);
00838          break;
00839        case PUT3:
00840        case PUT4:
00841          ERROR ("Multibyte (>16 bits) character in VF packet.\nI can't handle this!");
00842          break;
00843        case PUT_RULE:
00844          vf_putrule(&start, end, ptsize);
00845          break;
00846        case NOP:
00847          break;
00848        case PUSH:
00849          vf_push();
00850          break;
00851        case POP:
00852          vf_pop();
00853          break;
00854        case RIGHT1:
00855          vf_right1(&start, end, ptsize);
00856          break;
00857        case RIGHT2:
00858          vf_right2(&start, end, ptsize);
00859          break;
00860        case RIGHT3:
00861          vf_right3(&start, end, ptsize);
00862          break;
00863        case RIGHT4:
00864          vf_right4(&start, end, ptsize);
00865          break;
00866        case W0:
00867          vf_w0();
00868          break;
00869        case W1:
00870          vf_w1(&start, end, ptsize);
00871          break;
00872        case W2:
00873          vf_w2(&start, end, ptsize);
00874          break;
00875        case W3:
00876          vf_w3(&start, end, ptsize);
00877          break;
00878        case W4:
00879          vf_w4(&start, end, ptsize);
00880          break;
00881        case X0:
00882          vf_x0();
00883          break;
00884        case X1:
00885          vf_x1(&start, end, ptsize);
00886          break;
00887        case X2:
00888          vf_x2(&start, end, ptsize);
00889          break;
00890        case X3:
00891          vf_x3(&start, end, ptsize);
00892          break;
00893        case X4:
00894          vf_x4(&start, end, ptsize);
00895          break;
00896        case DOWN1:
00897          vf_down1(&start, end, ptsize);
00898          break;
00899        case DOWN2:
00900          vf_down2(&start, end, ptsize);
00901          break;
00902        case DOWN3:
00903          vf_down3(&start, end, ptsize);
00904          break;
00905        case DOWN4:
00906          vf_down4(&start, end, ptsize);
00907          break;
00908        case Y0:
00909          vf_y0();
00910          break;
00911        case Y1:
00912          vf_y1(&start, end, ptsize);
00913          break;
00914        case Y2:
00915          vf_y2(&start, end, ptsize);
00916          break;
00917        case Y3:
00918          vf_y3(&start, end, ptsize);
00919          break;
00920        case Y4:
00921          vf_y4(&start, end, ptsize);
00922          break;
00923        case Z0:
00924          vf_z0();
00925          break;
00926        case Z1:
00927          vf_z1(&start, end, ptsize);
00928          break;
00929        case Z2:
00930          vf_z2(&start, end, ptsize);
00931          break;
00932        case Z3:
00933          vf_z3(&start, end, ptsize);
00934          break;
00935        case Z4:
00936          vf_z4(&start, end, ptsize);
00937          break;
00938        case FNT1:
00939          vf_fnt1(&start, end, vf_font);
00940          break;
00941        case FNT2:
00942          vf_fnt2(&start, end, vf_font);
00943          break;
00944        case FNT3:
00945          vf_fnt3(&start, end, vf_font);
00946          break;
00947        case FNT4:
00948          vf_fnt4(&start, end, vf_font);
00949          break;
00950        case XXX1:
00951          vf_xxx1(&start, end);
00952          break;
00953        case XXX2:
00954          vf_xxx2(&start, end);
00955          break;
00956        case XXX3:
00957          vf_xxx3(&start, end);
00958          break;
00959        case XXX4:
00960          vf_xxx4(&start, end);
00961          break;
00962        default:
00963          if (opcode <= SET_CHAR_127) {
00964            vf_set (opcode);
00965          } else if (opcode >= FNT_NUM_0 && opcode <= FNT_NUM_63) {
00966            vf_fnt (opcode - FNT_NUM_0, vf_font);
00967          } else {
00968            fprintf (stderr, "Unexpected opcode: %d\n", opcode);
00969            ERROR ("Unexpected opcode in vf file\n");
00970          }
00971        }
00972     }
00973     dvi_vf_finish();
00974   } else {
00975     fprintf (stderr, "vf_set_char: font: %d", vf_font);
00976     ERROR ("Font not loaded\n");
00977   }
00978   return;
00979 }
00980 
00981 
00982 void vf_close_all_fonts(void)
00983 {
00984   unsigned long i;
00985   int j;
00986   dev_font *one_font;
00987 #ifdef MEM_DEBUG
00988 MEM_START
00989 #endif
00990   for (i=0; i<num_vf_fonts; i++) {
00991     /* Release the packet for each character */
00992     if (vf_fonts[i].ch_pkt) {
00993       for (j=0; j<vf_fonts[i].num_chars; j++) {
00994        if ((vf_fonts[i].ch_pkt)[j] != NULL)
00995          RELEASE ((vf_fonts[i].ch_pkt)[j]);
00996       }
00997       RELEASE (vf_fonts[i].ch_pkt);
00998     }
00999     if (vf_fonts[i].pkt_len)
01000       RELEASE (vf_fonts[i].pkt_len);
01001     if (vf_fonts[i].tex_name)
01002       RELEASE (vf_fonts[i].tex_name);
01003     /* Release each font record */
01004     for (j=0; j<vf_fonts[i].num_dev_fonts; j++) {
01005       one_font = &(vf_fonts[i].dev_fonts)[j];
01006       RELEASE (one_font -> directory);
01007       RELEASE (one_font -> name);
01008     }
01009     if (vf_fonts[i].dev_fonts != NULL)
01010       RELEASE (vf_fonts[i].dev_fonts);
01011   }
01012   if (vf_fonts != NULL)
01013     RELEASE (vf_fonts);
01014 #ifdef MEM_DEBUG
01015 MEM_END
01016 #endif
01017   return;
01018 }