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