121c2f794Smrg/*
282e12b1bSmrg
321c2f794SmrgCopyright 1990, 1998  The Open Group
421c2f794Smrg
521c2f794SmrgPermission to use, copy, modify, distribute, and sell this software and its
621c2f794Smrgdocumentation for any purpose is hereby granted without fee, provided that
721c2f794Smrgthe above copyright notice appear in all copies and that both that
821c2f794Smrgcopyright notice and this permission notice appear in supporting
921c2f794Smrgdocumentation.
1021c2f794Smrg
1121c2f794SmrgThe above copyright notice and this permission notice shall be included in
1221c2f794Smrgall copies or substantial portions of the Software.
1321c2f794Smrg
1421c2f794SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1521c2f794SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1621c2f794SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1721c2f794SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1821c2f794SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1921c2f794SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2021c2f794Smrg
2121c2f794SmrgExcept as contained in this notice, the name of The Open Group shall not be
2221c2f794Smrgused in advertising or otherwise to promote the sale, use or other dealings
2321c2f794Smrgin this Software without prior written authorization from The Open Group.
2421c2f794Smrg
2521c2f794Smrg * Copyright 1990 Network Computing Devices;
2682e12b1bSmrg * Portions Copyright 1987 by Digital Equipment Corporation
2721c2f794Smrg *
2821c2f794Smrg * Permission to use, copy, modify, distribute, and sell this software and
2921c2f794Smrg * its documentation for any purpose is hereby granted without fee, provided
3021c2f794Smrg * that the above copyright notice appear in all copies and that both that
3121c2f794Smrg * copyright notice and this permission notice appear in supporting
3221c2f794Smrg * documentation, and that the names of Network Computing Devices, or Digital
3321c2f794Smrg * not be used in advertising or publicity pertaining to distribution
3421c2f794Smrg * of the software without specific, written prior permission.
3521c2f794Smrg *
3621c2f794Smrg * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
3721c2f794Smrg * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
3821c2f794Smrg * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
3921c2f794Smrg * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
4021c2f794Smrg * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
4121c2f794Smrg * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
4221c2f794Smrg * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
4321c2f794Smrg * THIS SOFTWARE.
4421c2f794Smrg */
4521c2f794Smrg
4621c2f794Smrg/* Morten Storgaard Nielsen: chars.c,v 3.2-1 2000/01/30 14:11:19 kat Exp */
4721c2f794Smrg
4821c2f794Smrg#include	<stdio.h>
4921c2f794Smrg#include	<X11/Xlib.h>
5021c2f794Smrg#include	"fstobdf.h"
5121c2f794Smrg
5221c2f794Smrg#define BIT_ORDER	BitmapFormatBitOrderMSB
5321c2f794Smrg#ifdef BYTE_ORDER
5421c2f794Smrg#undef BYTE_ORDER
5521c2f794Smrg#endif
5621c2f794Smrg#define BYTE_ORDER	BitmapFormatByteOrderMSB
5721c2f794Smrg#define SCANLINE_UNIT	BitmapFormatScanlineUnit8
5821c2f794Smrg#define SCANLINE_PAD	BitmapFormatScanlinePad8
5921c2f794Smrg#define EXTENTS		BitmapFormatImageRectMin
6021c2f794Smrg
6121c2f794Smrg#define SCANLINE_PAD_BYTES	1
6221c2f794Smrg
6321c2f794Smrg#define GLWIDTHBYTESPADDED(bits, nBytes)				    \
6421c2f794Smrg	((nBytes) == 1 ? (((bits)  +  7) >> 3)		/* pad to 1 byte  */\
6521c2f794Smrg	:(nBytes) == 2 ? ((((bits) + 15) >> 3) & ~1)	/* pad to 2 bytes */\
6621c2f794Smrg	:(nBytes) == 4 ? ((((bits) + 31) >> 3) & ~3)	/* pad to 4 bytes */\
6721c2f794Smrg	:(nBytes) == 8 ? ((((bits) + 63) >> 3) & ~7)	/* pad to 8 bytes */\
6821c2f794Smrg	: 0)
6921c2f794Smrg
7021c2f794Smrgstatic void
7182e12b1bSmrgEmitBitmap(FILE *outFile,
72889a2364Smrg           FSXFontInfoHeader *fontHeader,
73889a2364Smrg           FSXCharInfo *charInfo,
74889a2364Smrg           unsigned int encoding,
75889a2364Smrg           int bpr,
76889a2364Smrg           unsigned char *data)
7721c2f794Smrg{
78889a2364Smrg    char *glyphName;
7921c2f794Smrg
8021c2f794Smrg    /*-
8121c2f794Smrg     * format:
8221c2f794Smrg     * STARTCHAR name
8321c2f794Smrg     * ENCODING index
8421c2f794Smrg     * SWIDTH scalablewidth 0
8521c2f794Smrg     * DWIDTH pixels 0
8621c2f794Smrg     * BBX width height xoff yoff
8721c2f794Smrg     * ATTRIBUTES xxxx
8821c2f794Smrg     * BITMAP hhhhhhhh ...
8921c2f794Smrg     * ENDCHAR
9021c2f794Smrg     *
9121c2f794Smrg     * where, SWIDTH * (point / 1000) * (yres / 72) = DWIDTH or,
9221c2f794Smrg     *        SWIDTH = 72000 *
9321c2f794Smrg     * DWIDTH / (point * yres)
9421c2f794Smrg     */
9521c2f794Smrg
9621c2f794Smrg    fprintf(outFile, "STARTCHAR ");
9721c2f794Smrg    glyphName = XKeysymToString((KeySym) encoding);
9821c2f794Smrg    if (glyphName)
99889a2364Smrg        fputs(glyphName, outFile);
10021c2f794Smrg    else
101889a2364Smrg        fprintf(outFile, (fontHeader->char_range.min_char.low > 0 ?
102889a2364Smrg                          "C%06o" : "C%03o"), encoding);
10321c2f794Smrg    fputc('\n', outFile);
10421c2f794Smrg    fprintf(outFile, "ENCODING %u\n", encoding);
10521c2f794Smrg    fprintf(outFile, "SWIDTH %ld 0\n",
106889a2364Smrg            (((long) charInfo->width) * 72000L) / (pointSize * yResolution));
10721c2f794Smrg    fprintf(outFile, "DWIDTH %d 0\n", charInfo->width);
10821c2f794Smrg    fprintf(outFile, "BBX %d %d %d %d\n",
109889a2364Smrg            charInfo->right - charInfo->left,
110889a2364Smrg            charInfo->ascent + charInfo->descent,
111889a2364Smrg            charInfo->left,
112889a2364Smrg            -charInfo->descent);
11321c2f794Smrg    if (charInfo->attributes)
114889a2364Smrg        fprintf(outFile, "ATTRIBUTES %04x\n", charInfo->attributes);
11521c2f794Smrg
11621c2f794Smrg    /*
11721c2f794Smrg     * emit the bitmap
11821c2f794Smrg     */
11921c2f794Smrg    fprintf(outFile, "BITMAP\n");
120889a2364Smrg    for (unsigned row = 0; row < (charInfo->ascent + charInfo->descent); row++) {
121889a2364Smrg        unsigned byte;
122889a2364Smrg        unsigned bit;
123889a2364Smrg
124889a2364Smrg        static const unsigned maskTab[] = {
125889a2364Smrg            (1 << 7), (1 << 6), (1 << 5), (1 << 4),
126889a2364Smrg            (1 << 3), (1 << 2), (1 << 1), (1 << 0),
127889a2364Smrg        };
128889a2364Smrg
129889a2364Smrg        byte = 0;
130889a2364Smrg        for (bit = 0; bit < (charInfo->right - charInfo->left); bit++) {
131889a2364Smrg            byte |= maskTab[bit & 7] & data[bit >> 3];
132889a2364Smrg            if ((bit & 7) == 7) {
133889a2364Smrg                fprintf(outFile, "%02x", byte);
134889a2364Smrg                byte = 0;
135889a2364Smrg            }
136889a2364Smrg        }
137889a2364Smrg        if ((bit & 7) != 0)
138889a2364Smrg            fprintf(outFile, "%02x", byte);
139889a2364Smrg        fputc('\n', outFile);
140889a2364Smrg        data += bpr;
14121c2f794Smrg    }
14221c2f794Smrg    fprintf(outFile, "ENDCHAR\n");
14321c2f794Smrg}
14421c2f794Smrg
14521c2f794SmrgBool
14682e12b1bSmrgEmitCharacters(FILE *outFile,
147889a2364Smrg               FSServer *fontServer,
148889a2364Smrg               FSXFontInfoHeader *fontHeader,
149889a2364Smrg               Font fontID)
15021c2f794Smrg{
15121c2f794Smrg    FSXCharInfo *extents;
15221c2f794Smrg    FSXCharInfo *charInfo;
153889a2364Smrg    FSOffset *offsets;
15421c2f794Smrg    unsigned char *glyph;
15521c2f794Smrg    unsigned char *glyphs;
15621c2f794Smrg    unsigned int nChars;
1571b2353dbSmrg    unsigned int firstCharLow;
1581b2353dbSmrg    unsigned int firstCharHigh;
1591b2353dbSmrg    unsigned int lastCharLow;
1601b2353dbSmrg    unsigned int lastCharHigh;
1611b2353dbSmrg    unsigned int chLow;
1621b2353dbSmrg    unsigned int chHigh;
16321c2f794Smrg    FSBitmapFormat format;
16421c2f794Smrg
16521c2f794Smrg    nChars = 0;
16621c2f794Smrg
167889a2364Smrg    format = BYTE_ORDER | BIT_ORDER | SCANLINE_UNIT | SCANLINE_PAD | EXTENTS;
16882e12b1bSmrg    firstCharLow = fontHeader->char_range.min_char.low;
16982e12b1bSmrg    firstCharHigh = fontHeader->char_range.min_char.high;
17021c2f794Smrg    lastCharLow = fontHeader->char_range.max_char.low;
17121c2f794Smrg    lastCharHigh = fontHeader->char_range.max_char.high;
17221c2f794Smrg
17321c2f794Smrg    (void) FSQueryXExtents16(fontServer, fontID, True, (FSChar2b *) 0, 0,
174889a2364Smrg                             &extents);
17521c2f794Smrg    (void) FSQueryXBitmaps16(fontServer, fontID, format, True, (FSChar2b *) 0,
176889a2364Smrg                             0, &offsets, &glyphs);
17721c2f794Smrg
17821c2f794Smrg    charInfo = extents;
17921c2f794Smrg    /* calculate the actual number of chars */
180889a2364Smrg    for (chHigh = 0; chHigh <= (lastCharHigh - firstCharHigh); chHigh++) {
181889a2364Smrg        for (chLow = 0; chLow <= (lastCharLow - firstCharLow); chLow++) {
182889a2364Smrg            if ((charInfo->width != 0) || (charInfo->left != charInfo->right))
183889a2364Smrg                nChars++;
184889a2364Smrg            charInfo++;
185889a2364Smrg        }
18621c2f794Smrg    }
18721c2f794Smrg
18821c2f794Smrg    fprintf(outFile, "CHARS %u\n", nChars);
18921c2f794Smrg
19021c2f794Smrg    /*
19121c2f794Smrg     * actually emit the characters
19221c2f794Smrg     */
19321c2f794Smrg    charInfo = extents;
19421c2f794Smrg    glyph = glyphs;
19521c2f794Smrg    for (chHigh = firstCharHigh; chHigh <= lastCharHigh; chHigh++) {
196889a2364Smrg        for (chLow = firstCharLow; chLow <= lastCharLow; chLow++) {
197889a2364Smrg            int bpr = GLWIDTHBYTESPADDED((charInfo->right - charInfo->left),
198889a2364Smrg                                         SCANLINE_PAD_BYTES);
199889a2364Smrg            unsigned int encoding = (chHigh << 8) + chLow;
200889a2364Smrg
201889a2364Smrg            if ((charInfo->width != 0) || (charInfo->right != charInfo->left))
202889a2364Smrg                EmitBitmap(outFile, fontHeader, charInfo, encoding, bpr, glyph);
203889a2364Smrg            glyph = glyphs +
204889a2364Smrg                offsets[encoding - ((firstCharHigh << 8) + firstCharLow) +
205889a2364Smrg                        1].position;
206889a2364Smrg            charInfo++;
207889a2364Smrg        }
20821c2f794Smrg    }
20921c2f794Smrg    FSFree((char *) extents);
21021c2f794Smrg    FSFree((char *) glyphs);
21121c2f794Smrg    FSFree((char *) offsets);
21221c2f794Smrg    return (True);
21321c2f794Smrg}
214