1 /* $TOG: t1funcs.c /main/23 1997/06/09 14:55:44 barstow $ */
2 /* Copyright International Business Machines,Corp. 1991
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.
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
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:
35 * Copyright 1990, 1991 Network Computing Devices;
36 * Portions Copyright 1987 by Digital Equipment Corporation
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.
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.
57 /* $XFree86: xc/lib/font/Type1/t1funcs.c,v 3.4.2.1 1997/07/05 15:55:35 dawes Exp $ */
61 Copyright (c) 1987, 1994 X Consortium
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:
71 The above copyright notice and this permission notice shall be included
72 in all copies or substantial portions of the Software.
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.
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.
93 #define _XOPEN_SOURCE /* to get prototype for hypot on some systems */
97 #include "X11/Xfuncs.h"
109 int Type1OpenScalable ();
110 static int Type1GetGlyphs();
111 void Type1CloseFont();
112 extern int Type1GetInfoScalable ();
114 static int Type1GetMetrics ();
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))
119 static void fillrun();
122 extern psfont *FontP;
123 extern psobj *ISOLatin1EncArrayP;
125 extern unsigned long *Xalloc();
129 int Type1OpenScalable (fpe, ppFont, flags, entry, fileName, vals, format,
130 fmask, non_cachable_font)
131 FontPathElementPtr fpe;
136 FontScalablePtr vals;
137 fsBitmapFormat format;
138 fsBitmapFormatMask fmask;
139 FontPtr non_cachable_font; /* We don't do licensing */
141 extern struct XYspace *IDENTITY;
142 extern Bool fontfcnA();
143 extern struct region *fontfcnB();
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 */
159 int len, rc, count = 0;
160 struct type1font *type1;
162 psobj *fontencoding = NULL;
165 long x0, total_width = 0, total_raw_width = 0;
166 double x1, y1, t1 = .001, t2 = 0.0, t3 = 0.0, t4 = .001;
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)
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)
184 #define PAD(bits, pad) (((bits)+(pad)-1)&-(pad))
186 pFont = (FontPtr) xalloc(sizeof(FontRec));
190 type1 = (struct type1font *)xalloc(sizeof(struct type1font));
195 bzero(type1, sizeof(struct type1font));
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])
201 if (size < 0 || NULL == (pool = (unsigned long *) xalloc(size))) {
207 addmemory(pool, size);
210 glyphs = type1->glyphs;
212 /* load font if not already loaded */
213 if (!fontfcnA(fileName, &rc)) {
218 return Type1ReturnCodeToXReturnCode(rc);
221 fontmatrix = &FontP->fontInfoP[FONTMATRIX].value;
222 if (objPIsArray(fontmatrix) && fontmatrix->len == 6)
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; \
236 S = (struct XYspace *) t1_Transform(IDENTITY, t1, t2, t3, t4);
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]));
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;
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"))
253 fontencoding = FontP->fontInfoP[ENCODING].value.data.arrayP;
257 fontencoding = ISOLatin1EncArrayP;
259 pFont->info.firstCol = 255;
260 pFont->info.lastCol = FIRSTCOL;
262 for (i=0; i < 256-FIRSTCOL; i++) {
268 codename = fontencoding[i + FIRSTCOL].data.valueP;
269 len = fontencoding[i + FIRSTCOL].len;
270 if (len == 7 && strcmp(codename,".notdef")==0)
273 /* See if this character is in the list of ranges specified
275 for (j = 0; j < vals->nranges; j++)
276 if (i + FIRSTCOL >= minchar(vals->ranges[j]) &&
277 i + FIRSTCOL <= maxchar(vals->ranges[j]))
280 /* If not, don't realize it. */
281 if (vals->nranges && j == vals->nranges)
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;
290 area = fontfcnB(S, codename, &len, &rc);
292 rc = Type1ReturnCodeToXReturnCode(rc);
301 h = area->ymax - area->ymin;
302 w = area->xmax - area->xmin;
303 paddedW = PAD(w, pad);
305 if (h > 0 && w > 0) {
306 size = h * paddedW / 8;
307 glyphs[i].bits = (char *)xalloc(size);
308 if (glyphs[i].bits == NULL) {
316 area->xmin = area->xmax = 0;
317 area->ymax = area->ymax = 0;
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)
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
332 size = paddedW = PAD(w, pad);
333 glyphs[i].bits = (char *)xalloc(size);
334 if (glyphs[i].bits == NULL) {
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);
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;
349 bzero(glyphs[i].bits, size);
350 if (h > 0 && w > 0) {
351 fill(glyphs[i].bits, h, paddedW, area, byte, bit, wordsize );
360 if (pFont->info.firstCol > pFont->info.lastCol)
367 if (i != 256 - FIRSTCOL) {
368 for (i--; i >= 0; i--)
369 if (glyphs[i].bits != NULL)
370 xfree(glyphs[i].bits);
375 type1->pDefault = NULL;
377 pFont->format = format;
381 pFont->glyph = glyph;
384 pFont->info.firstRow = 0;
385 pFont->info.lastRow = 0;
387 pFont->get_metrics = Type1GetMetrics;
388 pFont->get_glyphs = Type1GetGlyphs;
389 pFont->unload_font = Type1CloseFont;
390 pFont->unload_glyphs = NULL;
392 pFont->maxPrivate = -1;
393 pFont->devPrivates = 0;
395 pFont->fontPrivate = (unsigned char *) type1;
399 total_raw_width = (total_raw_width * 10 + count / 2) / count;
402 /* Predominant direction is R->L */
403 total_raw_width = -total_raw_width;
405 vals->width = (int)((double)total_raw_width *
406 vals->pixel_matrix[0] / 1000.0 +
407 (vals->pixel_matrix[0] > 0 ? .5 : -.5));
410 T1FillFontInfo(pFont, vals, fileName, entry->name.name, total_raw_width);
417 Type1GetGlyphs(pFont, count, chars, charEncoding, glyphCount, glyphs)
420 register unsigned char *chars;
421 FontEncoding charEncoding;
422 unsigned long *glyphCount; /* RETURN */
423 CharInfoPtr *glyphs; /* RETURN */
425 unsigned int firstRow;
426 unsigned int numRows;
427 CharInfoPtr *glyphsBase;
428 register unsigned int c;
429 register CharInfoPtr pci;
431 CharInfoPtr pDefault;
432 register struct type1font *type1Font;
433 register int firstCol;
435 type1Font = (struct type1font *) pFont->fontPrivate;
436 firstCol = pFont->info.firstCol;
437 pDefault = type1Font->pDefault;
440 switch (charEncoding) {
443 ((pci)->metrics.attributes || \
444 (pci)->metrics.ascent != -(pci)->metrics.descent || \
445 (pci)->metrics.leftSideBearing != (pci)->metrics.rightSideBearing)
449 if (pFont->info.firstRow > 0)
454 (pci = &type1Font->glyphs[c-FIRSTCOL]) &&
458 *glyphs++ = pDefault;
465 if (c < 256 && c >= firstCol &&
466 (pci = &type1Font->glyphs[c-FIRSTCOL]) &&
470 *glyphs++ = pDefault;
475 firstRow = pFont->info.firstRow;
476 numRows = pFont->info.lastRow - firstRow + 1;
478 r = (*chars++) - firstRow;
480 if (r < numRows && c < 256 && c >= firstCol &&
481 (pci = &type1Font->glyphs[(r << 8) + c - FIRSTCOL]) &&
485 *glyphs++ = pDefault;
489 *glyphCount = glyphs - glyphsBase;
496 Type1GetMetrics(pFont, count, chars, charEncoding, glyphCount, glyphs)
499 register unsigned char *chars;
500 FontEncoding charEncoding;
501 unsigned long *glyphCount; /* RETURN */
502 xCharInfo **glyphs; /* RETURN */
504 static CharInfoRec nonExistantChar;
507 struct type1font *type1Font;
508 CharInfoPtr oldDefault;
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;
518 void Type1CloseFont(pFont)
522 struct type1font *type1;
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);
530 if (pFont->info.props)
531 xfree(pFont->info.props);
533 if (pFont->info.isStringProp)
534 xfree(pFont->info.isStringProp);
536 if (pFont->devPrivates)
537 xfree(pFont->devPrivates);
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 */
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 */
559 for (edge = area->anchor; VALIDEDGE(edge); edge = edge->link->link) {
561 p = dest + (edge->ymin - ymin) * wbytes;
562 leftP = edge->xvalues;
563 rightP = edge->link->xvalues;
565 for (y = edge->ymin; y < edge->ymax; y++) {
566 fillrun(p, *leftP++ - xmin, *rightP++ - xmin, bit);
571 Now, as an afterthought, we'll go reorganize if odd byte order requires
574 if (byte == LSBFirst && wordsize != 8) {
580 register unsigned short data,*p;
582 p = (unsigned short *) dest;
584 for (i = h * w /16; --i >= 0;) {
586 *p++ = (data << 8) + (data >> 8);
593 register unsigned long data,*p;
595 p = (unsigned long *) dest;
597 for (i = h * w / 32; --i >= 0;) {
599 *p++ = (data << 24) + (data >> 24)
600 + (0xFF00 & (data >> 8))
601 + (0xFF0000 & (data << 8));
603 if (wordsize == 64) {
605 p = (unsigned long *) dest;
607 for (i = h * w / 64; --i >= 0;) {
616 abort("xiFill: unknown format");
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 */
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 */
634 middle = x1/8 - x0/8;
637 if (bit == LSBFirst) {
638 startmask = ALLONES << x0;
639 endmask = ~(ALLONES << x1);
642 startmask = ALLONES >> x0;
643 endmask = ~(ALLONES >> x1);
646 *p++ |= startmask & endmask;
650 *p++ = (char)ALLONES;
655 #define CAPABILITIES (CAP_MATRIX | CAP_CHARSUBSETTING)
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 }
665 Type1RegisterFontFileFunctions()
670 for (i=0; i < sizeof(renderers) / sizeof(FontRendererRec); i++)
671 FontFileRegisterRenderer(&renderers[i]);
674 int Type1ReturnCodeToXReturnCode(rc)
681 /* fall through to BadFontFormat */
683 return BadFontFormat;
684 case SCAN_OUT_OF_MEMORY:
686 case SCAN_FILE_OPEN_ERROR:
693 /* this should not happen */
694 ErrorF("Type1 return code not convertable to X return code: %d\n", rc);