#include <stdio.h>
#include <X11/Xlib.h>
#include "fstobdf.h"
extern unsigned long yResolution;
extern unsigned long pointSize;
#define BIT_ORDER BitmapFormatBitOrderMSB
#ifdef BYTE_ORDER
#undef BYTE_ORDER
#endif
#define BYTE_ORDER BitmapFormatByteOrderMSB
#define SCANLINE_UNIT BitmapFormatScanlineUnit8
#define SCANLINE_PAD BitmapFormatScanlinePad8
#define EXTENTS BitmapFormatImageRectMin
#define SCANLINE_PAD_BYTES 1
#define GLWIDTHBYTESPADDED(bits, nBytes) \
((nBytes) == 1 ? (((bits) + 7) >> 3) \
:(nBytes) == 2 ? ((((bits) + 15) >> 3) & ~1) \
:(nBytes) == 4 ? ((((bits) + 31) >> 3) & ~3) \
:(nBytes) == 8 ? ((((bits) + 63) >> 3) & ~7) \
: 0)
static void
EmitBitmap(FILE *outFile,
FSXFontInfoHeader *fontHeader,
FSXCharInfo *charInfo,
unsigned int encoding,
int bpr,
unsigned char *data)
{
char *glyphName;
unsigned int row;
fprintf(outFile, "STARTCHAR ");
glyphName = XKeysymToString((KeySym) encoding);
if (glyphName)
fputs(glyphName, outFile);
else
fprintf(outFile, (fontHeader->char_range.min_char.low > 0 ?
"C%06o" : "C%03o"), encoding);
fputc('\n', outFile);
fprintf(outFile, "ENCODING %u\n", encoding);
fprintf(outFile, "SWIDTH %ld 0\n",
(((long) charInfo->width) * 72000L) /
(pointSize * yResolution));
fprintf(outFile, "DWIDTH %d 0\n", charInfo->width);
fprintf(outFile, "BBX %d %d %d %d\n",
charInfo->right - charInfo->left,
charInfo->ascent + charInfo->descent,
charInfo->left,
-charInfo->descent);
if (charInfo->attributes)
fprintf(outFile, "ATTRIBUTES %04x\n", charInfo->attributes);
fprintf(outFile, "BITMAP\n");
for (row = 0; row < (charInfo->ascent + charInfo->descent); row++) {
unsigned byte;
unsigned bit;
static unsigned maskTab[] =
{
(1 << 7), (1 << 6), (1 << 5), (1 << 4),
(1 << 3), (1 << 2), (1 << 1), (1 << 0),
};
byte = 0;
for (bit = 0; bit < (charInfo->right - charInfo->left); bit++) {
byte |= maskTab[bit & 7] & data[bit >> 3];
if ((bit & 7) == 7) {
fprintf(outFile, "%02x", byte);
byte = 0;
}
}
if ((bit & 7) != 0)
fprintf(outFile, "%02x", byte);
fputc('\n', outFile);
data += bpr;
}
fprintf(outFile, "ENDCHAR\n");
}
Bool
EmitCharacters(FILE *outFile,
FSServer *fontServer,
FSXFontInfoHeader *fontHeader,
Font fontID)
{
FSXCharInfo *extents;
FSXCharInfo *charInfo;
int encoding;
FSOffset *offsets;
unsigned char *glyph;
unsigned char *glyphs;
unsigned int nChars;
int firstCharLow;
int firstCharHigh;
int lastCharLow;
int lastCharHigh;
int chLow;
int chHigh;
FSBitmapFormat format;
nChars = 0;
format = BYTE_ORDER | BIT_ORDER | SCANLINE_UNIT |
SCANLINE_PAD | EXTENTS;
firstCharLow = fontHeader->char_range.min_char.low;
firstCharHigh = fontHeader->char_range.min_char.high;
lastCharLow = fontHeader->char_range.max_char.low;
lastCharHigh = fontHeader->char_range.max_char.high;
(void) FSQueryXExtents16(fontServer, fontID, True, (FSChar2b *) 0, 0,
&extents);
(void) FSQueryXBitmaps16(fontServer, fontID, format, True, (FSChar2b *) 0,
0, &offsets, &glyphs);
charInfo = extents;
for (chHigh = 0; chHigh <= (lastCharHigh-firstCharHigh); chHigh++) {
for (chLow = 0; chLow <= (lastCharLow-firstCharLow); chLow++) {
if ((charInfo->width != 0) || (charInfo->left != charInfo->right))
nChars++;
charInfo++;
}
}
fprintf(outFile, "CHARS %u\n", nChars);
charInfo = extents;
glyph = glyphs;
for (chHigh = firstCharHigh; chHigh <= lastCharHigh; chHigh++) {
for (chLow = firstCharLow; chLow <= lastCharLow; chLow++) {
int bpr;
bpr = GLWIDTHBYTESPADDED((charInfo->right - charInfo->left),
SCANLINE_PAD_BYTES);
encoding=(chHigh << 8)+chLow;
if ((charInfo->width != 0) || (charInfo->right != charInfo->left))
EmitBitmap(outFile, fontHeader, charInfo, encoding, bpr, glyph);
glyph = glyphs +
offsets[encoding-((firstCharHigh << 8)+firstCharLow) + 1].position;
charInfo++;
}
}
FSFree((char *) extents);
FSFree((char *) glyphs);
FSFree((char *) offsets);
return (True);
}