Annotation of 43BSDTahoe/new/X/libsun/font.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * font.c 
        !             3:  *
        !             4:  * Copyright (c) 1985 Massachusetts Institue of Technology
        !             5:  * Copyright (c) 1986 Sun Microsystems, Inc.
        !             6:  * Copyright (c) 1986 David C. Martin, UC Berkeley
        !             7:  *
        !             8:  * David C. Martin
        !             9:  * ARPA: [email protected]
        !            10:  * UUCP: ...!ucbvax!dcmartin
        !            11:  *
        !            12:  * $Log:       font.c,v $
        !            13:  * Revision 10.4  86/11/29  13:48:04  jg
        !            14:  * fixes from Berkeley
        !            15:  * 
        !            16:  * Revision 1.20  86/07/27  13:46:41  dcmartin
        !            17:  * more modifications to LoadVFont() to fix bugs w/ invalid pixrect pointers
        !            18:  * and variable height fonts.
        !            19:  * 
        !            20:  * Revision 1.19  86/07/25  15:36:56  dcmartin
        !            21:  * modified code in StrikeToPixfont() to free all sub-structures in 
        !            22:  * FontPriv pointer.
        !            23:  * 
        !            24:  * Revision 1.18  86/07/25  15:30:46  dcmartin
        !            25:  * changed all calls to Xalloc() to malloc() due to necessity of getting NULLs
        !            26:  * when ENOMEM.
        !            27:  * 
        !            28:  * Revision 1.17  86/07/25  14:40:18  dcmartin
        !            29:  * changed the algorithm for determining variable width.
        !            30:  * should work for all fonts, now.
        !            31:  * 
        !            32:  * Revision 1.16  86/07/17  10:47:00  dcmartin
        !            33:  * can't include <sys/param.h> on Sun release 2.x due to brain damage in
        !            34:  * compiler as <sys/param.h> wants to include <sys/types.h> and so does
        !            35:  * <pixrect/pixrect_hs.h> in Xsun.h
        !            36:  * 
        !            37:  * Revision 1.15  86/07/17  10:36:33  dcmartin
        !            38:  * release version w/ new LoadXFont() and support for Sun vfont files.
        !            39:  * 
        !            40:  * Revision 1.14  86/07/17  10:31:49  dcmartin
        !            41:  * 
        !            42:  */
        !            43: 
        !            44: #ifndef lint
        !            45: static char rcs_id[] = "$Header: font.c,v 10.4 86/11/29 13:48:04 jg Rel $";
        !            46: #endif lint
        !            47: 
        !            48: #include <X/mit-copyright.h>
        !            49: 
        !            50: /*
        !            51:  * The Sun X drivers are a product of Sun Microsystems, Inc. and are provided
        !            52:  * for unrestricted use provided that this legend is included on all tape
        !            53:  * media and as a part of the software program in whole or part.  Users
        !            54:  * may copy or modify these drivers without charge, but are not authorized
        !            55:  * to license or distribute them to anyone else except as part of a product or
        !            56:  * program developed by the user.
        !            57:  * 
        !            58:  * THE SUN X DRIVERS ARE PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND
        !            59:  * INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A
        !            60:  * PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE
        !            61:  * PRACTICE.
        !            62:  *
        !            63:  * The Sun X Drivers are provided with no support and without any obligation
        !            64:  * on the part of Sun Microsystems, Inc. to assist in their use, correction,
        !            65:  * modification or enhancement.
        !            66:  * 
        !            67:  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
        !            68:  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THE SUN X
        !            69:  * DRIVERS OR ANY PART THEREOF.
        !            70:  * 
        !            71:  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
        !            72:  * or profits or other special, indirect and consequential damages, even if
        !            73:  * Sun has been advised of the possibility of such damages.
        !            74:  * 
        !            75:  * Sun Microsystems, Inc.
        !            76:  * 2550 Garcia Avenue
        !            77:  * Mountain View, California  94043
        !            78:  */
        !            79: 
        !            80: #ifdef sun
        !            81: 
        !            82: #include "Xsun.h"
        !            83: #include "vssite.h"
        !            84: #include "../libvs100/param.h"
        !            85: #include <vfont.h>
        !            86: #include <sys/file.h>
        !            87: #include <sys/stat.h>
        !            88: #include <errno.h>
        !            89: #include <strings.h>
        !            90: 
        !            91: /* 
        !            92:  * from /usr/include/sys/param.h
        !            93:  */
        !            94: #define MAXPATHLEN     1024 
        !            95: 
        !            96: extern int      errno;
        !            97: extern char    *getenv();
        !            98: extern char    *malloc();
        !            99: extern long    lseek();
        !           100: 
        !           101: #define XFONT          0
        !           102: #define VFONT          1
        !           103: #define ReverseShort(s)        ((ReverseByte[(unsigned char)(s)]<<8) \
        !           104:                        | ReverseByte[(unsigned char)((s)>>8)])
        !           105: 
        !           106: static short    ReverseByte[256] = {
        !           107:                0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,
        !           108:                0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0, 
        !           109:                0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8,
        !           110:                0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8, 
        !           111:                0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4,
        !           112:                0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4, 
        !           113:                0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec,
        !           114:                0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc, 
        !           115:                0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2,
        !           116:                0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2,
        !           117:                0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea,
        !           118:                0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa, 
        !           119:                0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6,
        !           120:                0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6, 
        !           121:                0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee,
        !           122:                0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe, 
        !           123:                0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1,
        !           124:                0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1, 
        !           125:                0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9,
        !           126:                0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9, 
        !           127:                0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5,
        !           128:                0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5, 
        !           129:                0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed,
        !           130:                0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd,
        !           131:                0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3,
        !           132:                0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3,
        !           133:                0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb,
        !           134:                0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb,
        !           135:                0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7,
        !           136:                0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7, 
        !           137:                0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef,
        !           138:                0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
        !           139: };
        !           140: 
        !           141: extern struct pixrectops       mem_ops;
        !           142: static struct mpr_data         mprd;
        !           143: 
        !           144: /*
        !           145:  * These define the biggest font that will successfully load.
        !           146:  */
        !           147: #define MAX_FONT_WIDTH         60
        !           148: #define MAX_FONT_HEIGHT                60
        !           149: 
        !           150: static struct pixrect          spr = {
        !           151:                                        &mem_ops, 
        !           152:                                        256 * MAX_FONT_WIDTH, 
        !           153:                                        MAX_FONT_HEIGHT, 
        !           154:                                        1, 
        !           155:                                        (caddr_t) &mprd
        !           156:                                };
        !           157: 
        !           158: static struct pixfont *
        !           159: StrikeToPixfont(fp)
        !           160: FONT   *fp;
        !           161: {
        !           162:        register FontPriv       *fpp = (FontPriv *) fp->data;
        !           163:        register struct pixfont *pf;
        !           164:        register int            i, w;
        !           165:        register short          *sh, limit;
        !           166:        register struct pixchar *pc;
        !           167: 
        !           168:        pf = (struct pixfont *) malloc(sizeof(struct pixfont));
        !           169:        if (pf == (struct pixfont *) NULL) {
        !           170:                errno = ENOMEM;
        !           171:                return(pf);
        !           172:        }
        !           173:        bzero(pf, sizeof(struct pixfont));
        !           174:        limit = (fpp->wpitch / 2) * fp->height;
        !           175:        sh = (short *) fpp->fltable[0];
        !           176:        do {
        !           177:                *sh = ReverseShort(*sh);
        !           178:                sh++;
        !           179:        } while (--limit != -1);
        !           180:        mprd.md_linebytes = fpp->wpitch;
        !           181:        mprd.md_image = (short *) fpp->fltable[0];
        !           182:        bzero((caddr_t) pf, sizeof(struct pixfont));
        !           183:        pf->pf_defaultsize.y = fp->height;
        !           184:        if (fp->fixed) {
        !           185:                pf->pf_defaultsize.x = fp->avg_width;
        !           186:        }
        !           187:        /* for all the characters */
        !           188:        for (i = fp->first; i <= fp->last; i++) {
        !           189:                if ((w = fpp->widths[i]) < 0) 
        !           190:                        continue;
        !           191:                pc = &(pf->pf_char[i]);
        !           192:                pc->pc_pr = mem_create(w, fp->height, 1);
        !           193:                pc->pc_home.x = 0;
        !           194:                pc->pc_home.y = fp->height - fp->base;
        !           195:                pc->pc_adv.x = w;
        !           196:                pc->pc_adv.y = 0;
        !           197:                pr_rop(pc->pc_pr, 0, 0, w, fp->height, PIX_SRC,
        !           198:                       &spr, fpp->leftarray[i], 0);
        !           199:        }
        !           200:        free((caddr_t) fpp->leftarray);
        !           201:        free((caddr_t) fpp->widths);
        !           202:        free((caddr_t) fpp->strike);
        !           203:        free((caddr_t) fpp->fltable);
        !           204:        free((caddr_t) fpp);
        !           205:        return(pf);
        !           206: } /* end StrikeToPixfont() */
        !           207: 
        !           208: /*
        !           209:  * LoadXFont - load an xfont format file
        !           210:  *
        !           211:  * The FontData structure consists of {
        !           212:  *     short   f_characters[5]
        !           213:  *     short   f_firstChar
        !           214:  *     short   f_lastChar
        !           215:  *     short   f_leftArray[2]
        !           216:  *     short   f_baseline
        !           217:  *     short   f_spaceIndex
        !           218:  *     short   f_fixedWidth
        !           219:  * }
        !           220:  *
        !           221:  * The five shorts of f_characters[] are:
        !           222:  *     [0] - location (in bytes) from start of file where font data begins
        !           223:  *     [1] - unused
        !           224:  *     [2] - width of font bitmap pointed at by [0]
        !           225:  *     [3] - height of font bitmap
        !           226:  *     [4] - bits per pixel of font bitmap
        !           227:  *
        !           228:  * The two shorts of f_leftArray[] are:
        !           229:  *     [0] - location (in bytes) from start of file of bitmap offset array
        !           230:  *     [1] - unused
        !           231:  *
        !           232:  */
        !           233: static FONT *
        !           234: LoadXFont(fildes, name)
        !           235: int    fildes;
        !           236: caddr_t        name;
        !           237: {
        !           238:        register int    i, j;
        !           239:        int             font_nbytes, totalWidth, datasiz, tablesiz;
        !           240:        char            *fontdata;
        !           241:        short           *offset_table, *width_table;
        !           242:        FONT            *fp;
        !           243:        FontData        font;
        !           244:        FontPriv        *fpriv;
        !           245:        struct stat     stb;
        !           246: 
        !           247:        /* read in the xfont header */
        !           248:        if (read(fildes, (caddr_t) &font, sizeof(FontData)) != 
        !           249:                sizeof(FontData)) {
        !           250:                errno = EINVAL;
        !           251:                return (NULL);
        !           252:        }
        !           253:        /* byte swap */
        !           254:        Swap_shorts((short *) &font, sizeof(FontData) / sizeof(short));
        !           255:        /* determine the number of bytes in the bitmap */
        !           256:        font_nbytes = BitmapSize(font.f_characters[2], font.f_characters[3]);
        !           257:        /* stat the file to determine size */
        !           258:        fstat(fildes, &stb);
        !           259:        /* if the location of the offset table is > location of bitmap ... */
        !           260:        if (font.f_leftArray[0] > font.f_characters[0]) {
        !           261:                /* check for sufficient space for font bitmap */
        !           262:                if (font.f_leftArray[0] - font.f_characters[0] < font_nbytes) {
        !           263:                        /* no */
        !           264:                        errno = EINVAL;
        !           265:                        return(NULL);
        !           266:                }
        !           267:                /* determine the space allocated for the offset table */
        !           268:                tablesiz = stb.st_size - font.f_leftArray[0];
        !           269:                /* determine the space allocated for the font data */
        !           270:                datasiz = font.f_leftArray[0] - font.f_characters[0];
        !           271:        } else {
        !           272:                /* check for sufficient space for font bitmap */
        !           273:                if (font_nbytes + font.f_characters[0] > stb.st_size) {
        !           274:                        errno = EINVAL;
        !           275:                        return(NULL);
        !           276:                }
        !           277:                /* determine the space allocated for the offset table */
        !           278:                tablesiz = font.f_characters[0] - font.f_leftArray[0];
        !           279:                /* determine the space allocated for the font data */
        !           280:                datasiz = stb.st_size - font.f_characters[0];
        !           281:        }
        !           282:        /* are we going to ask for more than we have? */
        !           283:        if (font_nbytes > datasiz) {
        !           284:                errno = EINVAL;
        !           285:                return(NULL);
        !           286:        }
        !           287:        /* allocate space for the font bitmap */
        !           288:        fontdata = (caddr_t) malloc(font_nbytes);
        !           289:        if (fontdata == (caddr_t) NULL) {
        !           290:                errno = ENOMEM;
        !           291:                return(NULL);
        !           292:        }
        !           293:        /* seek to start of bitmap */
        !           294:        lseek(fildes, (long) font.f_characters[0], 0);
        !           295:        /* read it in */
        !           296:        if (read(fildes, fontdata, font_nbytes) != font_nbytes) {
        !           297:                free(fontdata);
        !           298:                errno = EINVAL;
        !           299:                return (NULL);
        !           300:        }
        !           301:        /* byte swap */
        !           302:        Swap_shorts((short *) fontdata, font_nbytes / sizeof(short));
        !           303:        /* is there an offset table? */
        !           304:        if (tablesiz == 0) {
        !           305:                /* no -- this had better be a fixed width font */
        !           306:                if (font.f_fixedWidth == 0) {
        !           307:                        free(fontdata);
        !           308:                        errno = EINVAL;
        !           309:                        return(NULL);
        !           310:                }
        !           311:                /* determine table size */
        !           312:                tablesiz = sizeof(short) * 
        !           313:                    (font.f_lastChar - font.f_firstChar + 2);
        !           314:                /* allocate space for table */
        !           315:                offset_table = (short *) malloc(tablesiz);
        !           316:                if (offset_table == (short *) NULL) {
        !           317:                        free(fontdata);
        !           318:                        errno = ENOMEM;
        !           319:                        return(NULL);
        !           320:                }
        !           321:                /* zero out the offset table */
        !           322:                bzero(offset_table, tablesiz);
        !           323:                /* build the offset table */
        !           324:                for (j=0, i = font.f_firstChar; i < font.f_lastChar + 2; i++) {
        !           325:                        offset_table[i] = j;
        !           326:                        j += font.f_fixedWidth;
        !           327:                }
        !           328:        } else {
        !           329:                /* allocate space for table */
        !           330:                offset_table = (short *) malloc(tablesiz);
        !           331:                if (offset_table == (short *) NULL) {
        !           332:                        free(fontdata);
        !           333:                        errno = ENOMEM;
        !           334:                        return(NULL);
        !           335:                }
        !           336:                /* zero out the offset table */
        !           337:                bzero(offset_table, tablesiz);
        !           338:                /* seek to offset array */
        !           339:                lseek(fildes, (long) font.f_leftArray[0], 0);
        !           340:                /* read the offset array */
        !           341:                if (read(fildes, (caddr_t) &offset_table[font.f_firstChar], 
        !           342:                    tablesiz) != tablesiz) {
        !           343:                        free(fontdata);
        !           344:                        free((caddr_t) offset_table);
        !           345:                        errno = EINVAL;
        !           346:                        return (NULL);
        !           347:                }
        !           348:                Swap_shorts(offset_table, tablesiz / sizeof(short));
        !           349:        }
        !           350:        /* allocate a width table -- to be built from the offset table */
        !           351:        width_table = (short *) malloc(tablesiz);
        !           352:        if (width_table == (short *) NULL) {
        !           353:                free(fontdata);
        !           354:                free((caddr_t) offset_table);
        !           355:                errno = ENOMEM;
        !           356:                return(NULL);
        !           357:        }
        !           358:        /* allocate space for the device dependent private font data */
        !           359:        fpriv = (FontPriv *) malloc(sizeof(FontPriv));
        !           360:        if (fpriv == (FontPriv *) NULL) {
        !           361:                free(fontdata);
        !           362:                free((caddr_t) offset_table);
        !           363:                free((caddr_t) width_table);
        !           364:                errno = ENOMEM;
        !           365:                return(NULL);
        !           366:        }
        !           367:        /* initialize */
        !           368:        fpriv->maxwidth = 0;
        !           369:        totalWidth = 0;
        !           370:        /* convert the offset table to the width table */
        !           371:        for (i = font.f_firstChar; i <= font.f_lastChar; i++) {
        !           372:                width_table[i] = offset_table[i + 1] - offset_table[i];
        !           373:                if (width_table[i] > fpriv->maxwidth) {
        !           374:                        fpriv->maxwidth = width_table[i];
        !           375:                }
        !           376:                if (width_table[i] < 0) {
        !           377:                        errno = EINVAL;
        !           378:                        return(NULL);
        !           379:                }
        !           380:                totalWidth += width_table[i];
        !           381:        }
        !           382:        fpriv->widths = width_table;
        !           383:        fpriv->leftarray = offset_table;
        !           384:        /* allocate space for the strike font */
        !           385:        fpriv->strike = (BITMAP *) malloc(sizeof(BITMAP));
        !           386:        if (fpriv->strike == (BITMAP *) NULL) {
        !           387:                free(fontdata);
        !           388:                free((caddr_t) offset_table);
        !           389:                free((caddr_t) width_table);
        !           390:                free((caddr_t) fpriv);
        !           391:                errno = ENOMEM;
        !           392:                return(NULL);
        !           393:        }
        !           394:        /* determine the number of bytes per line of the bitmap */
        !           395:        fpriv->wpitch = (((font.f_characters[2] + 15) >> 3) & ~1);
        !           396:        /* set other strike stuff .. */
        !           397:        fpriv->strike->width = font.f_characters[2];
        !           398:        fpriv->strike->height = font.f_characters[3];
        !           399:        fpriv->strike->refcnt = 1;
        !           400:        fpriv->strike->data = (caddr_t) fontdata;
        !           401:        /* allocate space for the font line table */
        !           402:        fpriv->fltable = (char **) malloc(font.f_characters[3]*sizeof(char *));
        !           403:        if (fpriv->fltable == (char **) NULL) {
        !           404:                free(fontdata);
        !           405:                free((caddr_t) offset_table);
        !           406:                free((caddr_t) width_table);
        !           407:                free((caddr_t) fpriv->strike);
        !           408:                free((caddr_t) fpriv);
        !           409:                errno = ENOMEM;
        !           410:                return(NULL);
        !           411:        }
        !           412:        /* compute the font line table entries */
        !           413:        for (i = 0; i < font.f_characters[3]; i++) {
        !           414:                fpriv->fltable[i] = ((caddr_t) fontdata) + i * fpriv->wpitch;
        !           415:        }
        !           416:        /* allocate an xfont */
        !           417:        fp = (FONT *) malloc(sizeof(FONT));
        !           418:        if (fp == (FONT *) NULL) {
        !           419:                free(fontdata);
        !           420:                free((caddr_t) offset_table);
        !           421:                free((caddr_t) width_table);
        !           422:                free((caddr_t) fpriv->strike);
        !           423:                free((caddr_t) fpriv->fltable);
        !           424:                free((caddr_t) fpriv);
        !           425:                errno = ENOMEM;
        !           426:                return(NULL);
        !           427:        }
        !           428:        fp->first = font.f_firstChar;
        !           429:        fp->last = font.f_lastChar;
        !           430:        fp->height = font.f_characters[3];
        !           431:        fp->base = font.f_baseline;
        !           432:        fp->space = font.f_spaceIndex + font.f_firstChar;
        !           433:        fp->refcnt = 1;
        !           434:        /* set the average width */
        !           435:        fp->avg_width = totalWidth / (fp->last - fp->first + 1);
        !           436:        if (fp->avg_width == font.f_fixedWidth) {
        !           437:                fp->fixed = 1;
        !           438:                fpriv->maxwidth = fp->avg_width;
        !           439:        } else {
        !           440:                fp->fixed = 0;
        !           441:        }
        !           442:        /* allocate space for the name */
        !           443:        fp->name = (caddr_t) malloc(strlen(name) + 1);
        !           444:        if (fp->name == (caddr_t) NULL) {
        !           445:                free(fontdata);
        !           446:                free((caddr_t) offset_table);
        !           447:                free((caddr_t) width_table);
        !           448:                free((caddr_t) fpriv->fltable);
        !           449:                free((caddr_t) fpriv->strike);
        !           450:                free((caddr_t) fpriv);
        !           451:                free((caddr_t) fp);
        !           452:                errno = ENOMEM;
        !           453:                return(NULL);
        !           454:        }
        !           455:        /* copy the name */
        !           456:        (void) strcpy(fp->name, name);
        !           457:        /* change private font to pixfont */
        !           458:        fp->data = (caddr_t) fpriv;
        !           459:        fp->data = (caddr_t) StrikeToPixfont(fp);
        !           460:        return (fp);
        !           461: } /* end LoadXFont() */
        !           462: 
        !           463: static FONT *
        !           464: LoadVFont(fd, name)
        !           465: int            fd;
        !           466: caddr_t                name;
        !           467: {
        !           468:        register int            i;
        !           469:        int                     fixed = 1;
        !           470:        register struct pixfont *pf = (struct pixfont *) NULL;
        !           471:        register struct pixchar *pc;
        !           472:        FONT                    *fp;
        !           473:        FILE                    *fonts;
        !           474:        short                   magic;
        !           475:        struct header           hd;
        !           476:        struct dispatch         disp[NUM_DISPATCH];
        !           477:        struct stat             stb;
        !           478:        int                     maxheight, maxwidth, maxup, maxdown;
        !           479: 
        !           480: #define        fbase (sizeof hd + sizeof disp)
        !           481: 
        !           482:        fonts = fdopen(fd, "r");
        !           483:        if (fonts == 0)
        !           484:                return (0);
        !           485:        if (fread(&hd, sizeof hd, 1, fonts) != 1 ||
        !           486:            fread(disp, sizeof disp, 1, fonts) != 1)
        !           487:                goto bad;
        !           488:        if (hd.magic != VFONT_MAGIC)
        !           489:                goto bad;
        !           490:        fstat(fd, &stb);
        !           491:        if (stb.st_size != fbase + hd.size)
        !           492:                goto bad;
        !           493: 
        !           494:        /* 
        !           495:         * Allocate font header and set default sizes. The default width of the
        !           496:         * font is taken to be the width of a lower-case a, if there is one.
        !           497:         * The default interline spacing is taken to be 3/2 the height of an
        !           498:         * upper-case A above the baseline.
        !           499:         */
        !           500:        pf = (struct pixfont *) malloc(sizeof(struct pixfont));
        !           501:        if (pf == (struct pixfont *) NULL)
        !           502:                goto bad;
        !           503:        /* zero out the pixfont */
        !           504:        bzero(pf, sizeof(struct pixfont));
        !           505:        /* initialize */
        !           506:        maxwidth = maxup = maxdown = 0;
        !           507:        /* determine maximum width, up and down for font */
        !           508:        for (i = 0; i < NUM_DISPATCH; i++) {
        !           509:                register struct dispatch        *d = &disp[i];
        !           510: 
        !           511:                if (d->left + d->right > maxwidth)
        !           512:                        maxwidth = d->left + d->right;
        !           513:                if (d->up > maxup)
        !           514:                        maxup = d->up;
        !           515:                if (d->down > maxdown)
        !           516:                        maxdown = d->down;
        !           517:        }
        !           518:        maxheight = maxup + maxdown;
        !           519:        pf->pf_defaultsize.x = maxwidth;
        !           520:        pf->pf_defaultsize.y = maxheight;
        !           521:        /* Create memory pixrects for characters of font. */
        !           522:        for (i = 0; i < NUM_DISPATCH; i++) {
        !           523:                register struct dispatch        *d = &disp[i];
        !           524:                struct pr_size                  size;
        !           525:                struct pixrect                  *cpr;
        !           526:                int                             j, wb, ww;
        !           527:                short                           *sp;
        !           528: 
        !           529:                /* pointer to character */
        !           530:                pc = &pf->pf_char[i];
        !           531:                /* if there is no glyph, there is no character */
        !           532:                if (d->nbytes == 0) {
        !           533:                        pc->pc_pr = (struct pixrect *) NULL;
        !           534:                        pc->pc_home.x = 0;
        !           535:                        pc->pc_home.y = 0;
        !           536:                        pc->pc_adv.x = 0;
        !           537:                        pc->pc_adv.y = 0;
        !           538:                        continue;
        !           539:                }
        !           540:                /* total character width */
        !           541:                size.x = d->left + d->right;
        !           542:                /* total character height */
        !           543:                size.y = d->up + d->down;
        !           544:                /* check for variable width */
        !           545:                if (size.x != 0 && pf->pf_defaultsize.x != size.x)
        !           546:                        fixed = 0;
        !           547:                /* get width in bytes and words */
        !           548:                wb = (size.x + 7) >> 3;
        !           549:                ww = (size.x + 15) >> 4;
        !           550:                /* create a memory pixrect for character */
        !           551:                if ((cpr = mem_create(size, 1)) == (struct pixrect *) NULL)
        !           552:                        goto bad;
        !           553:                /* pointer to pixrect data */
        !           554:                sp = mpr_d(cpr)->md_image;
        !           555:                /* seek to character */
        !           556:                fseek(fonts, fbase + d->addr, 0);
        !           557:                /* read in the bytes */
        !           558:                for (j = 0; j < size.y; j++) {
        !           559:                        fread((caddr_t) sp, wb, 1, fonts);
        !           560:                        sp += ww;
        !           561:                }
        !           562:                /* check to make sure all characters are the same height */
        !           563:                if (size.y != maxheight) {
        !           564:                        register struct pixrect *npr;
        !           565: 
        !           566:                        npr = mem_create(size.x, maxheight, 1);
        !           567:                        if (npr == (struct pixrect *) NULL)
        !           568:                                goto bad;
        !           569:                        d->up = maxup - d->up;
        !           570:                        pr_rop(npr, 0, d->up, size.x, maxheight,
        !           571:                                PIX_SRC, cpr, 0, 0);
        !           572:                        (void) pr_destroy(cpr);
        !           573:                        cpr = npr;
        !           574:                }
        !           575:                /* set character pixrect pointer */
        !           576:                pc->pc_pr = cpr;
        !           577:                /* home from left edge */
        !           578:                pc->pc_home.x = -d->left;
        !           579:                /* home from baseline */
        !           580:                pc->pc_home.y = -d->up;
        !           581:                /* character horizonal advance */
        !           582:                pc->pc_adv.x = d->width;
        !           583:                /* character vertical advance (vfont == 0) */
        !           584:                pc->pc_adv.y = 0;
        !           585:        }
        !           586:        goto good;
        !           587: bad:
        !           588:        free(pf);
        !           589:        errno = EINVAL;
        !           590:        return(NULL);
        !           591: good:
        !           592:        fclose(fonts);
        !           593: 
        !           594:        /* allocate space for the X font description */
        !           595:        if ((fp = (FONT *) malloc(sizeof(FONT))) == (FONT *) NULL) {
        !           596:                free((caddr_t) pf);
        !           597:                errno = ENOMEM;
        !           598:                return(NULL);
        !           599:        }
        !           600:        /* allocate space for font name */
        !           601:        if ((fp->name = malloc(strlen(name) + 1)) == NULL) {
        !           602:                free((caddr_t) pf);
        !           603:                free((caddr_t) fp);
        !           604:                errno = ENOMEM;
        !           605:                return(NULL);
        !           606:        }
        !           607:        /* copy the name */
        !           608:        (void) strcpy(name, fp->name);
        !           609:        /* set the X font attributes */
        !           610:        if (fixed == 1) {
        !           611:                fp->fixed = 1;
        !           612:                fp->avg_width = pf->pf_defaultsize.x;
        !           613:        } else {
        !           614:                fp->fixed = 0;
        !           615:                fp->avg_width = 0;
        !           616:        }
        !           617:        fp->first = 0;
        !           618:        fp->last = 255;
        !           619:        fp->space = 32;
        !           620:        fp->height = maxheight;
        !           621:        fp->base = maxdown;
        !           622:        fp->refcnt = 1;
        !           623:        fp->data = (caddr_t) pf;
        !           624:        return(fp);
        !           625: } /* end LoadVFont() */
        !           626: 
        !           627: static int
        !           628: OpenFile(FileName, type_ptr)
        !           629: char   *FileName;
        !           630: int    *type_ptr;
        !           631: {
        !           632:        int             fd;
        !           633:        struct header   hdrbuf;
        !           634: 
        !           635:        /* open the file */
        !           636:        if ((fd = open(FileName, O_RDONLY, 0)) < 0) {
        !           637:                return(-1);
        !           638:        }       
        !           639:        /* read header buffer */
        !           640:        if (read(fd, (caddr_t) &hdrbuf, sizeof(struct header)) == 
        !           641:                sizeof(struct header)) {
        !           642:                /* read \something/ -- now check the magic number */
        !           643:                if (hdrbuf.magic == VFONT_MAGIC) {
        !           644:                        /* VFONT */
        !           645:                        *type_ptr = VFONT;
        !           646:                } else {
        !           647:                        /* XFONT */
        !           648:                        *type_ptr = XFONT;
        !           649:                }
        !           650:                /* rewind */
        !           651:                (void) lseek(fd, (long) 0, 0);
        !           652:                /* return the file descriptor */
        !           653:                return(fd);
        !           654:        }
        !           655:        /* bad read -- close and return -1 */
        !           656:        close(fd);
        !           657:        return(-1);
        !           658: } /* end OpenFile() */
        !           659: 
        !           660: static caddr_t
        !           661: SearchXFontPath(fname)
        !           662: register caddr_t       fname;
        !           663: {
        !           664:        register caddr_t        cp, pp, c2p;
        !           665:        static char             xfontpath[MAXPATHLEN];
        !           666: 
        !           667:        /* check for an absolute pathname */
        !           668:        if (*fname == '/') {
        !           669:                if (access(fname, R_OK) == 0)
        !           670:                        return(fname);
        !           671:                else
        !           672:                        return((caddr_t) NULL);
        !           673:        }
        !           674: 
        !           675:        /* get the environment variable for XFONTPATH */
        !           676:        if ((pp = getenv("XFONTPATH")) == (caddr_t) NULL) {
        !           677:                pp = DEFAULT_FONT_PATH;
        !           678:        }
        !           679: 
        !           680:        for (; *pp != '\0'; pp++) {
        !           681:                for (cp = xfontpath; *pp != ':' && *pp != '\0'; *cp++ = *pp++);
        !           682:                *cp++ = '/';
        !           683:                for (c2p = fname; *c2p != '\0'; *cp++ = *c2p++);
        !           684:                for (c2p = DEFAULT_FONT_SUFFIX; *c2p != '\0'; *cp++ = *c2p++);
        !           685:                *cp = '\0';
        !           686:                if (access(xfontpath, R_OK) == 0) {
        !           687:                        return(xfontpath);
        !           688:                }
        !           689:        }
        !           690:        return ((caddr_t) NULL);
        !           691: } /* end SearchXFontPath() */
        !           692: 
        !           693: static int
        !           694: FindFile(name, font_type)
        !           695: char   *name;
        !           696: int    *font_type;
        !           697: {
        !           698:        caddr_t         pathname;
        !           699:        int             fd;
        !           700: 
        !           701:        if ((pathname = SearchXFontPath(name)) == (caddr_t) NULL) {
        !           702:                return(-1);
        !           703:        }
        !           704:        if ((fd = OpenFile(pathname, font_type)) < 0) {
        !           705:                return(-1);
        !           706:        }
        !           707:        return(fd);
        !           708: } /* end FindFile() */
        !           709: 
        !           710: extern FONT *
        !           711: GetFont(name)
        !           712: caddr_t        name;
        !           713: {
        !           714:        int     fd, type;
        !           715:        FONT    *fp;
        !           716: 
        !           717:        if ((fd = FindFile(name, &type)) < 0) {
        !           718:                errno = EINVAL;
        !           719:                return ((FONT *) NULL);
        !           720:        }
        !           721: 
        !           722:        switch (type) {
        !           723:        case VFONT: 
        !           724:                fp = LoadVFont(fd, name); 
        !           725:                break;
        !           726:        case XFONT: 
        !           727:                fp = LoadXFont(fd, name); 
        !           728:                break;
        !           729:        default:
        !           730:                close(fd);
        !           731:                errno = EINVAL;
        !           732:                return((FONT *) NULL);
        !           733:        } /* end switch */
        !           734:        close(fd);
        !           735:        if (fp == (FONT *) NULL) {
        !           736:                errno = EINVAL;
        !           737:                return((FONT *) NULL);
        !           738:        }
        !           739:        return(fp);
        !           740: } /* end GetFont() */
        !           741: 
        !           742: FreeFont(font)
        !           743: FONT   *font;
        !           744: {
        !           745:        pf_close((caddr_t) font->data);
        !           746:        free(font->name);
        !           747:        free((caddr_t) font);
        !           748: }
        !           749: 
        !           750: #endif sun

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.