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