]> git.sesse.net Git - rdpsrv/blob - Xserver/lib/font/bitmap/snfread.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / lib / font / bitmap / snfread.c
1 /* $XConsortium: snfread.c,v 1.17 94/04/17 20:17:16 gildea Exp $ */
2 /************************************************************************
3 Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
4
5                         All Rights Reserved
6
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the name of Digital not be
12 used in advertising or publicity pertaining to distribution of the
13 software without specific, written prior permission.
14
15 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21 SOFTWARE.
22
23 ************************************************************************/
24
25 /*
26
27 Copyright (c) 1994  X Consortium
28
29 Permission is hereby granted, free of charge, to any person obtaining
30 a copy of this software and associated documentation files (the
31 "Software"), to deal in the Software without restriction, including
32 without limitation the rights to use, copy, modify, merge, publish,
33 distribute, sublicense, and/or sell copies of the Software, and to
34 permit persons to whom the Software is furnished to do so, subject to
35 the following conditions:
36
37 The above copyright notice and this permission notice shall be included
38 in all copies or substantial portions of the Software.
39
40 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
41 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
42 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
43 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
44 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
45 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
46 OTHER DEALINGS IN THE SOFTWARE.
47
48 Except as contained in this notice, the name of the X Consortium shall
49 not be used in advertising or otherwise to promote the sale, use or
50 other dealings in this Software without prior written authorization
51 from the X Consortium.
52
53 */
54
55 #include <ctype.h>
56 #include "fntfilst.h"
57 #include "bitmap.h"
58 #include "snfstr.h"
59
60 static void snfUnloadFont();
61
62 static int
63 snfReadCharInfo(file, charInfo, base)
64     FontFilePtr file;
65     CharInfoPtr charInfo;
66     char       *base;
67 {
68     snfCharInfoRec snfCharInfo;
69
70 #define Width(m)    ((m).rightSideBearing - (m).leftSideBearing)
71 #define Height(m)   ((m).ascent + (m).descent)
72
73     if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
74             sizeof(snfCharInfo)) {
75         return BadFontName;
76     }
77     charInfo->metrics = snfCharInfo.metrics;
78     if (snfCharInfo.exists)
79         charInfo->bits = base + snfCharInfo.byteOffset;
80     else
81         charInfo->bits = 0;
82     return Successful;
83 }
84
85 static int
86 snfReadxCharInfo(file, charInfo)
87     FontFilePtr file;
88     xCharInfo  *charInfo;
89 {
90     snfCharInfoRec snfCharInfo;
91
92     if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
93             sizeof(snfCharInfo)) {
94         return BadFontName;
95     }
96     *charInfo = snfCharInfo.metrics;
97     return Successful;
98 }
99
100 static
101 snfCopyInfo(snfInfo, pFontInfo)
102     snfFontInfoPtr snfInfo;
103     FontInfoPtr pFontInfo;
104 {
105     pFontInfo->firstCol = snfInfo->firstCol;
106     pFontInfo->lastCol = snfInfo->lastCol;
107     pFontInfo->firstRow = snfInfo->firstRow;
108     pFontInfo->lastRow = snfInfo->lastRow;
109     pFontInfo->defaultCh = snfInfo->chDefault;
110     pFontInfo->noOverlap = snfInfo->noOverlap;
111     pFontInfo->terminalFont = snfInfo->terminalFont;
112     pFontInfo->constantMetrics = snfInfo->constantMetrics;
113     pFontInfo->constantWidth = snfInfo->constantWidth;
114     pFontInfo->inkInside = snfInfo->inkInside;
115     pFontInfo->inkMetrics = snfInfo->inkMetrics;
116     pFontInfo->allExist = snfInfo->allExist;
117     pFontInfo->drawDirection = snfInfo->drawDirection;
118     pFontInfo->anamorphic = FALSE;
119     pFontInfo->cachable = TRUE;
120     pFontInfo->maxOverlap = 0;
121     pFontInfo->minbounds = snfInfo->minbounds.metrics;
122     pFontInfo->maxbounds = snfInfo->maxbounds.metrics;
123     pFontInfo->fontAscent = snfInfo->fontAscent;
124     pFontInfo->fontDescent = snfInfo->fontDescent;
125     pFontInfo->nprops = snfInfo->nProps;
126 }
127
128 static int
129 snfReadProps(snfInfo, pFontInfo, file)
130     snfFontInfoPtr snfInfo;
131     FontInfoPtr pFontInfo;
132     FontFilePtr file;
133 {
134     char       *strings;
135     FontPropPtr pfp;
136     snfFontPropPtr psnfp;
137     char       *propspace;
138     int         bytestoalloc;
139     int         i;
140
141     bytestoalloc = snfInfo->nProps * sizeof(snfFontPropRec) +
142         BYTESOFSTRINGINFO(snfInfo);
143     propspace = (char *) xalloc(bytestoalloc);
144     if (!propspace)
145         return AllocError;
146
147     if (FontFileRead(file, propspace, bytestoalloc) != bytestoalloc) {
148         xfree(propspace);
149         return BadFontName;
150     }
151     psnfp = (snfFontPropPtr) propspace;
152
153     strings = propspace + BYTESOFPROPINFO(snfInfo);
154
155     for (i = 0, pfp = pFontInfo->props; i < snfInfo->nProps; i++, pfp++, psnfp++) {
156         pfp->name = MakeAtom(&strings[psnfp->name],
157                              (unsigned) strlen(&strings[psnfp->name]), 1);
158         pFontInfo->isStringProp[i] = psnfp->indirect;
159         if (psnfp->indirect)
160             pfp->value = (INT32) MakeAtom(&strings[psnfp->value],
161                                (unsigned) strlen(&strings[psnfp->value]), 1);
162         else
163             pfp->value = psnfp->value;
164     }
165
166     xfree(propspace);
167     return Successful;
168 }
169
170 int
171 snfReadHeader(snfInfo, file)
172     snfFontInfoPtr snfInfo;
173     FontFilePtr file;
174 {
175     if (FontFileRead(file, (char *) snfInfo, sizeof *snfInfo) != sizeof *snfInfo)
176         return BadFontName;
177
178     if (snfInfo->version1 != FONT_FILE_VERSION ||
179             snfInfo->version2 != FONT_FILE_VERSION)
180         return BadFontName;
181     return Successful;
182 }
183
184 int
185 snfReadFont(pFont, file, bit, byte, glyph, scan)
186     FontPtr     pFont;
187     FontFilePtr file;
188     int         bit,
189                 byte,
190                 glyph,
191                 scan;
192 {
193     snfFontInfoRec fi;
194     unsigned    bytestoalloc;
195     int         i;
196     char       *fontspace;
197     BitmapFontPtr  bitmapFont;
198     int         num_chars;
199     int         bitmapsSize;
200     int         ret;
201     int         metrics_off;
202     int         encoding_off;
203     int         props_off;
204     int         isStringProp_off;
205     int         ink_off;
206     char        *bitmaps;
207     int         def_bit, def_byte, def_glyph, def_scan;
208
209     ret = snfReadHeader(&fi, file);
210     if (ret != Successful)
211         return ret;
212
213     SnfGetFormat (&def_bit, &def_byte, &def_glyph, &def_scan);
214
215     /*
216      * we'll allocate one chunk of memory and split it among the various parts
217      * of the font:
218      * 
219      * BitmapFontRec CharInfoRec's Glyphs Encoding DIX Properties Ink CharInfoRec's
220      *
221      * If the glyphpad is not the same as the font file, then the glyphs
222      * are allocated separately, to be later realloc'ed when we know
223      * how big to make them.
224      */
225
226     bitmapsSize = BYTESOFGLYPHINFO(&fi);
227     num_chars = n2dChars(&fi);
228     bytestoalloc = sizeof(BitmapFontRec);       /* bitmapFont */
229     metrics_off = bytestoalloc;
230     bytestoalloc += num_chars * sizeof(CharInfoRec);    /* metrics */
231     encoding_off = bytestoalloc;
232     bytestoalloc += num_chars * sizeof(CharInfoPtr);    /* encoding */
233     props_off = bytestoalloc;
234     bytestoalloc += fi.nProps * sizeof(FontPropRec);    /* props */
235     isStringProp_off = bytestoalloc;
236     bytestoalloc += fi.nProps * sizeof(char);   /* isStringProp */
237     bytestoalloc = (bytestoalloc + 3) & ~3;
238     ink_off = bytestoalloc;
239     if (fi.inkMetrics)
240         bytestoalloc += num_chars * sizeof(xCharInfo);  /* ink_metrics */
241
242     fontspace = (char *) xalloc(bytestoalloc);
243     if (!fontspace)
244         return AllocError;
245
246     bitmaps = (char *) xalloc (bitmapsSize);
247     if (!bitmaps)
248     {
249         xfree (fontspace);
250         return AllocError;
251     }
252     /*
253      * now fix up pointers
254      */
255
256     bitmapFont = (BitmapFontPtr) fontspace;
257     bitmapFont->num_chars = num_chars;
258     bitmapFont->metrics = (CharInfoPtr) (fontspace + metrics_off);
259     bitmapFont->encoding = (CharInfoPtr *) (fontspace + encoding_off);
260     bitmapFont->bitmaps = bitmaps;
261     bitmapFont->pDefault = NULL;
262     bitmapFont->bitmapExtra = NULL;
263     pFont->info.props = (FontPropPtr) (fontspace + props_off);
264     pFont->info.isStringProp = (char *) (fontspace + isStringProp_off);
265     if (fi.inkMetrics)
266         bitmapFont->ink_metrics = (xCharInfo *) (fontspace + ink_off);
267     else
268         bitmapFont->ink_metrics = 0;
269
270     /*
271      * read the CharInfo
272      */
273
274     ret = Successful;
275     for (i = 0; ret == Successful && i < num_chars; i++) {
276         ret = snfReadCharInfo(file, &bitmapFont->metrics[i], bitmaps);
277         if (bitmapFont->metrics[i].bits)
278             bitmapFont->encoding[i] = &bitmapFont->metrics[i];
279         else
280             bitmapFont->encoding[i] = 0;
281     }
282
283     if (ret != Successful) {
284         xfree(bitmaps);
285         xfree(fontspace);
286         return ret;
287     }
288     /*
289      * read the glyphs
290      */
291
292     if (FontFileRead(file, (char *) bitmaps, bitmapsSize) != bitmapsSize) {
293         xfree(bitmaps);
294         xfree(fontspace);
295         return BadFontName;
296     }
297
298     if (def_bit != bit)
299         BitOrderInvert(bitmaps, bitmapsSize);
300     if ((def_byte == def_bit) != (bit == byte)) {
301         switch (bit == byte ? def_scan : scan) {
302         case 1:
303             break;
304         case 2:
305             TwoByteSwap(bitmaps, bitmapsSize);
306             break;
307         case 4:
308             FourByteSwap(bitmaps, bitmapsSize);
309             break;
310         }
311     }
312     if (def_glyph != glyph) {
313         char        *padbitmaps;
314         int         sizepadbitmaps;
315         int         sizechar;
316         CharInfoPtr metric;
317
318         sizepadbitmaps = 0;
319         metric = bitmapFont->metrics;
320         for (i = 0; i < num_chars; i++)
321         {
322             if (metric->bits)
323                 sizepadbitmaps += BYTES_FOR_GLYPH(metric,glyph);
324             metric++;
325         }
326         padbitmaps = (char *) xalloc(sizepadbitmaps);
327         if (!padbitmaps) {
328             xfree (bitmaps);
329             xfree (fontspace);
330             return AllocError;
331         }
332         metric = bitmapFont->metrics;
333         bitmapFont->bitmaps = padbitmaps;
334         for (i = 0; i < num_chars; i++) {
335             sizechar = RepadBitmap(metric->bits, padbitmaps,
336                                def_glyph, glyph,
337                                metric->metrics.rightSideBearing -
338                                metric->metrics.leftSideBearing,
339                                metric->metrics.ascent + metric->metrics.descent);
340             metric->bits = padbitmaps;
341             padbitmaps += sizechar;
342             metric++;
343         }
344         xfree(bitmaps);
345     }
346
347     /* now read and atom'ize properties */
348
349     ret = snfReadProps(&fi, &pFont->info, file);
350     if (ret != Successful) {
351         xfree(fontspace);
352         return ret;
353     }
354     snfCopyInfo(&fi, &pFont->info);
355
356     /* finally, read the ink metrics if the exist */
357
358     if (fi.inkMetrics) {
359         ret = Successful;
360         ret = snfReadxCharInfo(file, &pFont->info.ink_minbounds);
361         ret = snfReadxCharInfo(file, &pFont->info.ink_maxbounds);
362         for (i = 0; ret == Successful && i < num_chars; i++)
363             ret = snfReadxCharInfo(file, &bitmapFont->ink_metrics[i]);
364         if (ret != Successful) {
365             xfree(fontspace);
366             return ret;
367         }
368     } else {
369         pFont->info.ink_minbounds = pFont->info.minbounds;
370         pFont->info.ink_maxbounds = pFont->info.maxbounds;
371     }
372
373     if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
374         unsigned int r,
375                     c,
376                     cols;
377
378         r = pFont->info.defaultCh >> 8;
379         c = pFont->info.defaultCh & 0xFF;
380         if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
381                 pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
382             cols = pFont->info.lastCol - pFont->info.firstCol + 1;
383             r = r - pFont->info.firstRow;
384             c = c - pFont->info.firstCol;
385             bitmapFont->pDefault = &bitmapFont->metrics[r * cols + c];
386         }
387     }
388     bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
389     pFont->fontPrivate = (pointer) bitmapFont;
390     pFont->get_glyphs = bitmapGetGlyphs;
391     pFont->get_metrics = bitmapGetMetrics;
392     pFont->unload_font = snfUnloadFont;
393     pFont->unload_glyphs = NULL;
394     pFont->bit = bit;
395     pFont->byte = byte;
396     pFont->glyph = glyph;
397     pFont->scan = scan;
398     return Successful;
399 }
400
401 int
402 snfReadFontInfo(pFontInfo, file)
403     FontInfoPtr pFontInfo;
404     FontFilePtr file;
405 {
406     int         ret;
407     snfFontInfoRec fi;
408     int         bytestoskip;
409     int         num_chars;
410
411     ret = snfReadHeader(&fi, file);
412     if (ret != Successful)
413         return ret;
414     snfCopyInfo(&fi, pFontInfo);
415
416     pFontInfo->props = (FontPropPtr) xalloc(fi.nProps * sizeof(FontPropRec));
417     if (!pFontInfo->props)
418         return AllocError;
419     pFontInfo->isStringProp = (char *) xalloc(fi.nProps * sizeof(char));
420     if (!pFontInfo->isStringProp) {
421         xfree(pFontInfo->props);
422         return AllocError;
423     }
424     num_chars = n2dChars(&fi);
425     bytestoskip = num_chars * sizeof(snfCharInfoRec);   /* charinfos */
426     bytestoskip += BYTESOFGLYPHINFO(&fi);
427     FontFileSkip(file, bytestoskip);
428
429     ret = snfReadProps(&fi, pFontInfo, file);
430     if (ret != Successful) {
431         xfree(pFontInfo->props);
432         xfree(pFontInfo->isStringProp);
433         return ret;
434     }
435     if (fi.inkMetrics) {
436         ret = snfReadxCharInfo(file, &pFontInfo->ink_minbounds);
437         if (ret != Successful) {
438             xfree(pFontInfo->props);
439             xfree(pFontInfo->isStringProp);
440             return ret;
441         }
442         ret = snfReadxCharInfo(file, &pFontInfo->ink_maxbounds);
443         if (ret != Successful) {
444             xfree(pFontInfo->props);
445             xfree(pFontInfo->isStringProp);
446             return ret;
447         }
448     } else {
449         pFontInfo->ink_minbounds = pFontInfo->minbounds;
450         pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
451     }
452     return Successful;
453
454 }
455
456 static void
457 snfUnloadFont(pFont)
458     FontPtr         pFont;
459 {
460     BitmapFontPtr   bitmapFont;
461
462     bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
463     xfree (bitmapFont->bitmaps);
464     xfree (bitmapFont);
465     xfree (pFont->devPrivates);
466     xfree (pFont);
467 }
468
469 static int  snf_set;
470 static int  snf_bit, snf_byte, snf_glyph, snf_scan;
471
472 SnfSetFormat (bit, byte, glyph, scan)
473     int bit, byte, glyph, scan;
474 {
475     snf_bit = bit;
476     snf_byte = byte;
477     snf_glyph = glyph;
478     snf_scan = scan;
479     snf_set = 1;
480 }
481
482 SnfGetFormat (bit, byte, glyph, scan)
483     int *bit, *byte, *glyph, *scan;
484 {
485     if (!snf_set)
486         FontDefaultFormat (&snf_bit, &snf_byte, &snf_glyph, &snf_scan);
487     *bit = snf_bit;
488     *byte = snf_byte;
489     *glyph = snf_glyph;
490     *scan = snf_scan;
491 }