Back to index

tetex-bin  3.0
vf.c
Go to the documentation of this file.
00001 /*========================================================================*\
00002 
00003 Copyright (c) 1992-2004  Paul Vojta
00004 
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to
00007 deal in the Software without restriction, including without limitation the
00008 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00009 sell copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011 
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00018 PAUL VOJTA OR ANY OTHER AUTHOR OF THIS SOFTWARE BE LIABLE FOR ANY CLAIM,
00019 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00020 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00021 OTHER DEALINGS IN THE SOFTWARE.
00022 
00023 \*========================================================================*/
00024 
00025 /*
00026  *     VF font reading routines.
00027  *     Public routine is read_index---because virtual characters are presumed
00028  *     to be short, we read the whole virtual font in at once, instead of
00029  *     faulting in characters as needed.
00030  */
00031 
00032 #include "xdvi-config.h"
00033 #include "dvi.h"
00034 #include "xdvi.h"
00035 #include "util.h"
00036 #include "dvi-init.h"
00037 #include "dvi-draw.h"
00038 
00039 #define       LONG_CHAR     242
00040 
00041 /*
00042  *     These are parameters which determine whether macros are combined for
00043  *     storage allocation purposes.  Small macros ( <= VF_PARM_1 bytes) are
00044  *     combined into chunks of size VF_PARM_2.
00045  */
00046 
00047 #ifndef       VF_PARM_1
00048 #define       VF_PARM_1     20
00049 #endif
00050 #ifndef       VF_PARM_2
00051 #define       VF_PARM_2     256
00052 #endif
00053 
00054 /*
00055  *     The main routine
00056  */
00057 
00058 unsigned long
00059 read_VF_index(struct font *fontp, wide_bool hushcs)
00060 {
00061     FILE *VF_file = fontp->file;
00062     ubyte cmnd;
00063     ubyte *avail, *availend;       /* available space for macros */
00064     long checksum;
00065     struct macro *newmacro;
00066     unsigned long maxcc = 0;
00067     Boolean dummy = False;
00068     
00069     fontp->read_char = NULL;
00070     fontp->flags |= FONT_VIRTUAL;
00071     fontp->set_char_p = set_vf_char;
00072     if (globals.debug & DBG_PK)
00073        printf("Reading VF file %s\n", fontp->filename);
00074     /*
00075      * Read preamble.
00076      */
00077     fseek(VF_file, (long)get_byte(VF_file), SEEK_CUR);  /* skip comment */
00078     checksum = get_bytes(VF_file, 4);
00079     if (checksum != fontp->checksum && checksum != 0 && fontp->checksum != 0
00080        && !hushcs)
00081        XDVI_WARNING((stderr, "Checksum mismatch (dvi = %lu, vf = %lu) in font file %s",
00082                     fontp->checksum, checksum, fontp->filename));
00083     (void)get_bytes(VF_file, 4);   /* skip design size */
00084     /*
00085      * Read the fonts.
00086      */
00087     fontp->vf_table = xmalloc(VFTABLELEN * sizeof(struct font *));
00088     memset((char *)fontp->vf_table, 0, VFTABLELEN * sizeof(struct font *));
00089     fontp->vf_chain = NULL;
00090     fontp->first_font = NULL;
00091     while ((cmnd = get_byte(VF_file)) >= FNTDEF1 && cmnd <= FNTDEF4) {
00092        struct font *newfontp = define_font(True,
00093                                        VF_file, cmnd, fontp,
00094                                        fontp->vf_table, VFTABLELEN,
00095                                        &fontp->vf_chain,
00096                                        &dummy);
00097        if (fontp->first_font == NULL)
00098            fontp->first_font = newfontp;
00099     }
00100     /*
00101      * Prepare macro array.
00102      */
00103     if (resource.omega) {
00104        fontp->maxchar = 65535;
00105        fontp->macro = xmalloc(65536 * sizeof(struct macro));
00106        memset((char *)fontp->macro, 0, 65536 * sizeof(struct macro));
00107     }
00108     else {
00109        fontp->macro = xmalloc(256 * sizeof(struct macro));
00110        memset((char *)fontp->macro, 0, 256 * sizeof(struct macro));
00111     }
00112     /*
00113      * Read macros.
00114      */
00115     avail = availend = NULL;
00116     for (; cmnd <= LONG_CHAR; cmnd = get_byte(VF_file)) {
00117        struct macro *m;
00118        int len;
00119        unsigned long cc;
00120        long width;
00121 
00122        if (cmnd == LONG_CHAR) {    /* long form packet */
00123            len = get_bytes(VF_file, 4);
00124            cc = get_bytes(VF_file, 4);
00125            width = get_bytes(VF_file, 4);
00126            if ((resource.omega && cc >= 65536)
00127               || (!resource.omega && cc >= 256)) {
00128               XDVI_WARNING((stderr, "Virtual character %lu in font %s ignored.",
00129                            cc, fontp->fontname));
00130               fseek(VF_file, (long)len, SEEK_CUR);
00131               continue;
00132            }
00133        }
00134        else { /* short form packet */
00135            len = cmnd;
00136            cc = get_byte(VF_file);
00137            width = get_bytes(VF_file, 3);
00138        }
00139        if (resource.omega) {
00140            maxcc = (cc > maxcc) ? cc : maxcc;
00141        }
00142        m = &fontp->macro[cc];
00143        m->dvi_adv = width * fontp->dimconv;
00144        if (len > 0) {
00145            if (len <= availend - avail) {
00146               m->pos = avail;
00147               avail += len;
00148            }
00149            else {
00150               m->free_me = True;
00151               if (len <= VF_PARM_1) {
00152                   m->pos = avail = xmalloc(VF_PARM_2);
00153                   availend = avail + VF_PARM_2;
00154                   avail += len;
00155               }
00156               else
00157                   m->pos = xmalloc((unsigned)len);
00158            }
00159            fread((char *)m->pos, 1, len, VF_file);
00160            m->end = m->pos + len;
00161        }
00162        if (globals.debug & DBG_PK)
00163             printf("Read VF macro for character %lu; dy = %ld, length = %d\n",
00164                   cc, m->dvi_adv, len);
00165     }
00166     if (cmnd != POST)
00167        XDVI_FATAL((stderr, "Wrong command byte found in VF macro list:  %d", cmnd));
00168 
00169     fclose(VF_file);
00170     fontp->file = NULL;
00171     if (resource.omega) {
00172        size_t i;
00173        newmacro = xmalloc((maxcc + 1) * sizeof(struct macro));
00174        for (i = 0; i <= maxcc; i++) {
00175            newmacro[i] = fontp->macro[i];
00176        }
00177        free(fontp->macro);
00178        fontp->macro = newmacro;
00179        fontp->maxchar = maxcc;
00180        return maxcc;
00181     }
00182     else
00183        return 0; /* dummy */
00184 }