]> git.sesse.net Git - rdpsrv/blob - Xserver/lib/font/Type1/t1funcs.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / lib / font / Type1 / t1funcs.c
1 /* $TOG: t1funcs.c /main/23 1997/06/09 14:55:44 barstow $ */
2 /* Copyright International Business Machines,Corp. 1991
3  * All Rights Reserved
4  *
5  * License, subject to the license given below, to use,
6  * copy, modify, and distribute this software * and its
7  * documentation for any purpose and without fee is hereby
8  * granted, provided that the above copyright notice appear
9  * in all copies and that both that copyright notice and
10  * this permission notice appear in supporting documentation,
11  * and that the name of IBM not be used in advertising or
12  * publicity pertaining to distribution of the software
13  * without specific, written prior permission.
14  *
15  * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
16  * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
17  * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
19  * THIRD PARTY RIGHTS.  THE ENTIRE RISK AS TO THE QUALITY AND
20  * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
21  * OR MAINTAIN, BELONGS TO THE LICENSEE.  SHOULD ANY PORTION OF
22  * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
23  * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION.  IN
24  * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
25  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
26  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
27  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
28  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
29  * SOFTWARE.
30  *
31  * Author: Jeffrey B. Lotspiech, IBM Almaden Research Center
32  *   Modeled on spfuncs.c by Dave Lemke, Network Computing Devices, Inc
33  *   which contains the following copyright and permission notices:
34  *
35  * Copyright 1990, 1991 Network Computing Devices;
36  * Portions Copyright 1987 by Digital Equipment Corporation
37  *
38  * Permission to use, copy, modify, distribute, and sell this software and its
39  * documentation for any purpose is hereby granted without fee, provided that
40  * the above copyright notice appear in all copies and that both that
41  * copyright notice and this permission notice appear in supporting
42  * documentation, and that the names of Network Computing Devices
43  * or Digital not be used in advertising or publicity pertaining to 
44  * distribution of the software without specific, written prior permission.  
45  * Network Computing Devices or Digital make no representations about the
46  * suitability of this software for any purpose.  It is provided "as is"
47  * without express or implied warranty.
48  *
49  * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
50  * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
51  * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
52  * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
53  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
54  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
55  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
56  */
57 /* $XFree86: xc/lib/font/Type1/t1funcs.c,v 3.4.2.1 1997/07/05 15:55:35 dawes Exp $ */
58
59 /*
60
61 Copyright (c) 1987, 1994  X Consortium
62
63 Permission is hereby granted, free of charge, to any person obtaining
64 a copy of this software and associated documentation files (the
65 "Software"), to deal in the Software without restriction, including
66 without limitation the rights to use, copy, modify, merge, publish,
67 distribute, sublicense, and/or sell copies of the Software, and to
68 permit persons to whom the Software is furnished to do so, subject to
69 the following conditions:
70
71 The above copyright notice and this permission notice shall be included
72 in all copies or substantial portions of the Software.
73
74 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
75 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
76 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
77 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
78 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
79 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
80 OTHER DEALINGS IN THE SOFTWARE.
81
82 Except as contained in this notice, the name of the X Consortium shall
83 not be used in advertising or otherwise to promote the sale, use or
84 other dealings in this Software without prior written authorization
85 from the X Consortium.
86
87 */
88  
89 #include <string.h>
90 #ifdef _XOPEN_SOURCE
91 #include <math.h>
92 #else
93 #define _XOPEN_SOURCE   /* to get prototype for hypot on some systems */
94 #include <math.h>
95 #undef _XOPEN_SOURCE
96 #endif
97 #include "X11/Xfuncs.h"
98 #include "fntfilst.h"
99 #include "FSproto.h"
100 #include "t1intf.h"
101  
102 #include "objects.h"
103 #include "spaces.h"
104 #include "regions.h"
105 #include "t1stdio.h"
106 #include "util.h"
107 #include "fontfcn.h"
108  
109 int         Type1OpenScalable ();
110 static int  Type1GetGlyphs();
111 void        Type1CloseFont();
112 extern int  Type1GetInfoScalable ();
113  
114 static int  Type1GetMetrics ();
115  
116 #define minchar(p) ((p).min_char_low + ((p).min_char_high << 8))
117 #define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8))
118
119 static void fillrun();
120  
121  
122 extern psfont *FontP;
123 extern psobj *ISOLatin1EncArrayP;
124
125 extern unsigned long *Xalloc();
126 static void fill();
127  
128 /*ARGSUSED*/
129 int Type1OpenScalable (fpe, ppFont, flags, entry, fileName, vals, format,
130                        fmask, non_cachable_font)
131     FontPathElementPtr  fpe;
132     FontPtr             *ppFont;
133     int                 flags;
134     FontEntryPtr        entry;
135     char                *fileName;
136     FontScalablePtr     vals;
137     fsBitmapFormat      format;
138     fsBitmapFormatMask  fmask;
139     FontPtr             non_cachable_font;      /* We don't do licensing */
140 {
141        extern struct XYspace *IDENTITY;
142        extern Bool fontfcnA();
143        extern struct region *fontfcnB();
144  
145  
146        FontPtr     pFont;
147        int         bit,
148                    byte,
149                    glyph,
150                    scan,
151                    image;
152        int pad,wordsize;     /* scan & image in bits                         */
153        unsigned long *pool;  /* memory pool for ximager objects              */
154        int size;             /* for memory size calculations                 */
155        struct XYspace *S;    /* coordinate space for character               */
156        struct region *area;
157        CharInfoRec *glyphs;
158        register int i;
159        int len, rc, count = 0;
160        struct type1font *type1;
161        char *p;
162        psobj *fontencoding = NULL;
163        fsRange char_range;
164        psobj *fontmatrix;
165        long x0, total_width = 0, total_raw_width = 0;
166        double x1, y1, t1 = .001, t2 = 0.0, t3 = 0.0, t4 = .001;
167        double sxmult;
168
169        /* Reject ridiculously small font sizes that will blow up the math */
170        if (hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]) < 1.0 ||
171            hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]) < 1.0)
172            return BadFontName;
173
174        /* set up default values */
175        FontDefaultFormat(&bit, &byte, &glyph, &scan);
176        /* get any changes made from above */
177        rc = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image);
178        if (rc != Successful)
179                return rc;
180  
181        pad                = glyph * 8;
182        wordsize           = scan * 8;
183  
184 #define  PAD(bits, pad)  (((bits)+(pad)-1)&-(pad))
185  
186        pFont = (FontPtr) xalloc(sizeof(FontRec));
187        if (pFont == NULL)
188            return AllocError;
189  
190        type1 = (struct type1font *)xalloc(sizeof(struct type1font));
191        if (type1 == NULL) {
192                xfree(pFont);
193                return AllocError;
194        }
195        bzero(type1, sizeof(struct type1font));
196  
197        /* heuristic for "maximum" size of pool we'll need: */
198        size = 200000 + 120 *
199               (int)hypot(vals->pixel_matrix[2], vals->pixel_matrix[3])
200               * sizeof(short);
201        if (size < 0 || NULL == (pool = (unsigned long *) xalloc(size))) {
202                xfree(type1);
203                xfree(pFont);
204                return AllocError;
205        }
206  
207        addmemory(pool, size);
208  
209  
210        glyphs = type1->glyphs;
211  
212        /* load font if not already loaded */
213        if (!fontfcnA(fileName, &rc)) {
214          delmemory();
215          xfree(type1);
216          xfree(pFont);
217          xfree(pool);
218          return Type1ReturnCodeToXReturnCode(rc);
219        }
220
221        fontmatrix = &FontP->fontInfoP[FONTMATRIX].value;
222        if (objPIsArray(fontmatrix) && fontmatrix->len == 6)
223        {
224 #define assign(n,d,f) if (objPIsInteger(fontmatrix->data.arrayP + n)) \
225                           d = fontmatrix->data.arrayP[n].data.integer; \
226                       else if (objPIsReal(fontmatrix->data.arrayP + n)) \
227                           d = fontmatrix->data.arrayP[n].data.real; \
228                       else d = f;
229
230            assign(0, t1, .001);
231            assign(1, t2, 0.0);
232            assign(2, t3, 0.0);
233            assign(3, t4, .001);
234        }
235
236        S = (struct XYspace *) t1_Transform(IDENTITY, t1, t2, t3, t4);
237
238        S = (struct XYspace *) Permanent(t1_Transform(S, vals->pixel_matrix[0],
239                                                        -vals->pixel_matrix[1],
240                                                         vals->pixel_matrix[2],
241                                                        -vals->pixel_matrix[3]));
242
243
244        /* multiplier for computation of raw values */
245        sxmult = hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]);
246        if (sxmult > EPS) sxmult = 1000.0 / sxmult;
247
248        p = entry->name.name + entry->name.length - 19;
249        if (entry->name.ndashes == 14 &&
250            p >= entry->name.name &&
251            !strcmp (p, "-adobe-fontspecific"))
252        {
253            fontencoding = FontP->fontInfoP[ENCODING].value.data.arrayP;
254        }
255
256        if (!fontencoding)
257            fontencoding = ISOLatin1EncArrayP;
258
259        pFont->info.firstCol = 255;
260        pFont->info.lastCol  = FIRSTCOL;
261
262        for (i=0; i < 256-FIRSTCOL; i++) {
263                long h,w;
264                long paddedW;
265                int j;
266                char *codename;
267
268                codename = fontencoding[i + FIRSTCOL].data.valueP;
269                len = fontencoding[i + FIRSTCOL].len;
270                if (len == 7 && strcmp(codename,".notdef")==0)
271                    continue;
272  
273                /* See if this character is in the list of ranges specified
274                   in the XLFD name */
275                for (j = 0; j < vals->nranges; j++)
276                    if (i + FIRSTCOL >= minchar(vals->ranges[j]) &&
277                        i + FIRSTCOL <= maxchar(vals->ranges[j]))
278                        break;
279
280                /* If not, don't realize it. */
281                if (vals->nranges && j == vals->nranges)
282                    continue;
283
284                if (pFont->info.firstCol > i + FIRSTCOL)
285                    pFont->info.firstCol = i + FIRSTCOL;
286                if (pFont->info.lastCol < i + FIRSTCOL)
287                    pFont->info.lastCol = i + FIRSTCOL;
288
289                rc = 0;
290                area = fontfcnB(S, codename, &len, &rc);
291                if (rc < 0) {
292                        rc = Type1ReturnCodeToXReturnCode(rc);
293                        break;
294                }
295                else if (rc > 0)
296                        continue;
297  
298                if (area == NULL)
299                        continue;
300  
301                h       = area->ymax - area->ymin;
302                w       = area->xmax - area->xmin;
303                paddedW = PAD(w, pad);
304  
305                if (h > 0 && w > 0) {
306                        size = h * paddedW / 8;
307                        glyphs[i].bits = (char *)xalloc(size);
308                        if (glyphs[i].bits == NULL) {
309                                rc = AllocError;
310                                break;
311                        }
312                }
313                else {
314                        size = 0;
315                        h = w = 0;
316                        area->xmin = area->xmax = 0;
317                        area->ymax = area->ymax = 0;
318                }
319  
320                glyphs[i].metrics.leftSideBearing  = area->xmin;
321                x1 = (double)(x0 = area->ending.x - area->origin.x);
322                y1 = (double)(area->ending.y - area->origin.y);
323                glyphs[i].metrics.characterWidth   =
324                    (x0 + (x0 > 0 ? FPHALF : -FPHALF)) / (1 << FRACTBITS);
325                if (!glyphs[i].metrics.characterWidth && size == 0)
326                {
327                    /* Zero size and zero extents: presumably caused by
328                       the choice of transformation.  Let's create a
329                       small bitmap so we're not mistaken for an undefined
330                       character. */
331                    h = w = 1;
332                    size = paddedW = PAD(w, pad);
333                    glyphs[i].bits = (char *)xalloc(size);
334                    if (glyphs[i].bits == NULL) {
335                        rc = AllocError;
336                        break;
337                    }
338                }
339                glyphs[i].metrics.attributes =
340                    NEARESTPEL((long)(hypot(x1, y1) * sxmult));
341                total_width += glyphs[i].metrics.attributes;
342                total_raw_width += abs((int)(INT16)glyphs[i].metrics.attributes);
343                count++;
344                glyphs[i].metrics.rightSideBearing = w + area->xmin;
345                glyphs[i].metrics.descent          = area->ymax - NEARESTPEL(area->origin.y);
346                glyphs[i].metrics.ascent           = h - glyphs[i].metrics.descent;
347  
348  
349                bzero(glyphs[i].bits, size);
350                if (h > 0 && w > 0) {
351                    fill(glyphs[i].bits, h, paddedW, area, byte, bit, wordsize );
352                }
353  
354                Destroy(area);
355        }
356  
357        delmemory();
358        xfree(pool);
359  
360        if (pFont->info.firstCol > pFont->info.lastCol)
361        {
362                xfree(type1);
363                xfree(pFont);
364                return BadFontName;
365        }
366  
367        if (i != 256 - FIRSTCOL) {
368                for (i--; i >= 0; i--)
369                        if (glyphs[i].bits != NULL)
370                                xfree(glyphs[i].bits);
371                xfree(type1);
372                xfree(pFont);
373                return rc;
374        }
375        type1->pDefault    = NULL;
376  
377        pFont->format      = format;
378  
379        pFont->bit         = bit;
380        pFont->byte        = byte;
381        pFont->glyph       = glyph;
382        pFont->scan        = scan;
383  
384        pFont->info.firstRow = 0;
385        pFont->info.lastRow  = 0;
386  
387        pFont->get_metrics = Type1GetMetrics;
388        pFont->get_glyphs  = Type1GetGlyphs;
389        pFont->unload_font = Type1CloseFont;
390        pFont->unload_glyphs = NULL;
391        pFont->refcnt = 0;
392        pFont->maxPrivate = -1;
393        pFont->devPrivates = 0;
394  
395        pFont->fontPrivate = (unsigned char *) type1;
396
397        if (count)
398        {
399            total_raw_width = (total_raw_width * 10 + count / 2) / count;
400            if (total_width < 0)
401            {
402                /* Predominant direction is R->L */
403                total_raw_width = -total_raw_width;
404            }
405            vals->width = (int)((double)total_raw_width *
406                                vals->pixel_matrix[0] / 1000.0 +
407                                (vals->pixel_matrix[0] > 0 ? .5 : -.5));
408        }
409
410        T1FillFontInfo(pFont, vals, fileName, entry->name.name, total_raw_width);
411  
412        *ppFont = pFont;
413        return Successful;
414 }
415  
416 static int
417 Type1GetGlyphs(pFont, count, chars, charEncoding, glyphCount, glyphs)
418     FontPtr     pFont;
419     unsigned long count;
420     register unsigned char *chars;
421     FontEncoding charEncoding;
422     unsigned long *glyphCount;  /* RETURN */
423     CharInfoPtr *glyphs;        /* RETURN */
424 {
425     unsigned int firstRow;
426     unsigned int numRows;
427     CharInfoPtr *glyphsBase;
428     register unsigned int c;
429     register CharInfoPtr pci;
430     unsigned int r;
431     CharInfoPtr pDefault;
432     register struct type1font *type1Font;
433     register int firstCol;
434  
435     type1Font  = (struct type1font *) pFont->fontPrivate;
436     firstCol   = pFont->info.firstCol;
437     pDefault   = type1Font->pDefault;
438     glyphsBase = glyphs;
439  
440     switch (charEncoding) {
441
442 #define EXIST(pci) \
443     ((pci)->metrics.attributes || \
444      (pci)->metrics.ascent != -(pci)->metrics.descent || \
445      (pci)->metrics.leftSideBearing != (pci)->metrics.rightSideBearing)
446  
447     case Linear8Bit:
448     case TwoD8Bit:
449         if (pFont->info.firstRow > 0)
450             break;
451         while (count--) {
452                 c = (*chars++);
453                 if (c >= firstCol &&
454                        (pci = &type1Font->glyphs[c-FIRSTCOL]) &&
455                        EXIST(pci))
456                     *glyphs++ = pci;
457                 else if (pDefault)
458                     *glyphs++ = pDefault;
459         }
460         break;
461     case Linear16Bit:
462         while (count--) {
463                 c = *chars++ << 8;
464                 c = (c | *chars++);
465                 if (c < 256 && c >= firstCol &&
466                         (pci = &type1Font->glyphs[c-FIRSTCOL]) &&
467                         EXIST(pci))
468                     *glyphs++ = pci;
469                 else if (pDefault)
470                     *glyphs++ = pDefault;
471         }
472         break;
473  
474     case TwoD16Bit:
475         firstRow = pFont->info.firstRow;
476         numRows = pFont->info.lastRow - firstRow + 1;
477         while (count--) {
478             r = (*chars++) - firstRow;
479             c = (*chars++);
480             if (r < numRows && c < 256 && c >= firstCol &&
481                     (pci = &type1Font->glyphs[(r << 8) + c - FIRSTCOL]) &&
482                     EXIST(pci))
483                 *glyphs++ = pci;
484             else if (pDefault)
485                 *glyphs++ = pDefault;
486         }
487         break;
488     }
489     *glyphCount = glyphs - glyphsBase;
490     return Successful;
491
492 #undef EXIST
493 }
494  
495 static int
496 Type1GetMetrics(pFont, count, chars, charEncoding, glyphCount, glyphs)
497     FontPtr     pFont;
498     unsigned long count;
499     register unsigned char *chars;
500     FontEncoding charEncoding;
501     unsigned long *glyphCount;  /* RETURN */
502     xCharInfo **glyphs;         /* RETURN */
503 {
504     static CharInfoRec nonExistantChar;
505  
506     int         ret;
507     struct type1font *type1Font;
508     CharInfoPtr oldDefault;
509  
510     type1Font = (struct type1font *) pFont->fontPrivate;
511     oldDefault = type1Font->pDefault;
512     type1Font->pDefault = &nonExistantChar;
513     ret = Type1GetGlyphs(pFont, count, chars, charEncoding, glyphCount, (CharInfoPtr *) glyphs);
514     type1Font->pDefault = oldDefault;
515     return ret;
516 }
517  
518 void Type1CloseFont(pFont)
519        FontPtr pFont;
520 {
521        register int i;
522        struct type1font *type1;
523  
524        type1 = (struct type1font *) pFont->fontPrivate;
525        for (i=0; i < 256 - FIRSTCOL; i++)
526                if (type1->glyphs[i].bits != NULL)
527                         xfree(type1->glyphs[i].bits);
528        xfree(type1);
529
530        if (pFont->info.props)
531            xfree(pFont->info.props);
532
533        if (pFont->info.isStringProp)
534            xfree(pFont->info.isStringProp);
535
536        if (pFont->devPrivates)
537            xfree(pFont->devPrivates);
538
539        xfree(pFont);
540 }
541  
542  
543  
544 static void fill(dest, h, w, area, byte, bit, wordsize)
545        register char *dest;  /* destination bitmap                           */
546        int h,w;              /* dimensions of 'dest', w padded               */
547        register struct region *area;  /* region to write to 'dest'           */
548        int byte,bit;         /* flags; LSBFirst or MSBFirst                  */
549        int wordsize;         /* number of bits per word for LSB/MSB purposes */
550 {
551        register struct edgelist *edge;  /* for looping through edges         */
552        register char *p;     /* current scan line in 'dest'                  */
553        register int y;       /* for looping through scans                    */
554        register int wbytes = w / 8;  /* number of bytes in width             */
555        register pel *leftP,*rightP;  /* pointers to X values, left and right */
556        int xmin = area->xmin;  /* upper left X                               */
557        int ymin = area->ymin;  /* upper left Y                               */
558  
559        for (edge = area->anchor; VALIDEDGE(edge); edge = edge->link->link) {
560  
561                p = dest + (edge->ymin - ymin) * wbytes;
562                leftP = edge->xvalues;
563                rightP = edge->link->xvalues;
564  
565                for (y = edge->ymin; y < edge->ymax; y++) {
566                        fillrun(p, *leftP++ - xmin, *rightP++ - xmin, bit);
567                        p += wbytes;
568                }
569        }
570 /*
571 Now, as an afterthought, we'll go reorganize if odd byte order requires
572 it:
573 */
574        if (byte == LSBFirst && wordsize != 8) {
575                register int i;
576  
577                switch (wordsize) {
578                    case 16:
579                    {
580                        register unsigned short data,*p;
581  
582                        p = (unsigned short *) dest;
583  
584                        for (i = h * w /16; --i >= 0;) {
585                                data = *p;
586                                *p++ = (data << 8) + (data >> 8);
587                        }
588                        break;
589                    }
590                    case 64:
591                    case 32:
592                    {
593                        register unsigned long data,*p;
594  
595                        p = (unsigned long *) dest;
596  
597                        for (i = h * w / 32; --i >= 0;) {
598                                data = *p;
599                                *p++ = (data << 24) + (data >> 24)
600                                       + (0xFF00 & (data >> 8))
601                                       + (0xFF0000 & (data << 8));
602                        }
603                        if (wordsize == 64) {
604  
605                                p = (unsigned long *) dest;
606  
607                                for (i = h * w / 64; --i >= 0;) {
608                                        data = *p++;
609                                        p[-1] = p[0];
610                                        *p++ = data;
611                                }
612                        }
613                        break;
614                    }
615                    default:
616                        abort("xiFill: unknown format");
617                }
618        }
619  
620 }
621  
622 #define  ALLONES  0xFF
623  
624 static void fillrun(p, x0, x1, bit)
625        register char *p;     /* address of this scan line                    */
626        pel x0,x1;            /* left and right X                             */
627        int bit;              /* format:  LSBFirst or MSBFirst                */
628 {
629        register int startmask,endmask;  /* bits to set in first and last char*/
630        register int middle;  /* number of chars between start and end + 1    */
631  
632        if (x1 <= x0)
633                return;
634        middle = x1/8 - x0/8;
635        p += x0/8;
636        x0 &= 7;  x1 &= 7;
637        if (bit == LSBFirst) {
638                startmask = ALLONES << x0;
639                endmask = ~(ALLONES << x1);
640        }
641        else {
642                startmask = ALLONES >> x0;
643                endmask = ~(ALLONES >> x1);
644        }
645        if (middle == 0)
646                *p++ |= startmask & endmask;
647        else {
648                *p++ |= startmask;
649                while (--middle > 0)
650                        *p++ = (char)ALLONES;
651                *p |= endmask;
652        }
653 }
654  
655 #define CAPABILITIES (CAP_MATRIX | CAP_CHARSUBSETTING)
656  
657 static FontRendererRec renderers[] = {
658   { ".pfa", 4, (int (*)()) 0, Type1OpenScalable,
659         (int (*)()) 0, Type1GetInfoScalable, 0, CAPABILITIES },
660   { ".pfb", 4, (int (*)()) 0, Type1OpenScalable,
661         (int (*)()) 0, Type1GetInfoScalable, 0, CAPABILITIES }
662 };
663  
664
665 Type1RegisterFontFileFunctions()
666 {
667     int i;
668  
669     T1InitStdProps();
670     for (i=0; i < sizeof(renderers) / sizeof(FontRendererRec); i++)
671             FontFileRegisterRenderer(&renderers[i]);
672 }
673
674 int Type1ReturnCodeToXReturnCode(rc)
675     int rc;
676 {
677     switch(rc) {
678     case SCAN_OK:
679         return Successful;
680     case SCAN_FILE_EOF:
681         /* fall through to BadFontFormat */
682     case SCAN_ERROR:
683         return BadFontFormat;
684     case SCAN_OUT_OF_MEMORY:
685         return AllocError;
686     case SCAN_FILE_OPEN_ERROR:
687         return BadFontName;
688     case SCAN_TRUE:
689     case SCAN_FALSE:
690     case SCAN_END:
691         /* fall through */
692     default:
693         /* this should not happen */
694         ErrorF("Type1 return code not convertable to X return code: %d\n", rc);
695         return rc;
696     }
697 }