123a0898aSmrg/************************************************************************
223a0898aSmrgCopyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
323a0898aSmrg
423a0898aSmrg                        All Rights Reserved
523a0898aSmrg
623a0898aSmrgPermission to use, copy, modify, and distribute this software and its
723a0898aSmrgdocumentation for any purpose and without fee is hereby granted,
823a0898aSmrgprovided that the above copyright notice appear in all copies and that
923a0898aSmrgboth that copyright notice and this permission notice appear in
1023a0898aSmrgsupporting documentation, and that the name of Digital not be
1123a0898aSmrgused in advertising or publicity pertaining to distribution of the
1223a0898aSmrgsoftware without specific, written prior permission.
1323a0898aSmrg
1423a0898aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
1523a0898aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
1623a0898aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
1723a0898aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
1823a0898aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
1923a0898aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
2023a0898aSmrgSOFTWARE.
2123a0898aSmrg
2223a0898aSmrg************************************************************************/
2323a0898aSmrg
2423a0898aSmrg/*
2523a0898aSmrg
2623a0898aSmrgCopyright 1994, 1998  The Open Group
2723a0898aSmrg
2823a0898aSmrgPermission to use, copy, modify, distribute, and sell this software and its
2923a0898aSmrgdocumentation for any purpose is hereby granted without fee, provided that
3023a0898aSmrgthe above copyright notice appear in all copies and that both that
3123a0898aSmrgcopyright notice and this permission notice appear in supporting
3223a0898aSmrgdocumentation.
3323a0898aSmrg
3423a0898aSmrgThe above copyright notice and this permission notice shall be included
3523a0898aSmrgin all copies or substantial portions of the Software.
3623a0898aSmrg
3723a0898aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
3823a0898aSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3923a0898aSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
4023a0898aSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
4123a0898aSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
4223a0898aSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
4323a0898aSmrgOTHER DEALINGS IN THE SOFTWARE.
4423a0898aSmrg
4523a0898aSmrgExcept as contained in this notice, the name of The Open Group shall
4623a0898aSmrgnot be used in advertising or otherwise to promote the sale, use or
4723a0898aSmrgother dealings in this Software without prior written authorization
4823a0898aSmrgfrom The Open Group.
4923a0898aSmrg
5023a0898aSmrg*/
5123a0898aSmrg
5223a0898aSmrg#ifdef HAVE_CONFIG_H
5323a0898aSmrg#include <config.h>
5423a0898aSmrg#endif
5523a0898aSmrg
5623a0898aSmrg#include <ctype.h>
5723a0898aSmrg#include <X11/fonts/fntfilst.h>
5823a0898aSmrg#include <X11/fonts/bitmap.h>
5923a0898aSmrg#include "snfstr.h"
6023a0898aSmrg
6123a0898aSmrg#include <stdarg.h>
6223a0898aSmrg
6341c30155Smrgstatic void _X_ATTRIBUTE_PRINTF(1, 2)
6423a0898aSmrgsnfError(const char* message, ...)
6523a0898aSmrg{
6623a0898aSmrg    va_list args;
6723a0898aSmrg
6823a0898aSmrg    va_start(args, message);
6923a0898aSmrg
7023a0898aSmrg    fprintf(stderr, "SNF Error: ");
7123a0898aSmrg    vfprintf(stderr, message, args);
7223a0898aSmrg    va_end(args);
7323a0898aSmrg}
7441c30155Smrg
7523a0898aSmrgstatic void snfUnloadFont(FontPtr pFont);
7623a0898aSmrg
7723a0898aSmrgstatic int
7823a0898aSmrgsnfReadCharInfo(FontFilePtr file, CharInfoPtr charInfo, char *base)
7923a0898aSmrg{
8023a0898aSmrg    snfCharInfoRec snfCharInfo;
8123a0898aSmrg
8223a0898aSmrg#define Width(m)    ((m).rightSideBearing - (m).leftSideBearing)
8323a0898aSmrg#define Height(m)   ((m).ascent + (m).descent)
8423a0898aSmrg
8523a0898aSmrg    if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
8623a0898aSmrg	    sizeof(snfCharInfo)) {
8723a0898aSmrg	return BadFontName;
8823a0898aSmrg    }
8923a0898aSmrg    charInfo->metrics = snfCharInfo.metrics;
9023a0898aSmrg    if (snfCharInfo.exists)
9123a0898aSmrg	charInfo->bits = base + snfCharInfo.byteOffset;
9223a0898aSmrg    else
9323a0898aSmrg	charInfo->bits = 0;
9423a0898aSmrg    return Successful;
9523a0898aSmrg}
9623a0898aSmrg
9723a0898aSmrgstatic int
9823a0898aSmrgsnfReadxCharInfo(FontFilePtr file, xCharInfo *charInfo)
9923a0898aSmrg{
10023a0898aSmrg    snfCharInfoRec snfCharInfo;
10123a0898aSmrg
10223a0898aSmrg    if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
10323a0898aSmrg	    sizeof(snfCharInfo)) {
10423a0898aSmrg	return BadFontName;
10523a0898aSmrg    }
10623a0898aSmrg    *charInfo = snfCharInfo.metrics;
10723a0898aSmrg    return Successful;
10823a0898aSmrg}
10923a0898aSmrg
11023a0898aSmrgstatic void
11123a0898aSmrgsnfCopyInfo(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo)
11223a0898aSmrg{
11323a0898aSmrg    pFontInfo->firstCol = snfInfo->firstCol;
11423a0898aSmrg    pFontInfo->lastCol = snfInfo->lastCol;
11523a0898aSmrg    pFontInfo->firstRow = snfInfo->firstRow;
11623a0898aSmrg    pFontInfo->lastRow = snfInfo->lastRow;
11723a0898aSmrg    pFontInfo->defaultCh = snfInfo->chDefault;
11823a0898aSmrg    pFontInfo->noOverlap = snfInfo->noOverlap;
11923a0898aSmrg    pFontInfo->terminalFont = snfInfo->terminalFont;
12023a0898aSmrg    pFontInfo->constantMetrics = snfInfo->constantMetrics;
12123a0898aSmrg    pFontInfo->constantWidth = snfInfo->constantWidth;
12223a0898aSmrg    pFontInfo->inkInside = snfInfo->inkInside;
12323a0898aSmrg    pFontInfo->inkMetrics = snfInfo->inkMetrics;
12423a0898aSmrg    pFontInfo->allExist = snfInfo->allExist;
12523a0898aSmrg    pFontInfo->drawDirection = snfInfo->drawDirection;
12623a0898aSmrg    pFontInfo->anamorphic = FALSE;
12723a0898aSmrg    pFontInfo->cachable = TRUE;
12823a0898aSmrg    pFontInfo->maxOverlap = 0;
12923a0898aSmrg    pFontInfo->minbounds = snfInfo->minbounds.metrics;
13023a0898aSmrg    pFontInfo->maxbounds = snfInfo->maxbounds.metrics;
13123a0898aSmrg    pFontInfo->fontAscent = snfInfo->fontAscent;
13223a0898aSmrg    pFontInfo->fontDescent = snfInfo->fontDescent;
13323a0898aSmrg    pFontInfo->nprops = snfInfo->nProps;
13423a0898aSmrg}
13523a0898aSmrg
13623a0898aSmrgstatic int
13723a0898aSmrgsnfReadProps(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo, FontFilePtr file)
13823a0898aSmrg{
13923a0898aSmrg    char       *strings;
14023a0898aSmrg    FontPropPtr pfp;
14123a0898aSmrg    snfFontPropPtr psnfp;
14223a0898aSmrg    char       *propspace;
14323a0898aSmrg    int         bytestoalloc;
14423a0898aSmrg    int         i;
14523a0898aSmrg
14623a0898aSmrg    bytestoalloc = snfInfo->nProps * sizeof(snfFontPropRec) +
14723a0898aSmrg	BYTESOFSTRINGINFO(snfInfo);
1487f7f5e4eSmrg    propspace = malloc(bytestoalloc);
14923a0898aSmrg    if (!propspace) {
15023a0898aSmrg      snfError("snfReadProps(): Couldn't allocate propspace (%d)\n", bytestoalloc);
15123a0898aSmrg	return AllocError;
15223a0898aSmrg    }
15323a0898aSmrg
15423a0898aSmrg    if (FontFileRead(file, propspace, bytestoalloc) != bytestoalloc) {
1557f7f5e4eSmrg	free(propspace);
15623a0898aSmrg	return BadFontName;
15723a0898aSmrg    }
15823a0898aSmrg    psnfp = (snfFontPropPtr) propspace;
15923a0898aSmrg
16023a0898aSmrg    strings = propspace + BYTESOFPROPINFO(snfInfo);
16123a0898aSmrg
16223a0898aSmrg    for (i = 0, pfp = pFontInfo->props; i < snfInfo->nProps; i++, pfp++, psnfp++) {
16323a0898aSmrg	pfp->name = MakeAtom(&strings[psnfp->name],
16423a0898aSmrg			     (unsigned) strlen(&strings[psnfp->name]), 1);
16523a0898aSmrg	pFontInfo->isStringProp[i] = psnfp->indirect;
16623a0898aSmrg	if (psnfp->indirect)
16723a0898aSmrg	    pfp->value = (INT32) MakeAtom(&strings[psnfp->value],
16823a0898aSmrg			       (unsigned) strlen(&strings[psnfp->value]), 1);
16923a0898aSmrg	else
17023a0898aSmrg	    pfp->value = psnfp->value;
17123a0898aSmrg    }
17223a0898aSmrg
1737f7f5e4eSmrg    free(propspace);
17423a0898aSmrg    return Successful;
17523a0898aSmrg}
17623a0898aSmrg
17723a0898aSmrgstatic int
17823a0898aSmrgsnfReadHeader(snfFontInfoPtr snfInfo, FontFilePtr file)
17923a0898aSmrg{
18023a0898aSmrg    if (FontFileRead(file, (char *) snfInfo, sizeof *snfInfo) != sizeof *snfInfo)
18123a0898aSmrg	return BadFontName;
18223a0898aSmrg
18323a0898aSmrg    if (snfInfo->version1 != FONT_FILE_VERSION ||
18423a0898aSmrg	    snfInfo->version2 != FONT_FILE_VERSION)
18523a0898aSmrg	return BadFontName;
18623a0898aSmrg    return Successful;
18723a0898aSmrg}
18823a0898aSmrg
18923a0898aSmrgstatic int  snf_set;
19023a0898aSmrgstatic int  snf_bit, snf_byte, snf_glyph, snf_scan;
19123a0898aSmrg
19223a0898aSmrgvoid
19323a0898aSmrgSnfSetFormat (int bit, int byte, int glyph, int scan)
19423a0898aSmrg{
19523a0898aSmrg    snf_bit = bit;
19623a0898aSmrg    snf_byte = byte;
19723a0898aSmrg    snf_glyph = glyph;
19823a0898aSmrg    snf_scan = scan;
19923a0898aSmrg    snf_set = 1;
20023a0898aSmrg}
20123a0898aSmrg
20223a0898aSmrgstatic void
20323a0898aSmrgSnfGetFormat (int *bit, int *byte, int *glyph, int *scan)
20423a0898aSmrg{
20523a0898aSmrg    if (!snf_set)
20623a0898aSmrg	FontDefaultFormat (&snf_bit, &snf_byte, &snf_glyph, &snf_scan);
20723a0898aSmrg    *bit = snf_bit;
20823a0898aSmrg    *byte = snf_byte;
20923a0898aSmrg    *glyph = snf_glyph;
21023a0898aSmrg    *scan = snf_scan;
21123a0898aSmrg}
21223a0898aSmrg
21323a0898aSmrgint
21441c30155SmrgsnfReadFont(FontPtr pFont, FontFilePtr file,
21523a0898aSmrg	    int bit, int byte, int glyph, int scan)
21623a0898aSmrg{
21723a0898aSmrg    snfFontInfoRec fi;
21823a0898aSmrg    unsigned    bytestoalloc;
21923a0898aSmrg    int         i, j;
22023a0898aSmrg    char       *fontspace;
22123a0898aSmrg    BitmapFontPtr  bitmapFont;
22223a0898aSmrg    int         num_chars;
22323a0898aSmrg    int         bitmapsSize;
22423a0898aSmrg    int         ret;
22523a0898aSmrg    int         metrics_off;
22623a0898aSmrg    int         encoding_off;
22723a0898aSmrg    int         props_off;
22823a0898aSmrg    int         isStringProp_off;
22923a0898aSmrg    int         ink_off;
23023a0898aSmrg    char	*bitmaps;
23123a0898aSmrg    int		def_bit, def_byte, def_glyph, def_scan;
23223a0898aSmrg
23323a0898aSmrg    ret = snfReadHeader(&fi, file);
23423a0898aSmrg    if (ret != Successful)
23523a0898aSmrg	return ret;
23623a0898aSmrg
23723a0898aSmrg    SnfGetFormat (&def_bit, &def_byte, &def_glyph, &def_scan);
23823a0898aSmrg
23923a0898aSmrg    /*
24023a0898aSmrg     * we'll allocate one chunk of memory and split it among the various parts
24123a0898aSmrg     * of the font:
24241c30155Smrg     *
24323a0898aSmrg     * BitmapFontRec CharInfoRec's Glyphs Encoding DIX Properties Ink CharInfoRec's
24423a0898aSmrg     *
24523a0898aSmrg     * If the glyphpad is not the same as the font file, then the glyphs
24623a0898aSmrg     * are allocated separately, to be later realloc'ed when we know
24723a0898aSmrg     * how big to make them.
24823a0898aSmrg     */
24923a0898aSmrg
25023a0898aSmrg    bitmapsSize = BYTESOFGLYPHINFO(&fi);
25123a0898aSmrg    num_chars = n2dChars(&fi);
25223a0898aSmrg    bytestoalloc = sizeof(BitmapFontRec);	/* bitmapFont */
25323a0898aSmrg    metrics_off = bytestoalloc;
25423a0898aSmrg    bytestoalloc += num_chars * sizeof(CharInfoRec);	/* metrics */
25523a0898aSmrg    encoding_off = bytestoalloc;
25641c30155Smrg    bytestoalloc += NUM_SEGMENTS(num_chars) * sizeof(CharInfoPtr**);
25723a0898aSmrg                                                /* encoding */
25823a0898aSmrg    props_off = bytestoalloc;
25923a0898aSmrg    bytestoalloc += fi.nProps * sizeof(FontPropRec);	/* props */
26023a0898aSmrg    isStringProp_off = bytestoalloc;
26123a0898aSmrg    bytestoalloc += fi.nProps * sizeof(char);	/* isStringProp */
26223a0898aSmrg    bytestoalloc = (bytestoalloc + 3) & ~3;
26323a0898aSmrg    ink_off = bytestoalloc;
26423a0898aSmrg    if (fi.inkMetrics)
26523a0898aSmrg	bytestoalloc += num_chars * sizeof(xCharInfo);	/* ink_metrics */
26623a0898aSmrg
2677f7f5e4eSmrg    fontspace = malloc(bytestoalloc);
26823a0898aSmrg    if (!fontspace) {
26923a0898aSmrg      snfError("snfReadFont(): Couldn't allocate fontspace (%d)\n", bytestoalloc);
27023a0898aSmrg	return AllocError;
27123a0898aSmrg    }
2727f7f5e4eSmrg    bitmaps = malloc (bitmapsSize);
27323a0898aSmrg    if (!bitmaps)
27423a0898aSmrg    {
27523a0898aSmrg      snfError("snfReadFont(): Couldn't allocate bitmaps (%d)\n", bitmapsSize);
2767f7f5e4eSmrg	free (fontspace);
27723a0898aSmrg	return AllocError;
27823a0898aSmrg    }
27923a0898aSmrg    /*
28023a0898aSmrg     * now fix up pointers
28123a0898aSmrg     */
28223a0898aSmrg
28323a0898aSmrg    bitmapFont = (BitmapFontPtr) fontspace;
28423a0898aSmrg    bitmapFont->num_chars = num_chars;
28523a0898aSmrg    bitmapFont->metrics = (CharInfoPtr) (fontspace + metrics_off);
28623a0898aSmrg    bitmapFont->encoding = (CharInfoPtr **) (fontspace + encoding_off);
28723a0898aSmrg    bitmapFont->bitmaps = bitmaps;
28823a0898aSmrg    bitmapFont->pDefault = NULL;
28923a0898aSmrg    bitmapFont->bitmapExtra = NULL;
29023a0898aSmrg    pFont->info.props = (FontPropPtr) (fontspace + props_off);
29123a0898aSmrg    pFont->info.isStringProp = (char *) (fontspace + isStringProp_off);
29223a0898aSmrg    if (fi.inkMetrics)
29323a0898aSmrg	bitmapFont->ink_metrics = (xCharInfo *) (fontspace + ink_off);
29423a0898aSmrg    else
29523a0898aSmrg	bitmapFont->ink_metrics = 0;
29623a0898aSmrg
29723a0898aSmrg    /*
29823a0898aSmrg     * read the CharInfo
29923a0898aSmrg     */
30023a0898aSmrg
30123a0898aSmrg    ret = Successful;
30241c30155Smrg    memset(bitmapFont->encoding, 0,
30323a0898aSmrg           NUM_SEGMENTS(num_chars)*sizeof(CharInfoPtr*));
30423a0898aSmrg    for (i = 0; ret == Successful && i < num_chars; i++) {
30523a0898aSmrg	ret = snfReadCharInfo(file, &bitmapFont->metrics[i], bitmaps);
30623a0898aSmrg	if (bitmapFont->metrics[i].bits) {
30723a0898aSmrg            if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
30823a0898aSmrg                bitmapFont->encoding[SEGMENT_MAJOR(i)]=
3097f7f5e4eSmrg                    calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr));
31023a0898aSmrg                if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
31123a0898aSmrg                    ret = AllocError;
31223a0898aSmrg                    break;
31323a0898aSmrg                }
31423a0898aSmrg            }
31523a0898aSmrg            ACCESSENCODINGL(bitmapFont->encoding,i) = &bitmapFont->metrics[i];
31623a0898aSmrg        }
31723a0898aSmrg    }
31823a0898aSmrg
31923a0898aSmrg    if (ret != Successful) {
3207f7f5e4eSmrg	free(bitmaps);
32123a0898aSmrg        if(bitmapFont->encoding) {
32223a0898aSmrg            for(j=0; j<SEGMENT_MAJOR(i); j++)
3237f7f5e4eSmrg                free(bitmapFont->encoding[i]);
32423a0898aSmrg        }
3257f7f5e4eSmrg	free(fontspace);
32623a0898aSmrg	return ret;
32723a0898aSmrg    }
32823a0898aSmrg    /*
32923a0898aSmrg     * read the glyphs
33023a0898aSmrg     */
33123a0898aSmrg
33223a0898aSmrg    if (FontFileRead(file, bitmaps, bitmapsSize) != bitmapsSize) {
3337f7f5e4eSmrg	free(bitmaps);
3347f7f5e4eSmrg	free(fontspace);
33523a0898aSmrg	return BadFontName;
33623a0898aSmrg    }
33723a0898aSmrg
33823a0898aSmrg    if (def_bit != bit)
33923a0898aSmrg	BitOrderInvert((unsigned char *)bitmaps, bitmapsSize);
34023a0898aSmrg    if ((def_byte == def_bit) != (bit == byte)) {
34123a0898aSmrg	switch (bit == byte ? def_scan : scan) {
34223a0898aSmrg	case 1:
34323a0898aSmrg	    break;
34423a0898aSmrg	case 2:
34523a0898aSmrg	    TwoByteSwap((unsigned char *)bitmaps, bitmapsSize);
34623a0898aSmrg	    break;
34723a0898aSmrg	case 4:
34823a0898aSmrg	    FourByteSwap((unsigned char *)bitmaps, bitmapsSize);
34923a0898aSmrg	    break;
35023a0898aSmrg	}
35123a0898aSmrg    }
35223a0898aSmrg    if (def_glyph != glyph) {
35323a0898aSmrg	char	    *padbitmaps;
35423a0898aSmrg	int         sizepadbitmaps;
35523a0898aSmrg	int	    sizechar;
35623a0898aSmrg	CharInfoPtr metric;
35723a0898aSmrg
35823a0898aSmrg	sizepadbitmaps = 0;
35923a0898aSmrg	metric = bitmapFont->metrics;
36023a0898aSmrg	for (i = 0; i < num_chars; i++)
36123a0898aSmrg	{
36223a0898aSmrg	    if (metric->bits)
36323a0898aSmrg		sizepadbitmaps += BYTES_FOR_GLYPH(metric,glyph);
36423a0898aSmrg	    metric++;
36523a0898aSmrg	}
3667f7f5e4eSmrg	padbitmaps = malloc(sizepadbitmaps);
36723a0898aSmrg	if (!padbitmaps) {
36823a0898aSmrg	    snfError("snfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
3697f7f5e4eSmrg	    free (bitmaps);
3707f7f5e4eSmrg	    free (fontspace);
37123a0898aSmrg	    return AllocError;
37223a0898aSmrg	}
37323a0898aSmrg	metric = bitmapFont->metrics;
37423a0898aSmrg	bitmapFont->bitmaps = padbitmaps;
37523a0898aSmrg	for (i = 0; i < num_chars; i++) {
37623a0898aSmrg	    sizechar = RepadBitmap(metric->bits, padbitmaps,
37723a0898aSmrg			       def_glyph, glyph,
37823a0898aSmrg			       metric->metrics.rightSideBearing -
37923a0898aSmrg			       metric->metrics.leftSideBearing,
38023a0898aSmrg			       metric->metrics.ascent + metric->metrics.descent);
38123a0898aSmrg	    metric->bits = padbitmaps;
38223a0898aSmrg	    padbitmaps += sizechar;
38323a0898aSmrg	    metric++;
38423a0898aSmrg	}
3857f7f5e4eSmrg	free(bitmaps);
38623a0898aSmrg    }
38723a0898aSmrg
38823a0898aSmrg    /* now read and atom'ize properties */
38923a0898aSmrg
39023a0898aSmrg    ret = snfReadProps(&fi, &pFont->info, file);
39123a0898aSmrg    if (ret != Successful) {
3927f7f5e4eSmrg	free(fontspace);
39323a0898aSmrg	return ret;
39423a0898aSmrg    }
39523a0898aSmrg    snfCopyInfo(&fi, &pFont->info);
39623a0898aSmrg
39723a0898aSmrg    /* finally, read the ink metrics if the exist */
39823a0898aSmrg
39923a0898aSmrg    if (fi.inkMetrics) {
40023a0898aSmrg	ret = Successful;
40123a0898aSmrg	ret = snfReadxCharInfo(file, &pFont->info.ink_minbounds);
40223a0898aSmrg	ret = snfReadxCharInfo(file, &pFont->info.ink_maxbounds);
40323a0898aSmrg	for (i = 0; ret == Successful && i < num_chars; i++)
40423a0898aSmrg	    ret = snfReadxCharInfo(file, &bitmapFont->ink_metrics[i]);
40523a0898aSmrg	if (ret != Successful) {
4067f7f5e4eSmrg	    free(fontspace);
40723a0898aSmrg	    return ret;
40823a0898aSmrg	}
40923a0898aSmrg    } else {
41023a0898aSmrg	pFont->info.ink_minbounds = pFont->info.minbounds;
41123a0898aSmrg	pFont->info.ink_maxbounds = pFont->info.maxbounds;
41223a0898aSmrg    }
41323a0898aSmrg
41423a0898aSmrg    if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
41523a0898aSmrg	unsigned int r,
41623a0898aSmrg	            c,
41723a0898aSmrg	            cols;
41823a0898aSmrg
41923a0898aSmrg	r = pFont->info.defaultCh >> 8;
42023a0898aSmrg	c = pFont->info.defaultCh & 0xFF;
42123a0898aSmrg	if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
42223a0898aSmrg		pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
42323a0898aSmrg	    cols = pFont->info.lastCol - pFont->info.firstCol + 1;
42423a0898aSmrg	    r = r - pFont->info.firstRow;
42523a0898aSmrg	    c = c - pFont->info.firstCol;
42623a0898aSmrg	    bitmapFont->pDefault = &bitmapFont->metrics[r * cols + c];
42723a0898aSmrg	}
42823a0898aSmrg    }
42923a0898aSmrg    bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
43023a0898aSmrg    pFont->fontPrivate = (pointer) bitmapFont;
43123a0898aSmrg    pFont->get_glyphs = bitmapGetGlyphs;
43223a0898aSmrg    pFont->get_metrics = bitmapGetMetrics;
43323a0898aSmrg    pFont->unload_font = snfUnloadFont;
43423a0898aSmrg    pFont->unload_glyphs = NULL;
43523a0898aSmrg    pFont->bit = bit;
43623a0898aSmrg    pFont->byte = byte;
43723a0898aSmrg    pFont->glyph = glyph;
43823a0898aSmrg    pFont->scan = scan;
43923a0898aSmrg    return Successful;
44023a0898aSmrg}
44123a0898aSmrg
44223a0898aSmrgint
44323a0898aSmrgsnfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
44423a0898aSmrg{
44523a0898aSmrg    int         ret;
44623a0898aSmrg    snfFontInfoRec fi;
44723a0898aSmrg    int         bytestoskip;
44823a0898aSmrg    int         num_chars;
44923a0898aSmrg
45023a0898aSmrg    ret = snfReadHeader(&fi, file);
45123a0898aSmrg    if (ret != Successful)
45223a0898aSmrg	return ret;
45323a0898aSmrg    snfCopyInfo(&fi, pFontInfo);
45423a0898aSmrg
4557f7f5e4eSmrg    pFontInfo->props = malloc(fi.nProps * sizeof(FontPropRec));
45623a0898aSmrg    if (!pFontInfo->props) {
45741c30155Smrg	snfError("snfReadFontInfo(): Couldn't allocate props (%d*%d)\n",
45841c30155Smrg		 fi.nProps, (int) sizeof(FontPropRec));
45923a0898aSmrg	return AllocError;
46023a0898aSmrg    }
4617f7f5e4eSmrg    pFontInfo->isStringProp = malloc(fi.nProps * sizeof(char));
46223a0898aSmrg    if (!pFontInfo->isStringProp) {
46341c30155Smrg	snfError("snfReadFontInfo(): Couldn't allocate isStringProp (%d*%d)\n",
46441c30155Smrg		 fi.nProps, (int) sizeof(char));
4657f7f5e4eSmrg	free(pFontInfo->props);
46623a0898aSmrg	return AllocError;
46723a0898aSmrg    }
46823a0898aSmrg    num_chars = n2dChars(&fi);
46923a0898aSmrg    bytestoskip = num_chars * sizeof(snfCharInfoRec);	/* charinfos */
47023a0898aSmrg    bytestoskip += BYTESOFGLYPHINFO(&fi);
47123a0898aSmrg    (void)FontFileSkip(file, bytestoskip);
47223a0898aSmrg
47323a0898aSmrg    ret = snfReadProps(&fi, pFontInfo, file);
47423a0898aSmrg    if (ret != Successful) {
4757f7f5e4eSmrg	free(pFontInfo->props);
4767f7f5e4eSmrg	free(pFontInfo->isStringProp);
47723a0898aSmrg	return ret;
47823a0898aSmrg    }
47923a0898aSmrg    if (fi.inkMetrics) {
48023a0898aSmrg	ret = snfReadxCharInfo(file, &pFontInfo->ink_minbounds);
48123a0898aSmrg	if (ret != Successful) {
4827f7f5e4eSmrg	    free(pFontInfo->props);
4837f7f5e4eSmrg	    free(pFontInfo->isStringProp);
48423a0898aSmrg	    return ret;
48523a0898aSmrg	}
48623a0898aSmrg	ret = snfReadxCharInfo(file, &pFontInfo->ink_maxbounds);
48723a0898aSmrg	if (ret != Successful) {
4887f7f5e4eSmrg	    free(pFontInfo->props);
4897f7f5e4eSmrg	    free(pFontInfo->isStringProp);
49023a0898aSmrg	    return ret;
49123a0898aSmrg	}
49223a0898aSmrg    } else {
49323a0898aSmrg	pFontInfo->ink_minbounds = pFontInfo->minbounds;
49423a0898aSmrg	pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
49523a0898aSmrg    }
49623a0898aSmrg    return Successful;
49723a0898aSmrg
49823a0898aSmrg}
49923a0898aSmrg
50023a0898aSmrgstatic void
50123a0898aSmrgsnfUnloadFont(FontPtr pFont)
50223a0898aSmrg{
50323a0898aSmrg    BitmapFontPtr   bitmapFont;
50423a0898aSmrg
50523a0898aSmrg    bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
5067f7f5e4eSmrg    free (bitmapFont->bitmaps);
5077f7f5e4eSmrg    free (bitmapFont);
50823a0898aSmrg    DestroyFontRec (pFont);
50923a0898aSmrg}
51023a0898aSmrg
511