1/*
2
3Copyright 1990, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25 * Copyright 1990 Network Computing Devices;
26 * Portions Copyright 1987 by Digital Equipment Corporation
27 *
28 * Permission to use, copy, modify, distribute, and sell this software and
29 * its documentation for any purpose is hereby granted without fee, provided
30 * that the above copyright notice appear in all copies and that both that
31 * copyright notice and this permission notice appear in supporting
32 * documentation, and that the names of Network Computing Devices, or Digital
33 * not be used in advertising or publicity pertaining to distribution
34 * of the software without specific, written prior permission.
35 *
36 * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
37 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
38 * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
39 * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
40 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
41 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
42 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
43 * THIS SOFTWARE.
44 */
45
46/* Morten Storgaard Nielsen: chars.c,v 3.2-1 2000/01/30 14:11:19 kat Exp */
47
48#include	<stdio.h>
49#include	<X11/Xlib.h>
50#include	"fstobdf.h"
51
52#define BIT_ORDER	BitmapFormatBitOrderMSB
53#ifdef BYTE_ORDER
54#undef BYTE_ORDER
55#endif
56#define BYTE_ORDER	BitmapFormatByteOrderMSB
57#define SCANLINE_UNIT	BitmapFormatScanlineUnit8
58#define SCANLINE_PAD	BitmapFormatScanlinePad8
59#define EXTENTS		BitmapFormatImageRectMin
60
61#define SCANLINE_PAD_BYTES	1
62
63#define GLWIDTHBYTESPADDED(bits, nBytes)				    \
64	((nBytes) == 1 ? (((bits)  +  7) >> 3)		/* pad to 1 byte  */\
65	:(nBytes) == 2 ? ((((bits) + 15) >> 3) & ~1)	/* pad to 2 bytes */\
66	:(nBytes) == 4 ? ((((bits) + 31) >> 3) & ~3)	/* pad to 4 bytes */\
67	:(nBytes) == 8 ? ((((bits) + 63) >> 3) & ~7)	/* pad to 8 bytes */\
68	: 0)
69
70static void
71EmitBitmap(FILE *outFile,
72           FSXFontInfoHeader *fontHeader,
73           FSXCharInfo *charInfo,
74           unsigned int encoding,
75           int bpr,
76           unsigned char *data)
77{
78    char *glyphName;
79
80    /*-
81     * format:
82     * STARTCHAR name
83     * ENCODING index
84     * SWIDTH scalablewidth 0
85     * DWIDTH pixels 0
86     * BBX width height xoff yoff
87     * ATTRIBUTES xxxx
88     * BITMAP hhhhhhhh ...
89     * ENDCHAR
90     *
91     * where, SWIDTH * (point / 1000) * (yres / 72) = DWIDTH or,
92     *        SWIDTH = 72000 *
93     * DWIDTH / (point * yres)
94     */
95
96    fprintf(outFile, "STARTCHAR ");
97    glyphName = XKeysymToString((KeySym) encoding);
98    if (glyphName)
99        fputs(glyphName, outFile);
100    else
101        fprintf(outFile, (fontHeader->char_range.min_char.low > 0 ?
102                          "C%06o" : "C%03o"), encoding);
103    fputc('\n', outFile);
104    fprintf(outFile, "ENCODING %u\n", encoding);
105    fprintf(outFile, "SWIDTH %ld 0\n",
106            (((long) charInfo->width) * 72000L) / (pointSize * yResolution));
107    fprintf(outFile, "DWIDTH %d 0\n", charInfo->width);
108    fprintf(outFile, "BBX %d %d %d %d\n",
109            charInfo->right - charInfo->left,
110            charInfo->ascent + charInfo->descent,
111            charInfo->left,
112            -charInfo->descent);
113    if (charInfo->attributes)
114        fprintf(outFile, "ATTRIBUTES %04x\n", charInfo->attributes);
115
116    /*
117     * emit the bitmap
118     */
119    fprintf(outFile, "BITMAP\n");
120    for (unsigned row = 0; row < (charInfo->ascent + charInfo->descent); row++) {
121        unsigned byte;
122        unsigned bit;
123
124        static const unsigned maskTab[] = {
125            (1 << 7), (1 << 6), (1 << 5), (1 << 4),
126            (1 << 3), (1 << 2), (1 << 1), (1 << 0),
127        };
128
129        byte = 0;
130        for (bit = 0; bit < (charInfo->right - charInfo->left); bit++) {
131            byte |= maskTab[bit & 7] & data[bit >> 3];
132            if ((bit & 7) == 7) {
133                fprintf(outFile, "%02x", byte);
134                byte = 0;
135            }
136        }
137        if ((bit & 7) != 0)
138            fprintf(outFile, "%02x", byte);
139        fputc('\n', outFile);
140        data += bpr;
141    }
142    fprintf(outFile, "ENDCHAR\n");
143}
144
145Bool
146EmitCharacters(FILE *outFile,
147               FSServer *fontServer,
148               FSXFontInfoHeader *fontHeader,
149               Font fontID)
150{
151    FSXCharInfo *extents;
152    FSXCharInfo *charInfo;
153    FSOffset *offsets;
154    unsigned char *glyph;
155    unsigned char *glyphs;
156    unsigned int nChars;
157    unsigned int firstCharLow;
158    unsigned int firstCharHigh;
159    unsigned int lastCharLow;
160    unsigned int lastCharHigh;
161    unsigned int chLow;
162    unsigned int chHigh;
163    FSBitmapFormat format;
164
165    nChars = 0;
166
167    format = BYTE_ORDER | BIT_ORDER | SCANLINE_UNIT | SCANLINE_PAD | EXTENTS;
168    firstCharLow = fontHeader->char_range.min_char.low;
169    firstCharHigh = fontHeader->char_range.min_char.high;
170    lastCharLow = fontHeader->char_range.max_char.low;
171    lastCharHigh = fontHeader->char_range.max_char.high;
172
173    (void) FSQueryXExtents16(fontServer, fontID, True, (FSChar2b *) 0, 0,
174                             &extents);
175    (void) FSQueryXBitmaps16(fontServer, fontID, format, True, (FSChar2b *) 0,
176                             0, &offsets, &glyphs);
177
178    charInfo = extents;
179    /* calculate the actual number of chars */
180    for (chHigh = 0; chHigh <= (lastCharHigh - firstCharHigh); chHigh++) {
181        for (chLow = 0; chLow <= (lastCharLow - firstCharLow); chLow++) {
182            if ((charInfo->width != 0) || (charInfo->left != charInfo->right))
183                nChars++;
184            charInfo++;
185        }
186    }
187
188    fprintf(outFile, "CHARS %u\n", nChars);
189
190    /*
191     * actually emit the characters
192     */
193    charInfo = extents;
194    glyph = glyphs;
195    for (chHigh = firstCharHigh; chHigh <= lastCharHigh; chHigh++) {
196        for (chLow = firstCharLow; chLow <= lastCharLow; chLow++) {
197            int bpr = GLWIDTHBYTESPADDED((charInfo->right - charInfo->left),
198                                         SCANLINE_PAD_BYTES);
199            unsigned int encoding = (chHigh << 8) + chLow;
200
201            if ((charInfo->width != 0) || (charInfo->right != charInfo->left))
202                EmitBitmap(outFile, fontHeader, charInfo, encoding, bpr, glyph);
203            glyph = glyphs +
204                offsets[encoding - ((firstCharHigh << 8) + firstCharLow) +
205                        1].position;
206            charInfo++;
207        }
208    }
209    FSFree((char *) extents);
210    FSFree((char *) glyphs);
211    FSFree((char *) offsets);
212    return (True);
213}
214