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