1 /* $TOG: spfont.c /main/24 1997/06/09 09:38:19 barstow $ */
2 /*
3  * Copyright 1990, 1991 Network Computing Devices;
4  * Portions Copyright 1987 by Digital Equipment Corporation
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and
7  * its documentation for any purpose is hereby granted without fee, provided
8  * that the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the names of Network Computing Devices or Digital
11  * not be used in advertising or publicity pertaining to distribution of
12  * the software without specific, written prior permission.
13  *
14  * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
15  * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
16  * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
17  * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  *
22  * Author: Dave Lemke, Network Computing Devices Inc
23  */
24 /* $XFree86: xc/lib/font/Speedo/spfont.c,v 3.1.8.1 1997/06/11 12:08:38 dawes Exp $ */
25 
26 /*
27 
28 Copyright (c) 1987  X Consortium
29 
30 Permission is hereby granted, free of charge, to any person obtaining
31 a copy of this software and associated documentation files (the
32 "Software"), to deal in the Software without restriction, including
33 without limitation the rights to use, copy, modify, merge, publish,
34 distribute, sublicense, and/or sell copies of the Software, and to
35 permit persons to whom the Software is furnished to do so, subject to
36 the following conditions:
37 
38 The above copyright notice and this permission notice shall be included
39 in all copies or substantial portions of the Software.
40 
41 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
42 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
43 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
44 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
45 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
46 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
47 OTHER DEALINGS IN THE SOFTWARE.
48 
49 Except as contained in this notice, the name of the X Consortium shall
50 not be used in advertising or otherwise to promote the sale, use or
51 other dealings in this Software without prior written authorization
52 from the X Consortium.
53 
54 */
55 
56 /*
57  * Speedo font loading
58  */
59 
60 #include	"FSproto.h"
61 #include	"spint.h"
62 #include	<servermd.h>
63 #ifdef _XOPEN_SOURCE
64 #include <math.h>
65 #else
66 #define _XOPEN_SOURCE	/* to get prototype for hypot on some systems */
67 #include <math.h>
68 #undef _XOPEN_SOURCE
69 #endif
70 
71 #ifndef M_PI
72 #define M_PI 3.14159
73 #endif /* M_PI */
74 #ifndef DEFAULT_BIT_ORDER
75 
76 #ifdef BITMAP_BIT_ORDER
77 #define DEFAULT_BIT_ORDER BITMAP_BIT_ORDER
78 #else
79 #define DEFAULT_BIT_ORDER UNKNOWN_BIT_ORDER
80 #endif
81 
82 #endif
83 
84 extern void SpeedoCloseFont();
85 static int sp_get_glyphs();
86 static int sp_get_metrics();
87 static int sp_load_font();
88 
89 static CharInfoRec junkDefault;
90 
91 static int
sp_get_glyphs(pFont,count,chars,charEncoding,glyphCount,glyphs)92 sp_get_glyphs(pFont, count, chars, charEncoding, glyphCount, glyphs)
93     FontPtr     pFont;
94     unsigned long count;
95     register unsigned char *chars;
96     FontEncoding charEncoding;
97     unsigned long *glyphCount;	/* RETURN */
98     CharInfoPtr *glyphs;	/* RETURN */
99 {
100     SpeedoFontPtr spf;
101     unsigned int firstCol;
102     register unsigned int numCols;
103     unsigned int firstRow;
104     unsigned int numRows;
105     CharInfoPtr *glyphsBase;
106     register unsigned int c;
107     register CharInfoPtr pci;
108     unsigned int r;
109     CharInfoPtr encoding;
110     CharInfoPtr pDefault;
111     int         itemSize;
112     int         err = Successful;
113 
114     spf = (SpeedoFontPtr) pFont->fontPrivate;
115     encoding = spf->encoding;
116     pDefault = spf->pDefault;
117     firstCol = pFont->info.firstCol;
118     numCols = pFont->info.lastCol - firstCol + 1;
119     glyphsBase = glyphs;
120 
121 
122     /* XXX - this should be much smarter */
123     /* make sure the glyphs are there */
124     if (charEncoding == Linear8Bit || charEncoding == TwoD8Bit)
125 	itemSize = 1;
126     else
127 	itemSize = 2;
128 
129 #ifdef notyet
130     if (!fsd->complete)
131 	err = fs_load_glyphs(NULL, pFont, count, itemSize, chars);
132 #endif
133 
134     if (err != Successful)
135 	return err;
136 
137     switch (charEncoding) {
138 
139     case Linear8Bit:
140     case TwoD8Bit:
141 	if (pFont->info.firstRow > 0)
142 	    break;
143 	if (pFont->info.allExist && pDefault) {
144 	    while (count--) {
145 		c = (*chars++) - firstCol;
146 		if (c < numCols)
147 		    *glyphs++ = &encoding[c];
148 		else
149 		    *glyphs++ = pDefault;
150 	    }
151 	} else {
152 	    while (count--) {
153 		c = (*chars++) - firstCol;
154 		if (c < numCols && (pci = &encoding[c])->bits)
155 		    *glyphs++ = pci;
156 		else if (pDefault)
157 		    *glyphs++ = pDefault;
158 	    }
159 	}
160 	break;
161     case Linear16Bit:
162 	if (pFont->info.allExist && pDefault) {
163 	    while (count--) {
164 		c = *chars++ << 8;
165 		c = (c | *chars++) - firstCol;
166 		if (c < numCols)
167 		    *glyphs++ = &encoding[c];
168 		else
169 		    *glyphs++ = pDefault;
170 	    }
171 	} else {
172 	    while (count--) {
173 		c = *chars++ << 8;
174 		c = (c | *chars++) - firstCol;
175 		if (c < numCols && (pci = &encoding[c])->bits)
176 		    *glyphs++ = pci;
177 		else if (pDefault)
178 		    *glyphs++ = pDefault;
179 	    }
180 	}
181 	break;
182 
183     case TwoD16Bit:
184 	firstRow = pFont->info.firstRow;
185 	numRows = pFont->info.lastRow - firstRow + 1;
186 	while (count--) {
187 	    r = (*chars++) - firstRow;
188 	    c = (*chars++) - firstCol;
189 	    if (r < numRows && c < numCols &&
190 		    (pci = &encoding[r * numCols + c])->bits)
191 		*glyphs++ = pci;
192 	    else if (pDefault)
193 		*glyphs++ = pDefault;
194 	}
195 	break;
196     }
197     *glyphCount = glyphs - glyphsBase;
198     return Successful;
199 }
200 
201 static CharInfoRec nonExistantChar;
202 
203 static int
sp_get_metrics(pFont,count,chars,charEncoding,glyphCount,glyphs)204 sp_get_metrics(pFont, count, chars, charEncoding, glyphCount, glyphs)
205     FontPtr     pFont;
206     unsigned long count;
207     register unsigned char *chars;
208     FontEncoding charEncoding;
209     unsigned long *glyphCount;	/* RETURN */
210     xCharInfo **glyphs;		/* RETURN */
211 {
212     int         ret;
213     SpeedoFontPtr spf;
214     CharInfoPtr	oldDefault;
215 
216     spf = (SpeedoFontPtr) pFont->fontPrivate;
217     oldDefault = spf->pDefault;
218     spf->pDefault = &nonExistantChar;
219     ret = sp_get_glyphs(pFont, count, chars, charEncoding,
220 			glyphCount, (CharInfoPtr *) glyphs);
221 
222     spf->pDefault = oldDefault;
223     return ret;
224 }
225 
226 int
sp_open_font(fontname,filename,entry,vals,format,fmask,flags,spfont)227 sp_open_font(fontname, filename, entry, vals, format, fmask, flags, spfont)
228     char       *fontname,
229                *filename;
230     FontEntryPtr entry;
231     FontScalablePtr vals;
232     fsBitmapFormat format;
233     fsBitmapFormatMask fmask;
234     Mask        flags;
235     SpeedoFontPtr *spfont;
236 {
237     SpeedoFontPtr spf;
238     SpeedoMasterFontPtr spmf;
239     int         ret;
240     specs_t     specs;
241     int		xx8, xy8, yx8, yy8;
242     double	sxmult;
243 
244     /* find a master (create it if necessary) */
245     spmf = (SpeedoMasterFontPtr) entry->u.scalable.extra->private;
246     if (!spmf)
247     {
248 	ret = sp_open_master(filename, &spmf);
249 	if (ret != Successful)
250 	    return ret;
251 	entry->u.scalable.extra->private = (pointer) spmf;
252 	spmf->entry = entry;
253     }
254 
255     spf = (SpeedoFontPtr) xalloc(sizeof(SpeedoFontRec));
256     if (!spf)
257 	return AllocError;
258     bzero((char *) spf, sizeof(SpeedoFontRec));
259 
260     *spfont = spf;
261 
262     /* clobber everything -- this may be leaking, but other wise evil
263      * stuff is left behind -- succesive transformed fonts get mangled */
264     bzero((char *)&sp_globals, sizeof(sp_globals));
265 
266     spf->master = spmf;
267     spf->entry = entry;
268     spmf->refcount++;
269     sp_reset_master(spmf);
270     /* now we've done enough that if we bail out we must call sp_close_font */
271 
272     spf->vals = *vals;
273 
274     /* set up specs */
275 
276     specs.pfont = &spmf->font;
277 
278     specs.xxmult = (int)(vals->pixel_matrix[0] * (double)(1L << 16));
279     specs.xymult = (int)(vals->pixel_matrix[2] * (double)(1L << 16));
280     specs.yxmult = (int)(vals->pixel_matrix[1] * (double)(1L << 16));
281     specs.yymult = (int)(vals->pixel_matrix[3] * (double)(1L << 16));
282 
283     specs.xoffset = 0L << 16; /* XXX tweak? */
284     specs.yoffset = 0L << 16; /* XXX tweak? */
285 
286     specs.flags = MODE_SCREEN;
287     specs.out_info = NULL;
288 
289     /* When Speedo tries to generate a very small font bitmap, it
290        often crashes or goes into an infinite loop.
291        Don't know why this is so, but until we can fix it properly,
292        return BadFontName for anything smaller than 4 pixels.
293        */
294 #define TINY_FACTOR (16 << 16)
295     xx8 = specs.xxmult >> 8;
296     xy8 = specs.xymult >> 8;
297     yx8 = specs.yxmult >> 8;
298     yy8 = specs.yymult >> 8;
299     if (xx8 * xx8 + xy8 * xy8 < TINY_FACTOR ||
300 	yx8 * yx8 + yy8 * yy8 < TINY_FACTOR)
301     {
302 	sp_close_font(spf);
303 	return BadFontName;
304     }
305 
306     /* clobber global state to avoid wrecking future transformed fonts */
307     bzero ((char *) &sp_globals, sizeof(sp_globals));
308 
309     if (!sp_set_specs(&specs))
310     {
311 	sp_close_font(spf);
312 	return BadFontName;
313     }
314 
315     spf->specs = specs;
316     spf->master = spmf;
317 
318     *spfont = spf;
319     return Successful;
320 }
321 
322 static int
sp_load_font(fontname,filename,entry,vals,format,fmask,pfont,flags)323 sp_load_font(fontname, filename, entry, vals, format, fmask, pfont, flags)
324     char       *fontname,
325                *filename;
326     FontEntryPtr    entry;
327     FontScalablePtr vals;
328     fsBitmapFormat format;
329     fsBitmapFormatMask fmask;
330     FontPtr     pfont;
331     Mask        flags;
332 {
333     SpeedoFontPtr spf;
334     SpeedoMasterFontPtr spmf;
335     int         esize;
336     int         ret;
337     long	sWidth;
338 
339     ret = sp_open_font(fontname, filename, entry, vals, format, fmask,
340 		       flags, &spf);
341 
342     if (ret != Successful)
343 	return ret;
344 
345     spmf = spf->master;
346     sp_reset_master(spmf);
347     esize = sizeof(CharInfoRec) * (spmf->max_id - spmf->first_char_id + 1);
348 
349     spf->encoding = (CharInfoPtr) xalloc(esize);
350     if (!spf->encoding) {
351 	sp_close_font(spf);
352 	return AllocError;
353     }
354     bzero((char *) spf->encoding, esize);
355 
356     sp_fp_cur = spf;
357 
358     sp_make_header(spf, &pfont->info);
359 
360     sp_compute_bounds(spf, &pfont->info, SaveMetrics, &sWidth);
361 
362     sp_compute_props(spf, fontname, &pfont->info, sWidth);
363 
364     pfont->fontPrivate = (pointer) spf;
365 
366 /* XXX */
367     flags |= FontLoadBitmaps;
368 
369     if (flags & FontLoadBitmaps) {
370 	sp_fp_cur = spf;
371 	ret = sp_build_all_bitmaps(pfont, format, fmask);
372     }
373     if (ret != Successful)
374 	return ret;
375 
376     /* compute remaining accelerators */
377     FontComputeInfoAccelerators(&pfont->info);
378 
379     pfont->format = format;
380 
381     pfont->get_metrics = sp_get_metrics;
382     pfont->get_glyphs = sp_get_glyphs;
383     pfont->unload_font = SpeedoCloseFont;
384     pfont->unload_glyphs = NULL;
385     pfont->refcnt = 0;
386     pfont->maxPrivate = -1;
387     pfont->devPrivates = (pointer *) 0;
388 
389     /* have to hold on to master for min/max id */
390     sp_close_master_file(spmf);
391 
392     return ret;
393 }
394 
395 int
SpeedoFontLoad(ppfont,fontname,filename,entry,vals,format,fmask,flags)396 SpeedoFontLoad(ppfont, fontname, filename, entry, vals, format, fmask, flags)
397     FontPtr    *ppfont;
398     char       *fontname;
399     char       *filename;
400     FontEntryPtr    entry;
401     FontScalablePtr vals;
402     fsBitmapFormat format;
403     fsBitmapFormatMask fmask;
404     Mask        flags;
405 {
406     FontPtr     pfont;
407     int         ret;
408 
409     /* Reject ridiculously small sizes that will blow up the math */
410     if (hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]) < 1.0 ||
411 	hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]) < 1.0)
412 	return BadFontName;
413 
414     pfont = (FontPtr) xalloc(sizeof(FontRec));
415     if (!pfont) {
416 	return AllocError;
417     }
418     ret = sp_load_font(fontname, filename, entry, vals, format, fmask,
419 		       pfont, flags);
420 
421     if (ret == Successful)
422 	*ppfont = pfont;
423     else
424 	xfree (pfont);
425 
426     return ret;
427 }
428 
429 void
sp_close_font(spf)430 sp_close_font(spf)
431     SpeedoFontPtr spf;
432 {
433     SpeedoMasterFontPtr spmf;
434 
435     spmf = spf->master;
436     --spmf->refcount;
437     if (spmf->refcount == 0)
438 	sp_close_master_font (spmf);
439     xfree(spf->encoding);
440     xfree(spf->bitmaps);
441     xfree(spf);
442 }
443 
444 void
SpeedoCloseFont(pfont)445 SpeedoCloseFont(pfont)
446     FontPtr     pfont;
447 {
448     SpeedoFontPtr spf;
449 
450     spf = (SpeedoFontPtr) pfont->fontPrivate;
451     sp_close_font(spf);
452     xfree(pfont->info.isStringProp);
453     xfree(pfont->info.props);
454     xfree(pfont->devPrivates);
455     xfree(pfont);
456 }
457