Back to index

tetex-bin  3.0
t1funcs.c
Go to the documentation of this file.
00001 /* $XConsortium: t1funcs.c,v 1.10 92/05/12 18:07:55 gildea Exp $ */
00002 /* Copyright International Business Machines,Corp. 1991
00003  * All Rights Reserved
00004  *
00005  * License, subject to the license given below, to use,
00006  * copy, modify, and distribute this software * and its
00007  * documentation for any purpose and without fee is hereby
00008  * granted, provided that the above copyright notice appear
00009  * in all copies and that both that copyright notice and
00010  * this permission notice appear in supporting documentation,
00011  * and that the name of IBM not be used in advertising or
00012  * publicity pertaining to distribution of the software
00013  * without specific, written prior permission.
00014  *
00015  * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
00016  * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
00017  * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
00018  * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
00019  * THIRD PARTY RIGHTS.  THE ENTIRE RISK AS TO THE QUALITY AND
00020  * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
00021  * OR MAINTAIN, BELONGS TO THE LICENSEE.  SHOULD ANY PORTION OF
00022  * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
00023  * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION.  IN
00024  * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
00025  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
00026  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
00027  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
00028  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00029  * SOFTWARE.
00030  *
00031  * Author: Jeffrey B. Lotspiech, IBM Almaden Research Center
00032  *   Modeled on spfuncs.c by Dave Lemke, Network Computing Devices, Inc
00033  *   which contains the following copyright and permission notices:
00034  *
00035  * Copyright 1990, 1991 Network Computing Devices;
00036  * Portions Copyright 1987 by Digital Equipment Corporation and the
00037  * Massachusetts Institute of Technology
00038  *
00039  * Permission to use, copy, modify, and distribute this protoype software
00040  * and its documentation to Members and Affiliates of the MIT X Consortium
00041  * any purpose and without fee is hereby granted, provided
00042  * that the above copyright notice appear in all copies and that both that
00043  * copyright notice and this permission notice appear in supporting
00044  * documentation, and that the names of Network Computing Devices, Digital or
00045  * MIT not be used in advertising or publicity pertaining to distribution of
00046  * the software without specific, written prior permission.
00047  *
00048  * NETWORK COMPUTING DEVICES, DIGITAL AND MIT DISCLAIM ALL WARRANTIES WITH
00049  * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00050  * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, DIGITAL OR MIT BE
00051  * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00052  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
00053  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
00054  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00055  */
00056  
00057 #include    "types.h"
00058 #include    <string.h>
00059 #include    "ffilest.h"
00060 #ifdef XSERVER
00061 #include    <X11/Xfuncs.h>
00062 #include    "FSproto.h"
00063 #endif
00064 #include    "t1intf.h"
00065 
00066 #include "objects.h"
00067 #include "spaces.h"
00068 #include "regions.h"
00069 #include "t1stdio.h"
00070 #include "util.h"
00071 #include "fontfcn.h"
00072 
00073 typedef char *encoding[256];
00074 
00075 #ifdef HAVE_PROTOTYPES
00076 int Type1OpenScalable(char **ev, struct _Font **ppFont, int flags,
00077                     struct _FontEntry *entry, char *fileName,
00078                     struct _FontScalable *vals, fsBitmapFormat format,
00079                     ULONG fmask, double efactor,double slant);
00080 static int Type1GetGlyphs(struct _Font *pFont, ULONG count,
00081                        unsigned char *chars, FontEncoding charEncoding,
00082                        ULONG *glyphCount, struct _CharInfo **glyphs );
00083 void Type1CloseFont(struct _Font *pFont);
00084 extern int Type1GetInfoScalable(struct _FontPathElement *fpe,
00085                             struct _FontInfo *pInfo,
00086                             struct _FontEntry *entry,
00087                             struct _FontName *fontName,
00088                             char *fileName,
00089                             struct _FontScalable *Vals);
00090 static int Type1GetMetrics(struct _Font *pFont, ULONG count,
00091                         unsigned char *chars, FontEncoding charEncoding,
00092                         ULONG *glyphCount, xCharInfo **glyphs );
00093 static void fillrun(register char *p,pel x0,pel x1,int bit);
00094 extern char * Xalloc(int size);
00095 extern void Xfree(void*);
00096 static void fill(char *dest,int h,int w,struct region *area,
00097                int byte,int bit,int wordsize);
00098 extern Bool fontfcnA(char *env,int *mode);
00099 extern struct region *fontfcnB(struct XYspace *S, unsigned char *code,
00100                             int *lenP, int *mode);
00101 extern int FontDefaultFormat(int *bit, int *byte, 
00102                           int *glyphs, int *scan);
00103 extern int CheckFSFormat(int format,int fmask,int *bit,int *byte,int *scan,int *glyph,int *image);
00104 extern void QueryFontLib(char *env,char *infoName,void *infoValue,int *rcodeP);
00105 extern void T1FillFontInfo(struct _Font *pFont,struct _FontScalable *Vals,char *Filename,char *Fontname);
00106 extern void T1InitStdProps(void);
00107 extern int FontFileRegisterRenderer(FontRendererRec *);
00108 #else
00109 int         Type1OpenScalable ();
00110 static int  Type1GetGlyphs();
00111 void        Type1CloseFont();
00112 extern int  Type1GetInfoScalable ();
00113  
00114 static int  Type1GetMetrics ();
00115  
00116 static void fillrun();
00117  
00118 extern char *Xalloc();
00119 extern void Xfree();
00120 static void fill();
00121 
00122 extern Bool fontfcnA();
00123 extern struct region *fontfcnB();
00124 extern int CheckFSFormat();
00125 extern void QueryFontLib();
00126 extern void T1FillFontInfo();
00127 extern void T1InitStdProps();
00128 extern int FontFileRegisterRenderer();
00129 #endif
00130 
00131 extern psfont *FontP;
00132 extern psobj *ISOLatin1EncArrayP;
00133  
00134 #define DECIPOINTSPERINCH 722.7
00135 
00136 extern int currentchar; /* for error reporting */
00137 
00138 /*ARGSUSED*/
00139 int Type1OpenScalable (ev, ppFont, flags, entry, fileName, vals, format,
00140                      fmask, efactor, slant)
00141     encoding         ev;
00142     FontPtr             *ppFont;
00143     int                 flags;
00144     FontEntryPtr        entry;
00145     char                *fileName;
00146     FontScalablePtr     vals;
00147     fsBitmapFormat      format;
00148     fsBitmapFormatMask  fmask;
00149     DOUBLE              efactor;
00150     DOUBLE              slant;
00151 {
00152        extern struct XYspace *IDENTITY;
00153  
00154        FontPtr     pFont;
00155        int         bit,
00156                    byte,
00157                    glyph,
00158                    scan,
00159                    image;
00160        int pad,wordsize;     /* scan & image in bits                         */
00161        int size;             /* for memory size calculations                 */
00162        struct XYspace *S;    /* coordinate space for character               */
00163        struct region *area;
00164        DOUBLE scale;         /* scale factor for font                        */
00165        DOUBLE txx, tyx, txy, tyy;
00166        CharInfoRec *glyphs;
00167        register int i;
00168        int len,rc;
00169        struct type1font *type1;
00170        char *p;
00171 
00172        /* set up default values */
00173        FontDefaultFormat(&bit, &byte, &glyph, &scan);
00174        /* get any changes made from above */
00175        rc = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image);
00176        if (rc != Successful)
00177                return rc;
00178  
00179        pad                = glyph * 8;
00180        wordsize           = scan * 8;
00181  
00182 #define  PAD(bits, pad)  (((bits)+(pad)-1)&-(pad))
00183  
00184        pFont = (FontPtr) Xalloc(sizeof(FontRec));
00185        if (pFont == NULL)
00186            return AllocError;
00187  
00188        type1 = (struct type1font *)Xalloc(sizeof(struct type1font));
00189        if (type1 == NULL) {
00190                Xfree(pFont);
00191                return AllocError;
00192        }
00193        (void) memset(type1, 0, sizeof(struct type1font));
00194 
00195        scale = (DOUBLE) vals->pixel;
00196 
00197       /* Code added by E. Schenk. July 25, 1992.
00198        * The following code reads the FontMatrix for the font,
00199        * and transforms the font using it. This is necessary
00200        * for fonts that are just an oblique, or extend of
00201        * a normal font. 
00202        */
00203        {  float fontmatrix[6];
00204          int rc;
00205          QueryFontLib(fileName,"FontMatrix",fontmatrix,&rc);
00206          if (!rc) {
00207             S = (struct XYspace *) Transform(IDENTITY,
00208                   fontmatrix[0], fontmatrix[1], fontmatrix[2], fontmatrix[3]);
00209          }
00210          else {
00211             S = (struct XYspace *) Scale(IDENTITY,0.001,0.001);
00212          }
00213        }
00214        /* End of additional code */
00215        
00216        if (efactor == 1.0 && slant == 0.0)
00217          S = (struct XYspace *)Permanent(Scale(S, scale, - scale));
00218        else {
00219           txx = (DOUBLE)vals->x * efactor * vals->point / DECIPOINTSPERINCH;
00220           tyy = (DOUBLE)vals->y * vals->point / DECIPOINTSPERINCH;
00221           tyx = 0.0;
00222           txy = (DOUBLE)vals->x * slant * vals->point / DECIPOINTSPERINCH;
00223           S = (struct XYspace *) Permanent(Transform(S, txx, tyx, txy, -tyy));
00224        }
00225  
00226        glyphs = type1->glyphs;
00227  
00228        /* load font if not already loaded */
00229        if (!fontfcnA(fileName, &rc))
00230           return (rc);
00231 
00232        for (i=0; i < 256-FIRSTCOL; i++) {
00233                LONG h,w;
00234                LONG paddedW;
00235 
00236               if (ev[i] == NULL) continue;
00237               len = strlen(ev[i]);
00238 
00239                currentchar = i;
00240 
00241                rc = 0;
00242               area = fontfcnB(S, ev[i], &len, &rc);
00243                if (rc < 0) {
00244                        rc = BadFontName;
00245                        break;
00246                }
00247                else if (rc > 0)
00248                        continue;
00249  
00250                if (area == NULL)
00251                        continue;
00252  
00253                h       = area->ymax - area->ymin;
00254                w       = area->xmax - area->xmin;
00255                paddedW = PAD(w, pad);
00256  
00257                if (h > 0 && w > 0) {
00258                        size = h * paddedW / 8;
00259                        glyphs[i].bits = (char *)Xalloc(size);
00260                        if (glyphs[i].bits == NULL) {
00261                                rc = AllocError;
00262                                break;
00263                        }
00264                }
00265                else {
00266                        h = w = 0;
00267                        area->xmin = area->xmax = 0;
00268                        area->ymax = area->ymax = 0;
00269                }
00270  
00271                glyphs[i].metrics.leftSideBearing  = area->xmin;
00272                glyphs[i].metrics.characterWidth   = NEARESTPEL(area->ending.x - area->origin.x);
00273                glyphs[i].metrics.rightSideBearing = w + area->xmin;
00274                glyphs[i].metrics.descent          = area->ymax - NEARESTPEL(area->origin.y);
00275                glyphs[i].metrics.ascent           = h - glyphs[i].metrics.descent;
00276  
00277                if (h > 0 && w > 0) {
00278                        (void) memset(glyphs[i].bits, 0, size);
00279                        fill(glyphs[i].bits, h, paddedW, area, byte, bit, wordsize );
00280                }
00281  
00282                Destroy(area);
00283        }
00284 
00285        if (i != 256 - FIRSTCOL) {
00286                for (i--; i >= 0; i--)
00287                        if (glyphs[i].bits != NULL)
00288                                Xfree(glyphs[i].bits);
00289                Xfree(type1);
00290                Xfree(pFont);
00291                return rc;
00292        }
00293        type1->pDefault    = NULL;
00294  
00295        pFont->format      = format;
00296  
00297        pFont->bit         = bit;
00298        pFont->byte        = byte;
00299        pFont->glyph       = glyph;
00300        pFont->scan        = scan;
00301  
00302        pFont->info.firstCol = FIRSTCOL;
00303        pFont->info.lastCol  = 255;
00304        pFont->info.firstRow = 0;
00305        pFont->info.lastRow  = 0;
00306  
00307        pFont->get_metrics = Type1GetMetrics;
00308        pFont->get_glyphs  = Type1GetGlyphs;
00309        pFont->unload_font = Type1CloseFont;
00310        pFont->refcnt = 0;
00311        pFont->maxPrivate = -1;
00312        pFont->devPrivates = 0;
00313  
00314        pFont->fontPrivate = (unsigned char *) type1;
00315  
00316        T1FillFontInfo(pFont, vals, fileName, entry->name.name);
00317  
00318        *ppFont = pFont;
00319        return Successful;
00320 }
00321 
00322 /* NOTE: ILH removed tests ...->characterWidth != 0 below because zero-width
00323          does not mean the character is empty, simply that it has zero escapement. */
00324  
00325 static int
00326 Type1GetGlyphs(pFont, count, chars, charEncoding, glyphCount, glyphs)
00327     FontPtr     pFont;
00328     ULONG count;
00329     register unsigned char *chars;
00330     FontEncoding charEncoding;
00331     ULONG *glyphCount;  /* RETURN */
00332     CharInfoPtr *glyphs;        /* RETURN */
00333 {
00334     unsigned int firstRow;
00335     unsigned int numRows;
00336     CharInfoPtr *glyphsBase;
00337     register unsigned int c;
00338     register CharInfoPtr pci;
00339     unsigned int r;
00340     CharInfoPtr pDefault;
00341     register struct type1font *type1Font;
00342     register int firstCol;
00343  
00344     type1Font  = (struct type1font *) pFont->fontPrivate;
00345     firstCol   = pFont->info.firstCol;
00346     pDefault   = type1Font->pDefault;
00347     glyphsBase = glyphs;
00348 
00349     switch (charEncoding) {
00350 
00351     case Linear8Bit:
00352     case TwoD8Bit:
00353         if (pFont->info.firstRow > 0)
00354             break;
00355         while (count--) {
00356                 c = (*chars++);
00357                 if (c >= firstCol)
00358                     *glyphs++ = &type1Font->glyphs[c-firstCol];
00359                 else if (pDefault)
00360                     *glyphs++ = pDefault;
00361         }
00362         break;
00363     case Linear16Bit:
00364         while (count--) {
00365                 c = *chars++ << 8;
00366                 c = (c | *chars++);
00367                 if (c < 256 && c >= firstCol)
00368                     *glyphs++ = &type1Font->glyphs[c-firstCol];
00369                 else if (pDefault)
00370                     *glyphs++ = pDefault;
00371         }
00372         break;
00373  
00374     case TwoD16Bit:
00375         firstRow = pFont->info.firstRow;
00376         numRows = pFont->info.lastRow - firstRow + 1;
00377         while (count--) {
00378             r = (*chars++) - firstRow;
00379             c = (*chars++);
00380             if (r < numRows && c < 256 && c >= firstCol)
00381                 *glyphs++ = &type1Font->glyphs[(r << 8) + c - firstCol];
00382             else if (pDefault)
00383                 *glyphs++ = pDefault;
00384         }
00385         break;
00386     }
00387     *glyphCount = glyphs - glyphsBase;
00388     return Successful;
00389 }
00390  
00391 static int
00392 Type1GetMetrics(pFont, count, chars, charEncoding, glyphCount, glyphs)
00393     FontPtr     pFont;
00394     ULONG count;
00395     register unsigned char *chars;
00396     FontEncoding charEncoding;
00397     ULONG *glyphCount;  /* RETURN */
00398     xCharInfo **glyphs;         /* RETURN */
00399 {
00400     static CharInfoRec nonExistantChar;
00401  
00402     int         ret;
00403     struct type1font *type1Font;
00404     CharInfoPtr oldDefault;
00405  
00406     type1Font = (struct type1font *) pFont->fontPrivate;
00407     oldDefault = type1Font->pDefault;
00408     type1Font->pDefault = &nonExistantChar;
00409     ret = Type1GetGlyphs(pFont, count, chars, charEncoding, glyphCount, (CharInfoPtr *) glyphs);
00410     type1Font->pDefault = oldDefault;
00411     return ret;
00412 }
00413  
00414 void Type1CloseFont(pFont)
00415        FontPtr pFont;
00416 {
00417        register int i;
00418        struct type1font *type1;
00419  
00420        type1 = (struct type1font *) pFont->fontPrivate;
00421        for (i=0; i < 256 - pFont->info.firstCol; i++)
00422                if (type1->glyphs[i].bits != NULL)
00423                         Xfree(type1->glyphs[i].bits);
00424        Xfree(type1);
00425 
00426        if (pFont->info.props)
00427           Xfree(pFont->info.props);
00428 
00429        if (pFont->info.isStringProp)
00430           Xfree(pFont->info.isStringProp);
00431 
00432        Xfree(pFont);
00433 }
00434  
00435  
00436  
00437 static void fill(dest, h, w, area, byte, bit, wordsize)
00438        register char *dest;  /* destination bitmap                           */
00439        int h,w;              /* dimensions of 'dest', w padded               */
00440        register struct region *area;  /* region to write to 'dest'           */
00441        int byte,bit;         /* flags; LSBFirst or MSBFirst                  */
00442        int wordsize;         /* number of bits per word for LSB/MSB purposes */
00443 {
00444        register struct edgelist *edge;  /* for looping through edges         */
00445        register char *p;     /* current scan line in 'dest'                  */
00446        register int y;       /* for looping through scans                    */
00447        register int wbytes = w / 8;  /* number of bytes in width             */
00448        register pel *leftP,*rightP;  /* pointers to X values, left and right */
00449        int xmin = area->xmin;  /* upper left X                               */
00450        int ymin = area->ymin;  /* upper left Y                               */
00451  
00452        for (edge = area->anchor; VALIDEDGE(edge); edge = edge->link->link) {
00453  
00454                p = dest + (edge->ymin - ymin) * wbytes;
00455                leftP = edge->xvalues;
00456                rightP = edge->link->xvalues;
00457  
00458                for (y = edge->ymin; y < edge->ymax; y++) {
00459                        fillrun(p, *leftP++ - xmin, *rightP++ - xmin, bit);
00460                        p += wbytes;
00461                }
00462        }
00463 /*
00464 Now, as an afterthought, we'll go reorganize if odd byte order requires
00465 it:
00466 */
00467        if (byte == LSBFirst && wordsize != 8) {
00468                register int i;
00469  
00470                switch (wordsize) {
00471                    case 16:
00472                    {
00473                        register unsigned short data,*p;
00474  
00475                        p = (unsigned short *) dest;
00476  
00477                        for (i = h * w /16; --i >= 0;) {
00478                                data = *p;
00479                                *p++ = (data << 8) + (data >> 8);
00480                        }
00481                        break;
00482                    }
00483                    case 64:
00484                    case 32:
00485                    {
00486                        register ULONG data,*p;
00487  
00488                        p = (ULONG *) dest;
00489  
00490                        for (i = h * w / 32; --i >= 0;) {
00491                                data = *p;
00492                                *p++ = (data << 24) + (data >> 24)
00493                                       + (0xFF00 & (data >> 8))
00494                                       + (0xFF0000 & (data << 8));
00495                        }
00496                        if (wordsize == 64) {
00497  
00498                                p = (ULONG *) dest;
00499  
00500                                for (i = h * w / 64; --i >= 0;) {
00501                                        data = *p++;
00502                                        p[-1] = p[0];
00503                                        *p++ = data;
00504                                }
00505                        }
00506                        break;
00507                    }
00508                    default:
00509                        t1_abort("xiFill: unknown format");
00510                }
00511        }
00512  
00513 }
00514  
00515 #define  ALLONES  0xFF
00516  
00517 static void fillrun(register char *p, pel x0, pel x1, int bit)
00518 {
00519        register int startmask,endmask;  /* bits to set in first and last char*/
00520        register int middle;  /* number of chars between start and end + 1    */
00521  
00522        if (x1 <= x0)
00523                return;
00524        middle = x1/8 - x0/8;
00525        p += x0/8;
00526        x0 &= 7;  x1 &= 7;
00527        if (bit == LSBFirst) {
00528                startmask = ALLONES << x0;
00529                endmask = ~(ALLONES << x1);
00530        }
00531        else {
00532                startmask = ALLONES >> x0;
00533                endmask = ~(ALLONES >> x1);
00534        }
00535        if (middle == 0)
00536                *p++ |= startmask & endmask;
00537        else {
00538                *p++ |= startmask;
00539                while (--middle > 0)
00540                        *p++ = ALLONES;
00541                *p |= endmask;
00542        }
00543 }
00544  
00545  
00546 static FontRendererRec renderers[] = {
00547   { ".pfa", 4, (int (*)()) 0, Type1OpenScalable,
00548         (int (*)()) 0, Type1GetInfoScalable, 0 },
00549   { ".pfb", 4, (int (*)()) 0, Type1OpenScalable,
00550         (int (*)()) 0, Type1GetInfoScalable, 0 }
00551 };
00552  
00553 Type1RegisterFontFileFunctions()
00554 {
00555     int i;
00556  
00557     T1InitStdProps();
00558     for (i=0; i < sizeof(renderers) / sizeof(FontRendererRec); i++)
00559             FontFileRegisterRenderer(&renderers[i]);
00560 }