aboutsummaryrefslogtreecommitdiff
path: root/libXfont/src/bitmap
diff options
context:
space:
mode:
Diffstat (limited to 'libXfont/src/bitmap')
-rw-r--r--libXfont/src/bitmap/bdfread.c1910
-rw-r--r--libXfont/src/bitmap/bdfutils.c672
-rw-r--r--libXfont/src/bitmap/bitmap.c314
-rw-r--r--libXfont/src/bitmap/bitmapfunc.c510
-rw-r--r--libXfont/src/bitmap/bitmaputil.c454
-rw-r--r--libXfont/src/bitmap/bitscale.c3380
-rw-r--r--libXfont/src/bitmap/fontink.c432
-rw-r--r--libXfont/src/bitmap/makefile16
-rw-r--r--libXfont/src/bitmap/pcfread.c1560
-rw-r--r--libXfont/src/bitmap/pcfwrite.c932
-rw-r--r--libXfont/src/bitmap/snfread.c1016
-rw-r--r--libXfont/src/bitmap/snfstr.h364
12 files changed, 5789 insertions, 5771 deletions
diff --git a/libXfont/src/bitmap/bdfread.c b/libXfont/src/bitmap/bdfread.c
index 2464c03cc..1ae3b85cd 100644
--- a/libXfont/src/bitmap/bdfread.c
+++ b/libXfont/src/bitmap/bdfread.c
@@ -1,955 +1,955 @@
-/************************************************************************
-Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-************************************************************************/
-
-/*
-
-Copyright 1994, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <ctype.h>
-#include <X11/fonts/fntfilst.h>
-#include <X11/fonts/fontutil.h>
-/* use bitmap structure */
-#include <X11/fonts/bitmap.h>
-#include <X11/fonts/bdfint.h>
-
-#if HAVE_STDINT_H
-#include <stdint.h>
-#elif !defined(INT32_MAX)
-#define INT32_MAX 0x7fffffff
-#endif
-
-#define INDICES 256
-#define MAXENCODING 0xFFFF
-#define BDFLINELEN 1024
-
-static Bool bdfPadToTerminal(FontPtr pFont);
-extern int bdfFileLineNum;
-
-/***====================================================================***/
-
-static Bool
-bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte,
- int glyph, int scan, CARD32 *sizes)
-{
- int widthBits,
- widthBytes,
- widthHexChars;
- int height,
- row;
- int i,
- inLineLen,
- nextByte;
- unsigned char *pInBits,
- *picture,
- *line = NULL;
- unsigned char lineBuf[BDFLINELEN];
-
- widthBits = GLYPHWIDTHPIXELS(pCI);
- height = GLYPHHEIGHTPIXELS(pCI);
-
- widthBytes = BYTES_PER_ROW(widthBits, glyph);
- if (widthBytes * height > 0) {
- picture = malloc(widthBytes * height);
- if (!picture) {
- bdfError("Couldn't allocate picture (%d*%d)\n", widthBytes, height);
- goto BAILOUT;
- }
- } else
- picture = NULL;
- pCI->bits = (char *) picture;
-
- if (sizes) {
- for (i = 0; i < GLYPHPADOPTIONS; i++)
- sizes[i] += BYTES_PER_ROW(widthBits, (1 << i)) * height;
- }
- nextByte = 0;
- widthHexChars = BYTES_PER_ROW(widthBits, 1);
-
-/* 5/31/89 (ef) -- hack, hack, hack. what *am* I supposed to do with */
-/* 0 width characters? */
-
- for (row = 0; row < height; row++) {
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- if (!line)
- break;
-
- if (widthBits == 0) {
- if ((!line) || (bdfIsPrefix(line, "ENDCHAR")))
- break;
- else
- continue;
- }
- pInBits = line;
- inLineLen = strlen((char *) pInBits);
-
- if (inLineLen & 1) {
- bdfError("odd number of characters in hex encoding\n");
- line[inLineLen++] = '0';
- line[inLineLen] = '\0';
- }
- inLineLen >>= 1;
- i = inLineLen;
- if (i > widthHexChars)
- i = widthHexChars;
- for (; i > 0; i--, pInBits += 2)
- picture[nextByte++] = bdfHexByte(pInBits);
-
- /* pad if line is too short */
- if (inLineLen < widthHexChars) {
- for (i = widthHexChars - inLineLen; i > 0; i--)
- picture[nextByte++] = 0;
- } else {
- unsigned char mask;
-
- mask = 0xff << (8 - (widthBits & 0x7));
- if (mask && picture[nextByte - 1] & ~mask) {
- picture[nextByte - 1] &= mask;
- }
- }
-
- if (widthBytes > widthHexChars) {
- i = widthBytes - widthHexChars;
- while (i-- > 0)
- picture[nextByte++] = 0;
- }
- }
-
- if ((line && (!bdfIsPrefix(line, "ENDCHAR"))) || (height == 0))
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
-
- if ((!line) || (!bdfIsPrefix(line, "ENDCHAR"))) {
- bdfError("missing 'ENDCHAR'\n");
- goto BAILOUT;
- }
- if (nextByte != height * widthBytes) {
- bdfError("bytes != rows * bytes_per_row (%d != %d * %d)\n",
- nextByte, height, widthBytes);
- goto BAILOUT;
- }
- if (picture != NULL) {
- if (bit == LSBFirst)
- BitOrderInvert(picture, nextByte);
- if (bit != byte) {
- if (scan == 2)
- TwoByteSwap(picture, nextByte);
- else if (scan == 4)
- FourByteSwap(picture, nextByte);
- }
- }
- return (TRUE);
-BAILOUT:
- if (picture)
- free(picture);
- pCI->bits = NULL;
- return (FALSE);
-}
-
-/***====================================================================***/
-
-static Bool
-bdfSkipBitmap(FontFilePtr file, int height)
-{
- unsigned char *line;
- int i = 0;
- unsigned char lineBuf[BDFLINELEN];
-
- do {
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- i++;
- } while (line && !bdfIsPrefix(line, "ENDCHAR") && i <= height);
-
- if (i > 1 && line && !bdfIsPrefix(line, "ENDCHAR")) {
- bdfError("Error in bitmap, missing 'ENDCHAR'\n");
- return (FALSE);
- }
- return (TRUE);
-}
-
-/***====================================================================***/
-
-static void
-bdfFreeFontBits(FontPtr pFont)
-{
- BitmapFontPtr bitmapFont;
- BitmapExtraPtr bitmapExtra;
- int i, nencoding;
-
- bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
- bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
- free(bitmapFont->ink_metrics);
- if(bitmapFont->encoding) {
- nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
- (pFont->info.lastRow - pFont->info.firstRow + 1);
- for(i=0; i<NUM_SEGMENTS(nencoding); i++)
- free(bitmapFont->encoding[i]);
- }
- free(bitmapFont->encoding);
- for (i = 0; i < bitmapFont->num_chars; i++)
- free(bitmapFont->metrics[i].bits);
- free(bitmapFont->metrics);
- if (bitmapExtra)
- {
- free (bitmapExtra->glyphNames);
- free (bitmapExtra->sWidths);
- free (bitmapExtra);
- }
- free(pFont->info.props);
- free(bitmapFont);
-}
-
-
-static Bool
-bdfReadCharacters(FontFilePtr file, FontPtr pFont, bdfFileState *pState,
- int bit, int byte, int glyph, int scan)
-{
- unsigned char *line;
- register CharInfoPtr ci;
- int i,
- ndx,
- nchars,
- nignored;
- unsigned int char_row, char_col;
- int numEncodedGlyphs = 0;
- CharInfoPtr *bdfEncoding[256];
- BitmapFontPtr bitmapFont;
- BitmapExtraPtr bitmapExtra;
- CARD32 *bitmapsSizes;
- unsigned char lineBuf[BDFLINELEN];
- int nencoding;
-
- bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
- bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
-
- if (bitmapExtra) {
- bitmapsSizes = bitmapExtra->bitmapsSizes;
- for (i = 0; i < GLYPHPADOPTIONS; i++)
- bitmapsSizes[i] = 0;
- } else
- bitmapsSizes = NULL;
-
- bzero(bdfEncoding, sizeof(bdfEncoding));
- bitmapFont->metrics = NULL;
- ndx = 0;
-
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
-
- if ((!line) || (sscanf((char *) line, "CHARS %d", &nchars) != 1)) {
- bdfError("bad 'CHARS' in bdf file\n");
- return (FALSE);
- }
- if (nchars < 1) {
- bdfError("invalid number of CHARS in BDF file\n");
- return (FALSE);
- }
- if (nchars > INT32_MAX / sizeof(CharInfoRec)) {
- bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
- sizeof(CharInfoRec));
- goto BAILOUT;
- }
- ci = calloc(nchars, sizeof(CharInfoRec));
- if (!ci) {
- bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
- sizeof(CharInfoRec));
- goto BAILOUT;
- }
- bitmapFont->metrics = ci;
-
- if (bitmapExtra) {
- bitmapExtra->glyphNames = malloc(nchars * sizeof(Atom));
- if (!bitmapExtra->glyphNames) {
- bdfError("Couldn't allocate glyphNames (%d*%d)\n",
- nchars, sizeof(Atom));
- goto BAILOUT;
- }
- }
- if (bitmapExtra) {
- bitmapExtra->sWidths = malloc(nchars * sizeof(int));
- if (!bitmapExtra->sWidths) {
- bdfError("Couldn't allocate sWidth (%d *%d)\n",
- nchars, sizeof(int));
- return FALSE;
- }
- }
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- pFont->info.firstRow = 256;
- pFont->info.lastRow = 0;
- pFont->info.firstCol = 256;
- pFont->info.lastCol = 0;
- nignored = 0;
- for (ndx = 0; (ndx < nchars) && (line) && (bdfIsPrefix(line, "STARTCHAR"));) {
- int t;
- int wx; /* x component of width */
- int wy; /* y component of width */
- int bw; /* bounding-box width */
- int bh; /* bounding-box height */
- int bl; /* bounding-box left */
- int bb; /* bounding-box bottom */
- int enc,
- enc2; /* encoding */
- unsigned char *p; /* temp pointer into line */
- char charName[100];
- int ignore;
-
- if (sscanf((char *) line, "STARTCHAR %s", charName) != 1) {
- bdfError("bad character name in BDF file\n");
- goto BAILOUT; /* bottom of function, free and return error */
- }
- if (bitmapExtra)
- bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL);
-
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) {
- bdfError("bad 'ENCODING' in BDF file\n");
- goto BAILOUT;
- }
- if (enc < -1 || (t == 2 && enc2 < -1)) {
- bdfError("bad ENCODING value");
- goto BAILOUT;
- }
- if (t == 2 && enc == -1)
- enc = enc2;
- ignore = 0;
- if (enc == -1) {
- if (!bitmapExtra) {
- nignored++;
- ignore = 1;
- }
- } else if (enc > MAXENCODING) {
- bdfError("char '%s' has encoding too large (%d)\n",
- charName, enc);
- } else {
- char_row = (enc >> 8) & 0xFF;
- char_col = enc & 0xFF;
- if (char_row < pFont->info.firstRow)
- pFont->info.firstRow = char_row;
- if (char_row > pFont->info.lastRow)
- pFont->info.lastRow = char_row;
- if (char_col < pFont->info.firstCol)
- pFont->info.firstCol = char_col;
- if (char_col > pFont->info.lastCol)
- pFont->info.lastCol = char_col;
- if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) {
- bdfEncoding[char_row] = malloc(256 * sizeof(CharInfoPtr));
- if (!bdfEncoding[char_row]) {
- bdfError("Couldn't allocate row %d of encoding (%d*%d)\n",
- char_row, INDICES, sizeof(CharInfoPtr));
- goto BAILOUT;
- }
- for (i = 0; i < 256; i++)
- bdfEncoding[char_row][i] = (CharInfoPtr) NULL;
- }
- if (bdfEncoding[char_row] != NULL) {
- bdfEncoding[char_row][char_col] = ci;
- numEncodedGlyphs++;
- }
- }
-
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) {
- bdfError("bad 'SWIDTH'\n");
- goto BAILOUT;
- }
- if (wy != 0) {
- bdfError("SWIDTH y value must be zero\n");
- goto BAILOUT;
- }
- if (bitmapExtra)
- bitmapExtra->sWidths[ndx] = wx;
-
-/* 5/31/89 (ef) -- we should be able to ditch the character and recover */
-/* from all of these. */
-
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- if ((!line) || (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2)) {
- bdfError("bad 'DWIDTH'\n");
- goto BAILOUT;
- }
- if (wy != 0) {
- bdfError("DWIDTH y value must be zero\n");
- goto BAILOUT;
- }
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- if ((!line) || (sscanf((char *) line, "BBX %d %d %d %d", &bw, &bh, &bl, &bb) != 4)) {
- bdfError("bad 'BBX'\n");
- goto BAILOUT;
- }
- if ((bh < 0) || (bw < 0)) {
- bdfError("character '%s' has a negative sized bitmap, %dx%d\n",
- charName, bw, bh);
- goto BAILOUT;
- }
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- if ((line) && (bdfIsPrefix(line, "ATTRIBUTES"))) {
- for (p = line + strlen("ATTRIBUTES ");
- (*p == ' ') || (*p == '\t');
- p++)
- /* empty for loop */ ;
- ci->metrics.attributes = (bdfHexByte(p) << 8) + bdfHexByte(p + 2);
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- } else
- ci->metrics.attributes = 0;
-
- if (!line || !bdfIsPrefix(line, "BITMAP")) {
- bdfError("missing 'BITMAP'\n");
- goto BAILOUT;
- }
- /* collect data for generated properties */
- if ((strlen(charName) == 1)) {
- if ((charName[0] >= '0') && (charName[0] <= '9')) {
- pState->digitWidths += wx;
- pState->digitCount++;
- } else if (charName[0] == 'x') {
- pState->exHeight = (bh + bb) <= 0 ? bh : bh + bb;
- }
- }
- if (!ignore) {
- ci->metrics.leftSideBearing = bl;
- ci->metrics.rightSideBearing = bl + bw;
- ci->metrics.ascent = bh + bb;
- ci->metrics.descent = -bb;
- ci->metrics.characterWidth = wx;
- ci->bits = NULL;
- bdfReadBitmap(ci, file, bit, byte, glyph, scan, bitmapsSizes);
- ci++;
- ndx++;
- } else
- bdfSkipBitmap(file, bh);
-
- line = bdfGetLine(file, lineBuf, BDFLINELEN); /* get STARTCHAR or
- * ENDFONT */
- }
-
- if (ndx + nignored != nchars) {
- bdfError("%d too few characters\n", nchars - (ndx + nignored));
- goto BAILOUT;
- }
- nchars = ndx;
- bitmapFont->num_chars = nchars;
- if ((line) && (bdfIsPrefix(line, "STARTCHAR"))) {
- bdfError("more characters than specified\n");
- goto BAILOUT;
- }
- if ((!line) || (!bdfIsPrefix(line, "ENDFONT"))) {
- bdfError("missing 'ENDFONT'\n");
- goto BAILOUT;
- }
- if (numEncodedGlyphs == 0)
- bdfWarning("No characters with valid encodings\n");
-
- nencoding = (pFont->info.lastRow - pFont->info.firstRow + 1) *
- (pFont->info.lastCol - pFont->info.firstCol + 1);
- bitmapFont->encoding = calloc(NUM_SEGMENTS(nencoding),sizeof(CharInfoPtr*));
- if (!bitmapFont->encoding) {
- bdfError("Couldn't allocate ppCI (%d,%d)\n",
- NUM_SEGMENTS(nencoding),
- sizeof(CharInfoPtr*));
- goto BAILOUT;
- }
- pFont->info.allExist = TRUE;
- i = 0;
- for (char_row = pFont->info.firstRow;
- char_row <= pFont->info.lastRow;
- char_row++) {
- if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) {
- pFont->info.allExist = FALSE;
- i += pFont->info.lastCol - pFont->info.firstCol + 1;
- } else {
- for (char_col = pFont->info.firstCol;
- char_col <= pFont->info.lastCol;
- char_col++) {
- if (!bdfEncoding[char_row][char_col])
- pFont->info.allExist = FALSE;
- else {
- if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
- bitmapFont->encoding[SEGMENT_MAJOR(i)]=
- calloc(BITMAP_FONT_SEGMENT_SIZE,
- sizeof(CharInfoPtr));
- if (!bitmapFont->encoding[SEGMENT_MAJOR(i)])
- goto BAILOUT;
- }
- ACCESSENCODINGL(bitmapFont->encoding,i) =
- bdfEncoding[char_row][char_col];
- }
- i++;
- }
- }
- }
- for (i = 0; i < 256; i++)
- if (bdfEncoding[i])
- free(bdfEncoding[i]);
- return (TRUE);
-BAILOUT:
- for (i = 0; i < 256; i++)
- if (bdfEncoding[i])
- free(bdfEncoding[i]);
- /* bdfFreeFontBits will clean up the rest */
- return (FALSE);
-}
-
-/***====================================================================***/
-
-static Bool
-bdfReadHeader(FontFilePtr file, bdfFileState *pState)
-{
- unsigned char *line;
- char namebuf[BDFLINELEN];
- unsigned char lineBuf[BDFLINELEN];
-
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- if (!line || sscanf((char *) line, "STARTFONT %s", namebuf) != 1 ||
- !bdfStrEqual(namebuf, "2.1")) {
- bdfError("bad 'STARTFONT'\n");
- return (FALSE);
- }
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- if (!line || sscanf((char *) line, "FONT %[^\n]", pState->fontName) != 1) {
- bdfError("bad 'FONT'\n");
- return (FALSE);
- }
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- if (!line || !bdfIsPrefix(line, "SIZE")) {
- bdfError("missing 'SIZE'\n");
- return (FALSE);
- }
- if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize,
- &pState->resolution_x, &pState->resolution_y) != 3) {
- bdfError("bad 'SIZE'\n");
- return (FALSE);
- }
- if (pState->pointSize < 1 ||
- pState->resolution_x < 1 || pState->resolution_y < 1) {
- bdfError("SIZE values must be > 0\n");
- return (FALSE);
- }
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- if (!line || !bdfIsPrefix(line, "FONTBOUNDINGBOX")) {
- bdfError("missing 'FONTBOUNDINGBOX'\n");
- return (FALSE);
- }
- return (TRUE);
-}
-
-/***====================================================================***/
-
-static Bool
-bdfReadProperties(FontFilePtr file, FontPtr pFont, bdfFileState *pState)
-{
- int nProps, props_left,
- nextProp;
- char *stringProps;
- FontPropPtr props;
- char namebuf[BDFLINELEN],
- secondbuf[BDFLINELEN],
- thirdbuf[BDFLINELEN];
- unsigned char *line;
- unsigned char lineBuf[BDFLINELEN];
- BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
-
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- if (!line || !bdfIsPrefix(line, "STARTPROPERTIES")) {
- bdfError("missing 'STARTPROPERTIES'\n");
- return (FALSE);
- }
- if (sscanf((char *) line, "STARTPROPERTIES %d", &nProps) != 1) {
- bdfError("bad 'STARTPROPERTIES'\n");
- return (FALSE);
- }
- pFont->info.isStringProp = NULL;
- pFont->info.props = NULL;
- pFont->info.nprops = 0;
-
- stringProps = malloc((nProps + BDF_GENPROPS) * sizeof(char));
- pFont->info.isStringProp = stringProps;
- if (stringProps == NULL) {
- bdfError("Couldn't allocate stringProps (%d*%d)\n",
- (nProps + BDF_GENPROPS), sizeof(Bool));
- goto BAILOUT;
- }
- pFont->info.props = props = calloc(nProps + BDF_GENPROPS,
- sizeof(FontPropRec));
- if (props == NULL) {
- bdfError("Couldn't allocate props (%d*%d)\n", nProps + BDF_GENPROPS,
- sizeof(FontPropRec));
- goto BAILOUT;
- }
-
- nextProp = 0;
- props_left = nProps;
- while (props_left-- > 0) {
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- if (line == NULL || bdfIsPrefix(line, "ENDPROPERTIES")) {
- bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n",
- nProps, nProps - props_left - 1);
- goto BAILOUT;
- }
- while (*line && isspace(*line))
- line++;
-
- switch (sscanf((char *) line, "%s%s%s", namebuf, secondbuf, thirdbuf)) {
- default:
- bdfError("missing '%s' parameter value\n", namebuf);
- goto BAILOUT;
-
- case 2:
- /*
- * Possibilites include: valid quoted string with no white space
- * valid integer value invalid value
- */
- if (secondbuf[0] == '"') {
- stringProps[nextProp] = TRUE;
- props[nextProp].value =
- bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
- if (!props[nextProp].value)
- goto BAILOUT;
- break;
- } else if (bdfIsInteger(secondbuf)) {
- stringProps[nextProp] = FALSE;
- props[nextProp].value = atoi(secondbuf);
- break;
- } else {
- bdfError("invalid '%s' parameter value\n", namebuf);
- goto BAILOUT;
- }
-
- case 3:
- /*
- * Possibilites include: valid quoted string with some white space
- * invalid value (reject even if second string is integer)
- */
- if (secondbuf[0] == '"') {
- stringProps[nextProp] = TRUE;
- props[nextProp].value =
- bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
- if (!props[nextProp].value)
- goto BAILOUT;
- break;
- } else {
- bdfError("invalid '%s' parameter value\n", namebuf);
- goto BAILOUT;
- }
- }
- props[nextProp].name = bdfForceMakeAtom(namebuf, NULL);
- if (props[nextProp].name == None) {
- bdfError("Empty property name.\n");
- goto BAILOUT;
- }
- if (!bdfSpecialProperty(pFont, &props[nextProp],
- stringProps[nextProp], pState))
- nextProp++;
- }
-
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- if (!line || !bdfIsPrefix(line, "ENDPROPERTIES")) {
- bdfError("missing 'ENDPROPERTIES'\n");
- goto BAILOUT;
- }
- if (!pState->haveFontAscent || !pState->haveFontDescent) {
- bdfError("missing 'FONT_ASCENT' or 'FONT_DESCENT' properties\n");
- goto BAILOUT;
- }
- if (bitmapFont->bitmapExtra) {
- bitmapFont->bitmapExtra->info.fontAscent = pFont->info.fontAscent;
- bitmapFont->bitmapExtra->info.fontDescent = pFont->info.fontDescent;
- }
- if (!pState->pointSizeProp) {
- props[nextProp].name = bdfForceMakeAtom("POINT_SIZE", NULL);
- props[nextProp].value = (INT32) (pState->pointSize * 10.0);
- stringProps[nextProp] = FALSE;
- pState->pointSizeProp = &props[nextProp];
- nextProp++;
- }
- if (!pState->fontProp) {
- props[nextProp].name = bdfForceMakeAtom("FONT", NULL);
- props[nextProp].value = (INT32) bdfForceMakeAtom(pState->fontName, NULL);
- stringProps[nextProp] = TRUE;
- pState->fontProp = &props[nextProp];
- nextProp++;
- }
- if (!pState->weightProp) {
- props[nextProp].name = bdfForceMakeAtom("WEIGHT", NULL);
- props[nextProp].value = -1; /* computed later */
- stringProps[nextProp] = FALSE;
- pState->weightProp = &props[nextProp];
- nextProp++;
- }
- if (!pState->resolutionProp &&
- pState->resolution_x == pState->resolution_y) {
- props[nextProp].name = bdfForceMakeAtom("RESOLUTION", NULL);
- props[nextProp].value = (INT32) ((pState->resolution_x * 100.0) / 72.27);
- stringProps[nextProp] = FALSE;
- pState->resolutionProp = &props[nextProp];
- nextProp++;
- }
- if (!pState->resolutionXProp) {
- props[nextProp].name = bdfForceMakeAtom("RESOLUTION_X", NULL);
- props[nextProp].value = (INT32) pState->resolution_x;
- stringProps[nextProp] = FALSE;
- pState->resolutionProp = &props[nextProp];
- nextProp++;
- }
- if (!pState->resolutionYProp) {
- props[nextProp].name = bdfForceMakeAtom("RESOLUTION_Y", NULL);
- props[nextProp].value = (INT32) pState->resolution_y;
- stringProps[nextProp] = FALSE;
- pState->resolutionProp = &props[nextProp];
- nextProp++;
- }
- if (!pState->xHeightProp) {
- props[nextProp].name = bdfForceMakeAtom("X_HEIGHT", NULL);
- props[nextProp].value = -1; /* computed later */
- stringProps[nextProp] = FALSE;
- pState->xHeightProp = &props[nextProp];
- nextProp++;
- }
- if (!pState->quadWidthProp) {
- props[nextProp].name = bdfForceMakeAtom("QUAD_WIDTH", NULL);
- props[nextProp].value = -1; /* computed later */
- stringProps[nextProp] = FALSE;
- pState->quadWidthProp = &props[nextProp];
- nextProp++;
- }
- pFont->info.nprops = nextProp;
- return (TRUE);
-BAILOUT:
- if (pFont->info.isStringProp) {
- free(pFont->info.isStringProp);
- pFont->info.isStringProp = NULL;
- }
- if (pFont->info.props) {
- free(pFont->info.props);
- pFont->info.props = NULL;
- }
- while (line && bdfIsPrefix(line, "ENDPROPERTIES"))
- line = bdfGetLine(file, lineBuf, BDFLINELEN);
- return (FALSE);
-}
-
-/***====================================================================***/
-
-static void
-bdfUnloadFont(FontPtr pFont)
-{
- bdfFreeFontBits (pFont);
- DestroyFontRec(pFont);
-}
-
-int
-bdfReadFont(FontPtr pFont, FontFilePtr file,
- int bit, int byte, int glyph, int scan)
-{
- bdfFileState state;
- xCharInfo *min,
- *max;
- BitmapFontPtr bitmapFont;
-
- pFont->fontPrivate = 0;
-
- bzero(&state, sizeof(bdfFileState));
- bdfFileLineNum = 0;
-
- if (!bdfReadHeader(file, &state))
- goto BAILOUT;
-
- bitmapFont = calloc(1, sizeof(BitmapFontRec));
- if (!bitmapFont) {
- bdfError("Couldn't allocate bitmapFontRec (%d)\n", sizeof(BitmapFontRec));
- goto BAILOUT;
- }
-
- pFont->fontPrivate = (pointer) bitmapFont;
- bitmapFont->metrics = 0;
- bitmapFont->ink_metrics = 0;
- bitmapFont->bitmaps = 0;
- bitmapFont->encoding = 0;
- bitmapFont->pDefault = NULL;
-
- bitmapFont->bitmapExtra = calloc(1, sizeof(BitmapExtraRec));
- if (!bitmapFont->bitmapExtra) {
- bdfError("Couldn't allocate bitmapExtra (%d)\n", sizeof(BitmapExtraRec));
- goto BAILOUT;
- }
-
- bitmapFont->bitmapExtra->glyphNames = 0;
- bitmapFont->bitmapExtra->sWidths = 0;
-
- if (!bdfReadProperties(file, pFont, &state))
- goto BAILOUT;
-
- if (!bdfReadCharacters(file, pFont, &state, bit, byte, glyph, scan))
- goto BAILOUT;
-
- if (state.haveDefaultCh) {
- unsigned int r, c, cols;
-
- r = pFont->info.defaultCh >> 8;
- c = pFont->info.defaultCh & 0xFF;
- if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
- pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
- cols = pFont->info.lastCol - pFont->info.firstCol + 1;
- r = r - pFont->info.firstRow;
- c = c - pFont->info.firstCol;
- bitmapFont->pDefault = ACCESSENCODING(bitmapFont->encoding,
- r * cols + c);
- }
- }
- pFont->bit = bit;
- pFont->byte = byte;
- pFont->glyph = glyph;
- pFont->scan = scan;
- pFont->info.anamorphic = FALSE;
- pFont->info.cachable = TRUE;
- bitmapComputeFontBounds(pFont);
- if (FontCouldBeTerminal(&pFont->info)) {
- bdfPadToTerminal(pFont);
- bitmapComputeFontBounds(pFont);
- }
- FontComputeInfoAccelerators(&pFont->info);
- if (bitmapFont->bitmapExtra)
- FontComputeInfoAccelerators(&bitmapFont->bitmapExtra->info);
- if (pFont->info.constantMetrics) {
- if (!bitmapAddInkMetrics(pFont)) {
- bdfError("Failed to add bitmap ink metrics\n");
- goto BAILOUT;
- }
- }
- if (bitmapFont->bitmapExtra)
- bitmapFont->bitmapExtra->info.inkMetrics = pFont->info.inkMetrics;
-
- bitmapComputeFontInkBounds(pFont);
-/* ComputeFontAccelerators (pFont); */
-
- /* generate properties */
- min = &pFont->info.ink_minbounds;
- max = &pFont->info.ink_maxbounds;
- if (state.xHeightProp && (state.xHeightProp->value == -1))
- state.xHeightProp->value = state.exHeight ?
- state.exHeight : min->ascent;
-
- if (state.quadWidthProp && (state.quadWidthProp->value == -1))
- state.quadWidthProp->value = state.digitCount ?
- (INT32) (state.digitWidths / state.digitCount) :
- (min->characterWidth + max->characterWidth) / 2;
-
- if (state.weightProp && (state.weightProp->value == -1))
- state.weightProp->value = bitmapComputeWeight(pFont);
-
- pFont->get_glyphs = bitmapGetGlyphs;
- pFont->get_metrics = bitmapGetMetrics;
- pFont->unload_font = bdfUnloadFont;
- pFont->unload_glyphs = NULL;
- return Successful;
-BAILOUT:
- if (pFont->fontPrivate)
- bdfFreeFontBits (pFont);
- return AllocError;
-}
-
-int
-bdfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
-{
- FontRec font;
- int ret;
-
- bzero(&font, sizeof (FontRec));
-
- ret = bdfReadFont(&font, file, MSBFirst, LSBFirst, 1, 1);
- if (ret == Successful) {
- *pFontInfo = font.info;
- font.info.props = 0;
- font.info.isStringProp = 0;
- font.info.nprops = 0;
- bdfFreeFontBits (&font);
- }
- return ret;
-}
-
-static Bool
-bdfPadToTerminal(FontPtr pFont)
-{
- BitmapFontPtr bitmapFont;
- BitmapExtraPtr bitmapExtra;
- int i;
- int new_size;
- CharInfoRec new;
- int w,
- h;
-
- bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
-
- bzero(&new, sizeof(CharInfoRec));
- new.metrics.ascent = pFont->info.fontAscent;
- new.metrics.descent = pFont->info.fontDescent;
- new.metrics.leftSideBearing = 0;
- new.metrics.rightSideBearing = pFont->info.minbounds.characterWidth;
- new.metrics.characterWidth = new.metrics.rightSideBearing;
- new_size = BYTES_FOR_GLYPH(&new, pFont->glyph);
-
- for (i = 0; i < bitmapFont->num_chars; i++) {
- new.bits = malloc(new_size);
- if (!new.bits) {
- bdfError("Couldn't allocate bits (%d)\n", new_size);
- return FALSE;
- }
- FontCharReshape(pFont, &bitmapFont->metrics[i], &new);
- new.metrics.attributes = bitmapFont->metrics[i].metrics.attributes;
- free(bitmapFont->metrics[i].bits);
- bitmapFont->metrics[i] = new;
- }
- bitmapExtra = bitmapFont->bitmapExtra;
- if (bitmapExtra) {
- w = GLYPHWIDTHPIXELS(&new);
- h = GLYPHHEIGHTPIXELS(&new);
- for (i = 0; i < GLYPHPADOPTIONS; i++)
- bitmapExtra->bitmapsSizes[i] = bitmapFont->num_chars *
- (BYTES_PER_ROW(w, 1 << i) * h);
- }
- return TRUE;
-}
+/************************************************************************
+Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+************************************************************************/
+
+/*
+
+Copyright 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+/* use bitmap structure */
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/bdfint.h>
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif !defined(INT32_MAX)
+#define INT32_MAX 0x7fffffff
+#endif
+
+#define INDICES 256
+#define MAXENCODING 0xFFFF
+#define BDFLINELEN 1024
+
+static Bool bdfPadToTerminal(FontPtr pFont);
+extern int bdfFileLineNum;
+
+/***====================================================================***/
+
+static Bool
+bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte,
+ int glyph, int scan, CARD32 *sizes)
+{
+ int widthBits,
+ widthBytes,
+ widthHexChars;
+ int height,
+ row;
+ int i,
+ inLineLen,
+ nextByte;
+ unsigned char *pInBits,
+ *picture,
+ *line = NULL;
+ unsigned char lineBuf[BDFLINELEN];
+
+ widthBits = GLYPHWIDTHPIXELS(pCI);
+ height = GLYPHHEIGHTPIXELS(pCI);
+
+ widthBytes = BYTES_PER_ROW(widthBits, glyph);
+ if (widthBytes * height > 0) {
+ picture = malloc(widthBytes * height);
+ if (!picture) {
+ bdfError("Couldn't allocate picture (%d*%d)\n", widthBytes, height);
+ goto BAILOUT;
+ }
+ } else
+ picture = NULL;
+ pCI->bits = (char *) picture;
+
+ if (sizes) {
+ for (i = 0; i < GLYPHPADOPTIONS; i++)
+ sizes[i] += BYTES_PER_ROW(widthBits, (1 << i)) * height;
+ }
+ nextByte = 0;
+ widthHexChars = BYTES_PER_ROW(widthBits, 1);
+
+/* 5/31/89 (ef) -- hack, hack, hack. what *am* I supposed to do with */
+/* 0 width characters? */
+
+ for (row = 0; row < height; row++) {
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line)
+ break;
+
+ if (widthBits == 0) {
+ if ((!line) || (bdfIsPrefix(line, "ENDCHAR")))
+ break;
+ else
+ continue;
+ }
+ pInBits = line;
+ inLineLen = strlen((char *) pInBits);
+
+ if (inLineLen & 1) {
+ bdfError("odd number of characters in hex encoding\n");
+ line[inLineLen++] = '0';
+ line[inLineLen] = '\0';
+ }
+ inLineLen >>= 1;
+ i = inLineLen;
+ if (i > widthHexChars)
+ i = widthHexChars;
+ for (; i > 0; i--, pInBits += 2)
+ picture[nextByte++] = bdfHexByte(pInBits);
+
+ /* pad if line is too short */
+ if (inLineLen < widthHexChars) {
+ for (i = widthHexChars - inLineLen; i > 0; i--)
+ picture[nextByte++] = 0;
+ } else {
+ unsigned char mask;
+
+ mask = 0xff << (8 - (widthBits & 0x7));
+ if (mask && picture[nextByte - 1] & ~mask) {
+ picture[nextByte - 1] &= mask;
+ }
+ }
+
+ if (widthBytes > widthHexChars) {
+ i = widthBytes - widthHexChars;
+ while (i-- > 0)
+ picture[nextByte++] = 0;
+ }
+ }
+
+ if ((line && (!bdfIsPrefix(line, "ENDCHAR"))) || (height == 0))
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+
+ if ((!line) || (!bdfIsPrefix(line, "ENDCHAR"))) {
+ bdfError("missing 'ENDCHAR'\n");
+ goto BAILOUT;
+ }
+ if (nextByte != height * widthBytes) {
+ bdfError("bytes != rows * bytes_per_row (%d != %d * %d)\n",
+ nextByte, height, widthBytes);
+ goto BAILOUT;
+ }
+ if (picture != NULL) {
+ if (bit == LSBFirst)
+ BitOrderInvert(picture, nextByte);
+ if (bit != byte) {
+ if (scan == 2)
+ TwoByteSwap(picture, nextByte);
+ else if (scan == 4)
+ FourByteSwap(picture, nextByte);
+ }
+ }
+ return (TRUE);
+BAILOUT:
+ if (picture)
+ free(picture);
+ pCI->bits = NULL;
+ return (FALSE);
+}
+
+/***====================================================================***/
+
+static Bool
+bdfSkipBitmap(FontFilePtr file, int height)
+{
+ unsigned char *line;
+ int i = 0;
+ unsigned char lineBuf[BDFLINELEN];
+
+ do {
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ i++;
+ } while (line && !bdfIsPrefix(line, "ENDCHAR") && i <= height);
+
+ if (i > 1 && line && !bdfIsPrefix(line, "ENDCHAR")) {
+ bdfError("Error in bitmap, missing 'ENDCHAR'\n");
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+/***====================================================================***/
+
+static void
+bdfFreeFontBits(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont;
+ BitmapExtraPtr bitmapExtra;
+ int i, nencoding;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
+ free(bitmapFont->ink_metrics);
+ if(bitmapFont->encoding) {
+ nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
+ (pFont->info.lastRow - pFont->info.firstRow + 1);
+ for(i=0; i<NUM_SEGMENTS(nencoding); i++)
+ free(bitmapFont->encoding[i]);
+ }
+ free(bitmapFont->encoding);
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ free(bitmapFont->metrics[i].bits);
+ free(bitmapFont->metrics);
+ if (bitmapExtra)
+ {
+ free (bitmapExtra->glyphNames);
+ free (bitmapExtra->sWidths);
+ free (bitmapExtra);
+ }
+ free(pFont->info.props);
+ free(bitmapFont);
+}
+
+
+static Bool
+bdfReadCharacters(FontFilePtr file, FontPtr pFont, bdfFileState *pState,
+ int bit, int byte, int glyph, int scan)
+{
+ unsigned char *line;
+ register CharInfoPtr ci;
+ int i,
+ ndx,
+ nchars,
+ nignored;
+ unsigned int char_row, char_col;
+ int numEncodedGlyphs = 0;
+ CharInfoPtr *bdfEncoding[256];
+ BitmapFontPtr bitmapFont;
+ BitmapExtraPtr bitmapExtra;
+ CARD32 *bitmapsSizes;
+ unsigned char lineBuf[BDFLINELEN];
+ int nencoding;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra;
+
+ if (bitmapExtra) {
+ bitmapsSizes = bitmapExtra->bitmapsSizes;
+ for (i = 0; i < GLYPHPADOPTIONS; i++)
+ bitmapsSizes[i] = 0;
+ } else
+ bitmapsSizes = NULL;
+
+ bzero(bdfEncoding, sizeof(bdfEncoding));
+ bitmapFont->metrics = NULL;
+ ndx = 0;
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+
+ if ((!line) || (sscanf((char *) line, "CHARS %d", &nchars) != 1)) {
+ bdfError("bad 'CHARS' in bdf file\n");
+ return (FALSE);
+ }
+ if (nchars < 1) {
+ bdfError("invalid number of CHARS in BDF file\n");
+ return (FALSE);
+ }
+ if (nchars > INT32_MAX / sizeof(CharInfoRec)) {
+ bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
+ sizeof(CharInfoRec));
+ goto BAILOUT;
+ }
+ ci = calloc(nchars, sizeof(CharInfoRec));
+ if (!ci) {
+ bdfError("Couldn't allocate pCI (%d*%d)\n", nchars,
+ sizeof(CharInfoRec));
+ goto BAILOUT;
+ }
+ bitmapFont->metrics = ci;
+
+ if (bitmapExtra) {
+ bitmapExtra->glyphNames = malloc(nchars * sizeof(Atom));
+ if (!bitmapExtra->glyphNames) {
+ bdfError("Couldn't allocate glyphNames (%d*%d)\n",
+ nchars, sizeof(Atom));
+ goto BAILOUT;
+ }
+ }
+ if (bitmapExtra) {
+ bitmapExtra->sWidths = malloc(nchars * sizeof(int));
+ if (!bitmapExtra->sWidths) {
+ bdfError("Couldn't allocate sWidth (%d *%d)\n",
+ nchars, sizeof(int));
+ return FALSE;
+ }
+ }
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ pFont->info.firstRow = 256;
+ pFont->info.lastRow = 0;
+ pFont->info.firstCol = 256;
+ pFont->info.lastCol = 0;
+ nignored = 0;
+ for (ndx = 0; (ndx < nchars) && (line) && (bdfIsPrefix(line, "STARTCHAR"));) {
+ int t;
+ int wx; /* x component of width */
+ int wy; /* y component of width */
+ int bw; /* bounding-box width */
+ int bh; /* bounding-box height */
+ int bl; /* bounding-box left */
+ int bb; /* bounding-box bottom */
+ int enc,
+ enc2; /* encoding */
+ unsigned char *p; /* temp pointer into line */
+ char charName[100];
+ int ignore;
+
+ if (sscanf((char *) line, "STARTCHAR %s", charName) != 1) {
+ bdfError("bad character name in BDF file\n");
+ goto BAILOUT; /* bottom of function, free and return error */
+ }
+ if (bitmapExtra)
+ bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL);
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) {
+ bdfError("bad 'ENCODING' in BDF file\n");
+ goto BAILOUT;
+ }
+ if (enc < -1 || (t == 2 && enc2 < -1)) {
+ bdfError("bad ENCODING value");
+ goto BAILOUT;
+ }
+ if (t == 2 && enc == -1)
+ enc = enc2;
+ ignore = 0;
+ if (enc == -1) {
+ if (!bitmapExtra) {
+ nignored++;
+ ignore = 1;
+ }
+ } else if (enc > MAXENCODING) {
+ bdfError("char '%s' has encoding too large (%d)\n",
+ charName, enc);
+ } else {
+ char_row = (enc >> 8) & 0xFF;
+ char_col = enc & 0xFF;
+ if (char_row < pFont->info.firstRow)
+ pFont->info.firstRow = char_row;
+ if (char_row > pFont->info.lastRow)
+ pFont->info.lastRow = char_row;
+ if (char_col < pFont->info.firstCol)
+ pFont->info.firstCol = char_col;
+ if (char_col > pFont->info.lastCol)
+ pFont->info.lastCol = char_col;
+ if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) {
+ bdfEncoding[char_row] = malloc(256 * sizeof(CharInfoPtr));
+ if (!bdfEncoding[char_row]) {
+ bdfError("Couldn't allocate row %d of encoding (%d*%d)\n",
+ char_row, INDICES, sizeof(CharInfoPtr));
+ goto BAILOUT;
+ }
+ for (i = 0; i < 256; i++)
+ bdfEncoding[char_row][i] = (CharInfoPtr) NULL;
+ }
+ if (bdfEncoding[char_row] != NULL) {
+ bdfEncoding[char_row][char_col] = ci;
+ numEncodedGlyphs++;
+ }
+ }
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) {
+ bdfError("bad 'SWIDTH'\n");
+ goto BAILOUT;
+ }
+ if (wy != 0) {
+ bdfError("SWIDTH y value must be zero\n");
+ goto BAILOUT;
+ }
+ if (bitmapExtra)
+ bitmapExtra->sWidths[ndx] = wx;
+
+/* 5/31/89 (ef) -- we should be able to ditch the character and recover */
+/* from all of these. */
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if ((!line) || (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2)) {
+ bdfError("bad 'DWIDTH'\n");
+ goto BAILOUT;
+ }
+ if (wy != 0) {
+ bdfError("DWIDTH y value must be zero\n");
+ goto BAILOUT;
+ }
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if ((!line) || (sscanf((char *) line, "BBX %d %d %d %d", &bw, &bh, &bl, &bb) != 4)) {
+ bdfError("bad 'BBX'\n");
+ goto BAILOUT;
+ }
+ if ((bh < 0) || (bw < 0)) {
+ bdfError("character '%s' has a negative sized bitmap, %dx%d\n",
+ charName, bw, bh);
+ goto BAILOUT;
+ }
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if ((line) && (bdfIsPrefix(line, "ATTRIBUTES"))) {
+ for (p = line + strlen("ATTRIBUTES ");
+ (*p == ' ') || (*p == '\t');
+ p++)
+ /* empty for loop */ ;
+ ci->metrics.attributes = (bdfHexByte(p) << 8) + bdfHexByte(p + 2);
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ } else
+ ci->metrics.attributes = 0;
+
+ if (!line || !bdfIsPrefix(line, "BITMAP")) {
+ bdfError("missing 'BITMAP'\n");
+ goto BAILOUT;
+ }
+ /* collect data for generated properties */
+ if ((strlen(charName) == 1)) {
+ if ((charName[0] >= '0') && (charName[0] <= '9')) {
+ pState->digitWidths += wx;
+ pState->digitCount++;
+ } else if (charName[0] == 'x') {
+ pState->exHeight = (bh + bb) <= 0 ? bh : bh + bb;
+ }
+ }
+ if (!ignore) {
+ ci->metrics.leftSideBearing = bl;
+ ci->metrics.rightSideBearing = bl + bw;
+ ci->metrics.ascent = bh + bb;
+ ci->metrics.descent = -bb;
+ ci->metrics.characterWidth = wx;
+ ci->bits = NULL;
+ bdfReadBitmap(ci, file, bit, byte, glyph, scan, bitmapsSizes);
+ ci++;
+ ndx++;
+ } else
+ bdfSkipBitmap(file, bh);
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN); /* get STARTCHAR or
+ * ENDFONT */
+ }
+
+ if (ndx + nignored != nchars) {
+ bdfError("%d too few characters\n", nchars - (ndx + nignored));
+ goto BAILOUT;
+ }
+ nchars = ndx;
+ bitmapFont->num_chars = nchars;
+ if ((line) && (bdfIsPrefix(line, "STARTCHAR"))) {
+ bdfError("more characters than specified\n");
+ goto BAILOUT;
+ }
+ if ((!line) || (!bdfIsPrefix(line, "ENDFONT"))) {
+ bdfError("missing 'ENDFONT'\n");
+ goto BAILOUT;
+ }
+ if (numEncodedGlyphs == 0)
+ bdfWarning("No characters with valid encodings\n");
+
+ nencoding = (pFont->info.lastRow - pFont->info.firstRow + 1) *
+ (pFont->info.lastCol - pFont->info.firstCol + 1);
+ bitmapFont->encoding = calloc(NUM_SEGMENTS(nencoding),sizeof(CharInfoPtr*));
+ if (!bitmapFont->encoding) {
+ bdfError("Couldn't allocate ppCI (%d,%d)\n",
+ NUM_SEGMENTS(nencoding),
+ sizeof(CharInfoPtr*));
+ goto BAILOUT;
+ }
+ pFont->info.allExist = TRUE;
+ i = 0;
+ for (char_row = pFont->info.firstRow;
+ char_row <= pFont->info.lastRow;
+ char_row++) {
+ if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) {
+ pFont->info.allExist = FALSE;
+ i += pFont->info.lastCol - pFont->info.firstCol + 1;
+ } else {
+ for (char_col = pFont->info.firstCol;
+ char_col <= pFont->info.lastCol;
+ char_col++) {
+ if (!bdfEncoding[char_row][char_col])
+ pFont->info.allExist = FALSE;
+ else {
+ if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
+ bitmapFont->encoding[SEGMENT_MAJOR(i)]=
+ calloc(BITMAP_FONT_SEGMENT_SIZE,
+ sizeof(CharInfoPtr));
+ if (!bitmapFont->encoding[SEGMENT_MAJOR(i)])
+ goto BAILOUT;
+ }
+ ACCESSENCODINGL(bitmapFont->encoding,i) =
+ bdfEncoding[char_row][char_col];
+ }
+ i++;
+ }
+ }
+ }
+ for (i = 0; i < 256; i++)
+ if (bdfEncoding[i])
+ free(bdfEncoding[i]);
+ return (TRUE);
+BAILOUT:
+ for (i = 0; i < 256; i++)
+ if (bdfEncoding[i])
+ free(bdfEncoding[i]);
+ /* bdfFreeFontBits will clean up the rest */
+ return (FALSE);
+}
+
+/***====================================================================***/
+
+static Bool
+bdfReadHeader(FontFilePtr file, bdfFileState *pState)
+{
+ unsigned char *line;
+ char namebuf[BDFLINELEN];
+ unsigned char lineBuf[BDFLINELEN];
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || sscanf((char *) line, "STARTFONT %s", namebuf) != 1 ||
+ !bdfStrEqual(namebuf, "2.1")) {
+ bdfError("bad 'STARTFONT'\n");
+ return (FALSE);
+ }
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || sscanf((char *) line, "FONT %[^\n]", pState->fontName) != 1) {
+ bdfError("bad 'FONT'\n");
+ return (FALSE);
+ }
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || !bdfIsPrefix(line, "SIZE")) {
+ bdfError("missing 'SIZE'\n");
+ return (FALSE);
+ }
+ if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize,
+ &pState->resolution_x, &pState->resolution_y) != 3) {
+ bdfError("bad 'SIZE'\n");
+ return (FALSE);
+ }
+ if (pState->pointSize < 1 ||
+ pState->resolution_x < 1 || pState->resolution_y < 1) {
+ bdfError("SIZE values must be > 0\n");
+ return (FALSE);
+ }
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || !bdfIsPrefix(line, "FONTBOUNDINGBOX")) {
+ bdfError("missing 'FONTBOUNDINGBOX'\n");
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+/***====================================================================***/
+
+static Bool
+bdfReadProperties(FontFilePtr file, FontPtr pFont, bdfFileState *pState)
+{
+ int nProps, props_left,
+ nextProp;
+ char *stringProps;
+ FontPropPtr props;
+ char namebuf[BDFLINELEN],
+ secondbuf[BDFLINELEN],
+ thirdbuf[BDFLINELEN];
+ unsigned char *line;
+ unsigned char lineBuf[BDFLINELEN];
+ BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || !bdfIsPrefix(line, "STARTPROPERTIES")) {
+ bdfError("missing 'STARTPROPERTIES'\n");
+ return (FALSE);
+ }
+ if (sscanf((char *) line, "STARTPROPERTIES %d", &nProps) != 1) {
+ bdfError("bad 'STARTPROPERTIES'\n");
+ return (FALSE);
+ }
+ pFont->info.isStringProp = NULL;
+ pFont->info.props = NULL;
+ pFont->info.nprops = 0;
+
+ stringProps = malloc((nProps + BDF_GENPROPS) * sizeof(char));
+ pFont->info.isStringProp = stringProps;
+ if (stringProps == NULL) {
+ bdfError("Couldn't allocate stringProps (%d*%d)\n",
+ (nProps + BDF_GENPROPS), sizeof(Bool));
+ goto BAILOUT;
+ }
+ pFont->info.props = props = calloc(nProps + BDF_GENPROPS,
+ sizeof(FontPropRec));
+ if (props == NULL) {
+ bdfError("Couldn't allocate props (%d*%d)\n", nProps + BDF_GENPROPS,
+ sizeof(FontPropRec));
+ goto BAILOUT;
+ }
+
+ nextProp = 0;
+ props_left = nProps;
+ while (props_left-- > 0) {
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (line == NULL || bdfIsPrefix(line, "ENDPROPERTIES")) {
+ bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n",
+ nProps, nProps - props_left - 1);
+ goto BAILOUT;
+ }
+ while (*line && isspace(*line))
+ line++;
+
+ switch (sscanf((char *) line, "%s%s%s", namebuf, secondbuf, thirdbuf)) {
+ default:
+ bdfError("missing '%s' parameter value\n", namebuf);
+ goto BAILOUT;
+
+ case 2:
+ /*
+ * Possibilites include: valid quoted string with no white space
+ * valid integer value invalid value
+ */
+ if (secondbuf[0] == '"') {
+ stringProps[nextProp] = TRUE;
+ props[nextProp].value =
+ bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
+ if (!props[nextProp].value)
+ goto BAILOUT;
+ break;
+ } else if (bdfIsInteger(secondbuf)) {
+ stringProps[nextProp] = FALSE;
+ props[nextProp].value = atoi(secondbuf);
+ break;
+ } else {
+ bdfError("invalid '%s' parameter value\n", namebuf);
+ goto BAILOUT;
+ }
+
+ case 3:
+ /*
+ * Possibilites include: valid quoted string with some white space
+ * invalid value (reject even if second string is integer)
+ */
+ if (secondbuf[0] == '"') {
+ stringProps[nextProp] = TRUE;
+ props[nextProp].value =
+ bdfGetPropertyValue((char *)line + strlen(namebuf) + 1);
+ if (!props[nextProp].value)
+ goto BAILOUT;
+ break;
+ } else {
+ bdfError("invalid '%s' parameter value\n", namebuf);
+ goto BAILOUT;
+ }
+ }
+ props[nextProp].name = bdfForceMakeAtom(namebuf, NULL);
+ if (props[nextProp].name == None) {
+ bdfError("Empty property name.\n");
+ goto BAILOUT;
+ }
+ if (!bdfSpecialProperty(pFont, &props[nextProp],
+ stringProps[nextProp], pState))
+ nextProp++;
+ }
+
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ if (!line || !bdfIsPrefix(line, "ENDPROPERTIES")) {
+ bdfError("missing 'ENDPROPERTIES'\n");
+ goto BAILOUT;
+ }
+ if (!pState->haveFontAscent || !pState->haveFontDescent) {
+ bdfError("missing 'FONT_ASCENT' or 'FONT_DESCENT' properties\n");
+ goto BAILOUT;
+ }
+ if (bitmapFont->bitmapExtra) {
+ bitmapFont->bitmapExtra->info.fontAscent = pFont->info.fontAscent;
+ bitmapFont->bitmapExtra->info.fontDescent = pFont->info.fontDescent;
+ }
+ if (!pState->pointSizeProp) {
+ props[nextProp].name = bdfForceMakeAtom("POINT_SIZE", NULL);
+ props[nextProp].value = (INT32) (pState->pointSize * 10.0);
+ stringProps[nextProp] = FALSE;
+ pState->pointSizeProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->fontProp) {
+ props[nextProp].name = bdfForceMakeAtom("FONT", NULL);
+ props[nextProp].value = (INT32) bdfForceMakeAtom(pState->fontName, NULL);
+ stringProps[nextProp] = TRUE;
+ pState->fontProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->weightProp) {
+ props[nextProp].name = bdfForceMakeAtom("WEIGHT", NULL);
+ props[nextProp].value = -1; /* computed later */
+ stringProps[nextProp] = FALSE;
+ pState->weightProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->resolutionProp &&
+ pState->resolution_x == pState->resolution_y) {
+ props[nextProp].name = bdfForceMakeAtom("RESOLUTION", NULL);
+ props[nextProp].value = (INT32) ((pState->resolution_x * 100.0) / 72.27);
+ stringProps[nextProp] = FALSE;
+ pState->resolutionProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->resolutionXProp) {
+ props[nextProp].name = bdfForceMakeAtom("RESOLUTION_X", NULL);
+ props[nextProp].value = (INT32) pState->resolution_x;
+ stringProps[nextProp] = FALSE;
+ pState->resolutionProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->resolutionYProp) {
+ props[nextProp].name = bdfForceMakeAtom("RESOLUTION_Y", NULL);
+ props[nextProp].value = (INT32) pState->resolution_y;
+ stringProps[nextProp] = FALSE;
+ pState->resolutionProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->xHeightProp) {
+ props[nextProp].name = bdfForceMakeAtom("X_HEIGHT", NULL);
+ props[nextProp].value = -1; /* computed later */
+ stringProps[nextProp] = FALSE;
+ pState->xHeightProp = &props[nextProp];
+ nextProp++;
+ }
+ if (!pState->quadWidthProp) {
+ props[nextProp].name = bdfForceMakeAtom("QUAD_WIDTH", NULL);
+ props[nextProp].value = -1; /* computed later */
+ stringProps[nextProp] = FALSE;
+ pState->quadWidthProp = &props[nextProp];
+ nextProp++;
+ }
+ pFont->info.nprops = nextProp;
+ return (TRUE);
+BAILOUT:
+ if (pFont->info.isStringProp) {
+ free(pFont->info.isStringProp);
+ pFont->info.isStringProp = NULL;
+ }
+ if (pFont->info.props) {
+ free(pFont->info.props);
+ pFont->info.props = NULL;
+ }
+ while (line && bdfIsPrefix(line, "ENDPROPERTIES"))
+ line = bdfGetLine(file, lineBuf, BDFLINELEN);
+ return (FALSE);
+}
+
+/***====================================================================***/
+
+static void
+bdfUnloadFont(FontPtr pFont)
+{
+ bdfFreeFontBits (pFont);
+ DestroyFontRec(pFont);
+}
+
+int
+bdfReadFont(FontPtr pFont, FontFilePtr file,
+ int bit, int byte, int glyph, int scan)
+{
+ bdfFileState state;
+ xCharInfo *min,
+ *max;
+ BitmapFontPtr bitmapFont;
+
+ pFont->fontPrivate = 0;
+
+ bzero(&state, sizeof(bdfFileState));
+ bdfFileLineNum = 0;
+
+ if (!bdfReadHeader(file, &state))
+ goto BAILOUT;
+
+ bitmapFont = calloc(1, sizeof(BitmapFontRec));
+ if (!bitmapFont) {
+ bdfError("Couldn't allocate bitmapFontRec (%d)\n", sizeof(BitmapFontRec));
+ goto BAILOUT;
+ }
+
+ pFont->fontPrivate = (pointer) bitmapFont;
+ bitmapFont->metrics = 0;
+ bitmapFont->ink_metrics = 0;
+ bitmapFont->bitmaps = 0;
+ bitmapFont->encoding = 0;
+ bitmapFont->pDefault = NULL;
+
+ bitmapFont->bitmapExtra = calloc(1, sizeof(BitmapExtraRec));
+ if (!bitmapFont->bitmapExtra) {
+ bdfError("Couldn't allocate bitmapExtra (%d)\n", sizeof(BitmapExtraRec));
+ goto BAILOUT;
+ }
+
+ bitmapFont->bitmapExtra->glyphNames = 0;
+ bitmapFont->bitmapExtra->sWidths = 0;
+
+ if (!bdfReadProperties(file, pFont, &state))
+ goto BAILOUT;
+
+ if (!bdfReadCharacters(file, pFont, &state, bit, byte, glyph, scan))
+ goto BAILOUT;
+
+ if (state.haveDefaultCh) {
+ unsigned int r, c, cols;
+
+ r = pFont->info.defaultCh >> 8;
+ c = pFont->info.defaultCh & 0xFF;
+ if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
+ pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
+ cols = pFont->info.lastCol - pFont->info.firstCol + 1;
+ r = r - pFont->info.firstRow;
+ c = c - pFont->info.firstCol;
+ bitmapFont->pDefault = ACCESSENCODING(bitmapFont->encoding,
+ r * cols + c);
+ }
+ }
+ pFont->bit = bit;
+ pFont->byte = byte;
+ pFont->glyph = glyph;
+ pFont->scan = scan;
+ pFont->info.anamorphic = FALSE;
+ pFont->info.cachable = TRUE;
+ bitmapComputeFontBounds(pFont);
+ if (FontCouldBeTerminal(&pFont->info)) {
+ bdfPadToTerminal(pFont);
+ bitmapComputeFontBounds(pFont);
+ }
+ FontComputeInfoAccelerators(&pFont->info);
+ if (bitmapFont->bitmapExtra)
+ FontComputeInfoAccelerators(&bitmapFont->bitmapExtra->info);
+ if (pFont->info.constantMetrics) {
+ if (!bitmapAddInkMetrics(pFont)) {
+ bdfError("Failed to add bitmap ink metrics\n");
+ goto BAILOUT;
+ }
+ }
+ if (bitmapFont->bitmapExtra)
+ bitmapFont->bitmapExtra->info.inkMetrics = pFont->info.inkMetrics;
+
+ bitmapComputeFontInkBounds(pFont);
+/* ComputeFontAccelerators (pFont); */
+
+ /* generate properties */
+ min = &pFont->info.ink_minbounds;
+ max = &pFont->info.ink_maxbounds;
+ if (state.xHeightProp && (state.xHeightProp->value == -1))
+ state.xHeightProp->value = state.exHeight ?
+ state.exHeight : min->ascent;
+
+ if (state.quadWidthProp && (state.quadWidthProp->value == -1))
+ state.quadWidthProp->value = state.digitCount ?
+ (INT32) (state.digitWidths / state.digitCount) :
+ (min->characterWidth + max->characterWidth) / 2;
+
+ if (state.weightProp && (state.weightProp->value == -1))
+ state.weightProp->value = bitmapComputeWeight(pFont);
+
+ pFont->get_glyphs = bitmapGetGlyphs;
+ pFont->get_metrics = bitmapGetMetrics;
+ pFont->unload_font = bdfUnloadFont;
+ pFont->unload_glyphs = NULL;
+ return Successful;
+BAILOUT:
+ if (pFont->fontPrivate)
+ bdfFreeFontBits (pFont);
+ return AllocError;
+}
+
+int
+bdfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
+{
+ FontRec font;
+ int ret;
+
+ bzero(&font, sizeof (FontRec));
+
+ ret = bdfReadFont(&font, file, MSBFirst, LSBFirst, 1, 1);
+ if (ret == Successful) {
+ *pFontInfo = font.info;
+ font.info.props = 0;
+ font.info.isStringProp = 0;
+ font.info.nprops = 0;
+ bdfFreeFontBits (&font);
+ }
+ return ret;
+}
+
+static Bool
+bdfPadToTerminal(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont;
+ BitmapExtraPtr bitmapExtra;
+ int i;
+ int new_size;
+ CharInfoRec new;
+ int w,
+ h;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+
+ bzero(&new, sizeof(CharInfoRec));
+ new.metrics.ascent = pFont->info.fontAscent;
+ new.metrics.descent = pFont->info.fontDescent;
+ new.metrics.leftSideBearing = 0;
+ new.metrics.rightSideBearing = pFont->info.minbounds.characterWidth;
+ new.metrics.characterWidth = new.metrics.rightSideBearing;
+ new_size = BYTES_FOR_GLYPH(&new, pFont->glyph);
+
+ for (i = 0; i < bitmapFont->num_chars; i++) {
+ new.bits = malloc(new_size);
+ if (!new.bits) {
+ bdfError("Couldn't allocate bits (%d)\n", new_size);
+ return FALSE;
+ }
+ FontCharReshape(pFont, &bitmapFont->metrics[i], &new);
+ new.metrics.attributes = bitmapFont->metrics[i].metrics.attributes;
+ free(bitmapFont->metrics[i].bits);
+ bitmapFont->metrics[i] = new;
+ }
+ bitmapExtra = bitmapFont->bitmapExtra;
+ if (bitmapExtra) {
+ w = GLYPHWIDTHPIXELS(&new);
+ h = GLYPHHEIGHTPIXELS(&new);
+ for (i = 0; i < GLYPHPADOPTIONS; i++)
+ bitmapExtra->bitmapsSizes[i] = bitmapFont->num_chars *
+ (BYTES_PER_ROW(w, 1 << i) * h);
+ }
+ return TRUE;
+}
diff --git a/libXfont/src/bitmap/bdfutils.c b/libXfont/src/bitmap/bdfutils.c
index 1d6cc7253..7cae0de6a 100644
--- a/libXfont/src/bitmap/bdfutils.c
+++ b/libXfont/src/bitmap/bdfutils.c
@@ -1,336 +1,336 @@
-/************************************************************************
-Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-************************************************************************/
-
-/*
-
-Copyright 1994, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include <X11/fonts/fntfilst.h>
-#include <X11/fonts/fontstruct.h>
-/* use bitmap structure */
-#include <X11/fonts/bitmap.h>
-#include <X11/fonts/bdfint.h>
-
-int bdfFileLineNum;
-
-/***====================================================================***/
-
-void
-bdfError(char* message, ...)
-{
- va_list args;
-
- va_start (args, message);
- fprintf(stderr, "BDF Error on line %d: ", bdfFileLineNum);
- vfprintf(stderr, message, args);
- va_end (args);
-}
-
-/***====================================================================***/
-
-void
-bdfWarning(char *message, ...)
-{
- va_list args;
-
- va_start (args, message);
- fprintf(stderr, "BDF Warning on line %d: ", bdfFileLineNum);
- vfprintf(stderr, message, args);
- va_end (args);
-}
-
-/*
- * read the next (non-comment) line and keep a count for error messages.
- * Returns buf, or NULL if EOF.
- */
-
-unsigned char *
-bdfGetLine(FontFilePtr file, unsigned char *buf, int len)
-{
- int c;
- unsigned char *b;
-
- for (;;) {
- b = buf;
- while ((c = FontFileGetc(file)) != FontFileEOF) {
- if (c == '\r')
- continue;
- if (c == '\n') {
- bdfFileLineNum++;
- break;
- }
- if (b - buf >= (len - 1))
- break;
- *b++ = c;
- }
- *b = '\0';
- if (c == FontFileEOF)
- return NULL;
- if (b != buf && !bdfIsPrefix(buf, "COMMENT"))
- break;
- }
- return buf;
-}
-
-/***====================================================================***/
-
-Atom
-bdfForceMakeAtom(char *str, int *size)
-{
- register int len = strlen(str);
- Atom the_atom;
-
- if (size != NULL)
- *size += len + 1;
- the_atom = MakeAtom(str, len, TRUE);
- if (the_atom == None)
- bdfError("Atom allocation failed\n");
- return the_atom;
-}
-
-/***====================================================================***/
-
-/*
- * Handle quoted strings.
- */
-
-Atom
-bdfGetPropertyValue(char *s)
-{
- register char *p,
- *pp;
- char *orig_s = s;
- Atom atom;
-
- /* strip leading white space */
- while (*s && (*s == ' ' || *s == '\t'))
- s++;
- if (*s == 0) {
- return bdfForceMakeAtom(s, NULL);
- }
- if (*s != '"') {
- pp = s;
- /* no white space in value */
- for (pp = s; *pp; pp++)
- if (*pp == ' ' || *pp == '\t' || *pp == '\015' || *pp == '\n') {
- *pp = 0;
- break;
- }
- return bdfForceMakeAtom(s, NULL);
- }
- /* quoted string: strip outer quotes and undouble inner quotes */
- s++;
- pp = p = malloc((unsigned) strlen(s) + 1);
- if (pp == NULL) {
- bdfError("Couldn't allocate property value string (%d)\n", strlen(s) + 1);
- return None;
- }
- while (*s) {
- if (*s == '"') {
- if (*(s + 1) != '"') {
- *p++ = 0;
- atom = bdfForceMakeAtom(pp, NULL);
- free(pp);
- return atom;
- } else {
- s++;
- }
- }
- *p++ = *s++;
- }
- free (pp);
- bdfError("unterminated quoted string property: %s\n", (pointer) orig_s);
- return None;
-}
-
-/***====================================================================***/
-
-/*
- * return TRUE if string is a valid integer
- */
-int
-bdfIsInteger(char *str)
-{
- char c;
-
- c = *str++;
- if (!(isdigit(c) || c == '-' || c == '+'))
- return (FALSE);
-
- while ((c = *str++))
- if (!isdigit(c))
- return (FALSE);
-
- return (TRUE);
-}
-
-/***====================================================================***/
-
-/*
- * make a byte from the first two hex characters in glyph picture
- */
-
-unsigned char
-bdfHexByte(unsigned char *s)
-{
- unsigned char b = 0;
- register char c;
- int i;
-
- for (i = 2; i; i--) {
- c = *s++;
- if ((c >= '0') && (c <= '9'))
- b = (b << 4) + (c - '0');
- else if ((c >= 'A') && (c <= 'F'))
- b = (b << 4) + 10 + (c - 'A');
- else if ((c >= 'a') && (c <= 'f'))
- b = (b << 4) + 10 + (c - 'a');
- else
- bdfError("bad hex char '%c'", c);
- }
- return b;
-}
-
-/***====================================================================***/
-
-/*
- * check for known special property values
- */
-
-static char *SpecialAtoms[] = {
- "FONT_ASCENT",
-#define BDF_FONT_ASCENT 0
- "FONT_DESCENT",
-#define BDF_FONT_DESCENT 1
- "DEFAULT_CHAR",
-#define BDF_DEFAULT_CHAR 2
- "POINT_SIZE",
-#define BDF_POINT_SIZE 3
- "RESOLUTION",
-#define BDF_RESOLUTION 4
- "X_HEIGHT",
-#define BDF_X_HEIGHT 5
- "WEIGHT",
-#define BDF_WEIGHT 6
- "QUAD_WIDTH",
-#define BDF_QUAD_WIDTH 7
- "FONT",
-#define BDF_FONT 8
- "RESOLUTION_X",
-#define BDF_RESOLUTION_X 9
- "RESOLUTION_Y",
-#define BDF_RESOLUTION_Y 10
- 0,
-};
-
-Bool
-bdfSpecialProperty(FontPtr pFont, FontPropPtr prop,
- char isString, bdfFileState *bdfState)
-{
- char **special;
- char *name;
-
- name = NameForAtom(prop->name);
- for (special = SpecialAtoms; *special; special++)
- if (!strcmp(name, *special))
- break;
-
- switch (special - SpecialAtoms) {
- case BDF_FONT_ASCENT:
- if (!isString) {
- pFont->info.fontAscent = prop->value;
- bdfState->haveFontAscent = TRUE;
- }
- return TRUE;
- case BDF_FONT_DESCENT:
- if (!isString) {
- pFont->info.fontDescent = prop->value;
- bdfState->haveFontDescent = TRUE;
- }
- return TRUE;
- case BDF_DEFAULT_CHAR:
- if (!isString) {
- pFont->info.defaultCh = prop->value;
- bdfState->haveDefaultCh = TRUE;
- }
- return TRUE;
- case BDF_POINT_SIZE:
- bdfState->pointSizeProp = prop;
- return FALSE;
- case BDF_RESOLUTION:
- bdfState->resolutionProp = prop;
- return FALSE;
- case BDF_X_HEIGHT:
- bdfState->xHeightProp = prop;
- return FALSE;
- case BDF_WEIGHT:
- bdfState->weightProp = prop;
- return FALSE;
- case BDF_QUAD_WIDTH:
- bdfState->quadWidthProp = prop;
- return FALSE;
- case BDF_FONT:
- bdfState->fontProp = prop;
- return FALSE;
- case BDF_RESOLUTION_X:
- bdfState->resolutionXProp = prop;
- return FALSE;
- case BDF_RESOLUTION_Y:
- bdfState->resolutionYProp = prop;
- return FALSE;
- default:
- return FALSE;
- }
-}
+/************************************************************************
+Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+************************************************************************/
+
+/*
+
+Copyright 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontstruct.h>
+/* use bitmap structure */
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/bdfint.h>
+
+int bdfFileLineNum;
+
+/***====================================================================***/
+
+void
+bdfError(char* message, ...)
+{
+ va_list args;
+
+ va_start (args, message);
+ fprintf(stderr, "BDF Error on line %d: ", bdfFileLineNum);
+ vfprintf(stderr, message, args);
+ va_end (args);
+}
+
+/***====================================================================***/
+
+void
+bdfWarning(char *message, ...)
+{
+ va_list args;
+
+ va_start (args, message);
+ fprintf(stderr, "BDF Warning on line %d: ", bdfFileLineNum);
+ vfprintf(stderr, message, args);
+ va_end (args);
+}
+
+/*
+ * read the next (non-comment) line and keep a count for error messages.
+ * Returns buf, or NULL if EOF.
+ */
+
+unsigned char *
+bdfGetLine(FontFilePtr file, unsigned char *buf, int len)
+{
+ int c;
+ unsigned char *b;
+
+ for (;;) {
+ b = buf;
+ while ((c = FontFileGetc(file)) != FontFileEOF) {
+ if (c == '\r')
+ continue;
+ if (c == '\n') {
+ bdfFileLineNum++;
+ break;
+ }
+ if (b - buf >= (len - 1))
+ break;
+ *b++ = c;
+ }
+ *b = '\0';
+ if (c == FontFileEOF)
+ return NULL;
+ if (b != buf && !bdfIsPrefix(buf, "COMMENT"))
+ break;
+ }
+ return buf;
+}
+
+/***====================================================================***/
+
+Atom
+bdfForceMakeAtom(char *str, int *size)
+{
+ register int len = strlen(str);
+ Atom the_atom;
+
+ if (size != NULL)
+ *size += len + 1;
+ the_atom = MakeAtom(str, len, TRUE);
+ if (the_atom == None)
+ bdfError("Atom allocation failed\n");
+ return the_atom;
+}
+
+/***====================================================================***/
+
+/*
+ * Handle quoted strings.
+ */
+
+Atom
+bdfGetPropertyValue(char *s)
+{
+ register char *p,
+ *pp;
+ char *orig_s = s;
+ Atom atom;
+
+ /* strip leading white space */
+ while (*s && (*s == ' ' || *s == '\t'))
+ s++;
+ if (*s == 0) {
+ return bdfForceMakeAtom(s, NULL);
+ }
+ if (*s != '"') {
+ pp = s;
+ /* no white space in value */
+ for (pp = s; *pp; pp++)
+ if (*pp == ' ' || *pp == '\t' || *pp == '\015' || *pp == '\n') {
+ *pp = 0;
+ break;
+ }
+ return bdfForceMakeAtom(s, NULL);
+ }
+ /* quoted string: strip outer quotes and undouble inner quotes */
+ s++;
+ pp = p = malloc((unsigned) strlen(s) + 1);
+ if (pp == NULL) {
+ bdfError("Couldn't allocate property value string (%d)\n", strlen(s) + 1);
+ return None;
+ }
+ while (*s) {
+ if (*s == '"') {
+ if (*(s + 1) != '"') {
+ *p++ = 0;
+ atom = bdfForceMakeAtom(pp, NULL);
+ free(pp);
+ return atom;
+ } else {
+ s++;
+ }
+ }
+ *p++ = *s++;
+ }
+ free (pp);
+ bdfError("unterminated quoted string property: %s\n", (pointer) orig_s);
+ return None;
+}
+
+/***====================================================================***/
+
+/*
+ * return TRUE if string is a valid integer
+ */
+int
+bdfIsInteger(char *str)
+{
+ char c;
+
+ c = *str++;
+ if (!(isdigit(c) || c == '-' || c == '+'))
+ return (FALSE);
+
+ while ((c = *str++))
+ if (!isdigit(c))
+ return (FALSE);
+
+ return (TRUE);
+}
+
+/***====================================================================***/
+
+/*
+ * make a byte from the first two hex characters in glyph picture
+ */
+
+unsigned char
+bdfHexByte(unsigned char *s)
+{
+ unsigned char b = 0;
+ register char c;
+ int i;
+
+ for (i = 2; i; i--) {
+ c = *s++;
+ if ((c >= '0') && (c <= '9'))
+ b = (b << 4) + (c - '0');
+ else if ((c >= 'A') && (c <= 'F'))
+ b = (b << 4) + 10 + (c - 'A');
+ else if ((c >= 'a') && (c <= 'f'))
+ b = (b << 4) + 10 + (c - 'a');
+ else
+ bdfError("bad hex char '%c'", c);
+ }
+ return b;
+}
+
+/***====================================================================***/
+
+/*
+ * check for known special property values
+ */
+
+static char *SpecialAtoms[] = {
+ "FONT_ASCENT",
+#define BDF_FONT_ASCENT 0
+ "FONT_DESCENT",
+#define BDF_FONT_DESCENT 1
+ "DEFAULT_CHAR",
+#define BDF_DEFAULT_CHAR 2
+ "POINT_SIZE",
+#define BDF_POINT_SIZE 3
+ "RESOLUTION",
+#define BDF_RESOLUTION 4
+ "X_HEIGHT",
+#define BDF_X_HEIGHT 5
+ "WEIGHT",
+#define BDF_WEIGHT 6
+ "QUAD_WIDTH",
+#define BDF_QUAD_WIDTH 7
+ "FONT",
+#define BDF_FONT 8
+ "RESOLUTION_X",
+#define BDF_RESOLUTION_X 9
+ "RESOLUTION_Y",
+#define BDF_RESOLUTION_Y 10
+ 0,
+};
+
+Bool
+bdfSpecialProperty(FontPtr pFont, FontPropPtr prop,
+ char isString, bdfFileState *bdfState)
+{
+ char **special;
+ char *name;
+
+ name = NameForAtom(prop->name);
+ for (special = SpecialAtoms; *special; special++)
+ if (!strcmp(name, *special))
+ break;
+
+ switch (special - SpecialAtoms) {
+ case BDF_FONT_ASCENT:
+ if (!isString) {
+ pFont->info.fontAscent = prop->value;
+ bdfState->haveFontAscent = TRUE;
+ }
+ return TRUE;
+ case BDF_FONT_DESCENT:
+ if (!isString) {
+ pFont->info.fontDescent = prop->value;
+ bdfState->haveFontDescent = TRUE;
+ }
+ return TRUE;
+ case BDF_DEFAULT_CHAR:
+ if (!isString) {
+ pFont->info.defaultCh = prop->value;
+ bdfState->haveDefaultCh = TRUE;
+ }
+ return TRUE;
+ case BDF_POINT_SIZE:
+ bdfState->pointSizeProp = prop;
+ return FALSE;
+ case BDF_RESOLUTION:
+ bdfState->resolutionProp = prop;
+ return FALSE;
+ case BDF_X_HEIGHT:
+ bdfState->xHeightProp = prop;
+ return FALSE;
+ case BDF_WEIGHT:
+ bdfState->weightProp = prop;
+ return FALSE;
+ case BDF_QUAD_WIDTH:
+ bdfState->quadWidthProp = prop;
+ return FALSE;
+ case BDF_FONT:
+ bdfState->fontProp = prop;
+ return FALSE;
+ case BDF_RESOLUTION_X:
+ bdfState->resolutionXProp = prop;
+ return FALSE;
+ case BDF_RESOLUTION_Y:
+ bdfState->resolutionYProp = prop;
+ return FALSE;
+ default:
+ return FALSE;
+ }
+}
diff --git a/libXfont/src/bitmap/bitmap.c b/libXfont/src/bitmap/bitmap.c
index 1ceb4bb17..f837deafd 100644
--- a/libXfont/src/bitmap/bitmap.c
+++ b/libXfont/src/bitmap/bitmap.c
@@ -1,157 +1,157 @@
-/*
-
-Copyright 1991, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-
-/*
- * Author: Keith Packard, MIT X Consortium
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <X11/fonts/fntfilst.h>
-#include <X11/fonts/bitmap.h>
-
-int
-bitmapGetGlyphs(FontPtr pFont, unsigned long count, unsigned char *chars,
- FontEncoding charEncoding,
- unsigned long *glyphCount, /* RETURN */
- CharInfoPtr *glyphs) /* RETURN */
-{
- BitmapFontPtr bitmapFont;
- unsigned int firstCol;
- register unsigned int numCols;
- unsigned int firstRow;
- unsigned int numRows;
- CharInfoPtr *glyphsBase;
- register unsigned int c;
- register CharInfoPtr pci;
- unsigned int r;
- CharInfoPtr **encoding;
- CharInfoPtr pDefault;
-
- bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
- encoding = bitmapFont->encoding;
- pDefault = bitmapFont->pDefault;
- firstCol = pFont->info.firstCol;
- numCols = pFont->info.lastCol - firstCol + 1;
- glyphsBase = glyphs;
- switch (charEncoding) {
-
- case Linear8Bit:
- case TwoD8Bit:
- if (pFont->info.firstRow > 0)
- break;
- if (pFont->info.allExist && pDefault) {
- while (count--) {
- c = (*chars++) - firstCol;
- if (c < numCols)
- *glyphs++ = ACCESSENCODING(encoding,c);
- else
- *glyphs++ = pDefault;
- }
- } else {
- while (count--) {
- c = (*chars++) - firstCol;
- if (c < numCols && (pci = ACCESSENCODING(encoding,c)))
- *glyphs++ = pci;
- else if (pDefault)
- *glyphs++ = pDefault;
- }
- }
- break;
- case Linear16Bit:
- if (pFont->info.allExist && pDefault) {
- while (count--) {
- c = *chars++ << 8;
- c = (c | *chars++) - firstCol;
- if (c < numCols)
- *glyphs++ = ACCESSENCODING(encoding,c);
- else
- *glyphs++ = pDefault;
- }
- } else {
- while (count--) {
- c = *chars++ << 8;
- c = (c | *chars++) - firstCol;
- if (c < numCols && (pci = ACCESSENCODING(encoding,c)))
- *glyphs++ = pci;
- else if (pDefault)
- *glyphs++ = pDefault;
- }
- }
- break;
-
- case TwoD16Bit:
- firstRow = pFont->info.firstRow;
- numRows = pFont->info.lastRow - firstRow + 1;
- while (count--) {
- r = (*chars++) - firstRow;
- c = (*chars++) - firstCol;
- if (r < numRows && c < numCols &&
- (pci = ACCESSENCODING(encoding, r * numCols + c)))
- *glyphs++ = pci;
- else if (pDefault)
- *glyphs++ = pDefault;
- }
- break;
- }
- *glyphCount = glyphs - glyphsBase;
- return Successful;
-}
-
-static CharInfoRec nonExistantChar;
-
-int
-bitmapGetMetrics(FontPtr pFont, unsigned long count, unsigned char *chars,
- FontEncoding charEncoding,
- unsigned long *glyphCount, /* RETURN */
- xCharInfo **glyphs) /* RETURN */
-{
- int ret;
- xCharInfo *ink_metrics;
- CharInfoPtr metrics;
- BitmapFontPtr bitmapFont;
- CharInfoPtr oldDefault;
- int i;
-
- bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
- oldDefault = bitmapFont->pDefault;
- bitmapFont->pDefault = &nonExistantChar;
- ret = bitmapGetGlyphs(pFont, count, chars, charEncoding, glyphCount, (CharInfoPtr *) glyphs);
- if (ret == Successful) {
- if (bitmapFont->ink_metrics) {
- metrics = bitmapFont->metrics;
- ink_metrics = bitmapFont->ink_metrics;
- for (i = 0; i < *glyphCount; i++) {
- if (glyphs[i] != (xCharInfo *) & nonExistantChar)
- glyphs[i] = ink_metrics + (((CharInfoPtr) glyphs[i]) - metrics);
- }
- }
- }
- bitmapFont->pDefault = oldDefault;
- return ret;
-}
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+
+int
+bitmapGetGlyphs(FontPtr pFont, unsigned long count, unsigned char *chars,
+ FontEncoding charEncoding,
+ unsigned long *glyphCount, /* RETURN */
+ CharInfoPtr *glyphs) /* RETURN */
+{
+ BitmapFontPtr bitmapFont;
+ unsigned int firstCol;
+ register unsigned int numCols;
+ unsigned int firstRow;
+ unsigned int numRows;
+ CharInfoPtr *glyphsBase;
+ register unsigned int c;
+ register CharInfoPtr pci;
+ unsigned int r;
+ CharInfoPtr **encoding;
+ CharInfoPtr pDefault;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ encoding = bitmapFont->encoding;
+ pDefault = bitmapFont->pDefault;
+ firstCol = pFont->info.firstCol;
+ numCols = pFont->info.lastCol - firstCol + 1;
+ glyphsBase = glyphs;
+ switch (charEncoding) {
+
+ case Linear8Bit:
+ case TwoD8Bit:
+ if (pFont->info.firstRow > 0)
+ break;
+ if (pFont->info.allExist && pDefault) {
+ while (count--) {
+ c = (*chars++) - firstCol;
+ if (c < numCols)
+ *glyphs++ = ACCESSENCODING(encoding,c);
+ else
+ *glyphs++ = pDefault;
+ }
+ } else {
+ while (count--) {
+ c = (*chars++) - firstCol;
+ if (c < numCols && (pci = ACCESSENCODING(encoding,c)))
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ }
+ break;
+ case Linear16Bit:
+ if (pFont->info.allExist && pDefault) {
+ while (count--) {
+ c = *chars++ << 8;
+ c = (c | *chars++) - firstCol;
+ if (c < numCols)
+ *glyphs++ = ACCESSENCODING(encoding,c);
+ else
+ *glyphs++ = pDefault;
+ }
+ } else {
+ while (count--) {
+ c = *chars++ << 8;
+ c = (c | *chars++) - firstCol;
+ if (c < numCols && (pci = ACCESSENCODING(encoding,c)))
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ }
+ break;
+
+ case TwoD16Bit:
+ firstRow = pFont->info.firstRow;
+ numRows = pFont->info.lastRow - firstRow + 1;
+ while (count--) {
+ r = (*chars++) - firstRow;
+ c = (*chars++) - firstCol;
+ if (r < numRows && c < numCols &&
+ (pci = ACCESSENCODING(encoding, r * numCols + c)))
+ *glyphs++ = pci;
+ else if (pDefault)
+ *glyphs++ = pDefault;
+ }
+ break;
+ }
+ *glyphCount = glyphs - glyphsBase;
+ return Successful;
+}
+
+static CharInfoRec nonExistantChar;
+
+int
+bitmapGetMetrics(FontPtr pFont, unsigned long count, unsigned char *chars,
+ FontEncoding charEncoding,
+ unsigned long *glyphCount, /* RETURN */
+ xCharInfo **glyphs) /* RETURN */
+{
+ int ret;
+ xCharInfo *ink_metrics;
+ CharInfoPtr metrics;
+ BitmapFontPtr bitmapFont;
+ CharInfoPtr oldDefault;
+ int i;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ oldDefault = bitmapFont->pDefault;
+ bitmapFont->pDefault = &nonExistantChar;
+ ret = bitmapGetGlyphs(pFont, count, chars, charEncoding, glyphCount, (CharInfoPtr *) glyphs);
+ if (ret == Successful) {
+ if (bitmapFont->ink_metrics) {
+ metrics = bitmapFont->metrics;
+ ink_metrics = bitmapFont->ink_metrics;
+ for (i = 0; i < *glyphCount; i++) {
+ if (glyphs[i] != (xCharInfo *) & nonExistantChar)
+ glyphs[i] = ink_metrics + (((CharInfoPtr) glyphs[i]) - metrics);
+ }
+ }
+ }
+ bitmapFont->pDefault = oldDefault;
+ return ret;
+}
diff --git a/libXfont/src/bitmap/bitmapfunc.c b/libXfont/src/bitmap/bitmapfunc.c
index 47ce488d0..b13a4c42e 100644
--- a/libXfont/src/bitmap/bitmapfunc.c
+++ b/libXfont/src/bitmap/bitmapfunc.c
@@ -1,254 +1,256 @@
-/*
-
-Copyright 1991, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-
-/*
- * Author: Keith Packard, MIT X Consortium
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-/*
- * Translate monolithic #defines to modular definitions
- */
-
-#ifdef PCFFORMAT
-#define XFONT_PCFFORMAT 1
-#endif
-
-#ifdef SNFFORMAT
-#define XFONT_SNFFORMAT 1
-#endif
-
-#ifdef BDFFORMAT
-#define XFONT_BDFFORMAT 1
-#endif
-
-#include <X11/fonts/fntfilst.h>
-#include <X11/fonts/bitmap.h>
-#include <X11/fonts/fontutil.h>
-#include <X11/fonts/bdfint.h>
-#include <X11/fonts/pcf.h>
-#include "snfstr.h"
-
-typedef struct _BitmapFileFunctions {
- int (*ReadFont) (FontPtr /* pFont */, FontFilePtr /* file */,
- int /* bit */, int /* byte */,
- int /* glyph */, int /* scan */);
- int (*ReadInfo) ( FontInfoPtr /* pFontInfo */,
- FontFilePtr /* file */ );
-} BitmapFileFunctionsRec, *BitmapFileFunctionsPtr;
-
-static int BitmapGetRenderIndex(FontRendererPtr renderer);
-
-/*
- * the readers[] and renderers[] arrays must be in the same order,
- * and also in the same order as scale[] and find_scale[] in bitscale.c
- *
- */
-static BitmapFileFunctionsRec readers[] = {
-#if XFONT_PCFFORMAT
- { pcfReadFont, pcfReadFontInfo} ,
- { pcfReadFont, pcfReadFontInfo} ,
-# ifdef X_GZIP_FONT_COMPRESSION
- { pcfReadFont, pcfReadFontInfo} ,
-# endif
-# ifdef X_BZIP2_FONT_COMPRESSION
- { pcfReadFont, pcfReadFontInfo} ,
-# endif
-#endif
-#if XFONT_SNFFORMAT
- { snfReadFont, snfReadFontInfo},
- { snfReadFont, snfReadFontInfo},
-# ifdef X_GZIP_FONT_COMPRESSION
- { snfReadFont, snfReadFontInfo} ,
-# endif
-# ifdef X_BZIP2_FONT_COMPRESSION
- { snfReadFont, snfReadFontInfo} ,
-# endif
-#endif
-#if XFONT_BDFFORMAT
- { bdfReadFont, bdfReadFontInfo} ,
- { bdfReadFont, bdfReadFontInfo} ,
-# ifdef X_GZIP_FONT_COMPRESSION
- { bdfReadFont, bdfReadFontInfo} ,
-# endif
-# ifdef X_BZIP2_FONT_COMPRESSION
- { bdfReadFont, bdfReadFontInfo} ,
-# endif
-#endif
-};
-
-
-#define CAPABILITIES (CAP_MATRIX | CAP_CHARSUBSETTING)
-
-static int
-BitmapOpenBitmap (FontPathElementPtr fpe, FontPtr *ppFont, int flags,
- FontEntryPtr entry, char *fileName,
- fsBitmapFormat format, fsBitmapFormatMask fmask,
- FontPtr non_cachable_font) /* We don't do licensing */
-{
- FontFilePtr file;
- FontPtr pFont;
- int i;
- int ret;
- int bit,
- byte,
- glyph,
- scan,
- image;
-
- i = BitmapGetRenderIndex(entry->u.bitmap.renderer);
- file = FontFileOpen (fileName);
- if (!file)
- return BadFontName;
- if (!(pFont = CreateFontRec())) {
- fprintf(stderr, "Error: Couldn't allocate pFont (%ld)\n",
- (unsigned long)sizeof(FontRec));
- FontFileClose (file);
- return AllocError;
- }
- /* set up default values */
- FontDefaultFormat(&bit, &byte, &glyph, &scan);
- /* get any changes made from above */
- ret = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image);
-
- /* Fill in font record. Data format filled in by reader. */
- pFont->refcnt = 0;
-
- ret = (*readers[i].ReadFont) (pFont, file, bit, byte, glyph, scan);
-
- FontFileClose (file);
- if (ret != Successful) {
- free(pFont);
- } else {
- *ppFont = pFont;
- }
- return ret;
-}
-
-static int
-BitmapGetInfoBitmap (FontPathElementPtr fpe, FontInfoPtr pFontInfo,
- FontEntryPtr entry, char *fileName)
-{
- FontFilePtr file;
- int i;
- int ret;
- FontRendererPtr renderer;
-
- renderer = FontFileMatchRenderer (fileName);
- if (!renderer)
- return BadFontName;
- i = BitmapGetRenderIndex(renderer);
- file = FontFileOpen (fileName);
- if (!file)
- return BadFontName;
- ret = (*readers[i].ReadInfo) (pFontInfo, file);
- FontFileClose (file);
- return ret;
-}
-
-static FontRendererRec renderers[] = {
-#if XFONT_PCFFORMAT
- { ".pcf", 4, BitmapOpenBitmap, BitmapOpenScalable,
- BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
- CAPABILITIES },
- { ".pcf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
- BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
- CAPABILITIES },
-# ifdef X_GZIP_FONT_COMPRESSION
- { ".pcf.gz", 7,
- BitmapOpenBitmap, BitmapOpenScalable,
- BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
- CAPABILITIES },
-# endif
-# ifdef X_BZIP2_FONT_COMPRESSION
- { ".pcf.bz2", 8,
- BitmapOpenBitmap, BitmapOpenScalable,
- BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
- CAPABILITIES },
-# endif
-#endif
-#if XFONT_SNFFORMAT
- { ".snf", 4, BitmapOpenBitmap, BitmapOpenScalable,
- BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
- CAPABILITIES },
- { ".snf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
- BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
- CAPABILITIES },
-# ifdef X_GZIP_FONT_COMPRESSION
- { ".snf.gz", 7, BitmapOpenBitmap, BitmapOpenScalable,
- BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
- CAPABILITIES },
-# endif
-# ifdef X_BZIP2_FONT_COMPRESSION
- { ".snf.bz2", 8, BitmapOpenBitmap, BitmapOpenScalable,
- BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
- CAPABILITIES },
-# endif
-#endif
-#if XFONT_BDFFORMAT
- { ".bdf", 4, BitmapOpenBitmap, BitmapOpenScalable,
- BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
- CAPABILITIES },
- { ".bdf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
- BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
- CAPABILITIES },
-# ifdef X_GZIP_FONT_COMPRESSION
- { ".bdf.gz", 7, BitmapOpenBitmap, BitmapOpenScalable,
- BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
- CAPABILITIES },
-# endif
-# ifdef X_BZIP2_FONT_COMPRESSION
- { ".bdf.bz2", 8, BitmapOpenBitmap, BitmapOpenScalable,
- BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
- CAPABILITIES },
-# endif
-#endif
-};
-
-#define numRenderers (sizeof renderers / sizeof renderers[0])
-
-void
-BitmapRegisterFontFileFunctions (void)
-{
- int i;
-
- for (i = 0; i < numRenderers; i++)
- FontFileRegisterRenderer (&renderers[i]);
-}
-
-/*
- * compute offset into renderers array - used to find the font reader,
- * the font info reader, and the bitmap scaling routine. All users
- * of this routine must be kept in step with the renderer array.
- */
-static int
-BitmapGetRenderIndex(FontRendererPtr renderer)
-{
- return renderer - renderers;
-}
+/*
+
+Copyright 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * Translate monolithic #defines to modular definitions
+ */
+
+#ifdef PCFFORMAT
+#define XFONT_PCFFORMAT 1
+#endif
+
+#ifdef SNFFORMAT
+#define XFONT_SNFFORMAT 1
+#endif
+
+#ifdef BDFFORMAT
+#define XFONT_BDFFORMAT 1
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/bdfint.h>
+#include <X11/fonts/pcf.h>
+#include "snfstr.h"
+
+typedef struct _BitmapFileFunctions {
+ int (*ReadFont) (FontPtr /* pFont */, FontFilePtr /* file */,
+ int /* bit */, int /* byte */,
+ int /* glyph */, int /* scan */);
+ int (*ReadInfo) ( FontInfoPtr /* pFontInfo */,
+ FontFilePtr /* file */ );
+} BitmapFileFunctionsRec, *BitmapFileFunctionsPtr;
+
+static int BitmapGetRenderIndex(FontRendererPtr renderer);
+
+/*
+ * the readers[] and renderers[] arrays must be in the same order,
+ * and also in the same order as scale[] and find_scale[] in bitscale.c
+ *
+ */
+static BitmapFileFunctionsRec readers[] = {
+#if XFONT_PCFFORMAT
+ { pcfReadFont, pcfReadFontInfo} ,
+ { pcfReadFont, pcfReadFontInfo} ,
+# ifdef X_GZIP_FONT_COMPRESSION
+ { pcfReadFont, pcfReadFontInfo} ,
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { pcfReadFont, pcfReadFontInfo} ,
+# endif
+#endif
+#if XFONT_SNFFORMAT
+ { snfReadFont, snfReadFontInfo},
+ { snfReadFont, snfReadFontInfo},
+# ifdef X_GZIP_FONT_COMPRESSION
+ { snfReadFont, snfReadFontInfo} ,
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { snfReadFont, snfReadFontInfo} ,
+# endif
+#endif
+#if XFONT_BDFFORMAT
+ { bdfReadFont, bdfReadFontInfo} ,
+ { bdfReadFont, bdfReadFontInfo} ,
+# ifdef X_GZIP_FONT_COMPRESSION
+ { bdfReadFont, bdfReadFontInfo} ,
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { bdfReadFont, bdfReadFontInfo} ,
+# endif
+#endif
+ { NULL, NULL }
+};
+
+
+#define CAPABILITIES (CAP_MATRIX | CAP_CHARSUBSETTING)
+
+static int
+BitmapOpenBitmap (FontPathElementPtr fpe, FontPtr *ppFont, int flags,
+ FontEntryPtr entry, char *fileName,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ FontPtr non_cachable_font) /* We don't do licensing */
+{
+ FontFilePtr file;
+ FontPtr pFont;
+ int i;
+ int ret;
+ int bit,
+ byte,
+ glyph,
+ scan,
+ image;
+
+ i = BitmapGetRenderIndex(entry->u.bitmap.renderer);
+ file = FontFileOpen (fileName);
+ if (!file)
+ return BadFontName;
+ if (!(pFont = CreateFontRec())) {
+ fprintf(stderr, "Error: Couldn't allocate pFont (%ld)\n",
+ (unsigned long)sizeof(FontRec));
+ FontFileClose (file);
+ return AllocError;
+ }
+ /* set up default values */
+ FontDefaultFormat(&bit, &byte, &glyph, &scan);
+ /* get any changes made from above */
+ ret = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image);
+
+ /* Fill in font record. Data format filled in by reader. */
+ pFont->refcnt = 0;
+
+ ret = (*readers[i].ReadFont) (pFont, file, bit, byte, glyph, scan);
+
+ FontFileClose (file);
+ if (ret != Successful) {
+ free(pFont);
+ } else {
+ *ppFont = pFont;
+ }
+ return ret;
+}
+
+static int
+BitmapGetInfoBitmap (FontPathElementPtr fpe, FontInfoPtr pFontInfo,
+ FontEntryPtr entry, char *fileName)
+{
+ FontFilePtr file;
+ int i;
+ int ret;
+ FontRendererPtr renderer;
+
+ renderer = FontFileMatchRenderer (fileName);
+ if (!renderer)
+ return BadFontName;
+ i = BitmapGetRenderIndex(renderer);
+ file = FontFileOpen (fileName);
+ if (!file)
+ return BadFontName;
+ ret = (*readers[i].ReadInfo) (pFontInfo, file);
+ FontFileClose (file);
+ return ret;
+}
+
+static FontRendererRec renderers[] = {
+#if XFONT_PCFFORMAT
+ { ".pcf", 4, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+ { ".pcf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# ifdef X_GZIP_FONT_COMPRESSION
+ { ".pcf.gz", 7,
+ BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { ".pcf.bz2", 8,
+ BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
+#endif
+#if XFONT_SNFFORMAT
+ { ".snf", 4, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+ { ".snf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# ifdef X_GZIP_FONT_COMPRESSION
+ { ".snf.gz", 7, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { ".snf.bz2", 8, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
+#endif
+#if XFONT_BDFFORMAT
+ { ".bdf", 4, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+ { ".bdf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# ifdef X_GZIP_FONT_COMPRESSION
+ { ".bdf.gz", 7, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
+# ifdef X_BZIP2_FONT_COMPRESSION
+ { ".bdf.bz2", 8, BitmapOpenBitmap, BitmapOpenScalable,
+ BitmapGetInfoBitmap, BitmapGetInfoScalable, 0,
+ CAPABILITIES },
+# endif
+#endif
+ { NULL, 0, NULL, 0, NULL, NULL, 0, 0 }
+};
+
+#define numRenderers (sizeof renderers / sizeof renderers[0] - 1)
+
+void
+BitmapRegisterFontFileFunctions (void)
+{
+ int i;
+
+ for (i = 0; i < numRenderers; i++)
+ FontFileRegisterRenderer (&renderers[i]);
+}
+
+/*
+ * compute offset into renderers array - used to find the font reader,
+ * the font info reader, and the bitmap scaling routine. All users
+ * of this routine must be kept in step with the renderer array.
+ */
+static int
+BitmapGetRenderIndex(FontRendererPtr renderer)
+{
+ return renderer - renderers;
+}
diff --git a/libXfont/src/bitmap/bitmaputil.c b/libXfont/src/bitmap/bitmaputil.c
index 0a1c87e73..c44bf9cae 100644
--- a/libXfont/src/bitmap/bitmaputil.c
+++ b/libXfont/src/bitmap/bitmaputil.c
@@ -1,229 +1,225 @@
-/*
-
-Copyright 1990, 1994, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <X11/fonts/fntfilst.h>
-#include <X11/fonts/bitmap.h>
-#include <X11/fonts/bdfint.h>
-
-#ifndef MAXSHORT
-#define MAXSHORT 32767
-#endif
-
-#ifndef MINSHORT
-#define MINSHORT -32768
-#endif
-
-static xCharInfo initMinMetrics = {
-MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, 0xFFFF};
-static xCharInfo initMaxMetrics = {
-MINSHORT, MINSHORT, MINSHORT, MINSHORT, MINSHORT, 0x0000};
-
-#define MINMAX(field,ci) \
- if (minbounds->field > (ci)->field) \
- minbounds->field = (ci)->field; \
- if (maxbounds->field < (ci)->field) \
- maxbounds->field = (ci)->field;
-
-#define COMPUTE_MINMAX(ci) \
- if ((ci)->ascent || (ci)->descent || \
- (ci)->leftSideBearing || (ci)->rightSideBearing || \
- (ci)->characterWidth) \
- { \
- MINMAX(ascent, (ci)); \
- MINMAX(descent, (ci)); \
- MINMAX(leftSideBearing, (ci)); \
- MINMAX(rightSideBearing, (ci)); \
- MINMAX(characterWidth, (ci)); \
- }
-
-void
-bitmapComputeFontBounds(FontPtr pFont)
-{
- BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
- int nchars;
- int r,
- c;
- CharInfoPtr ci;
- int maxOverlap;
- int overlap;
- xCharInfo *minbounds,
- *maxbounds;
- int i;
- int numneg = 0, numpos = 0;
-
- if (bitmapFont->bitmapExtra) {
- minbounds = &bitmapFont->bitmapExtra->info.minbounds;
- maxbounds = &bitmapFont->bitmapExtra->info.maxbounds;
- } else {
- minbounds = &pFont->info.minbounds;
- maxbounds = &pFont->info.maxbounds;
- }
- *minbounds = initMinMetrics;
- *maxbounds = initMaxMetrics;
- maxOverlap = MINSHORT;
- nchars = bitmapFont->num_chars;
- for (i = 0, ci = bitmapFont->metrics; i < nchars; i++, ci++) {
- COMPUTE_MINMAX(&ci->metrics);
- if (ci->metrics.characterWidth < 0)
- numneg++;
- else
- numpos++;
- minbounds->attributes &= ci->metrics.attributes;
- maxbounds->attributes |= ci->metrics.attributes;
- overlap = ci->metrics.rightSideBearing - ci->metrics.characterWidth;
- if (maxOverlap < overlap)
- maxOverlap = overlap;
- }
- if (bitmapFont->bitmapExtra) {
- if (numneg > numpos)
- bitmapFont->bitmapExtra->info.drawDirection = RightToLeft;
- else
- bitmapFont->bitmapExtra->info.drawDirection = LeftToRight;
- bitmapFont->bitmapExtra->info.maxOverlap = maxOverlap;
- minbounds = &pFont->info.minbounds;
- maxbounds = &pFont->info.maxbounds;
- *minbounds = initMinMetrics;
- *maxbounds = initMaxMetrics;
- i = 0;
- maxOverlap = MINSHORT;
- for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
- for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) {
- ci = ACCESSENCODING(bitmapFont->encoding, i);
- if (ci) {
- COMPUTE_MINMAX(&ci->metrics);
- if (ci->metrics.characterWidth < 0)
- numneg++;
- else
- numpos++;
- minbounds->attributes &= ci->metrics.attributes;
- maxbounds->attributes |= ci->metrics.attributes;
- overlap = ci->metrics.rightSideBearing -
- ci->metrics.characterWidth;
- if (maxOverlap < overlap)
- maxOverlap = overlap;
- }
- i++;
- }
- }
- }
- if (numneg > numpos)
- pFont->info.drawDirection = RightToLeft;
- else
- pFont->info.drawDirection = LeftToRight;
- pFont->info.maxOverlap = maxOverlap;
-}
-
-void
-bitmapComputeFontInkBounds(FontPtr pFont)
-{
- BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
- int nchars;
- int r,
- c;
- CharInfoPtr cit;
- xCharInfo *ci;
- int offset;
- xCharInfo *minbounds,
- *maxbounds;
- int i;
-
- if (!bitmapFont->ink_metrics) {
- if (bitmapFont->bitmapExtra) {
- bitmapFont->bitmapExtra->info.ink_minbounds = bitmapFont->bitmapExtra->info.minbounds;
- bitmapFont->bitmapExtra->info.ink_maxbounds = bitmapFont->bitmapExtra->info.maxbounds;
- }
- pFont->info.ink_minbounds = pFont->info.minbounds;
- pFont->info.ink_maxbounds = pFont->info.maxbounds;
- } else {
- if (bitmapFont->bitmapExtra) {
- minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds;
- maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds;
- } else {
- minbounds = &pFont->info.ink_minbounds;
- maxbounds = &pFont->info.ink_maxbounds;
- }
- *minbounds = initMinMetrics;
- *maxbounds = initMaxMetrics;
- nchars = bitmapFont->num_chars;
- for (i = 0, ci = bitmapFont->ink_metrics; i < nchars; i++, ci++) {
- COMPUTE_MINMAX(ci);
- minbounds->attributes &= ci->attributes;
- maxbounds->attributes |= ci->attributes;
- }
- if (bitmapFont->bitmapExtra) {
- minbounds = &pFont->info.ink_minbounds;
- maxbounds = &pFont->info.ink_maxbounds;
- *minbounds = initMinMetrics;
- *maxbounds = initMaxMetrics;
- i=0;
- for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
- for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) {
- cit = ACCESSENCODING(bitmapFont->encoding, i);
- if (cit) {
- offset = cit - bitmapFont->metrics;
- ci = &bitmapFont->ink_metrics[offset];
- COMPUTE_MINMAX(ci);
- minbounds->attributes &= ci->attributes;
- maxbounds->attributes |= ci->attributes;
- }
- i++;
- }
- }
- }
- }
-}
-
-Bool
-bitmapAddInkMetrics(FontPtr pFont)
-{
- BitmapFontPtr bitmapFont;
- int i;
-
- bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
- bitmapFont->ink_metrics = malloc(bitmapFont->num_chars * sizeof(xCharInfo));
- if (!bitmapFont->ink_metrics) {
- fprintf(stderr, "Error: Couldn't allocate ink_metrics (%d*%ld)\n",
- bitmapFont->num_chars, (unsigned long)sizeof(xCharInfo));
- return FALSE;
- }
- for (i = 0; i < bitmapFont->num_chars; i++)
- FontCharInkMetrics(pFont, &bitmapFont->metrics[i], &bitmapFont->ink_metrics[i]);
- pFont->info.inkMetrics = TRUE;
- return TRUE;
-}
-
-/* ARGSUSED */
-int
-bitmapComputeWeight(FontPtr pFont)
-{
- return 10;
-}
+/*
+
+Copyright 1990, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/bdfint.h>
+
+#define MAXSHORT 32767
+
+#define MINSHORT -32768
+
+static xCharInfo initMinMetrics = {
+MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, 0xFFFF};
+static xCharInfo initMaxMetrics = {
+MINSHORT, MINSHORT, MINSHORT, MINSHORT, MINSHORT, 0x0000};
+
+#define MINMAX(field,ci) \
+ if (minbounds->field > (ci)->field) \
+ minbounds->field = (ci)->field; \
+ if (maxbounds->field < (ci)->field) \
+ maxbounds->field = (ci)->field;
+
+#define COMPUTE_MINMAX(ci) \
+ if ((ci)->ascent || (ci)->descent || \
+ (ci)->leftSideBearing || (ci)->rightSideBearing || \
+ (ci)->characterWidth) \
+ { \
+ MINMAX(ascent, (ci)); \
+ MINMAX(descent, (ci)); \
+ MINMAX(leftSideBearing, (ci)); \
+ MINMAX(rightSideBearing, (ci)); \
+ MINMAX(characterWidth, (ci)); \
+ }
+
+void
+bitmapComputeFontBounds(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ int nchars;
+ int r,
+ c;
+ CharInfoPtr ci;
+ int maxOverlap;
+ int overlap;
+ xCharInfo *minbounds,
+ *maxbounds;
+ int i;
+ int numneg = 0, numpos = 0;
+
+ if (bitmapFont->bitmapExtra) {
+ minbounds = &bitmapFont->bitmapExtra->info.minbounds;
+ maxbounds = &bitmapFont->bitmapExtra->info.maxbounds;
+ } else {
+ minbounds = &pFont->info.minbounds;
+ maxbounds = &pFont->info.maxbounds;
+ }
+ *minbounds = initMinMetrics;
+ *maxbounds = initMaxMetrics;
+ maxOverlap = MINSHORT;
+ nchars = bitmapFont->num_chars;
+ for (i = 0, ci = bitmapFont->metrics; i < nchars; i++, ci++) {
+ COMPUTE_MINMAX(&ci->metrics);
+ if (ci->metrics.characterWidth < 0)
+ numneg++;
+ else
+ numpos++;
+ minbounds->attributes &= ci->metrics.attributes;
+ maxbounds->attributes |= ci->metrics.attributes;
+ overlap = ci->metrics.rightSideBearing - ci->metrics.characterWidth;
+ if (maxOverlap < overlap)
+ maxOverlap = overlap;
+ }
+ if (bitmapFont->bitmapExtra) {
+ if (numneg > numpos)
+ bitmapFont->bitmapExtra->info.drawDirection = RightToLeft;
+ else
+ bitmapFont->bitmapExtra->info.drawDirection = LeftToRight;
+ bitmapFont->bitmapExtra->info.maxOverlap = maxOverlap;
+ minbounds = &pFont->info.minbounds;
+ maxbounds = &pFont->info.maxbounds;
+ *minbounds = initMinMetrics;
+ *maxbounds = initMaxMetrics;
+ i = 0;
+ maxOverlap = MINSHORT;
+ for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
+ for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) {
+ ci = ACCESSENCODING(bitmapFont->encoding, i);
+ if (ci) {
+ COMPUTE_MINMAX(&ci->metrics);
+ if (ci->metrics.characterWidth < 0)
+ numneg++;
+ else
+ numpos++;
+ minbounds->attributes &= ci->metrics.attributes;
+ maxbounds->attributes |= ci->metrics.attributes;
+ overlap = ci->metrics.rightSideBearing -
+ ci->metrics.characterWidth;
+ if (maxOverlap < overlap)
+ maxOverlap = overlap;
+ }
+ i++;
+ }
+ }
+ }
+ if (numneg > numpos)
+ pFont->info.drawDirection = RightToLeft;
+ else
+ pFont->info.drawDirection = LeftToRight;
+ pFont->info.maxOverlap = maxOverlap;
+}
+
+void
+bitmapComputeFontInkBounds(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ int nchars;
+ int r,
+ c;
+ CharInfoPtr cit;
+ xCharInfo *ci;
+ int offset;
+ xCharInfo *minbounds,
+ *maxbounds;
+ int i;
+
+ if (!bitmapFont->ink_metrics) {
+ if (bitmapFont->bitmapExtra) {
+ bitmapFont->bitmapExtra->info.ink_minbounds = bitmapFont->bitmapExtra->info.minbounds;
+ bitmapFont->bitmapExtra->info.ink_maxbounds = bitmapFont->bitmapExtra->info.maxbounds;
+ }
+ pFont->info.ink_minbounds = pFont->info.minbounds;
+ pFont->info.ink_maxbounds = pFont->info.maxbounds;
+ } else {
+ if (bitmapFont->bitmapExtra) {
+ minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds;
+ maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds;
+ } else {
+ minbounds = &pFont->info.ink_minbounds;
+ maxbounds = &pFont->info.ink_maxbounds;
+ }
+ *minbounds = initMinMetrics;
+ *maxbounds = initMaxMetrics;
+ nchars = bitmapFont->num_chars;
+ for (i = 0, ci = bitmapFont->ink_metrics; i < nchars; i++, ci++) {
+ COMPUTE_MINMAX(ci);
+ minbounds->attributes &= ci->attributes;
+ maxbounds->attributes |= ci->attributes;
+ }
+ if (bitmapFont->bitmapExtra) {
+ minbounds = &pFont->info.ink_minbounds;
+ maxbounds = &pFont->info.ink_maxbounds;
+ *minbounds = initMinMetrics;
+ *maxbounds = initMaxMetrics;
+ i=0;
+ for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) {
+ for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) {
+ cit = ACCESSENCODING(bitmapFont->encoding, i);
+ if (cit) {
+ offset = cit - bitmapFont->metrics;
+ ci = &bitmapFont->ink_metrics[offset];
+ COMPUTE_MINMAX(ci);
+ minbounds->attributes &= ci->attributes;
+ maxbounds->attributes |= ci->attributes;
+ }
+ i++;
+ }
+ }
+ }
+ }
+}
+
+Bool
+bitmapAddInkMetrics(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont;
+ int i;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ bitmapFont->ink_metrics = malloc(bitmapFont->num_chars * sizeof(xCharInfo));
+ if (!bitmapFont->ink_metrics) {
+ fprintf(stderr, "Error: Couldn't allocate ink_metrics (%d*%ld)\n",
+ bitmapFont->num_chars, (unsigned long)sizeof(xCharInfo));
+ return FALSE;
+ }
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ FontCharInkMetrics(pFont, &bitmapFont->metrics[i], &bitmapFont->ink_metrics[i]);
+ pFont->info.inkMetrics = TRUE;
+ return TRUE;
+}
+
+/* ARGSUSED */
+int
+bitmapComputeWeight(FontPtr pFont)
+{
+ return 10;
+}
diff --git a/libXfont/src/bitmap/bitscale.c b/libXfont/src/bitmap/bitscale.c
index 50818c66e..a80f375a0 100644
--- a/libXfont/src/bitmap/bitscale.c
+++ b/libXfont/src/bitmap/bitscale.c
@@ -1,1688 +1,1692 @@
-/*
-
-Copyright 1991, 1994, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-/*
- * Author: Keith Packard, MIT X Consortium
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-/*
- * Translate monolithic #defines to modular definitions
- */
-
-#ifdef PCFFORMAT
-#define XFONT_PCFFORMAT 1
-#endif
-
-#ifdef SNFFORMAT
-#define XFONT_SNFFORMAT 1
-#endif
-
-#ifdef BDFFORMAT
-#define XFONT_BDFFORMAT 1
-#endif
-
-#include <X11/fonts/fntfilst.h>
-#include <X11/fonts/bitmap.h>
-#include <X11/fonts/fontutil.h>
-#include <math.h>
-
-#ifndef MAX
-#define MAX(a,b) (((a)>(b)) ? a : b)
-#endif
-
-/* Should get this from elsewhere */
-extern unsigned long serverGeneration;
-
-static void bitmapUnloadScalable (FontPtr pFont);
-static void ScaleBitmap ( FontPtr pFont, CharInfoPtr opci,
- CharInfoPtr pci, double *inv_xform,
- double widthMult, double heightMult );
-static FontPtr BitmapScaleBitmaps(FontPtr pf, FontPtr opf,
- double widthMult, double heightMult,
- FontScalablePtr vals);
-
-enum scaleType {
- atom, truncate_atom, pixel_size, point_size, resolution_x,
- resolution_y, average_width, scaledX, scaledY, unscaled, fontname,
- raw_ascent, raw_descent, raw_pixelsize, raw_pointsize,
- raw_average_width, uncomputed
-};
-
-typedef struct _fontProp {
- char *name;
- Atom atom;
- enum scaleType type;
-} fontProp;
-
-static FontEntryPtr FindBestToScale ( FontPathElementPtr fpe,
- FontEntryPtr entry,
- FontScalablePtr vals,
- FontScalablePtr best,
- double *dxp, double *dyp,
- double *sdxp, double *sdyp,
- FontPathElementPtr *fpep );
-
-static unsigned long bitscaleGeneration = 0; /* initialization flag */
-
-static fontProp fontNamePropTable[] = {
- { "FOUNDRY", 0, atom },
- { "FAMILY_NAME", 0, atom },
- { "WEIGHT_NAME", 0, atom },
- { "SLANT", 0, atom },
- { "SETWIDTH_NAME", 0, atom },
- { "ADD_STYLE_NAME", 0, atom },
- { "PIXEL_SIZE", 0, pixel_size },
- { "POINT_SIZE", 0, point_size },
- { "RESOLUTION_X", 0, resolution_x },
- { "RESOLUTION_Y", 0, resolution_y },
- { "SPACING", 0, atom },
- { "AVERAGE_WIDTH", 0, average_width },
- { "CHARSET_REGISTRY", 0, atom },
- { "CHARSET_ENCODING", 0, truncate_atom },
- { "FONT", 0, fontname },
- { "RAW_ASCENT", 0, raw_ascent },
- { "RAW_DESCENT", 0, raw_descent },
- { "RAW_PIXEL_SIZE", 0, raw_pixelsize },
- { "RAW_POINT_SIZE", 0, raw_pointsize },
- { "RAW_AVERAGE_WIDTH", 0, raw_average_width }
-};
-
-#define TRANSFORM_POINT(matrix, x, y, dest) \
- ((dest)[0] = (matrix)[0] * (x) + (matrix)[2] * (y), \
- (dest)[1] = (matrix)[1] * (x) + (matrix)[3] * (y))
-
-#define CHECK_EXTENT(lsb, rsb, desc, asc, data) \
- ((lsb) > (data)[0] ? (lsb) = (data)[0] : 0 , \
- (rsb) < (data)[0] ? (rsb) = (data)[0] : 0, \
- (-desc) > (data)[1] ? (desc) = -(data)[1] : 0 , \
- (asc) < (data)[1] ? (asc) = (data)[1] : 0)
-
-#define NPROPS (sizeof(fontNamePropTable) / sizeof(fontProp))
-
-/* Warning: order of the next two tables is critically interdependent.
- Location of "unscaled" properties at the end of fontPropTable[]
- is important. */
-
-static fontProp fontPropTable[] = {
- { "MIN_SPACE", 0, scaledX },
- { "NORM_SPACE", 0, scaledX },
- { "MAX_SPACE", 0, scaledX },
- { "END_SPACE", 0, scaledX },
- { "AVG_CAPITAL_WIDTH", 0, scaledX },
- { "AVG_LOWERCASE_WIDTH", 0, scaledX },
- { "QUAD_WIDTH", 0, scaledX },
- { "FIGURE_WIDTH", 0, scaledX },
- { "SUPERSCRIPT_X", 0, scaledX },
- { "SUPERSCRIPT_Y", 0, scaledY },
- { "SUBSCRIPT_X", 0, scaledX },
- { "SUBSCRIPT_Y", 0, scaledY },
- { "SUPERSCRIPT_SIZE", 0, scaledY },
- { "SUBSCRIPT_SIZE", 0, scaledY },
- { "SMALL_CAP_SIZE", 0, scaledY },
- { "UNDERLINE_POSITION", 0, scaledY },
- { "UNDERLINE_THICKNESS", 0, scaledY },
- { "STRIKEOUT_ASCENT", 0, scaledY },
- { "STRIKEOUT_DESCENT", 0, scaledY },
- { "CAP_HEIGHT", 0, scaledY },
- { "X_HEIGHT", 0, scaledY },
- { "ITALIC_ANGLE", 0, unscaled },
- { "RELATIVE_SETWIDTH", 0, unscaled },
- { "RELATIVE_WEIGHT", 0, unscaled },
- { "WEIGHT", 0, unscaled },
- { "DESTINATION", 0, unscaled },
- { "PCL_FONT_NAME", 0, unscaled },
- { "_ADOBE_POSTSCRIPT_FONTNAME", 0, unscaled }
-};
-
-static fontProp rawFontPropTable[] = {
- { "RAW_MIN_SPACE", 0, },
- { "RAW_NORM_SPACE", 0, },
- { "RAW_MAX_SPACE", 0, },
- { "RAW_END_SPACE", 0, },
- { "RAW_AVG_CAPITAL_WIDTH", 0, },
- { "RAW_AVG_LOWERCASE_WIDTH", 0, },
- { "RAW_QUAD_WIDTH", 0, },
- { "RAW_FIGURE_WIDTH", 0, },
- { "RAW_SUPERSCRIPT_X", 0, },
- { "RAW_SUPERSCRIPT_Y", 0, },
- { "RAW_SUBSCRIPT_X", 0, },
- { "RAW_SUBSCRIPT_Y", 0, },
- { "RAW_SUPERSCRIPT_SIZE", 0, },
- { "RAW_SUBSCRIPT_SIZE", 0, },
- { "RAW_SMALL_CAP_SIZE", 0, },
- { "RAW_UNDERLINE_POSITION", 0, },
- { "RAW_UNDERLINE_THICKNESS", 0, },
- { "RAW_STRIKEOUT_ASCENT", 0, },
- { "RAW_STRIKEOUT_DESCENT", 0, },
- { "RAW_CAP_HEIGHT", 0, },
- { "RAW_X_HEIGHT", 0, }
-};
-
-static void
-initFontPropTable(void)
-{
- int i;
- fontProp *t;
-
- i = sizeof(fontNamePropTable) / sizeof(fontProp);
- for (t = fontNamePropTable; i; i--, t++)
- t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
-
- i = sizeof(fontPropTable) / sizeof(fontProp);
- for (t = fontPropTable; i; i--, t++)
- t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
-
- i = sizeof(rawFontPropTable) / sizeof(fontProp);
- for (t = rawFontPropTable; i; i--, t++)
- t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
-}
-
-#if 0
-static FontEntryPtr
-GetScalableEntry (FontPathElementPtr fpe, FontNamePtr name)
-{
- FontDirectoryPtr dir;
-
- dir = (FontDirectoryPtr) fpe->private;
- return FontFileFindNameInDir (&dir->scalable, name);
-}
-#endif
-
-static double
-get_matrix_horizontal_component(double *matrix)
-{
- return hypot(matrix[0], matrix[1]);
-}
-
-static double
-get_matrix_vertical_component(double *matrix)
-{
- return hypot(matrix[2], matrix[3]);
-}
-
-
-static Bool
-ComputeScaleFactors(FontScalablePtr from, FontScalablePtr to,
- double *dx, double *dy, double *sdx, double *sdy,
- double *rescale_x)
-{
- double srcpixelset, destpixelset, srcpixel, destpixel;
-
- srcpixelset = get_matrix_horizontal_component(from->pixel_matrix);
- destpixelset = get_matrix_horizontal_component(to->pixel_matrix);
- srcpixel = get_matrix_vertical_component(from->pixel_matrix);
- destpixel = get_matrix_vertical_component(to->pixel_matrix);
-
- if (srcpixelset >= EPS)
- {
- *dx = destpixelset / srcpixelset;
- *sdx = 1000.0 / srcpixelset;
- }
- else
- *sdx = *dx = 0;
-
- *rescale_x = 1.0;
-
- /* If client specified a width, it overrides setsize; in this
- context, we interpret width as applying to the font before any
- rotation, even though that's not what is ultimately returned in
- the width field. */
- if (from->width > 0 && to->width > 0 && fabs(*dx) > EPS)
- {
- double rescale = (double)to->width / (double)from->width;
-
- /* If the client specified a transformation matrix, the rescaling
- for width does *not* override the setsize. Instead, just check
- for consistency between the setsize from the matrix and the
- setsize that would result from rescaling according to the width.
- This assumes (perhaps naively) that the width is correctly
- reported in the name. As an interesting side effect, this test
- may result in choosing a different source bitmap (one that
- scales consistently between the setsize *and* the width) than it
- would choose if a width were not specified. Sort of a hidden
- multiple-master functionality. */
- if ((to->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY ||
- (to->values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY)
- {
- /* Reject if resulting width difference is >= 1 pixel */
- if (fabs(rescale * from->width - *dx * from->width) >= 10)
- return FALSE;
- }
- else
- {
- *rescale_x = rescale/(*dx);
- *dx = rescale;
- }
- }
-
- if (srcpixel >= EPS)
- {
- *dy = destpixel / srcpixel;
- *sdy = 1000.0 / srcpixel;
- }
- else
- *sdy = *dy = 0;
-
- return TRUE;
-}
-
-/* favor enlargement over reduction because of aliasing resulting
- from reduction */
-#define SCORE(m,s) \
-if (m >= 1.0) { \
- if (m == 1.0) \
- score += (16 * s); \
- else if (m == 2.0) \
- score += (4 * s); \
- else \
- score += (int)(((double)(3 * s)) / m); \
-} else { \
- score += (int)(((double)(2 * s)) * m); \
-}
-
-/* don't need to favor enlargement when looking for bitmap that can
- be used unscalable */
-#define SCORE2(m,s) \
-if (m >= 1.0) \
- score += (int)(((double)(8 * s)) / m); \
-else \
- score += (int)(((double)(8 * s)) * m);
-
-static FontEntryPtr
-FindBestToScale(FontPathElementPtr fpe, FontEntryPtr entry,
- FontScalablePtr vals, FontScalablePtr best,
- double *dxp, double *dyp,
- double *sdxp, double *sdyp,
- FontPathElementPtr *fpep)
-{
- FontScalableRec temp;
- int source, i;
- int best_score, best_unscaled_score,
- score;
- double dx = 0.0, sdx = 0.0, dx_amount = 0.0,
- dy = 0.0, sdy = 0.0, dy_amount = 0.0,
- best_dx = 0.0, best_sdx = 0.0, best_dx_amount = 0.0,
- best_dy = 0.0, best_sdy = 0.0, best_dy_amount = 0.0,
- best_unscaled_sdx = 0.0, best_unscaled_sdy = 0.0,
- rescale_x = 0.0, best_rescale_x = 0.0,
- best_unscaled_rescale_x = 0.0;
- FontEntryPtr zero;
- FontNameRec zeroName;
- char zeroChars[MAXFONTNAMELEN];
- FontDirectoryPtr dir;
- FontScaledPtr scaled;
- FontScalableExtraPtr extra;
- FontScaledPtr best_scaled, best_unscaled;
- FontPathElementPtr best_fpe = NULL, best_unscaled_fpe = NULL;
- FontEntryPtr bitmap = NULL;
- FontEntryPtr result;
- int aliascount = 20;
- FontPathElementPtr bitmap_fpe = NULL;
- FontNameRec xlfdName;
-
- /* find the best match */
- rescale_x = 1.0;
- best_scaled = 0;
- best_score = 0;
- best_unscaled = 0;
- best_unscaled_score = -1;
- best_dx_amount = best_dy_amount = HUGE_VAL;
- memcpy (zeroChars, entry->name.name, entry->name.length);
- zeroChars[entry->name.length] = '\0';
- zeroName.name = zeroChars;
- FontParseXLFDName (zeroChars, &temp, FONT_XLFD_REPLACE_ZERO);
- zeroName.length = strlen (zeroChars);
- zeroName.ndashes = entry->name.ndashes;
- xlfdName.name = vals->xlfdName;
- xlfdName.length = strlen(xlfdName.name);
- xlfdName.ndashes = FontFileCountDashes(xlfdName.name, xlfdName.length);
- restart_bestscale_loop: ;
- /*
- * Look through all the registered bitmap sources for
- * the same zero name as ours; entries along that one
- * can be scaled as desired.
- */
- for (source = 0; source < FontFileBitmapSources.count; source++)
- {
- /* There might already be a bitmap that satisfies the request
- but didn't have a zero name that was found by the scalable
- font matching logic. Keep track if there is. */
- if (bitmap == NULL && vals->xlfdName != NULL)
- {
- bitmap_fpe = FontFileBitmapSources.fpe[source];
- dir = (FontDirectoryPtr) bitmap_fpe->private;
- bitmap = FontFileFindNameInDir (&dir->nonScalable, &xlfdName);
- if (bitmap && bitmap->type != FONT_ENTRY_BITMAP)
- {
- if (bitmap->type == FONT_ENTRY_ALIAS && aliascount > 0)
- {
- aliascount--;
- xlfdName.name = bitmap->u.alias.resolved;
- xlfdName.length = strlen(xlfdName.name);
- xlfdName.ndashes = FontFileCountDashes(xlfdName.name,
- xlfdName.length);
- bitmap = NULL;
- goto restart_bestscale_loop;
- }
- else
- bitmap = NULL;
- }
- }
-
- if (FontFileBitmapSources.fpe[source] == fpe)
- zero = entry;
- else
- {
- dir = (FontDirectoryPtr) FontFileBitmapSources.fpe[source]->private;
- zero = FontFileFindNameInDir (&dir->scalable, &zeroName);
- if (!zero)
- continue;
- }
- extra = zero->u.scalable.extra;
- for (i = 0; i < extra->numScaled; i++)
- {
- scaled = &extra->scaled[i];
- if (!scaled->bitmap)
- continue;
- if (!ComputeScaleFactors(&scaled->vals, vals, &dx, &dy, &sdx, &sdy,
- &rescale_x))
- continue;
- score = 0;
- dx_amount = dx;
- dy_amount = dy;
- SCORE(dy_amount, 10);
- SCORE(dx_amount, 1);
- if ((score > best_score) ||
- ((score == best_score) &&
- ((dy_amount < best_dy_amount) ||
- ((dy_amount == best_dy_amount) &&
- (dx_amount < best_dx_amount)))))
- {
- best_fpe = FontFileBitmapSources.fpe[source];
- best_scaled = scaled;
- best_score = score;
- best_dx = dx;
- best_dy = dy;
- best_sdx = sdx;
- best_sdy = sdy;
- best_dx_amount = dx_amount;
- best_dy_amount = dy_amount;
- best_rescale_x = rescale_x;
- }
- /* Is this font a candidate for use without ugly rescaling? */
- if (fabs(dx) > EPS && fabs(dy) > EPS &&
- fabs(vals->pixel_matrix[0] * rescale_x -
- scaled->vals.pixel_matrix[0]) < 1 &&
- fabs(vals->pixel_matrix[1] * rescale_x -
- scaled->vals.pixel_matrix[1]) < EPS &&
- fabs(vals->pixel_matrix[2] -
- scaled->vals.pixel_matrix[2]) < EPS &&
- fabs(vals->pixel_matrix[3] -
- scaled->vals.pixel_matrix[3]) < 1)
- {
- /* Yes. The pixel sizes are close on the diagonal and
- extremely close off the diagonal. */
- score = 0;
- SCORE2(vals->pixel_matrix[3] /
- scaled->vals.pixel_matrix[3], 10);
- SCORE2(vals->pixel_matrix[0] * rescale_x /
- scaled->vals.pixel_matrix[0], 1);
- if (score > best_unscaled_score)
- {
- best_unscaled_fpe = FontFileBitmapSources.fpe[source];
- best_unscaled = scaled;
- best_unscaled_sdx = sdx / dx;
- best_unscaled_sdy = sdy / dy;
- best_unscaled_score = score;
- best_unscaled_rescale_x = rescale_x;
- }
- }
- }
- }
- if (best_unscaled)
- {
- *best = best_unscaled->vals;
- *fpep = best_unscaled_fpe;
- *dxp = 1.0;
- *dyp = 1.0;
- *sdxp = best_unscaled_sdx;
- *sdyp = best_unscaled_sdy;
- rescale_x = best_unscaled_rescale_x;
- result = best_unscaled->bitmap;
- }
- else if (best_scaled)
- {
- *best = best_scaled->vals;
- *fpep = best_fpe;
- *dxp = best_dx;
- *dyp = best_dy;
- *sdxp = best_sdx;
- *sdyp = best_sdy;
- rescale_x = best_rescale_x;
- result = best_scaled->bitmap;
- }
- else
- result = NULL;
-
- if (bitmap != NULL && (result == NULL || *dxp != 1.0 || *dyp != 1.0))
- {
- *fpep = bitmap_fpe;
- FontParseXLFDName (bitmap->name.name, best, FONT_XLFD_REPLACE_NONE);
- if (ComputeScaleFactors(best, best, dxp, dyp, sdxp, sdyp, &rescale_x))
- result = bitmap;
- else
- result = NULL;
- }
-
- if (result && rescale_x != 1.0)
- {
- /* We have rescaled horizontally due to an XLFD width field. Change
- the matrix appropriately */
- vals->pixel_matrix[0] *= rescale_x;
- vals->pixel_matrix[1] *= rescale_x;
- vals->values_supplied = vals->values_supplied & ~POINTSIZE_MASK;
- /* Recompute and reround the FontScalablePtr values after
- rescaling for the new width. */
- FontFileCompleteXLFD(vals, vals);
- }
-
- return result;
-}
-
-static long
-doround(double x)
-{
- return (x >= 0) ? (long)(x + .5) : (long)(x - .5);
-}
-
-static int
-computeProps(FontPropPtr pf, char *wasStringProp,
- FontPropPtr npf, char *isStringProp,
- unsigned int nprops, double xfactor, double yfactor,
- double sXfactor, double sYfactor)
-{
- int n;
- int count;
- fontProp *t;
- double rawfactor = 0.0;
-
- for (count = 0; nprops > 0; nprops--, pf++, wasStringProp++) {
- n = sizeof(fontPropTable) / sizeof(fontProp);
- for (t = fontPropTable; n && (t->atom != pf->name); n--, t++);
- if (!n)
- continue;
-
- switch (t->type) {
- case scaledX:
- npf->value = doround(xfactor * (double)pf->value);
- rawfactor = sXfactor;
- break;
- case scaledY:
- npf->value = doround(yfactor * (double)pf->value);
- rawfactor = sYfactor;
- break;
- case unscaled:
- npf->value = pf->value;
- npf->name = pf->name;
- npf++;
- count++;
- *isStringProp++ = *wasStringProp;
- break;
- default:
- break;
- }
- if (t->type != unscaled)
- {
- npf->name = pf->name;
- npf++;
- count++;
- npf->value = doround(rawfactor * (double)pf->value);
- npf->name = rawFontPropTable[t - fontPropTable].atom;
- npf++;
- count++;
- *isStringProp++ = *wasStringProp;
- *isStringProp++ = *wasStringProp;
- }
- }
- return count;
-}
-
-
-static int
-ComputeScaledProperties(FontInfoPtr sourceFontInfo, /* the font to be scaled */
- char *name, /* name of resulting font */
- FontScalablePtr vals,
- double dx, double dy, /* scale factors in x and y */
- double sdx, double sdy, /* directions */
- long sWidth, /* 1000-pixel average width */
- FontPropPtr *pProps, /* returns properties;
- preallocated */
- char **pIsStringProp) /* return booleans;
- preallocated */
-{
- int n;
- char *ptr1 = NULL, *ptr2 = NULL;
- char *ptr3;
- FontPropPtr fp;
- fontProp *fpt;
- char *isStringProp;
- int nProps;
-
- if (bitscaleGeneration != serverGeneration) {
- initFontPropTable();
- bitscaleGeneration = serverGeneration;
- }
- nProps = NPROPS + 1 + sizeof(fontPropTable) / sizeof(fontProp) +
- sizeof(rawFontPropTable) / sizeof(fontProp);
- fp = malloc(sizeof(FontPropRec) * nProps);
- *pProps = fp;
- if (!fp) {
- fprintf(stderr, "Error: Couldn't allocate font properties (%ld*%d)\n",
- (unsigned long)sizeof(FontPropRec), nProps);
- return 1;
- }
- isStringProp = malloc (nProps);
- *pIsStringProp = isStringProp;
- if (!isStringProp)
- {
- fprintf(stderr, "Error: Couldn't allocate isStringProp (%d)\n", nProps);
- free (fp);
- return 1;
- }
- ptr2 = name;
- for (fpt = fontNamePropTable, n = NPROPS;
- n;
- fp++, fpt++, n--, isStringProp++)
- {
-
- if (*ptr2)
- {
- ptr1 = ptr2 + 1;
- if (!(ptr2 = strchr(ptr1, '-'))) ptr2 = strchr(ptr1, '\0');
- }
-
- *isStringProp = 0;
- switch (fpt->type) {
- case atom:
- fp->value = MakeAtom(ptr1, ptr2 - ptr1, TRUE);
- *isStringProp = 1;
- break;
- case truncate_atom:
- for (ptr3 = ptr1; *ptr3; ptr3++)
- if (*ptr3 == '[')
- break;
- if (!*ptr3) ptr3 = ptr2;
- fp->value = MakeAtom(ptr1, ptr3 - ptr1, TRUE);
- *isStringProp = 1;
- break;
- case pixel_size:
- fp->value = doround(vals->pixel_matrix[3]);
- break;
- case point_size:
- fp->value = doround(vals->point_matrix[3] * 10.0);
- break;
- case resolution_x:
- fp->value = vals->x;
- break;
- case resolution_y:
- fp->value = vals->y;
- break;
- case average_width:
- fp->value = vals->width;
- break;
- case fontname:
- fp->value = MakeAtom(name, strlen(name), TRUE);
- *isStringProp = 1;
- break;
- case raw_ascent:
- fp->value = sourceFontInfo->fontAscent * sdy;
- break;
- case raw_descent:
- fp->value = sourceFontInfo->fontDescent * sdy;
- break;
- case raw_pointsize:
- fp->value = (long)(72270.0 / (double)vals->y + .5);
- break;
- case raw_pixelsize:
- fp->value = 1000;
- break;
- case raw_average_width:
- fp->value = sWidth;
- break;
- default:
- break;
- }
- fp->name = fpt->atom;
- }
- n = NPROPS;
- n += computeProps(sourceFontInfo->props, sourceFontInfo->isStringProp,
- fp, isStringProp, sourceFontInfo->nprops, dx, dy,
- sdx, sdy);
- return n;
-}
-
-
-static int
-compute_xform_matrix(FontScalablePtr vals, double dx, double dy,
- double *xform, double *inv_xform,
- double *xmult, double *ymult)
-{
- double det;
- double pixel = get_matrix_vertical_component(vals->pixel_matrix);
- double pixelset = get_matrix_horizontal_component(vals->pixel_matrix);
-
- if (pixel < EPS || pixelset < EPS) return 0;
-
- /* Initialize the transformation matrix to the scaling factors */
- xform[0] = dx / pixelset;
- xform[1] = xform[2] = 0.0;
- xform[3] = dy / pixel;
-
-/* Inline matrix multiply -- somewhat ugly to minimize register usage */
-#define MULTIPLY_XFORM(a,b,c,d) \
-{ \
- register double aa = (a), bb = (b), cc = (c), dd = (d); \
- register double temp; \
- temp = aa * xform[0] + cc * xform[1]; \
- aa = aa * xform[2] + cc * xform[3]; \
- xform[1] = bb * xform[0] + dd * xform[1]; \
- xform[3] = bb * xform[2] + dd * xform[3]; \
- xform[0] = temp; \
- xform[2] = aa; \
-}
-
- /* Rescale the transformation matrix for size of source font */
- MULTIPLY_XFORM(vals->pixel_matrix[0],
- vals->pixel_matrix[1],
- vals->pixel_matrix[2],
- vals->pixel_matrix[3]);
-
- *xmult = xform[0];
- *ymult = xform[3];
-
-
- if (inv_xform == NULL) return 1;
-
- /* Compute the determinant for use in inverting the matrix. */
- det = xform[0] * xform[3] - xform[1] * xform[2];
-
- /* If the determinant is tiny or zero, give up */
- if (fabs(det) < EPS) return 0;
-
- /* Compute the inverse */
- inv_xform[0] = xform[3] / det;
- inv_xform[1] = -xform[1] / det;
- inv_xform[2] = -xform[2] / det;
- inv_xform[3] = xform[0] / det;
-
- return 1;
-}
-
-/*
- * ScaleFont
- * returns a pointer to the new scaled font, or NULL (due to AllocError).
- */
-static FontPtr
-ScaleFont(FontPtr opf, /* originating font */
- double widthMult, /* glyphs width scale factor */
- double heightMult, /* glyphs height scale factor */
- double sWidthMult, /* scalable glyphs width scale factor */
- double sHeightMult, /* scalable glyphs height scale factor */
- FontScalablePtr vals,
- double *newWidthMult, /* return: X component of glyphs width
- scale factor */
- double *newHeightMult, /* return: Y component of glyphs height
- scale factor */
- long *sWidth) /* return: average 1000-pixel width */
-{
- FontPtr pf;
- FontInfoPtr pfi,
- opfi;
- BitmapFontPtr bitmapFont,
- obitmapFont;
- CharInfoPtr pci,
- opci;
- int nchars = 0; /* how many characters in the font */
- int i;
- int firstCol, lastCol, firstRow, lastRow;
- double xform[4], inv_xform[4];
- double xmult, ymult;
- int totalwidth = 0, totalchars = 0;
-#define OLDINDEX(i) (((i)/(lastCol - firstCol + 1) + \
- firstRow - opf->info.firstRow) * \
- (opf->info.lastCol - opf->info.firstCol + 1) + \
- (i)%(lastCol - firstCol + 1) + \
- firstCol - opf->info.firstCol)
-
- *sWidth = 0;
-
- opfi = &opf->info;
- obitmapFont = (BitmapFontPtr) opf->fontPrivate;
-
- bitmapFont = 0;
- if (!(pf = CreateFontRec())) {
- fprintf(stderr, "Error: Couldn't allocate FontRec (%ld)\n",
- (unsigned long)sizeof(FontRec));
- goto bail;
- }
- pf->refcnt = 0;
- pf->bit = opf->bit;
- pf->byte = opf->byte;
- pf->glyph = opf->glyph;
- pf->scan = opf->scan;
-
- pf->get_glyphs = bitmapGetGlyphs;
- pf->get_metrics = bitmapGetMetrics;
- pf->unload_font = bitmapUnloadScalable;
- pf->unload_glyphs = NULL;
-
- pfi = &pf->info;
- *pfi = *opfi;
- /* If charset subsetting specified in vals, determine what our range
- needs to be for the output font */
- if (vals->nranges)
- {
- int i;
-
- pfi->allExist = 0;
- firstCol = 255;
- lastCol = 0;
- firstRow = 255;
- lastRow = 0;
-
- for (i = 0; i < vals->nranges; i++)
- {
- if (vals->ranges[i].min_char_high != vals->ranges[i].max_char_high)
- {
- firstCol = opfi->firstCol;
- lastCol = opfi->lastCol;
- }
- if (firstCol > vals->ranges[i].min_char_low)
- firstCol = vals->ranges[i].min_char_low;
- if (lastCol < vals->ranges[i].max_char_low)
- lastCol = vals->ranges[i].max_char_low;
- if (firstRow > vals->ranges[i].min_char_high)
- firstRow = vals->ranges[i].min_char_high;
- if (lastRow < vals->ranges[i].max_char_high)
- lastRow = vals->ranges[i].max_char_high;
- }
-
- if (firstCol > lastCol || firstRow > lastRow)
- goto bail;
-
- if (firstCol < opfi->firstCol)
- firstCol = opfi->firstCol;
- if (lastCol > opfi->lastCol)
- lastCol = opfi->lastCol;
- if (firstRow < opfi->firstRow)
- firstRow = opfi->firstRow;
- if (lastRow > opfi->lastRow)
- lastRow = opfi->lastRow;
- }
- else
- {
- firstCol = opfi->firstCol;
- lastCol = opfi->lastCol;
- firstRow = opfi->firstRow;
- lastRow = opfi->lastRow;
- }
-
- bitmapFont = malloc(sizeof(BitmapFontRec));
- if (!bitmapFont) {
- fprintf(stderr, "Error: Couldn't allocate bitmapFont (%ld)\n",
- (unsigned long)sizeof(BitmapFontRec));
- goto bail;
- }
- nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1);
- pfi->firstRow = firstRow;
- pfi->lastRow = lastRow;
- pfi->firstCol = firstCol;
- pfi->lastCol = lastCol;
- pf->fontPrivate = (pointer) bitmapFont;
- bitmapFont->version_num = obitmapFont->version_num;
- bitmapFont->num_chars = nchars;
- bitmapFont->num_tables = obitmapFont->num_tables;
- bitmapFont->metrics = 0;
- bitmapFont->ink_metrics = 0;
- bitmapFont->bitmaps = 0;
- bitmapFont->encoding = 0;
- bitmapFont->bitmapExtra = 0;
- bitmapFont->pDefault = 0;
- bitmapFont->metrics = malloc(nchars * sizeof(CharInfoRec));
- if (!bitmapFont->metrics) {
- fprintf(stderr, "Error: Couldn't allocate metrics (%d*%ld)\n",
- nchars, (unsigned long)sizeof(CharInfoRec));
- goto bail;
- }
- bitmapFont->encoding = calloc(NUM_SEGMENTS(nchars), sizeof(CharInfoPtr*));
- if (!bitmapFont->encoding) {
- fprintf(stderr, "Error: Couldn't allocate encoding (%d*%ld)\n",
- nchars, (unsigned long)sizeof(CharInfoPtr));
- goto bail;
- }
-
-#undef MAXSHORT
-#define MAXSHORT 32767
-#undef MINSHORT
-#define MINSHORT -32768
-
- pfi->anamorphic = FALSE;
- if (heightMult != widthMult)
- pfi->anamorphic = TRUE;
- pfi->cachable = TRUE;
-
- if (!compute_xform_matrix(vals, widthMult, heightMult, xform,
- inv_xform, &xmult, &ymult))
- goto bail;
-
- pfi->fontAscent = opfi->fontAscent * ymult;
- pfi->fontDescent = opfi->fontDescent * ymult;
-
- pfi->minbounds.leftSideBearing = MAXSHORT;
- pfi->minbounds.rightSideBearing = MAXSHORT;
- pfi->minbounds.ascent = MAXSHORT;
- pfi->minbounds.descent = MAXSHORT;
- pfi->minbounds.characterWidth = MAXSHORT;
- pfi->minbounds.attributes = MAXSHORT;
-
- pfi->maxbounds.leftSideBearing = MINSHORT;
- pfi->maxbounds.rightSideBearing = MINSHORT;
- pfi->maxbounds.ascent = MINSHORT;
- pfi->maxbounds.descent = MINSHORT;
- pfi->maxbounds.characterWidth = MINSHORT;
- pfi->maxbounds.attributes = MINSHORT;
-
- /* Compute the transformation and inverse transformation matrices.
- Can fail if the determinant is zero. */
-
- pci = bitmapFont->metrics;
- for (i = 0; i < nchars; i++)
- {
- if ((opci = ACCESSENCODING(obitmapFont->encoding,OLDINDEX(i))))
- {
- double newlsb, newrsb, newdesc, newasc, point[2];
-
-#define minchar(p) ((p).min_char_low + ((p).min_char_high << 8))
-#define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8))
-
- if (vals->nranges)
- {
- int row = i / (lastCol - firstCol + 1) + firstRow;
- int col = i % (lastCol - firstCol + 1) + firstCol;
- int ch = (row << 8) + col;
- int j;
- for (j = 0; j < vals->nranges; j++)
- if (ch >= minchar(vals->ranges[j]) &&
- ch <= maxchar(vals->ranges[j]))
- break;
- if (j == vals->nranges)
- {
- continue;
- }
- }
-
- if (opci->metrics.leftSideBearing == 0 &&
- opci->metrics.rightSideBearing == 0 &&
- opci->metrics.ascent == 0 &&
- opci->metrics.descent == 0 &&
- opci->metrics.characterWidth == 0)
- {
- continue;
- }
-
- if(!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
- bitmapFont->encoding[SEGMENT_MAJOR(i)]=
- calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr));
- if(!bitmapFont->encoding[SEGMENT_MAJOR(i)])
- goto bail;
- }
- ACCESSENCODINGL(bitmapFont->encoding, i) = pci;
-
- /* Compute new extents for this glyph */
- TRANSFORM_POINT(xform,
- opci->metrics.leftSideBearing,
- -opci->metrics.descent,
- point);
- newlsb = point[0];
- newrsb = newlsb;
- newdesc = -point[1];
- newasc = -newdesc;
- TRANSFORM_POINT(xform,
- opci->metrics.leftSideBearing,
- opci->metrics.ascent,
- point);
- CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
- TRANSFORM_POINT(xform,
- opci->metrics.rightSideBearing,
- -opci->metrics.descent,
- point);
- CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
- TRANSFORM_POINT(xform,
- opci->metrics.rightSideBearing,
- opci->metrics.ascent,
- point);
- CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
-
- pci->metrics.leftSideBearing = (int)floor(newlsb);
- pci->metrics.rightSideBearing = (int)floor(newrsb + .5);
- pci->metrics.descent = (int)ceil(newdesc);
- pci->metrics.ascent = (int)floor(newasc + .5);
- /* Accumulate total width of characters before transformation,
- to ascertain predominant direction of font. */
- totalwidth += opci->metrics.characterWidth;
- pci->metrics.characterWidth =
- doround((double)opci->metrics.characterWidth * xmult);
- pci->metrics.attributes =
- doround((double)opci->metrics.characterWidth * sWidthMult);
- if (!pci->metrics.characterWidth)
- {
- /* Since transformation may shrink width, height, and
- escapement to zero, make sure existing characters
- are not mistaken for undefined characters. */
-
- if (pci->metrics.rightSideBearing ==
- pci->metrics.leftSideBearing)
- pci->metrics.rightSideBearing++;
- if (pci->metrics.ascent == -pci->metrics.descent)
- pci->metrics.ascent++;
- }
-
- pci++;
- }
- }
-
-
- /*
- * For each character, set the per-character metrics, scale the glyph, and
- * check per-font minbounds and maxbounds character information.
- */
-
- pci = bitmapFont->metrics;
- for (i = 0; i < nchars; i++)
- {
- if ((pci = ACCESSENCODING(bitmapFont->encoding,i)) &&
- (opci = ACCESSENCODING(obitmapFont->encoding,OLDINDEX(i))))
- {
- totalchars++;
- *sWidth += abs((int)(INT16)pci->metrics.attributes);
-#define MINMAX(field) \
- if (pfi->minbounds.field > pci->metrics.field) \
- pfi->minbounds.field = pci->metrics.field; \
- if (pfi->maxbounds.field < pci->metrics.field) \
- pfi->maxbounds.field = pci->metrics.field
-
- MINMAX(leftSideBearing);
- MINMAX(rightSideBearing);
- MINMAX(ascent);
- MINMAX(descent);
- MINMAX(characterWidth);
-
- /* Hack: Cast attributes into a signed quantity. Tread lightly
- for now and don't go changing the global Xproto.h file */
- if ((INT16)pfi->minbounds.attributes >
- (INT16)pci->metrics.attributes)
- pfi->minbounds.attributes = pci->metrics.attributes;
- if ((INT16)pfi->maxbounds.attributes <
- (INT16)pci->metrics.attributes)
- pfi->maxbounds.attributes = pci->metrics.attributes;
-#undef MINMAX
- }
- }
- pfi->ink_minbounds = pfi->minbounds;
- pfi->ink_maxbounds = pfi->maxbounds;
- if (totalchars)
- {
- *sWidth = (*sWidth * 10 + totalchars / 2) / totalchars;
- if (totalwidth < 0)
- {
- /* Dominant direction is R->L */
- *sWidth = -*sWidth;
- }
-
- if (pfi->minbounds.characterWidth == pfi->maxbounds.characterWidth)
- vals->width = pfi->minbounds.characterWidth * 10;
- else
- vals->width = doround((double)*sWidth * vals->pixel_matrix[0] /
- 1000.0);
- }
- else
- {
- vals->width = 0;
- *sWidth = 0;
- }
- FontComputeInfoAccelerators (pfi);
-
- if (pfi->defaultCh != (unsigned short) NO_SUCH_CHAR) {
- unsigned int r,
- c,
- cols;
-
- r = pfi->defaultCh >> 8;
- c = pfi->defaultCh & 0xFF;
- if (pfi->firstRow <= r && r <= pfi->lastRow &&
- pfi->firstCol <= c && c <= pfi->lastCol) {
- cols = pfi->lastCol - pfi->firstCol + 1;
- r = r - pfi->firstRow;
- c = c - pfi->firstCol;
- bitmapFont->pDefault =
- ACCESSENCODING(bitmapFont->encoding, r * cols + c);
- }
- }
-
- *newWidthMult = xmult;
- *newHeightMult = ymult;
- return pf;
-bail:
- if (pf)
- free(pf);
- if (bitmapFont) {
- free(bitmapFont->metrics);
- free(bitmapFont->ink_metrics);
- free(bitmapFont->bitmaps);
- if(bitmapFont->encoding)
- for(i=0; i<NUM_SEGMENTS(nchars); i++)
- free(bitmapFont->encoding[i]);
- free(bitmapFont->encoding);
- }
- return NULL;
-}
-
-static void
-ScaleBitmap(FontPtr pFont, CharInfoPtr opci, CharInfoPtr pci,
- double *inv_xform, double widthMult, double heightMult)
-{
- register char *bitmap, /* The bits */
- *newBitmap;
- register int bpr, /* Padding information */
- newBpr;
- int width, /* Extents information */
- height,
- newWidth,
- newHeight;
- register int row, /* Loop variables */
- col;
- INT32 deltaX, /* Increments for resampling loop */
- deltaY;
- INT32 xValue, /* Subscripts for resampling loop */
- yValue;
- double point[2];
- unsigned char *char_grayscale = 0;
- INT32 *diffusion_workspace = NULL, *thisrow = NULL,
- *nextrow = NULL, pixmult = 0;
- int box_x = 0, box_y = 0;
-
- static unsigned char masklsb[] =
- { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 };
- static unsigned char maskmsb[] =
- { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };
- unsigned char *mask = (pFont->bit == LSBFirst ? masklsb : maskmsb);
-
-
- bitmap = opci->bits;
- newBitmap = pci->bits;
- width = GLYPHWIDTHPIXELS(opci);
- height = GLYPHHEIGHTPIXELS(opci);
- newWidth = GLYPHWIDTHPIXELS(pci);
- newHeight = GLYPHHEIGHTPIXELS(pci);
- if (!newWidth || !newHeight || !width || !height)
- return;
-
- bpr = BYTES_PER_ROW(width, pFont->glyph);
- newBpr = BYTES_PER_ROW(newWidth, pFont->glyph);
-
- if (widthMult > 0.0 && heightMult > 0.0 &&
- (widthMult < 1.0 || heightMult < 1.0))
- {
- /* We are reducing in one or both dimensions. In an attempt to
- reduce aliasing, we'll antialias by passing the original
- glyph through a low-pass box filter (which results in a
- grayscale image), then use error diffusion to create bitonal
- output in the resampling loop. */
-
- /* First compute the sizes of the box filter */
- widthMult = ceil(1.0 / widthMult);
- heightMult = ceil(1.0 / heightMult);
- box_x = width / 2;
- box_y = height / 2;
- if (widthMult < (double)box_x) box_x = (int)widthMult;
- if (heightMult < (double)box_y) box_y = (int)heightMult;
- /* The pixmult value (below) is used to darken the image before
- we perform error diffusion: a necessary concession to the
- fact that it's very difficult to generate readable halftoned
- glyphs. The degree of darkening is proportional to the size
- of the blurring filter, hence inversely proportional to the
- darkness of the lightest gray that results from antialiasing.
- The result is that characters that exercise this logic (those
- generated by reducing from a larger source font) tend to err
- on the side of being too bold instead of being too light to
- be readable. */
- pixmult = box_x * box_y * 192;
-
- if (box_x > 1 || box_y > 1)
- {
- /* Looks like we need to anti-alias. Create a workspace to
- contain the grayscale character plus an additional row and
- column for scratch */
- char_grayscale = malloc((width + 1) * (height + 1));
- if (char_grayscale)
- {
- diffusion_workspace = calloc((newWidth + 2) * 2, sizeof(int));
- if (!diffusion_workspace)
- {
- fprintf(stderr, "Warning: Couldn't allocate diffusion"
- " workspace (%ld)\n",
- (newWidth + 2) * 2 * (unsigned long)sizeof(int));
- free(char_grayscale);
- char_grayscale = (unsigned char *)0;
- }
- /* Initialize our error diffusion workspace for later use */
- thisrow = diffusion_workspace + 1;
- nextrow = diffusion_workspace + newWidth + 3;
- } else {
- fprintf(stderr, "Warning: Couldn't allocate character grayscale (%d)\n", (width + 1) * (height + 1));
- }
- }
- }
-
- if (char_grayscale)
- {
- /* We will be doing antialiasing. First copy the bitmap into
- our buffer, mapping input range [0,1] to output range
- [0,255]. */
- register unsigned char *srcptr, *dstptr;
- srcptr = (unsigned char *)bitmap;
- dstptr = char_grayscale;
- for (row = 0; row < height; row++)
- {
- for (col = 0; col < width; col++)
- *dstptr++ = (srcptr[col >> 3] & mask[col & 0x7]) ? 255 : 0;
- srcptr += bpr; /* On to next row of source */
- dstptr++; /* Skip scratch column in dest */
- }
- if (box_x > 1)
- {
- /* Our box filter has a width > 1... let's filter the rows */
-
- int right_width = box_x / 2;
- int left_width = box_x - right_width - 1;
-
- for (row = 0; row < height; row++)
- {
- int sum = 0;
- int left_size = 0, right_size = 0;
-
- srcptr = char_grayscale + (width + 1) * row;
- dstptr = char_grayscale + (width + 1) * height; /* scratch */
-
- /* We've computed the shape of our full box filter. Now
- compute the right-hand part of the moving sum */
- for (right_size = 0; right_size < right_width; right_size++)
- sum += srcptr[right_size];
-
- /* Now start moving the sum, growing the box filter, and
- dropping averages into our scratch buffer */
- for (left_size = 0; left_size < left_width; left_size++)
- {
- sum += srcptr[right_width];
- *dstptr++ = sum / (left_size + right_width + 1);
- srcptr++;
- }
-
- /* The box filter has reached full width... continue
- computation of moving average until the right side
- hits the wall. */
- for (col = left_size; col + right_size < width; col++)
- {
- sum += srcptr[right_width];
- *dstptr++ = sum / box_x;
- sum -= srcptr[-left_width];
- srcptr++;
- }
-
- /* Collapse the right side of the box filter */
- for (; right_size > 0; right_size--)
- {
- *dstptr++ = sum / (left_width + right_size);
- sum -= srcptr[-left_width];
- srcptr++;
- }
-
- /* Done with the row... copy dest back over source */
- memmove(char_grayscale + (width + 1) * row,
- char_grayscale + (width + 1) * height,
- width);
- }
- }
- if (box_y > 1)
- {
- /* Our box filter has a height > 1... let's filter the columns */
-
- int bottom_height = box_y / 2;
- int top_height = box_y - bottom_height - 1;
-
- for (col = 0; col < width; col++)
- {
- int sum = 0;
- int top_size = 0, bottom_size = 0;
-
- srcptr = char_grayscale + col;
- dstptr = char_grayscale + width; /* scratch */
-
- /* We've computed the shape of our full box filter. Now
- compute the bottom part of the moving sum */
- for (bottom_size = 0;
- bottom_size < bottom_height;
- bottom_size++)
- sum += srcptr[bottom_size * (width + 1)];
-
- /* Now start moving the sum, growing the box filter, and
- dropping averages into our scratch buffer */
- for (top_size = 0; top_size < top_height; top_size++)
- {
- sum += srcptr[bottom_height * (width + 1)];
- *dstptr = sum / (top_size + bottom_height + 1);
- dstptr += width + 1;
- srcptr += width + 1;
- }
-
- /* The box filter has reached full height... continue
- computation of moving average until the bottom
- hits the wall. */
- for (row = top_size; row + bottom_size < height; row++)
- {
- sum += srcptr[bottom_height * (width + 1)];
- *dstptr = sum / box_y;
- dstptr += width + 1;
- sum -= srcptr[-top_height * (width + 1)];
- srcptr += width + 1;
- }
-
- /* Collapse the bottom of the box filter */
- for (; bottom_size > 0; bottom_size--)
- {
- *dstptr = sum / (top_height + bottom_size);
- dstptr += width + 1;
- sum -= srcptr[-top_height * (width + 1)];
- srcptr += width + 1;
- }
-
- /* Done with the column... copy dest back over source */
-
- dstptr = char_grayscale + col;
- srcptr = char_grayscale + width; /* scratch */
- for (row = 0; row < height; row++)
- {
- *dstptr = *srcptr;
- dstptr += width + 1;
- srcptr += width + 1;
- }
- }
- }
-
- /* Increase the grayvalue to increase ink a bit */
- srcptr = char_grayscale;
- for (row = 0; row < height; row++)
- {
- for (col = 0; col < width; col++)
- {
- register int pixvalue = (int)*srcptr * pixmult / 256;
- if (pixvalue > 255) pixvalue = 255;
- *srcptr = pixvalue;
- srcptr++;
- }
- srcptr++;
- }
- }
-
- /* Compute the increment values for the resampling loop */
- TRANSFORM_POINT(inv_xform, 1, 0, point);
- deltaX = (INT32)(point[0] * 65536.0);
- deltaY = (INT32)(-point[1] * 65536.0);
-
- /* Resampling loop: resamples original glyph for generation of new
- glyph in transformed coordinate system. */
-
- for (row = 0; row < newHeight; row++)
- {
- /* Compute inverse transformation for start of this row */
- TRANSFORM_POINT(inv_xform,
- (double)(pci->metrics.leftSideBearing) + .5,
- (double)(pci->metrics.ascent - row) - .5,
- point);
-
- /* Adjust for coordinate system to get resampling point */
- point[0] -= opci->metrics.leftSideBearing;
- point[1] = opci->metrics.ascent - point[1];
-
- /* Convert to integer coordinates */
- xValue = (INT32)(point[0] * 65536.0);
- yValue = (INT32)(point[1] * 65536.0);
-
- if (char_grayscale)
- {
- INT32 *temp;
- for (col = 0; col < newWidth; col++)
- {
- register int x = xValue >> 16, y = yValue >> 16;
- int pixvalue, error;
-
- pixvalue = ((x >= 0 && x < width && y >= 0 && y < height) ?
- char_grayscale[x + y * (width + 1)] : 0) +
- thisrow[col] / 16;
- if (pixvalue > 255) pixvalue = 255;
- else if (pixvalue < 0) pixvalue = 0;
-
- /* Choose the bit value and set resulting error value */
- if (pixvalue >= 128)
- {
- newBitmap[(col >> 3) + row * newBpr] |= mask[col & 0x7];
- error = pixvalue - 255;
- }
- else
- error = -pixvalue;
-
- /* Diffuse the error */
- thisrow[col + 1] += error * 7;
- nextrow[col - 1] += error * 3;
- nextrow[col] += error * 5;
- nextrow[col + 1] = error;
-
- xValue += deltaX;
- yValue += deltaY;
- }
-
- /* Add in error values that fell off either end */
- nextrow[0] += nextrow[-1];
- nextrow[newWidth - 2] += thisrow[newWidth];
- nextrow[newWidth - 1] += nextrow[newWidth];
- nextrow[newWidth] = 0;
-
- temp = nextrow;
- nextrow = thisrow;
- thisrow = temp;
- nextrow[-1] = nextrow[0] = 0;
- }
- else
- {
- for (col = 0; col < newWidth; col++)
- {
- register int x = xValue >> 16, y = yValue >> 16;
-
- if (x >= 0 && x < width && y >= 0 && y < height)
- {
- /* Use point-sampling for rescaling. */
-
- if (bitmap[(x >> 3) + y * bpr] & mask[x & 0x7])
- newBitmap[(col >> 3) + row * newBpr] |= mask[col & 0x7];
- }
-
- xValue += deltaX;
- yValue += deltaY;
- }
- }
- }
-
-
- if (char_grayscale)
- {
- free(char_grayscale);
- free(diffusion_workspace);
- }
-}
-
-static FontPtr
-BitmapScaleBitmaps(FontPtr pf, /* scaled font */
- FontPtr opf, /* originating font */
- double widthMult, /* glyphs width scale factor */
- double heightMult, /* glyphs height scale factor */
- FontScalablePtr vals)
-{
- register int i;
- int nchars = 0;
- char *glyphBytes;
- BitmapFontPtr bitmapFont,
- obitmapFont;
- CharInfoPtr pci,
- opci;
- FontInfoPtr pfi;
- int glyph;
- unsigned bytestoalloc = 0;
- int firstCol, lastCol, firstRow, lastRow;
-
- double xform[4], inv_xform[4];
- double xmult, ymult;
-
- bitmapFont = (BitmapFontPtr) pf->fontPrivate;
- obitmapFont = (BitmapFontPtr) opf->fontPrivate;
-
- if (!compute_xform_matrix(vals, widthMult, heightMult, xform,
- inv_xform, &xmult, &ymult))
- goto bail;
-
- pfi = &pf->info;
- firstCol = pfi->firstCol;
- lastCol = pfi->lastCol;
- firstRow = pfi->firstRow;
- lastRow = pfi->lastRow;
-
- nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1);
- glyph = pf->glyph;
- for (i = 0; i < nchars; i++)
- {
- if ((pci = ACCESSENCODING(bitmapFont->encoding, i)))
- bytestoalloc += BYTES_FOR_GLYPH(pci, glyph);
- }
-
- /* Do we add the font malloc stuff for VALUE ADDED ? */
- /* Will need to remember to free in the Unload routine */
-
-
- bitmapFont->bitmaps = calloc(1, bytestoalloc);
- if (!bitmapFont->bitmaps) {
- fprintf(stderr, "Error: Couldn't allocate bitmaps (%d)\n", bytestoalloc);
- goto bail;
- }
-
- glyphBytes = bitmapFont->bitmaps;
- for (i = 0; i < nchars; i++)
- {
- if ((pci = ACCESSENCODING(bitmapFont->encoding, i)) &&
- (opci = ACCESSENCODING(obitmapFont->encoding, OLDINDEX(i))))
- {
- pci->bits = glyphBytes;
- ScaleBitmap (pf, opci, pci, inv_xform,
- widthMult, heightMult);
- glyphBytes += BYTES_FOR_GLYPH(pci, glyph);
- }
- }
- return pf;
-
-bail:
- if (pf)
- free(pf);
- if (bitmapFont) {
- free(bitmapFont->metrics);
- free(bitmapFont->ink_metrics);
- free(bitmapFont->bitmaps);
- if(bitmapFont->encoding)
- for(i=0; i<NUM_SEGMENTS(nchars); i++)
- free(bitmapFont->encoding[i]);
- free(bitmapFont->encoding);
- }
- return NULL;
-}
-
-/* ARGSUSED */
-int
-BitmapOpenScalable (FontPathElementPtr fpe,
- FontPtr *pFont,
- int flags,
- FontEntryPtr entry,
- char *fileName, /* unused */
- FontScalablePtr vals,
- fsBitmapFormat format,
- fsBitmapFormatMask fmask,
- FontPtr non_cachable_font) /* We don't do licensing */
-{
- FontScalableRec best;
- FontPtr font = NullFont;
- double dx, sdx,
- dy, sdy,
- savedX, savedY;
- FontPropPtr props;
- char *isStringProp = NULL;
- int propCount;
- int status;
- long sWidth;
-
- FontEntryPtr scaleFrom;
- FontPathElementPtr scaleFPE = NULL;
- FontPtr sourceFont;
- char fontName[MAXFONTNAMELEN];
-
- /* Can't deal with mix-endian fonts yet */
-
-
- /* Reject outrageously small font sizes to keep the math from
- blowing up. */
- if (get_matrix_vertical_component(vals->pixel_matrix) < 1.0 ||
- get_matrix_horizontal_component(vals->pixel_matrix) < 1.0)
- return BadFontName;
-
- scaleFrom = FindBestToScale(fpe, entry, vals, &best, &dx, &dy, &sdx, &sdy,
- &scaleFPE);
-
- if (!scaleFrom)
- return BadFontName;
-
- status = FontFileOpenBitmap(scaleFPE, &sourceFont, LoadAll, scaleFrom,
- format, fmask);
-
- if (status != Successful)
- return BadFontName;
-
- if (!vals->width)
- vals->width = best.width * dx;
-
- /* Compute the scaled font */
-
- savedX = dx;
- savedY = dy;
- font = ScaleFont(sourceFont, dx, dy, sdx, sdy, vals, &dx, &dy, &sWidth);
- if (font)
- font = BitmapScaleBitmaps(font, sourceFont, savedX, savedY, vals);
-
- if (!font)
- {
- if (!sourceFont->refcnt)
- FontFileCloseFont((FontPathElementPtr) 0, sourceFont);
- return AllocError;
- }
-
- /* Prepare font properties for the new font */
-
- strcpy (fontName, scaleFrom->name.name);
- FontParseXLFDName (fontName, vals, FONT_XLFD_REPLACE_VALUE);
-
- propCount = ComputeScaledProperties(&sourceFont->info, fontName, vals,
- dx, dy, sdx, sdy, sWidth, &props,
- &isStringProp);
-
- if (!sourceFont->refcnt)
- FontFileCloseFont((FontPathElementPtr) 0, sourceFont);
-
- font->info.props = props;
- font->info.nprops = propCount;
- font->info.isStringProp = isStringProp;
-
- if (propCount && (!props || !isStringProp))
- {
- bitmapUnloadScalable(font);
- return AllocError;
- }
-
- *pFont = font;
- return Successful;
-}
-
-int
-BitmapGetInfoScalable (FontPathElementPtr fpe,
- FontInfoPtr pFontInfo,
- FontEntryPtr entry,
- FontNamePtr fontName,
- char *fileName,
- FontScalablePtr vals)
-{
- FontPtr pfont;
- int flags = 0;
- long format = 0; /* It doesn't matter what format for just info */
- long fmask = 0;
- int ret;
-
- ret = BitmapOpenScalable(fpe, &pfont, flags, entry, fileName, vals,
- format, fmask, NULL);
- if (ret != Successful)
- return ret;
- *pFontInfo = pfont->info;
-
- pfont->info.nprops = 0;
- pfont->info.props = NULL;
- pfont->info.isStringProp = NULL;
-
- (*pfont->unload_font)(pfont);
- return Successful;
-}
-
-static void
-bitmapUnloadScalable (FontPtr pFont)
-{
- BitmapFontPtr bitmapFont;
- FontInfoPtr pfi;
- int i, nencoding;
-
- bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
- pfi = &pFont->info;
- free (pfi->props);
- free (pfi->isStringProp);
- if(bitmapFont->encoding) {
- nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
- (pFont->info.lastRow - pFont->info.firstRow + 1);
- for(i=0; i<NUM_SEGMENTS(nencoding); i++)
- free(bitmapFont->encoding[i]);
- }
- free (bitmapFont->encoding);
- free (bitmapFont->bitmaps);
- free (bitmapFont->ink_metrics);
- free (bitmapFont->metrics);
- free (pFont->fontPrivate);
- DestroyFontRec (pFont);
-}
+/*
+
+Copyright 1991, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * Translate monolithic #defines to modular definitions
+ */
+
+#ifdef PCFFORMAT
+#define XFONT_PCFFORMAT 1
+#endif
+
+#ifdef SNFFORMAT
+#define XFONT_SNFFORMAT 1
+#endif
+
+#ifdef BDFFORMAT
+#define XFONT_BDFFORMAT 1
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/fontutil.h>
+#include <math.h>
+
+#ifndef MAX
+#define MAX(a,b) (((a)>(b)) ? a : b)
+#endif
+
+#ifdef _MSC_VER
+#define hypot _hypot
+#endif
+
+/* Should get this from elsewhere */
+extern unsigned long serverGeneration;
+
+static void bitmapUnloadScalable (FontPtr pFont);
+static void ScaleBitmap ( FontPtr pFont, CharInfoPtr opci,
+ CharInfoPtr pci, double *inv_xform,
+ double widthMult, double heightMult );
+static FontPtr BitmapScaleBitmaps(FontPtr pf, FontPtr opf,
+ double widthMult, double heightMult,
+ FontScalablePtr vals);
+
+enum scaleType {
+ atom, truncate_atom, pixel_size, point_size, resolution_x,
+ resolution_y, average_width, scaledX, scaledY, unscaled, fontname,
+ raw_ascent, raw_descent, raw_pixelsize, raw_pointsize,
+ raw_average_width, uncomputed
+};
+
+typedef struct _fontProp {
+ char *name;
+ Atom atom;
+ enum scaleType type;
+} fontProp;
+
+static FontEntryPtr FindBestToScale ( FontPathElementPtr fpe,
+ FontEntryPtr entry,
+ FontScalablePtr vals,
+ FontScalablePtr best,
+ double *dxp, double *dyp,
+ double *sdxp, double *sdyp,
+ FontPathElementPtr *fpep );
+
+static unsigned long bitscaleGeneration = 0; /* initialization flag */
+
+static fontProp fontNamePropTable[] = {
+ { "FOUNDRY", 0, atom },
+ { "FAMILY_NAME", 0, atom },
+ { "WEIGHT_NAME", 0, atom },
+ { "SLANT", 0, atom },
+ { "SETWIDTH_NAME", 0, atom },
+ { "ADD_STYLE_NAME", 0, atom },
+ { "PIXEL_SIZE", 0, pixel_size },
+ { "POINT_SIZE", 0, point_size },
+ { "RESOLUTION_X", 0, resolution_x },
+ { "RESOLUTION_Y", 0, resolution_y },
+ { "SPACING", 0, atom },
+ { "AVERAGE_WIDTH", 0, average_width },
+ { "CHARSET_REGISTRY", 0, atom },
+ { "CHARSET_ENCODING", 0, truncate_atom },
+ { "FONT", 0, fontname },
+ { "RAW_ASCENT", 0, raw_ascent },
+ { "RAW_DESCENT", 0, raw_descent },
+ { "RAW_PIXEL_SIZE", 0, raw_pixelsize },
+ { "RAW_POINT_SIZE", 0, raw_pointsize },
+ { "RAW_AVERAGE_WIDTH", 0, raw_average_width }
+};
+
+#define TRANSFORM_POINT(matrix, x, y, dest) \
+ ((dest)[0] = (matrix)[0] * (x) + (matrix)[2] * (y), \
+ (dest)[1] = (matrix)[1] * (x) + (matrix)[3] * (y))
+
+#define CHECK_EXTENT(lsb, rsb, desc, asc, data) \
+ ((lsb) > (data)[0] ? (lsb) = (data)[0] : 0 , \
+ (rsb) < (data)[0] ? (rsb) = (data)[0] : 0, \
+ (-desc) > (data)[1] ? (desc) = -(data)[1] : 0 , \
+ (asc) < (data)[1] ? (asc) = (data)[1] : 0)
+
+#define NPROPS (sizeof(fontNamePropTable) / sizeof(fontProp))
+
+/* Warning: order of the next two tables is critically interdependent.
+ Location of "unscaled" properties at the end of fontPropTable[]
+ is important. */
+
+static fontProp fontPropTable[] = {
+ { "MIN_SPACE", 0, scaledX },
+ { "NORM_SPACE", 0, scaledX },
+ { "MAX_SPACE", 0, scaledX },
+ { "END_SPACE", 0, scaledX },
+ { "AVG_CAPITAL_WIDTH", 0, scaledX },
+ { "AVG_LOWERCASE_WIDTH", 0, scaledX },
+ { "QUAD_WIDTH", 0, scaledX },
+ { "FIGURE_WIDTH", 0, scaledX },
+ { "SUPERSCRIPT_X", 0, scaledX },
+ { "SUPERSCRIPT_Y", 0, scaledY },
+ { "SUBSCRIPT_X", 0, scaledX },
+ { "SUBSCRIPT_Y", 0, scaledY },
+ { "SUPERSCRIPT_SIZE", 0, scaledY },
+ { "SUBSCRIPT_SIZE", 0, scaledY },
+ { "SMALL_CAP_SIZE", 0, scaledY },
+ { "UNDERLINE_POSITION", 0, scaledY },
+ { "UNDERLINE_THICKNESS", 0, scaledY },
+ { "STRIKEOUT_ASCENT", 0, scaledY },
+ { "STRIKEOUT_DESCENT", 0, scaledY },
+ { "CAP_HEIGHT", 0, scaledY },
+ { "X_HEIGHT", 0, scaledY },
+ { "ITALIC_ANGLE", 0, unscaled },
+ { "RELATIVE_SETWIDTH", 0, unscaled },
+ { "RELATIVE_WEIGHT", 0, unscaled },
+ { "WEIGHT", 0, unscaled },
+ { "DESTINATION", 0, unscaled },
+ { "PCL_FONT_NAME", 0, unscaled },
+ { "_ADOBE_POSTSCRIPT_FONTNAME", 0, unscaled }
+};
+
+static fontProp rawFontPropTable[] = {
+ { "RAW_MIN_SPACE", 0, },
+ { "RAW_NORM_SPACE", 0, },
+ { "RAW_MAX_SPACE", 0, },
+ { "RAW_END_SPACE", 0, },
+ { "RAW_AVG_CAPITAL_WIDTH", 0, },
+ { "RAW_AVG_LOWERCASE_WIDTH", 0, },
+ { "RAW_QUAD_WIDTH", 0, },
+ { "RAW_FIGURE_WIDTH", 0, },
+ { "RAW_SUPERSCRIPT_X", 0, },
+ { "RAW_SUPERSCRIPT_Y", 0, },
+ { "RAW_SUBSCRIPT_X", 0, },
+ { "RAW_SUBSCRIPT_Y", 0, },
+ { "RAW_SUPERSCRIPT_SIZE", 0, },
+ { "RAW_SUBSCRIPT_SIZE", 0, },
+ { "RAW_SMALL_CAP_SIZE", 0, },
+ { "RAW_UNDERLINE_POSITION", 0, },
+ { "RAW_UNDERLINE_THICKNESS", 0, },
+ { "RAW_STRIKEOUT_ASCENT", 0, },
+ { "RAW_STRIKEOUT_DESCENT", 0, },
+ { "RAW_CAP_HEIGHT", 0, },
+ { "RAW_X_HEIGHT", 0, }
+};
+
+static void
+initFontPropTable(void)
+{
+ int i;
+ fontProp *t;
+
+ i = sizeof(fontNamePropTable) / sizeof(fontProp);
+ for (t = fontNamePropTable; i; i--, t++)
+ t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+
+ i = sizeof(fontPropTable) / sizeof(fontProp);
+ for (t = fontPropTable; i; i--, t++)
+ t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+
+ i = sizeof(rawFontPropTable) / sizeof(fontProp);
+ for (t = rawFontPropTable; i; i--, t++)
+ t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+}
+
+#if 0
+static FontEntryPtr
+GetScalableEntry (FontPathElementPtr fpe, FontNamePtr name)
+{
+ FontDirectoryPtr dir;
+
+ dir = (FontDirectoryPtr) fpe->private;
+ return FontFileFindNameInDir (&dir->scalable, name);
+}
+#endif
+
+static double
+get_matrix_horizontal_component(double *matrix)
+{
+ return hypot(matrix[0], matrix[1]);
+}
+
+static double
+get_matrix_vertical_component(double *matrix)
+{
+ return hypot(matrix[2], matrix[3]);
+}
+
+
+static Bool
+ComputeScaleFactors(FontScalablePtr from, FontScalablePtr to,
+ double *dx, double *dy, double *sdx, double *sdy,
+ double *rescale_x)
+{
+ double srcpixelset, destpixelset, srcpixel, destpixel;
+
+ srcpixelset = get_matrix_horizontal_component(from->pixel_matrix);
+ destpixelset = get_matrix_horizontal_component(to->pixel_matrix);
+ srcpixel = get_matrix_vertical_component(from->pixel_matrix);
+ destpixel = get_matrix_vertical_component(to->pixel_matrix);
+
+ if (srcpixelset >= EPS)
+ {
+ *dx = destpixelset / srcpixelset;
+ *sdx = 1000.0 / srcpixelset;
+ }
+ else
+ *sdx = *dx = 0;
+
+ *rescale_x = 1.0;
+
+ /* If client specified a width, it overrides setsize; in this
+ context, we interpret width as applying to the font before any
+ rotation, even though that's not what is ultimately returned in
+ the width field. */
+ if (from->width > 0 && to->width > 0 && fabs(*dx) > EPS)
+ {
+ double rescale = (double)to->width / (double)from->width;
+
+ /* If the client specified a transformation matrix, the rescaling
+ for width does *not* override the setsize. Instead, just check
+ for consistency between the setsize from the matrix and the
+ setsize that would result from rescaling according to the width.
+ This assumes (perhaps naively) that the width is correctly
+ reported in the name. As an interesting side effect, this test
+ may result in choosing a different source bitmap (one that
+ scales consistently between the setsize *and* the width) than it
+ would choose if a width were not specified. Sort of a hidden
+ multiple-master functionality. */
+ if ((to->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY ||
+ (to->values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY)
+ {
+ /* Reject if resulting width difference is >= 1 pixel */
+ if (fabs(rescale * from->width - *dx * from->width) >= 10)
+ return FALSE;
+ }
+ else
+ {
+ *rescale_x = rescale/(*dx);
+ *dx = rescale;
+ }
+ }
+
+ if (srcpixel >= EPS)
+ {
+ *dy = destpixel / srcpixel;
+ *sdy = 1000.0 / srcpixel;
+ }
+ else
+ *sdy = *dy = 0;
+
+ return TRUE;
+}
+
+/* favor enlargement over reduction because of aliasing resulting
+ from reduction */
+#define SCORE(m,s) \
+if (m >= 1.0) { \
+ if (m == 1.0) \
+ score += (16 * s); \
+ else if (m == 2.0) \
+ score += (4 * s); \
+ else \
+ score += (int)(((double)(3 * s)) / m); \
+} else { \
+ score += (int)(((double)(2 * s)) * m); \
+}
+
+/* don't need to favor enlargement when looking for bitmap that can
+ be used unscalable */
+#define SCORE2(m,s) \
+if (m >= 1.0) \
+ score += (int)(((double)(8 * s)) / m); \
+else \
+ score += (int)(((double)(8 * s)) * m);
+
+static FontEntryPtr
+FindBestToScale(FontPathElementPtr fpe, FontEntryPtr entry,
+ FontScalablePtr vals, FontScalablePtr best,
+ double *dxp, double *dyp,
+ double *sdxp, double *sdyp,
+ FontPathElementPtr *fpep)
+{
+ FontScalableRec temp;
+ int source, i;
+ int best_score, best_unscaled_score,
+ score;
+ double dx = 0.0, sdx = 0.0, dx_amount = 0.0,
+ dy = 0.0, sdy = 0.0, dy_amount = 0.0,
+ best_dx = 0.0, best_sdx = 0.0, best_dx_amount = 0.0,
+ best_dy = 0.0, best_sdy = 0.0, best_dy_amount = 0.0,
+ best_unscaled_sdx = 0.0, best_unscaled_sdy = 0.0,
+ rescale_x = 0.0, best_rescale_x = 0.0,
+ best_unscaled_rescale_x = 0.0;
+ FontEntryPtr zero;
+ FontNameRec zeroName;
+ char zeroChars[MAXFONTNAMELEN];
+ FontDirectoryPtr dir;
+ FontScaledPtr scaled;
+ FontScalableExtraPtr extra;
+ FontScaledPtr best_scaled, best_unscaled;
+ FontPathElementPtr best_fpe = NULL, best_unscaled_fpe = NULL;
+ FontEntryPtr bitmap = NULL;
+ FontEntryPtr result;
+ int aliascount = 20;
+ FontPathElementPtr bitmap_fpe = NULL;
+ FontNameRec xlfdName;
+
+ /* find the best match */
+ rescale_x = 1.0;
+ best_scaled = 0;
+ best_score = 0;
+ best_unscaled = 0;
+ best_unscaled_score = -1;
+ best_dx_amount = best_dy_amount = HUGE_VAL;
+ memcpy (zeroChars, entry->name.name, entry->name.length);
+ zeroChars[entry->name.length] = '\0';
+ zeroName.name = zeroChars;
+ FontParseXLFDName (zeroChars, &temp, FONT_XLFD_REPLACE_ZERO);
+ zeroName.length = strlen (zeroChars);
+ zeroName.ndashes = entry->name.ndashes;
+ xlfdName.name = vals->xlfdName;
+ xlfdName.length = strlen(xlfdName.name);
+ xlfdName.ndashes = FontFileCountDashes(xlfdName.name, xlfdName.length);
+ restart_bestscale_loop: ;
+ /*
+ * Look through all the registered bitmap sources for
+ * the same zero name as ours; entries along that one
+ * can be scaled as desired.
+ */
+ for (source = 0; source < FontFileBitmapSources.count; source++)
+ {
+ /* There might already be a bitmap that satisfies the request
+ but didn't have a zero name that was found by the scalable
+ font matching logic. Keep track if there is. */
+ if (bitmap == NULL && vals->xlfdName != NULL)
+ {
+ bitmap_fpe = FontFileBitmapSources.fpe[source];
+ dir = (FontDirectoryPtr) bitmap_fpe->private;
+ bitmap = FontFileFindNameInDir (&dir->nonScalable, &xlfdName);
+ if (bitmap && bitmap->type != FONT_ENTRY_BITMAP)
+ {
+ if (bitmap->type == FONT_ENTRY_ALIAS && aliascount > 0)
+ {
+ aliascount--;
+ xlfdName.name = bitmap->u.alias.resolved;
+ xlfdName.length = strlen(xlfdName.name);
+ xlfdName.ndashes = FontFileCountDashes(xlfdName.name,
+ xlfdName.length);
+ bitmap = NULL;
+ goto restart_bestscale_loop;
+ }
+ else
+ bitmap = NULL;
+ }
+ }
+
+ if (FontFileBitmapSources.fpe[source] == fpe)
+ zero = entry;
+ else
+ {
+ dir = (FontDirectoryPtr) FontFileBitmapSources.fpe[source]->private;
+ zero = FontFileFindNameInDir (&dir->scalable, &zeroName);
+ if (!zero)
+ continue;
+ }
+ extra = zero->u.scalable.extra;
+ for (i = 0; i < extra->numScaled; i++)
+ {
+ scaled = &extra->scaled[i];
+ if (!scaled->bitmap)
+ continue;
+ if (!ComputeScaleFactors(&scaled->vals, vals, &dx, &dy, &sdx, &sdy,
+ &rescale_x))
+ continue;
+ score = 0;
+ dx_amount = dx;
+ dy_amount = dy;
+ SCORE(dy_amount, 10);
+ SCORE(dx_amount, 1);
+ if ((score > best_score) ||
+ ((score == best_score) &&
+ ((dy_amount < best_dy_amount) ||
+ ((dy_amount == best_dy_amount) &&
+ (dx_amount < best_dx_amount)))))
+ {
+ best_fpe = FontFileBitmapSources.fpe[source];
+ best_scaled = scaled;
+ best_score = score;
+ best_dx = dx;
+ best_dy = dy;
+ best_sdx = sdx;
+ best_sdy = sdy;
+ best_dx_amount = dx_amount;
+ best_dy_amount = dy_amount;
+ best_rescale_x = rescale_x;
+ }
+ /* Is this font a candidate for use without ugly rescaling? */
+ if (fabs(dx) > EPS && fabs(dy) > EPS &&
+ fabs(vals->pixel_matrix[0] * rescale_x -
+ scaled->vals.pixel_matrix[0]) < 1 &&
+ fabs(vals->pixel_matrix[1] * rescale_x -
+ scaled->vals.pixel_matrix[1]) < EPS &&
+ fabs(vals->pixel_matrix[2] -
+ scaled->vals.pixel_matrix[2]) < EPS &&
+ fabs(vals->pixel_matrix[3] -
+ scaled->vals.pixel_matrix[3]) < 1)
+ {
+ /* Yes. The pixel sizes are close on the diagonal and
+ extremely close off the diagonal. */
+ score = 0;
+ SCORE2(vals->pixel_matrix[3] /
+ scaled->vals.pixel_matrix[3], 10);
+ SCORE2(vals->pixel_matrix[0] * rescale_x /
+ scaled->vals.pixel_matrix[0], 1);
+ if (score > best_unscaled_score)
+ {
+ best_unscaled_fpe = FontFileBitmapSources.fpe[source];
+ best_unscaled = scaled;
+ best_unscaled_sdx = sdx / dx;
+ best_unscaled_sdy = sdy / dy;
+ best_unscaled_score = score;
+ best_unscaled_rescale_x = rescale_x;
+ }
+ }
+ }
+ }
+ if (best_unscaled)
+ {
+ *best = best_unscaled->vals;
+ *fpep = best_unscaled_fpe;
+ *dxp = 1.0;
+ *dyp = 1.0;
+ *sdxp = best_unscaled_sdx;
+ *sdyp = best_unscaled_sdy;
+ rescale_x = best_unscaled_rescale_x;
+ result = best_unscaled->bitmap;
+ }
+ else if (best_scaled)
+ {
+ *best = best_scaled->vals;
+ *fpep = best_fpe;
+ *dxp = best_dx;
+ *dyp = best_dy;
+ *sdxp = best_sdx;
+ *sdyp = best_sdy;
+ rescale_x = best_rescale_x;
+ result = best_scaled->bitmap;
+ }
+ else
+ result = NULL;
+
+ if (bitmap != NULL && (result == NULL || *dxp != 1.0 || *dyp != 1.0))
+ {
+ *fpep = bitmap_fpe;
+ FontParseXLFDName (bitmap->name.name, best, FONT_XLFD_REPLACE_NONE);
+ if (ComputeScaleFactors(best, best, dxp, dyp, sdxp, sdyp, &rescale_x))
+ result = bitmap;
+ else
+ result = NULL;
+ }
+
+ if (result && rescale_x != 1.0)
+ {
+ /* We have rescaled horizontally due to an XLFD width field. Change
+ the matrix appropriately */
+ vals->pixel_matrix[0] *= rescale_x;
+ vals->pixel_matrix[1] *= rescale_x;
+ vals->values_supplied = vals->values_supplied & ~POINTSIZE_MASK;
+ /* Recompute and reround the FontScalablePtr values after
+ rescaling for the new width. */
+ FontFileCompleteXLFD(vals, vals);
+ }
+
+ return result;
+}
+
+static long
+doround(double x)
+{
+ return (x >= 0) ? (long)(x + .5) : (long)(x - .5);
+}
+
+static int
+computeProps(FontPropPtr pf, char *wasStringProp,
+ FontPropPtr npf, char *isStringProp,
+ unsigned int nprops, double xfactor, double yfactor,
+ double sXfactor, double sYfactor)
+{
+ int n;
+ int count;
+ fontProp *t;
+ double rawfactor = 0.0;
+
+ for (count = 0; nprops > 0; nprops--, pf++, wasStringProp++) {
+ n = sizeof(fontPropTable) / sizeof(fontProp);
+ for (t = fontPropTable; n && (t->atom != pf->name); n--, t++);
+ if (!n)
+ continue;
+
+ switch (t->type) {
+ case scaledX:
+ npf->value = doround(xfactor * (double)pf->value);
+ rawfactor = sXfactor;
+ break;
+ case scaledY:
+ npf->value = doround(yfactor * (double)pf->value);
+ rawfactor = sYfactor;
+ break;
+ case unscaled:
+ npf->value = pf->value;
+ npf->name = pf->name;
+ npf++;
+ count++;
+ *isStringProp++ = *wasStringProp;
+ break;
+ default:
+ break;
+ }
+ if (t->type != unscaled)
+ {
+ npf->name = pf->name;
+ npf++;
+ count++;
+ npf->value = doround(rawfactor * (double)pf->value);
+ npf->name = rawFontPropTable[t - fontPropTable].atom;
+ npf++;
+ count++;
+ *isStringProp++ = *wasStringProp;
+ *isStringProp++ = *wasStringProp;
+ }
+ }
+ return count;
+}
+
+
+static int
+ComputeScaledProperties(FontInfoPtr sourceFontInfo, /* the font to be scaled */
+ char *name, /* name of resulting font */
+ FontScalablePtr vals,
+ double dx, double dy, /* scale factors in x and y */
+ double sdx, double sdy, /* directions */
+ long sWidth, /* 1000-pixel average width */
+ FontPropPtr *pProps, /* returns properties;
+ preallocated */
+ char **pIsStringProp) /* return booleans;
+ preallocated */
+{
+ int n;
+ char *ptr1 = NULL, *ptr2 = NULL;
+ char *ptr3;
+ FontPropPtr fp;
+ fontProp *fpt;
+ char *isStringProp;
+ int nProps;
+
+ if (bitscaleGeneration != serverGeneration) {
+ initFontPropTable();
+ bitscaleGeneration = serverGeneration;
+ }
+ nProps = NPROPS + 1 + sizeof(fontPropTable) / sizeof(fontProp) +
+ sizeof(rawFontPropTable) / sizeof(fontProp);
+ fp = malloc(sizeof(FontPropRec) * nProps);
+ *pProps = fp;
+ if (!fp) {
+ fprintf(stderr, "Error: Couldn't allocate font properties (%ld*%d)\n",
+ (unsigned long)sizeof(FontPropRec), nProps);
+ return 1;
+ }
+ isStringProp = malloc (nProps);
+ *pIsStringProp = isStringProp;
+ if (!isStringProp)
+ {
+ fprintf(stderr, "Error: Couldn't allocate isStringProp (%d)\n", nProps);
+ free (fp);
+ return 1;
+ }
+ ptr2 = name;
+ for (fpt = fontNamePropTable, n = NPROPS;
+ n;
+ fp++, fpt++, n--, isStringProp++)
+ {
+
+ if (*ptr2)
+ {
+ ptr1 = ptr2 + 1;
+ if (!(ptr2 = strchr(ptr1, '-'))) ptr2 = strchr(ptr1, '\0');
+ }
+
+ *isStringProp = 0;
+ switch (fpt->type) {
+ case atom:
+ fp->value = MakeAtom(ptr1, ptr2 - ptr1, TRUE);
+ *isStringProp = 1;
+ break;
+ case truncate_atom:
+ for (ptr3 = ptr1; *ptr3; ptr3++)
+ if (*ptr3 == '[')
+ break;
+ if (!*ptr3) ptr3 = ptr2;
+ fp->value = MakeAtom(ptr1, ptr3 - ptr1, TRUE);
+ *isStringProp = 1;
+ break;
+ case pixel_size:
+ fp->value = doround(vals->pixel_matrix[3]);
+ break;
+ case point_size:
+ fp->value = doround(vals->point_matrix[3] * 10.0);
+ break;
+ case resolution_x:
+ fp->value = vals->x;
+ break;
+ case resolution_y:
+ fp->value = vals->y;
+ break;
+ case average_width:
+ fp->value = vals->width;
+ break;
+ case fontname:
+ fp->value = MakeAtom(name, strlen(name), TRUE);
+ *isStringProp = 1;
+ break;
+ case raw_ascent:
+ fp->value = sourceFontInfo->fontAscent * sdy;
+ break;
+ case raw_descent:
+ fp->value = sourceFontInfo->fontDescent * sdy;
+ break;
+ case raw_pointsize:
+ fp->value = (long)(72270.0 / (double)vals->y + .5);
+ break;
+ case raw_pixelsize:
+ fp->value = 1000;
+ break;
+ case raw_average_width:
+ fp->value = sWidth;
+ break;
+ default:
+ break;
+ }
+ fp->name = fpt->atom;
+ }
+ n = NPROPS;
+ n += computeProps(sourceFontInfo->props, sourceFontInfo->isStringProp,
+ fp, isStringProp, sourceFontInfo->nprops, dx, dy,
+ sdx, sdy);
+ return n;
+}
+
+
+static int
+compute_xform_matrix(FontScalablePtr vals, double dx, double dy,
+ double *xform, double *inv_xform,
+ double *xmult, double *ymult)
+{
+ double det;
+ double pixel = get_matrix_vertical_component(vals->pixel_matrix);
+ double pixelset = get_matrix_horizontal_component(vals->pixel_matrix);
+
+ if (pixel < EPS || pixelset < EPS) return 0;
+
+ /* Initialize the transformation matrix to the scaling factors */
+ xform[0] = dx / pixelset;
+ xform[1] = xform[2] = 0.0;
+ xform[3] = dy / pixel;
+
+/* Inline matrix multiply -- somewhat ugly to minimize register usage */
+#define MULTIPLY_XFORM(a,b,c,d) \
+{ \
+ register double aa = (a), bb = (b), cc = (c), dd = (d); \
+ register double temp; \
+ temp = aa * xform[0] + cc * xform[1]; \
+ aa = aa * xform[2] + cc * xform[3]; \
+ xform[1] = bb * xform[0] + dd * xform[1]; \
+ xform[3] = bb * xform[2] + dd * xform[3]; \
+ xform[0] = temp; \
+ xform[2] = aa; \
+}
+
+ /* Rescale the transformation matrix for size of source font */
+ MULTIPLY_XFORM(vals->pixel_matrix[0],
+ vals->pixel_matrix[1],
+ vals->pixel_matrix[2],
+ vals->pixel_matrix[3]);
+
+ *xmult = xform[0];
+ *ymult = xform[3];
+
+
+ if (inv_xform == NULL) return 1;
+
+ /* Compute the determinant for use in inverting the matrix. */
+ det = xform[0] * xform[3] - xform[1] * xform[2];
+
+ /* If the determinant is tiny or zero, give up */
+ if (fabs(det) < EPS) return 0;
+
+ /* Compute the inverse */
+ inv_xform[0] = xform[3] / det;
+ inv_xform[1] = -xform[1] / det;
+ inv_xform[2] = -xform[2] / det;
+ inv_xform[3] = xform[0] / det;
+
+ return 1;
+}
+
+/*
+ * ScaleFont
+ * returns a pointer to the new scaled font, or NULL (due to AllocError).
+ */
+static FontPtr
+ScaleFont(FontPtr opf, /* originating font */
+ double widthMult, /* glyphs width scale factor */
+ double heightMult, /* glyphs height scale factor */
+ double sWidthMult, /* scalable glyphs width scale factor */
+ double sHeightMult, /* scalable glyphs height scale factor */
+ FontScalablePtr vals,
+ double *newWidthMult, /* return: X component of glyphs width
+ scale factor */
+ double *newHeightMult, /* return: Y component of glyphs height
+ scale factor */
+ long *sWidth) /* return: average 1000-pixel width */
+{
+ FontPtr pf;
+ FontInfoPtr pfi,
+ opfi;
+ BitmapFontPtr bitmapFont,
+ obitmapFont;
+ CharInfoPtr pci,
+ opci;
+ int nchars = 0; /* how many characters in the font */
+ int i;
+ int firstCol, lastCol, firstRow, lastRow;
+ double xform[4], inv_xform[4];
+ double xmult, ymult;
+ int totalwidth = 0, totalchars = 0;
+#define OLDINDEX(i) (((i)/(lastCol - firstCol + 1) + \
+ firstRow - opf->info.firstRow) * \
+ (opf->info.lastCol - opf->info.firstCol + 1) + \
+ (i)%(lastCol - firstCol + 1) + \
+ firstCol - opf->info.firstCol)
+
+ *sWidth = 0;
+
+ opfi = &opf->info;
+ obitmapFont = (BitmapFontPtr) opf->fontPrivate;
+
+ bitmapFont = 0;
+ if (!(pf = CreateFontRec())) {
+ fprintf(stderr, "Error: Couldn't allocate FontRec (%ld)\n",
+ (unsigned long)sizeof(FontRec));
+ goto bail;
+ }
+ pf->refcnt = 0;
+ pf->bit = opf->bit;
+ pf->byte = opf->byte;
+ pf->glyph = opf->glyph;
+ pf->scan = opf->scan;
+
+ pf->get_glyphs = bitmapGetGlyphs;
+ pf->get_metrics = bitmapGetMetrics;
+ pf->unload_font = bitmapUnloadScalable;
+ pf->unload_glyphs = NULL;
+
+ pfi = &pf->info;
+ *pfi = *opfi;
+ /* If charset subsetting specified in vals, determine what our range
+ needs to be for the output font */
+ if (vals->nranges)
+ {
+ int i;
+
+ pfi->allExist = 0;
+ firstCol = 255;
+ lastCol = 0;
+ firstRow = 255;
+ lastRow = 0;
+
+ for (i = 0; i < vals->nranges; i++)
+ {
+ if (vals->ranges[i].min_char_high != vals->ranges[i].max_char_high)
+ {
+ firstCol = opfi->firstCol;
+ lastCol = opfi->lastCol;
+ }
+ if (firstCol > vals->ranges[i].min_char_low)
+ firstCol = vals->ranges[i].min_char_low;
+ if (lastCol < vals->ranges[i].max_char_low)
+ lastCol = vals->ranges[i].max_char_low;
+ if (firstRow > vals->ranges[i].min_char_high)
+ firstRow = vals->ranges[i].min_char_high;
+ if (lastRow < vals->ranges[i].max_char_high)
+ lastRow = vals->ranges[i].max_char_high;
+ }
+
+ if (firstCol > lastCol || firstRow > lastRow)
+ goto bail;
+
+ if (firstCol < opfi->firstCol)
+ firstCol = opfi->firstCol;
+ if (lastCol > opfi->lastCol)
+ lastCol = opfi->lastCol;
+ if (firstRow < opfi->firstRow)
+ firstRow = opfi->firstRow;
+ if (lastRow > opfi->lastRow)
+ lastRow = opfi->lastRow;
+ }
+ else
+ {
+ firstCol = opfi->firstCol;
+ lastCol = opfi->lastCol;
+ firstRow = opfi->firstRow;
+ lastRow = opfi->lastRow;
+ }
+
+ bitmapFont = malloc(sizeof(BitmapFontRec));
+ if (!bitmapFont) {
+ fprintf(stderr, "Error: Couldn't allocate bitmapFont (%ld)\n",
+ (unsigned long)sizeof(BitmapFontRec));
+ goto bail;
+ }
+ nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1);
+ pfi->firstRow = firstRow;
+ pfi->lastRow = lastRow;
+ pfi->firstCol = firstCol;
+ pfi->lastCol = lastCol;
+ pf->fontPrivate = (pointer) bitmapFont;
+ bitmapFont->version_num = obitmapFont->version_num;
+ bitmapFont->num_chars = nchars;
+ bitmapFont->num_tables = obitmapFont->num_tables;
+ bitmapFont->metrics = 0;
+ bitmapFont->ink_metrics = 0;
+ bitmapFont->bitmaps = 0;
+ bitmapFont->encoding = 0;
+ bitmapFont->bitmapExtra = 0;
+ bitmapFont->pDefault = 0;
+ bitmapFont->metrics = malloc(nchars * sizeof(CharInfoRec));
+ if (!bitmapFont->metrics) {
+ fprintf(stderr, "Error: Couldn't allocate metrics (%d*%ld)\n",
+ nchars, (unsigned long)sizeof(CharInfoRec));
+ goto bail;
+ }
+ bitmapFont->encoding = calloc(NUM_SEGMENTS(nchars), sizeof(CharInfoPtr*));
+ if (!bitmapFont->encoding) {
+ fprintf(stderr, "Error: Couldn't allocate encoding (%d*%ld)\n",
+ nchars, (unsigned long)sizeof(CharInfoPtr));
+ goto bail;
+ }
+
+#undef MAXSHORT
+#define MAXSHORT 32767
+#undef MINSHORT
+#define MINSHORT -32768
+
+ pfi->anamorphic = FALSE;
+ if (heightMult != widthMult)
+ pfi->anamorphic = TRUE;
+ pfi->cachable = TRUE;
+
+ if (!compute_xform_matrix(vals, widthMult, heightMult, xform,
+ inv_xform, &xmult, &ymult))
+ goto bail;
+
+ pfi->fontAscent = opfi->fontAscent * ymult;
+ pfi->fontDescent = opfi->fontDescent * ymult;
+
+ pfi->minbounds.leftSideBearing = MAXSHORT;
+ pfi->minbounds.rightSideBearing = MAXSHORT;
+ pfi->minbounds.ascent = MAXSHORT;
+ pfi->minbounds.descent = MAXSHORT;
+ pfi->minbounds.characterWidth = MAXSHORT;
+ pfi->minbounds.attributes = MAXSHORT;
+
+ pfi->maxbounds.leftSideBearing = MINSHORT;
+ pfi->maxbounds.rightSideBearing = MINSHORT;
+ pfi->maxbounds.ascent = MINSHORT;
+ pfi->maxbounds.descent = MINSHORT;
+ pfi->maxbounds.characterWidth = MINSHORT;
+ pfi->maxbounds.attributes = MINSHORT;
+
+ /* Compute the transformation and inverse transformation matrices.
+ Can fail if the determinant is zero. */
+
+ pci = bitmapFont->metrics;
+ for (i = 0; i < nchars; i++)
+ {
+ if ((opci = ACCESSENCODING(obitmapFont->encoding,OLDINDEX(i))))
+ {
+ double newlsb, newrsb, newdesc, newasc, point[2];
+
+#define minchar(p) ((p).min_char_low + ((p).min_char_high << 8))
+#define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8))
+
+ if (vals->nranges)
+ {
+ int row = i / (lastCol - firstCol + 1) + firstRow;
+ int col = i % (lastCol - firstCol + 1) + firstCol;
+ int ch = (row << 8) + col;
+ int j;
+ for (j = 0; j < vals->nranges; j++)
+ if (ch >= minchar(vals->ranges[j]) &&
+ ch <= maxchar(vals->ranges[j]))
+ break;
+ if (j == vals->nranges)
+ {
+ continue;
+ }
+ }
+
+ if (opci->metrics.leftSideBearing == 0 &&
+ opci->metrics.rightSideBearing == 0 &&
+ opci->metrics.ascent == 0 &&
+ opci->metrics.descent == 0 &&
+ opci->metrics.characterWidth == 0)
+ {
+ continue;
+ }
+
+ if(!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
+ bitmapFont->encoding[SEGMENT_MAJOR(i)]=
+ calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr));
+ if(!bitmapFont->encoding[SEGMENT_MAJOR(i)])
+ goto bail;
+ }
+ ACCESSENCODINGL(bitmapFont->encoding, i) = pci;
+
+ /* Compute new extents for this glyph */
+ TRANSFORM_POINT(xform,
+ opci->metrics.leftSideBearing,
+ -opci->metrics.descent,
+ point);
+ newlsb = point[0];
+ newrsb = newlsb;
+ newdesc = -point[1];
+ newasc = -newdesc;
+ TRANSFORM_POINT(xform,
+ opci->metrics.leftSideBearing,
+ opci->metrics.ascent,
+ point);
+ CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+ TRANSFORM_POINT(xform,
+ opci->metrics.rightSideBearing,
+ -opci->metrics.descent,
+ point);
+ CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+ TRANSFORM_POINT(xform,
+ opci->metrics.rightSideBearing,
+ opci->metrics.ascent,
+ point);
+ CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point);
+
+ pci->metrics.leftSideBearing = (int)floor(newlsb);
+ pci->metrics.rightSideBearing = (int)floor(newrsb + .5);
+ pci->metrics.descent = (int)ceil(newdesc);
+ pci->metrics.ascent = (int)floor(newasc + .5);
+ /* Accumulate total width of characters before transformation,
+ to ascertain predominant direction of font. */
+ totalwidth += opci->metrics.characterWidth;
+ pci->metrics.characterWidth =
+ doround((double)opci->metrics.characterWidth * xmult);
+ pci->metrics.attributes =
+ doround((double)opci->metrics.characterWidth * sWidthMult);
+ if (!pci->metrics.characterWidth)
+ {
+ /* Since transformation may shrink width, height, and
+ escapement to zero, make sure existing characters
+ are not mistaken for undefined characters. */
+
+ if (pci->metrics.rightSideBearing ==
+ pci->metrics.leftSideBearing)
+ pci->metrics.rightSideBearing++;
+ if (pci->metrics.ascent == -pci->metrics.descent)
+ pci->metrics.ascent++;
+ }
+
+ pci++;
+ }
+ }
+
+
+ /*
+ * For each character, set the per-character metrics, scale the glyph, and
+ * check per-font minbounds and maxbounds character information.
+ */
+
+ pci = bitmapFont->metrics;
+ for (i = 0; i < nchars; i++)
+ {
+ if ((pci = ACCESSENCODING(bitmapFont->encoding,i)) &&
+ (opci = ACCESSENCODING(obitmapFont->encoding,OLDINDEX(i))))
+ {
+ totalchars++;
+ *sWidth += abs((int)(INT16)pci->metrics.attributes);
+#define MINMAX(field) \
+ if (pfi->minbounds.field > pci->metrics.field) \
+ pfi->minbounds.field = pci->metrics.field; \
+ if (pfi->maxbounds.field < pci->metrics.field) \
+ pfi->maxbounds.field = pci->metrics.field
+
+ MINMAX(leftSideBearing);
+ MINMAX(rightSideBearing);
+ MINMAX(ascent);
+ MINMAX(descent);
+ MINMAX(characterWidth);
+
+ /* Hack: Cast attributes into a signed quantity. Tread lightly
+ for now and don't go changing the global Xproto.h file */
+ if ((INT16)pfi->minbounds.attributes >
+ (INT16)pci->metrics.attributes)
+ pfi->minbounds.attributes = pci->metrics.attributes;
+ if ((INT16)pfi->maxbounds.attributes <
+ (INT16)pci->metrics.attributes)
+ pfi->maxbounds.attributes = pci->metrics.attributes;
+#undef MINMAX
+ }
+ }
+ pfi->ink_minbounds = pfi->minbounds;
+ pfi->ink_maxbounds = pfi->maxbounds;
+ if (totalchars)
+ {
+ *sWidth = (*sWidth * 10 + totalchars / 2) / totalchars;
+ if (totalwidth < 0)
+ {
+ /* Dominant direction is R->L */
+ *sWidth = -*sWidth;
+ }
+
+ if (pfi->minbounds.characterWidth == pfi->maxbounds.characterWidth)
+ vals->width = pfi->minbounds.characterWidth * 10;
+ else
+ vals->width = doround((double)*sWidth * vals->pixel_matrix[0] /
+ 1000.0);
+ }
+ else
+ {
+ vals->width = 0;
+ *sWidth = 0;
+ }
+ FontComputeInfoAccelerators (pfi);
+
+ if (pfi->defaultCh != (unsigned short) NO_SUCH_CHAR) {
+ unsigned int r,
+ c,
+ cols;
+
+ r = pfi->defaultCh >> 8;
+ c = pfi->defaultCh & 0xFF;
+ if (pfi->firstRow <= r && r <= pfi->lastRow &&
+ pfi->firstCol <= c && c <= pfi->lastCol) {
+ cols = pfi->lastCol - pfi->firstCol + 1;
+ r = r - pfi->firstRow;
+ c = c - pfi->firstCol;
+ bitmapFont->pDefault =
+ ACCESSENCODING(bitmapFont->encoding, r * cols + c);
+ }
+ }
+
+ *newWidthMult = xmult;
+ *newHeightMult = ymult;
+ return pf;
+bail:
+ if (pf)
+ free(pf);
+ if (bitmapFont) {
+ free(bitmapFont->metrics);
+ free(bitmapFont->ink_metrics);
+ free(bitmapFont->bitmaps);
+ if(bitmapFont->encoding)
+ for(i=0; i<NUM_SEGMENTS(nchars); i++)
+ free(bitmapFont->encoding[i]);
+ free(bitmapFont->encoding);
+ }
+ return NULL;
+}
+
+static void
+ScaleBitmap(FontPtr pFont, CharInfoPtr opci, CharInfoPtr pci,
+ double *inv_xform, double widthMult, double heightMult)
+{
+ register char *bitmap, /* The bits */
+ *newBitmap;
+ register int bpr, /* Padding information */
+ newBpr;
+ int width, /* Extents information */
+ height,
+ newWidth,
+ newHeight;
+ register int row, /* Loop variables */
+ col;
+ INT32 deltaX, /* Increments for resampling loop */
+ deltaY;
+ INT32 xValue, /* Subscripts for resampling loop */
+ yValue;
+ double point[2];
+ unsigned char *char_grayscale = 0;
+ INT32 *diffusion_workspace = NULL, *thisrow = NULL,
+ *nextrow = NULL, pixmult = 0;
+ int box_x = 0, box_y = 0;
+
+ static unsigned char masklsb[] =
+ { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 };
+ static unsigned char maskmsb[] =
+ { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };
+ unsigned char *mask = (pFont->bit == LSBFirst ? masklsb : maskmsb);
+
+
+ bitmap = opci->bits;
+ newBitmap = pci->bits;
+ width = GLYPHWIDTHPIXELS(opci);
+ height = GLYPHHEIGHTPIXELS(opci);
+ newWidth = GLYPHWIDTHPIXELS(pci);
+ newHeight = GLYPHHEIGHTPIXELS(pci);
+ if (!newWidth || !newHeight || !width || !height)
+ return;
+
+ bpr = BYTES_PER_ROW(width, pFont->glyph);
+ newBpr = BYTES_PER_ROW(newWidth, pFont->glyph);
+
+ if (widthMult > 0.0 && heightMult > 0.0 &&
+ (widthMult < 1.0 || heightMult < 1.0))
+ {
+ /* We are reducing in one or both dimensions. In an attempt to
+ reduce aliasing, we'll antialias by passing the original
+ glyph through a low-pass box filter (which results in a
+ grayscale image), then use error diffusion to create bitonal
+ output in the resampling loop. */
+
+ /* First compute the sizes of the box filter */
+ widthMult = ceil(1.0 / widthMult);
+ heightMult = ceil(1.0 / heightMult);
+ box_x = width / 2;
+ box_y = height / 2;
+ if (widthMult < (double)box_x) box_x = (int)widthMult;
+ if (heightMult < (double)box_y) box_y = (int)heightMult;
+ /* The pixmult value (below) is used to darken the image before
+ we perform error diffusion: a necessary concession to the
+ fact that it's very difficult to generate readable halftoned
+ glyphs. The degree of darkening is proportional to the size
+ of the blurring filter, hence inversely proportional to the
+ darkness of the lightest gray that results from antialiasing.
+ The result is that characters that exercise this logic (those
+ generated by reducing from a larger source font) tend to err
+ on the side of being too bold instead of being too light to
+ be readable. */
+ pixmult = box_x * box_y * 192;
+
+ if (box_x > 1 || box_y > 1)
+ {
+ /* Looks like we need to anti-alias. Create a workspace to
+ contain the grayscale character plus an additional row and
+ column for scratch */
+ char_grayscale = malloc((width + 1) * (height + 1));
+ if (char_grayscale)
+ {
+ diffusion_workspace = calloc((newWidth + 2) * 2, sizeof(int));
+ if (!diffusion_workspace)
+ {
+ fprintf(stderr, "Warning: Couldn't allocate diffusion"
+ " workspace (%ld)\n",
+ (newWidth + 2) * 2 * (unsigned long)sizeof(int));
+ free(char_grayscale);
+ char_grayscale = (unsigned char *)0;
+ }
+ /* Initialize our error diffusion workspace for later use */
+ thisrow = diffusion_workspace + 1;
+ nextrow = diffusion_workspace + newWidth + 3;
+ } else {
+ fprintf(stderr, "Warning: Couldn't allocate character grayscale (%d)\n", (width + 1) * (height + 1));
+ }
+ }
+ }
+
+ if (char_grayscale)
+ {
+ /* We will be doing antialiasing. First copy the bitmap into
+ our buffer, mapping input range [0,1] to output range
+ [0,255]. */
+ register unsigned char *srcptr, *dstptr;
+ srcptr = (unsigned char *)bitmap;
+ dstptr = char_grayscale;
+ for (row = 0; row < height; row++)
+ {
+ for (col = 0; col < width; col++)
+ *dstptr++ = (srcptr[col >> 3] & mask[col & 0x7]) ? 255 : 0;
+ srcptr += bpr; /* On to next row of source */
+ dstptr++; /* Skip scratch column in dest */
+ }
+ if (box_x > 1)
+ {
+ /* Our box filter has a width > 1... let's filter the rows */
+
+ int right_width = box_x / 2;
+ int left_width = box_x - right_width - 1;
+
+ for (row = 0; row < height; row++)
+ {
+ int sum = 0;
+ int left_size = 0, right_size = 0;
+
+ srcptr = char_grayscale + (width + 1) * row;
+ dstptr = char_grayscale + (width + 1) * height; /* scratch */
+
+ /* We've computed the shape of our full box filter. Now
+ compute the right-hand part of the moving sum */
+ for (right_size = 0; right_size < right_width; right_size++)
+ sum += srcptr[right_size];
+
+ /* Now start moving the sum, growing the box filter, and
+ dropping averages into our scratch buffer */
+ for (left_size = 0; left_size < left_width; left_size++)
+ {
+ sum += srcptr[right_width];
+ *dstptr++ = sum / (left_size + right_width + 1);
+ srcptr++;
+ }
+
+ /* The box filter has reached full width... continue
+ computation of moving average until the right side
+ hits the wall. */
+ for (col = left_size; col + right_size < width; col++)
+ {
+ sum += srcptr[right_width];
+ *dstptr++ = sum / box_x;
+ sum -= srcptr[-left_width];
+ srcptr++;
+ }
+
+ /* Collapse the right side of the box filter */
+ for (; right_size > 0; right_size--)
+ {
+ *dstptr++ = sum / (left_width + right_size);
+ sum -= srcptr[-left_width];
+ srcptr++;
+ }
+
+ /* Done with the row... copy dest back over source */
+ memmove(char_grayscale + (width + 1) * row,
+ char_grayscale + (width + 1) * height,
+ width);
+ }
+ }
+ if (box_y > 1)
+ {
+ /* Our box filter has a height > 1... let's filter the columns */
+
+ int bottom_height = box_y / 2;
+ int top_height = box_y - bottom_height - 1;
+
+ for (col = 0; col < width; col++)
+ {
+ int sum = 0;
+ int top_size = 0, bottom_size = 0;
+
+ srcptr = char_grayscale + col;
+ dstptr = char_grayscale + width; /* scratch */
+
+ /* We've computed the shape of our full box filter. Now
+ compute the bottom part of the moving sum */
+ for (bottom_size = 0;
+ bottom_size < bottom_height;
+ bottom_size++)
+ sum += srcptr[bottom_size * (width + 1)];
+
+ /* Now start moving the sum, growing the box filter, and
+ dropping averages into our scratch buffer */
+ for (top_size = 0; top_size < top_height; top_size++)
+ {
+ sum += srcptr[bottom_height * (width + 1)];
+ *dstptr = sum / (top_size + bottom_height + 1);
+ dstptr += width + 1;
+ srcptr += width + 1;
+ }
+
+ /* The box filter has reached full height... continue
+ computation of moving average until the bottom
+ hits the wall. */
+ for (row = top_size; row + bottom_size < height; row++)
+ {
+ sum += srcptr[bottom_height * (width + 1)];
+ *dstptr = sum / box_y;
+ dstptr += width + 1;
+ sum -= srcptr[-top_height * (width + 1)];
+ srcptr += width + 1;
+ }
+
+ /* Collapse the bottom of the box filter */
+ for (; bottom_size > 0; bottom_size--)
+ {
+ *dstptr = sum / (top_height + bottom_size);
+ dstptr += width + 1;
+ sum -= srcptr[-top_height * (width + 1)];
+ srcptr += width + 1;
+ }
+
+ /* Done with the column... copy dest back over source */
+
+ dstptr = char_grayscale + col;
+ srcptr = char_grayscale + width; /* scratch */
+ for (row = 0; row < height; row++)
+ {
+ *dstptr = *srcptr;
+ dstptr += width + 1;
+ srcptr += width + 1;
+ }
+ }
+ }
+
+ /* Increase the grayvalue to increase ink a bit */
+ srcptr = char_grayscale;
+ for (row = 0; row < height; row++)
+ {
+ for (col = 0; col < width; col++)
+ {
+ register int pixvalue = (int)*srcptr * pixmult / 256;
+ if (pixvalue > 255) pixvalue = 255;
+ *srcptr = pixvalue;
+ srcptr++;
+ }
+ srcptr++;
+ }
+ }
+
+ /* Compute the increment values for the resampling loop */
+ TRANSFORM_POINT(inv_xform, 1, 0, point);
+ deltaX = (INT32)(point[0] * 65536.0);
+ deltaY = (INT32)(-point[1] * 65536.0);
+
+ /* Resampling loop: resamples original glyph for generation of new
+ glyph in transformed coordinate system. */
+
+ for (row = 0; row < newHeight; row++)
+ {
+ /* Compute inverse transformation for start of this row */
+ TRANSFORM_POINT(inv_xform,
+ (double)(pci->metrics.leftSideBearing) + .5,
+ (double)(pci->metrics.ascent - row) - .5,
+ point);
+
+ /* Adjust for coordinate system to get resampling point */
+ point[0] -= opci->metrics.leftSideBearing;
+ point[1] = opci->metrics.ascent - point[1];
+
+ /* Convert to integer coordinates */
+ xValue = (INT32)(point[0] * 65536.0);
+ yValue = (INT32)(point[1] * 65536.0);
+
+ if (char_grayscale)
+ {
+ INT32 *temp;
+ for (col = 0; col < newWidth; col++)
+ {
+ register int x = xValue >> 16, y = yValue >> 16;
+ int pixvalue, error;
+
+ pixvalue = ((x >= 0 && x < width && y >= 0 && y < height) ?
+ char_grayscale[x + y * (width + 1)] : 0) +
+ thisrow[col] / 16;
+ if (pixvalue > 255) pixvalue = 255;
+ else if (pixvalue < 0) pixvalue = 0;
+
+ /* Choose the bit value and set resulting error value */
+ if (pixvalue >= 128)
+ {
+ newBitmap[(col >> 3) + row * newBpr] |= mask[col & 0x7];
+ error = pixvalue - 255;
+ }
+ else
+ error = -pixvalue;
+
+ /* Diffuse the error */
+ thisrow[col + 1] += error * 7;
+ nextrow[col - 1] += error * 3;
+ nextrow[col] += error * 5;
+ nextrow[col + 1] = error;
+
+ xValue += deltaX;
+ yValue += deltaY;
+ }
+
+ /* Add in error values that fell off either end */
+ nextrow[0] += nextrow[-1];
+ nextrow[newWidth - 2] += thisrow[newWidth];
+ nextrow[newWidth - 1] += nextrow[newWidth];
+ nextrow[newWidth] = 0;
+
+ temp = nextrow;
+ nextrow = thisrow;
+ thisrow = temp;
+ nextrow[-1] = nextrow[0] = 0;
+ }
+ else
+ {
+ for (col = 0; col < newWidth; col++)
+ {
+ register int x = xValue >> 16, y = yValue >> 16;
+
+ if (x >= 0 && x < width && y >= 0 && y < height)
+ {
+ /* Use point-sampling for rescaling. */
+
+ if (bitmap[(x >> 3) + y * bpr] & mask[x & 0x7])
+ newBitmap[(col >> 3) + row * newBpr] |= mask[col & 0x7];
+ }
+
+ xValue += deltaX;
+ yValue += deltaY;
+ }
+ }
+ }
+
+
+ if (char_grayscale)
+ {
+ free(char_grayscale);
+ free(diffusion_workspace);
+ }
+}
+
+static FontPtr
+BitmapScaleBitmaps(FontPtr pf, /* scaled font */
+ FontPtr opf, /* originating font */
+ double widthMult, /* glyphs width scale factor */
+ double heightMult, /* glyphs height scale factor */
+ FontScalablePtr vals)
+{
+ register int i;
+ int nchars = 0;
+ char *glyphBytes;
+ BitmapFontPtr bitmapFont,
+ obitmapFont;
+ CharInfoPtr pci,
+ opci;
+ FontInfoPtr pfi;
+ int glyph;
+ unsigned bytestoalloc = 0;
+ int firstCol, lastCol, firstRow, lastRow;
+
+ double xform[4], inv_xform[4];
+ double xmult, ymult;
+
+ bitmapFont = (BitmapFontPtr) pf->fontPrivate;
+ obitmapFont = (BitmapFontPtr) opf->fontPrivate;
+
+ if (!compute_xform_matrix(vals, widthMult, heightMult, xform,
+ inv_xform, &xmult, &ymult))
+ goto bail;
+
+ pfi = &pf->info;
+ firstCol = pfi->firstCol;
+ lastCol = pfi->lastCol;
+ firstRow = pfi->firstRow;
+ lastRow = pfi->lastRow;
+
+ nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1);
+ glyph = pf->glyph;
+ for (i = 0; i < nchars; i++)
+ {
+ if ((pci = ACCESSENCODING(bitmapFont->encoding, i)))
+ bytestoalloc += BYTES_FOR_GLYPH(pci, glyph);
+ }
+
+ /* Do we add the font malloc stuff for VALUE ADDED ? */
+ /* Will need to remember to free in the Unload routine */
+
+
+ bitmapFont->bitmaps = calloc(1, bytestoalloc);
+ if (!bitmapFont->bitmaps) {
+ fprintf(stderr, "Error: Couldn't allocate bitmaps (%d)\n", bytestoalloc);
+ goto bail;
+ }
+
+ glyphBytes = bitmapFont->bitmaps;
+ for (i = 0; i < nchars; i++)
+ {
+ if ((pci = ACCESSENCODING(bitmapFont->encoding, i)) &&
+ (opci = ACCESSENCODING(obitmapFont->encoding, OLDINDEX(i))))
+ {
+ pci->bits = glyphBytes;
+ ScaleBitmap (pf, opci, pci, inv_xform,
+ widthMult, heightMult);
+ glyphBytes += BYTES_FOR_GLYPH(pci, glyph);
+ }
+ }
+ return pf;
+
+bail:
+ if (pf)
+ free(pf);
+ if (bitmapFont) {
+ free(bitmapFont->metrics);
+ free(bitmapFont->ink_metrics);
+ free(bitmapFont->bitmaps);
+ if(bitmapFont->encoding)
+ for(i=0; i<NUM_SEGMENTS(nchars); i++)
+ free(bitmapFont->encoding[i]);
+ free(bitmapFont->encoding);
+ }
+ return NULL;
+}
+
+/* ARGSUSED */
+int
+BitmapOpenScalable (FontPathElementPtr fpe,
+ FontPtr *pFont,
+ int flags,
+ FontEntryPtr entry,
+ char *fileName, /* unused */
+ FontScalablePtr vals,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask,
+ FontPtr non_cachable_font) /* We don't do licensing */
+{
+ FontScalableRec best;
+ FontPtr font = NullFont;
+ double dx, sdx,
+ dy, sdy,
+ savedX, savedY;
+ FontPropPtr props;
+ char *isStringProp = NULL;
+ int propCount;
+ int status;
+ long sWidth;
+
+ FontEntryPtr scaleFrom;
+ FontPathElementPtr scaleFPE = NULL;
+ FontPtr sourceFont;
+ char fontName[MAXFONTNAMELEN];
+
+ /* Can't deal with mix-endian fonts yet */
+
+
+ /* Reject outrageously small font sizes to keep the math from
+ blowing up. */
+ if (get_matrix_vertical_component(vals->pixel_matrix) < 1.0 ||
+ get_matrix_horizontal_component(vals->pixel_matrix) < 1.0)
+ return BadFontName;
+
+ scaleFrom = FindBestToScale(fpe, entry, vals, &best, &dx, &dy, &sdx, &sdy,
+ &scaleFPE);
+
+ if (!scaleFrom)
+ return BadFontName;
+
+ status = FontFileOpenBitmap(scaleFPE, &sourceFont, LoadAll, scaleFrom,
+ format, fmask);
+
+ if (status != Successful)
+ return BadFontName;
+
+ if (!vals->width)
+ vals->width = best.width * dx;
+
+ /* Compute the scaled font */
+
+ savedX = dx;
+ savedY = dy;
+ font = ScaleFont(sourceFont, dx, dy, sdx, sdy, vals, &dx, &dy, &sWidth);
+ if (font)
+ font = BitmapScaleBitmaps(font, sourceFont, savedX, savedY, vals);
+
+ if (!font)
+ {
+ if (!sourceFont->refcnt)
+ FontFileCloseFont((FontPathElementPtr) 0, sourceFont);
+ return AllocError;
+ }
+
+ /* Prepare font properties for the new font */
+
+ strcpy (fontName, scaleFrom->name.name);
+ FontParseXLFDName (fontName, vals, FONT_XLFD_REPLACE_VALUE);
+
+ propCount = ComputeScaledProperties(&sourceFont->info, fontName, vals,
+ dx, dy, sdx, sdy, sWidth, &props,
+ &isStringProp);
+
+ if (!sourceFont->refcnt)
+ FontFileCloseFont((FontPathElementPtr) 0, sourceFont);
+
+ font->info.props = props;
+ font->info.nprops = propCount;
+ font->info.isStringProp = isStringProp;
+
+ if (propCount && (!props || !isStringProp))
+ {
+ bitmapUnloadScalable(font);
+ return AllocError;
+ }
+
+ *pFont = font;
+ return Successful;
+}
+
+int
+BitmapGetInfoScalable (FontPathElementPtr fpe,
+ FontInfoPtr pFontInfo,
+ FontEntryPtr entry,
+ FontNamePtr fontName,
+ char *fileName,
+ FontScalablePtr vals)
+{
+ FontPtr pfont;
+ int flags = 0;
+ long format = 0; /* It doesn't matter what format for just info */
+ long fmask = 0;
+ int ret;
+
+ ret = BitmapOpenScalable(fpe, &pfont, flags, entry, fileName, vals,
+ format, fmask, NULL);
+ if (ret != Successful)
+ return ret;
+ *pFontInfo = pfont->info;
+
+ pfont->info.nprops = 0;
+ pfont->info.props = NULL;
+ pfont->info.isStringProp = NULL;
+
+ (*pfont->unload_font)(pfont);
+ return Successful;
+}
+
+static void
+bitmapUnloadScalable (FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont;
+ FontInfoPtr pfi;
+ int i, nencoding;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ pfi = &pFont->info;
+ free (pfi->props);
+ free (pfi->isStringProp);
+ if(bitmapFont->encoding) {
+ nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
+ (pFont->info.lastRow - pFont->info.firstRow + 1);
+ for(i=0; i<NUM_SEGMENTS(nencoding); i++)
+ free(bitmapFont->encoding[i]);
+ }
+ free (bitmapFont->encoding);
+ free (bitmapFont->bitmaps);
+ free (bitmapFont->ink_metrics);
+ free (bitmapFont->metrics);
+ free (pFont->fontPrivate);
+ DestroyFontRec (pFont);
+}
diff --git a/libXfont/src/bitmap/fontink.c b/libXfont/src/bitmap/fontink.c
index ad7091fa6..551b81b28 100644
--- a/libXfont/src/bitmap/fontink.c
+++ b/libXfont/src/bitmap/fontink.c
@@ -1,216 +1,216 @@
-/*
-
-Copyright 1990, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-/*
- * Author: Keith Packard, MIT X Consortium
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <X11/fonts/fntfilst.h>
-#include <X11/fonts/bitmap.h>
-#include <X11/fonts/bdfint.h>
-
-static unsigned char ink_mask_msb[8] = {
- 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
-};
-
-static unsigned char ink_mask_lsb[8] = {
- 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
-};
-
-void
-FontCharInkMetrics(FontPtr pFont, CharInfoPtr pCI, xCharInfo *pInk)
-{
- int leftBearing,
- ascent,
- descent;
- register int vpos,
- hpos,
- bpos = 0;
- int bitmapByteWidth,
- bitmapByteWidthPadded;
- int bitmapBitWidth;
- int span;
- register unsigned char *p;
- unsigned char *ink_mask = 0;
- register int bmax;
- register unsigned char charbits;
-
- if (pFont->bit == MSBFirst)
- ink_mask = ink_mask_msb;
- else if (pFont->bit == LSBFirst)
- ink_mask = ink_mask_lsb;
- pInk->characterWidth = pCI->metrics.characterWidth;
- pInk->attributes = pCI->metrics.attributes;
-
- leftBearing = pCI->metrics.leftSideBearing;
- ascent = pCI->metrics.ascent;
- descent = pCI->metrics.descent;
- bitmapBitWidth = GLYPHWIDTHPIXELS(pCI);
- bitmapByteWidth = GLYPHWIDTHBYTES(pCI);
- bitmapByteWidthPadded = BYTES_PER_ROW(bitmapBitWidth, pFont->glyph);
- span = bitmapByteWidthPadded - bitmapByteWidth;
-
- p = (unsigned char *) pCI->bits;
- for (vpos = descent + ascent; --vpos >= 0;) {
- for (hpos = bitmapByteWidth; --hpos >= 0;) {
- if (*p++ != 0)
- goto found_ascent;
- }
- p += span;
- }
- /*
- * special case -- font with no bits gets all zeros
- */
- pInk->leftSideBearing = leftBearing;
- pInk->rightSideBearing = leftBearing;
- pInk->ascent = 0;
- pInk->descent = 0;
- return;
-found_ascent:
- pInk->ascent = vpos - descent + 1;
-
- p = ((unsigned char *) pCI->bits) + bitmapByteWidthPadded *
- (descent + ascent - 1) + bitmapByteWidth;
-
- for (vpos = descent + ascent; --vpos >= 0;) {
- for (hpos = bitmapByteWidth; --hpos >= 0;) {
- if (*--p != 0)
- goto found_descent;
- }
- p -= span;
- }
-found_descent:
- pInk->descent = vpos - ascent + 1;
-
- bmax = 8;
- for (hpos = 0; hpos < bitmapByteWidth; hpos++) {
- charbits = 0;
- p = (unsigned char *) pCI->bits + hpos;
- for (vpos = descent + ascent; --vpos >= 0; p += bitmapByteWidthPadded)
- charbits |= *p;
- if (charbits) {
- if (hpos == bitmapByteWidth - 1)
- bmax = bitmapBitWidth - (hpos << 3);
- p = ink_mask;
- for (bpos = bmax; --bpos >= 0;) {
- if (charbits & *p++)
- goto found_left;
- }
- }
- }
-found_left:
- pInk->leftSideBearing = leftBearing + (hpos << 3) + bmax - bpos - 1;
-
- bmax = bitmapBitWidth - ((bitmapByteWidth - 1) << 3);
- for (hpos = bitmapByteWidth; --hpos >= 0;) {
- charbits = 0;
- p = (unsigned char *) pCI->bits + hpos;
- for (vpos = descent + ascent; --vpos >= 0; p += bitmapByteWidthPadded)
- charbits |= *p;
- if (charbits) {
- p = ink_mask + bmax;
- for (bpos = bmax; --bpos >= 0;) {
- if (charbits & *--p)
- goto found_right;
- }
- }
- bmax = 8;
- }
-found_right:
- pInk->rightSideBearing = leftBearing + (hpos << 3) + bpos + 1;
-}
-
-#define ISBITONMSB(x, line) ((line)[(x)/8] & (1 << (7-((x)%8))))
-#define SETBITMSB(x, line) ((line)[(x)/8] |= (1 << (7-((x)%8))))
-#define ISBITONLSB(x, line) ((line)[(x)/8] & (1 << ((x)%8)))
-#define SETBITLSB(x, line) ((line)[(x)/8] |= (1 << ((x)%8)))
-
-#define Min(a,b) ((a)<(b)?(a):(b))
-#define Max(a,b) ((a)>(b)?(a):(b))
-
-void
-FontCharReshape(FontPtr pFont, CharInfoPtr pSrc, CharInfoPtr pDst)
-{
- int x,
- y;
- unsigned char *in_line,
- *out_line;
- unsigned char *oldglyph,
- *newglyph;
- int inwidth;
- int outwidth,
- outheight;
- int out_bytes,
- in_bytes;
- int y_min,
- y_max,
- x_min,
- x_max;
-
- newglyph = (unsigned char *) pDst->bits;
- outwidth = pDst->metrics.rightSideBearing - pDst->metrics.leftSideBearing;
- outheight = pDst->metrics.descent + pDst->metrics.ascent;
- out_bytes = BYTES_PER_ROW(outwidth, pFont->glyph);
-
- oldglyph = (unsigned char *) pSrc->bits;
- inwidth = pSrc->metrics.rightSideBearing - pSrc->metrics.leftSideBearing;
- in_bytes = BYTES_PER_ROW(inwidth, pFont->glyph);
-
- bzero(newglyph, out_bytes * outheight);
- in_line = oldglyph;
- out_line = newglyph;
- y_min = Max(-pSrc->metrics.ascent, -pDst->metrics.ascent);
- y_max = Min(pSrc->metrics.descent, pDst->metrics.descent);
- x_min = Max(pSrc->metrics.leftSideBearing, pDst->metrics.leftSideBearing);
- x_max = Min(pSrc->metrics.rightSideBearing, pDst->metrics.rightSideBearing);
- in_line += (y_min + pSrc->metrics.ascent) * in_bytes;
- out_line += (y_min + pDst->metrics.ascent) * out_bytes;
- if (pFont->bit == MSBFirst) {
- for (y = y_min; y < y_max; y++) {
- for (x = x_min; x < x_max; x++) {
- if (ISBITONMSB(x - pSrc->metrics.leftSideBearing, in_line))
- SETBITMSB(x - pDst->metrics.leftSideBearing, out_line);
- }
- in_line += in_bytes;
- out_line += out_bytes;
- }
- } else {
- for (y = y_min; y < y_max; y++) {
- for (x = x_min; x < x_max; x++) {
- if (ISBITONLSB(x - pSrc->metrics.leftSideBearing, in_line))
- SETBITLSB(x - pDst->metrics.leftSideBearing, out_line);
- }
- in_line += in_bytes;
- out_line += out_bytes;
- }
- }
-}
+/*
+
+Copyright 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/bdfint.h>
+
+static unsigned char ink_mask_msb[8] = {
+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
+};
+
+static unsigned char ink_mask_lsb[8] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+};
+
+void
+FontCharInkMetrics(FontPtr pFont, CharInfoPtr pCI, xCharInfo *pInk)
+{
+ int leftBearing,
+ ascent,
+ descent;
+ register int vpos,
+ hpos,
+ bpos = 0;
+ int bitmapByteWidth,
+ bitmapByteWidthPadded;
+ int bitmapBitWidth;
+ int span;
+ register unsigned char *p;
+ unsigned char *ink_mask = 0;
+ register int bmax;
+ register unsigned char charbits;
+
+ if (pFont->bit == MSBFirst)
+ ink_mask = ink_mask_msb;
+ else if (pFont->bit == LSBFirst)
+ ink_mask = ink_mask_lsb;
+ pInk->characterWidth = pCI->metrics.characterWidth;
+ pInk->attributes = pCI->metrics.attributes;
+
+ leftBearing = pCI->metrics.leftSideBearing;
+ ascent = pCI->metrics.ascent;
+ descent = pCI->metrics.descent;
+ bitmapBitWidth = GLYPHWIDTHPIXELS(pCI);
+ bitmapByteWidth = GLYPHWIDTHBYTES(pCI);
+ bitmapByteWidthPadded = BYTES_PER_ROW(bitmapBitWidth, pFont->glyph);
+ span = bitmapByteWidthPadded - bitmapByteWidth;
+
+ p = (unsigned char *) pCI->bits;
+ for (vpos = descent + ascent; --vpos >= 0;) {
+ for (hpos = bitmapByteWidth; --hpos >= 0;) {
+ if (*p++ != 0)
+ goto found_ascent;
+ }
+ p += span;
+ }
+ /*
+ * special case -- font with no bits gets all zeros
+ */
+ pInk->leftSideBearing = leftBearing;
+ pInk->rightSideBearing = leftBearing;
+ pInk->ascent = 0;
+ pInk->descent = 0;
+ return;
+found_ascent:
+ pInk->ascent = vpos - descent + 1;
+
+ p = ((unsigned char *) pCI->bits) + bitmapByteWidthPadded *
+ (descent + ascent - 1) + bitmapByteWidth;
+
+ for (vpos = descent + ascent; --vpos >= 0;) {
+ for (hpos = bitmapByteWidth; --hpos >= 0;) {
+ if (*--p != 0)
+ goto found_descent;
+ }
+ p -= span;
+ }
+found_descent:
+ pInk->descent = vpos - ascent + 1;
+
+ bmax = 8;
+ for (hpos = 0; hpos < bitmapByteWidth; hpos++) {
+ charbits = 0;
+ p = (unsigned char *) pCI->bits + hpos;
+ for (vpos = descent + ascent; --vpos >= 0; p += bitmapByteWidthPadded)
+ charbits |= *p;
+ if (charbits) {
+ if (hpos == bitmapByteWidth - 1)
+ bmax = bitmapBitWidth - (hpos << 3);
+ p = ink_mask;
+ for (bpos = bmax; --bpos >= 0;) {
+ if (charbits & *p++)
+ goto found_left;
+ }
+ }
+ }
+found_left:
+ pInk->leftSideBearing = leftBearing + (hpos << 3) + bmax - bpos - 1;
+
+ bmax = bitmapBitWidth - ((bitmapByteWidth - 1) << 3);
+ for (hpos = bitmapByteWidth; --hpos >= 0;) {
+ charbits = 0;
+ p = (unsigned char *) pCI->bits + hpos;
+ for (vpos = descent + ascent; --vpos >= 0; p += bitmapByteWidthPadded)
+ charbits |= *p;
+ if (charbits) {
+ p = ink_mask + bmax;
+ for (bpos = bmax; --bpos >= 0;) {
+ if (charbits & *--p)
+ goto found_right;
+ }
+ }
+ bmax = 8;
+ }
+found_right:
+ pInk->rightSideBearing = leftBearing + (hpos << 3) + bpos + 1;
+}
+
+#define ISBITONMSB(x, line) ((line)[(x)/8] & (1 << (7-((x)%8))))
+#define SETBITMSB(x, line) ((line)[(x)/8] |= (1 << (7-((x)%8))))
+#define ISBITONLSB(x, line) ((line)[(x)/8] & (1 << ((x)%8)))
+#define SETBITLSB(x, line) ((line)[(x)/8] |= (1 << ((x)%8)))
+
+#define Min(a,b) ((a)<(b)?(a):(b))
+#define Max(a,b) ((a)>(b)?(a):(b))
+
+void
+FontCharReshape(FontPtr pFont, CharInfoPtr pSrc, CharInfoPtr pDst)
+{
+ int x,
+ y;
+ unsigned char *in_line,
+ *out_line;
+ unsigned char *oldglyph,
+ *newglyph;
+ int inwidth;
+ int outwidth,
+ outheight;
+ int out_bytes,
+ in_bytes;
+ int y_min,
+ y_max,
+ x_min,
+ x_max;
+
+ newglyph = (unsigned char *) pDst->bits;
+ outwidth = pDst->metrics.rightSideBearing - pDst->metrics.leftSideBearing;
+ outheight = pDst->metrics.descent + pDst->metrics.ascent;
+ out_bytes = BYTES_PER_ROW(outwidth, pFont->glyph);
+
+ oldglyph = (unsigned char *) pSrc->bits;
+ inwidth = pSrc->metrics.rightSideBearing - pSrc->metrics.leftSideBearing;
+ in_bytes = BYTES_PER_ROW(inwidth, pFont->glyph);
+
+ bzero(newglyph, out_bytes * outheight);
+ in_line = oldglyph;
+ out_line = newglyph;
+ y_min = Max(-pSrc->metrics.ascent, -pDst->metrics.ascent);
+ y_max = Min(pSrc->metrics.descent, pDst->metrics.descent);
+ x_min = Max(pSrc->metrics.leftSideBearing, pDst->metrics.leftSideBearing);
+ x_max = Min(pSrc->metrics.rightSideBearing, pDst->metrics.rightSideBearing);
+ in_line += (y_min + pSrc->metrics.ascent) * in_bytes;
+ out_line += (y_min + pDst->metrics.ascent) * out_bytes;
+ if (pFont->bit == MSBFirst) {
+ for (y = y_min; y < y_max; y++) {
+ for (x = x_min; x < x_max; x++) {
+ if (ISBITONMSB(x - pSrc->metrics.leftSideBearing, in_line))
+ SETBITMSB(x - pDst->metrics.leftSideBearing, out_line);
+ }
+ in_line += in_bytes;
+ out_line += out_bytes;
+ }
+ } else {
+ for (y = y_min; y < y_max; y++) {
+ for (x = x_min; x < x_max; x++) {
+ if (ISBITONLSB(x - pSrc->metrics.leftSideBearing, in_line))
+ SETBITLSB(x - pDst->metrics.leftSideBearing, out_line);
+ }
+ in_line += in_bytes;
+ out_line += out_bytes;
+ }
+ }
+}
diff --git a/libXfont/src/bitmap/makefile b/libXfont/src/bitmap/makefile
new file mode 100644
index 000000000..f7ea10fdc
--- /dev/null
+++ b/libXfont/src/bitmap/makefile
@@ -0,0 +1,16 @@
+LIBRARY = libbitmap
+
+CSRCS = \
+ bdfread.c \
+ bdfutils.c \
+ bitmap.c \
+ bitmapfunc.c \
+ bitmaputil.c \
+ bitscale.c \
+ fontink.c \
+ pcfread.c \
+ pcfwrite.c \
+ snfread.c
+
+INCLUDES := ../.. $(INCLUDES)
+
diff --git a/libXfont/src/bitmap/pcfread.c b/libXfont/src/bitmap/pcfread.c
index 32f9856fa..759319e94 100644
--- a/libXfont/src/bitmap/pcfread.c
+++ b/libXfont/src/bitmap/pcfread.c
@@ -1,780 +1,780 @@
-/*
-
-Copyright 1990, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-/*
- * Author: Keith Packard, MIT X Consortium
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <X11/fonts/fntfilst.h>
-#include <X11/fonts/bitmap.h>
-#include <X11/fonts/pcf.h>
-
-#ifndef MAX
-#define MAX(a,b) (((a)>(b)) ? a : b)
-#endif
-
-#include <stdarg.h>
-#include <stdint.h>
-
-void
-pcfError(const char* message, ...)
-{
- va_list args;
-
- va_start(args, message);
-
- fprintf(stderr, "PCF Error: ");
- vfprintf(stderr, message, args);
- va_end(args);
-}
-
-/* Read PCF font files */
-
-static void pcfUnloadFont ( FontPtr pFont );
-static int position;
-
-
-#define IS_EOF(file) ((file)->eof == BUFFILEEOF)
-
-#define FONT_FILE_GETC_ERR(f) (tmp = FontFileGetc(f), BAIL_ON_EOF)
-
-static int
-pcfGetLSB32(FontFilePtr file)
-{
- int c;
-
- c = FontFileGetc(file);
- c |= FontFileGetc(file) << 8;
- c |= FontFileGetc(file) << 16;
- c |= FontFileGetc(file) << 24;
- position += 4;
- return c;
-}
-
-static int
-pcfGetINT32(FontFilePtr file, CARD32 format)
-{
- int c;
-
- if (PCF_BYTE_ORDER(format) == MSBFirst) {
- c = FontFileGetc(file) << 24;
- c |= FontFileGetc(file) << 16;
- c |= FontFileGetc(file) << 8;
- c |= FontFileGetc(file);
- } else {
- c = FontFileGetc(file);
- c |= FontFileGetc(file) << 8;
- c |= FontFileGetc(file) << 16;
- c |= FontFileGetc(file) << 24;
- }
- position += 4;
- return c;
-}
-
-static int
-pcfGetINT16(FontFilePtr file, CARD32 format)
-{
- int c;
-
- if (PCF_BYTE_ORDER(format) == MSBFirst) {
- c = FontFileGetc(file) << 8;
- c |= FontFileGetc(file);
- } else {
- c = FontFileGetc(file);
- c |= FontFileGetc(file) << 8;
- }
- position += 2;
- return c;
-}
-
-#define pcfGetINT8(file, format) (position++, FontFileGetc(file))
-
-static PCFTablePtr
-pcfReadTOC(FontFilePtr file, int *countp)
-{
- CARD32 version;
- PCFTablePtr tables;
- int count;
- int i;
-
- position = 0;
- version = pcfGetLSB32(file);
- if (version != PCF_FILE_VERSION)
- return (PCFTablePtr) NULL;
- count = pcfGetLSB32(file);
- if (IS_EOF(file)) return (PCFTablePtr) NULL;
- if (count < 0 || count > INT32_MAX / sizeof(PCFTableRec)) {
- pcfError("pcfReadTOC(): invalid file format\n");
- return NULL;
- }
- tables = malloc(count * sizeof(PCFTableRec));
- if (!tables) {
- pcfError("pcfReadTOC(): Couldn't allocate tables (%d*%d)\n", count, sizeof(PCFTableRec));
- return (PCFTablePtr) NULL;
- }
- for (i = 0; i < count; i++) {
- tables[i].type = pcfGetLSB32(file);
- tables[i].format = pcfGetLSB32(file);
- tables[i].size = pcfGetLSB32(file);
- tables[i].offset = pcfGetLSB32(file);
- if (IS_EOF(file)) goto Bail;
- }
-
- *countp = count;
- return tables;
-
- Bail:
- free(tables);
- return (PCFTablePtr) NULL;
-}
-
-/*
- * PCF supports two formats for metrics, both the regular
- * jumbo size, and 'lite' metrics, which are useful
- * for most fonts which have even vaguely reasonable
- * metrics
- */
-
-static Bool
-pcfGetMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
-{
- metric->leftSideBearing = pcfGetINT16(file, format);
- metric->rightSideBearing = pcfGetINT16(file, format);
- metric->characterWidth = pcfGetINT16(file, format);
- metric->ascent = pcfGetINT16(file, format);
- metric->descent = pcfGetINT16(file, format);
- metric->attributes = pcfGetINT16(file, format);
- if (IS_EOF(file)) return FALSE;
-
- return TRUE;
-}
-
-static Bool
-pcfGetCompressedMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
-{
- metric->leftSideBearing = pcfGetINT8(file, format) - 0x80;
- metric->rightSideBearing = pcfGetINT8(file, format) - 0x80;
- metric->characterWidth = pcfGetINT8(file, format) - 0x80;
- metric->ascent = pcfGetINT8(file, format) - 0x80;
- metric->descent = pcfGetINT8(file, format) - 0x80;
- metric->attributes = 0;
- if (IS_EOF(file)) return FALSE;
-
- return TRUE;
-}
-
-/*
- * Position the file to the begining of the specified table
- * in the font file
- */
-static Bool
-pcfSeekToType(FontFilePtr file, PCFTablePtr tables, int ntables,
- CARD32 type, CARD32 *formatp, CARD32 *sizep)
-{
- int i;
-
- for (i = 0; i < ntables; i++)
- if (tables[i].type == type) {
- if (position > tables[i].offset)
- return FALSE;
- if (!FontFileSkip(file, tables[i].offset - position))
- return FALSE;
- position = tables[i].offset;
- *sizep = tables[i].size;
- *formatp = tables[i].format;
- return TRUE;
- }
- return FALSE;
-}
-
-static Bool
-pcfHasType (PCFTablePtr tables, int ntables, CARD32 type)
-{
- int i;
-
- for (i = 0; i < ntables; i++)
- if (tables[i].type == type)
- return TRUE;
- return FALSE;
-}
-
-/*
- * pcfGetProperties
- *
- * Reads the font properties from the font file, filling in the FontInfo rec
- * supplied. Used by by both ReadFont and ReadFontInfo routines.
- */
-
-static Bool
-pcfGetProperties(FontInfoPtr pFontInfo, FontFilePtr file,
- PCFTablePtr tables, int ntables)
-{
- FontPropPtr props = 0;
- int nprops;
- char *isStringProp = 0;
- CARD32 format;
- int i;
- CARD32 size;
- int string_size;
- char *strings;
-
- /* font properties */
-
- if (!pcfSeekToType(file, tables, ntables, PCF_PROPERTIES, &format, &size))
- goto Bail;
- format = pcfGetLSB32(file);
- if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
- goto Bail;
- nprops = pcfGetINT32(file, format);
- if (nprops <= 0 || nprops > INT32_MAX / sizeof(FontPropRec)) {
- pcfError("pcfGetProperties(): invalid nprops value (%d)\n", nprops);
- goto Bail;
- }
- if (IS_EOF(file)) goto Bail;
- props = malloc(nprops * sizeof(FontPropRec));
- if (!props) {
- pcfError("pcfGetProperties(): Couldn't allocate props (%d*%d)\n", nprops, sizeof(FontPropRec));
- goto Bail;
- }
- isStringProp = malloc(nprops * sizeof(char));
- if (!isStringProp) {
- pcfError("pcfGetProperties(): Couldn't allocate isStringProp (%d*%d)\n", nprops, sizeof(char));
- goto Bail;
- }
- for (i = 0; i < nprops; i++) {
- props[i].name = pcfGetINT32(file, format);
- isStringProp[i] = pcfGetINT8(file, format);
- props[i].value = pcfGetINT32(file, format);
- if (props[i].name < 0
- || (isStringProp[i] != 0 && isStringProp[i] != 1)
- || (isStringProp[i] && props[i].value < 0)) {
- pcfError("pcfGetProperties(): invalid file format %d %d %d\n",
- props[i].name, isStringProp[i], props[i].value);
- goto Bail;
- }
- if (IS_EOF(file)) goto Bail;
- }
- /* pad the property array */
- /*
- * clever here - nprops is the same as the number of odd-units read, as
- * only isStringProp are odd length
- */
- if (nprops & 3)
- {
- i = 4 - (nprops & 3);
- (void)FontFileSkip(file, i);
- position += i;
- }
- if (IS_EOF(file)) goto Bail;
- string_size = pcfGetINT32(file, format);
- if (string_size < 0) goto Bail;
- if (IS_EOF(file)) goto Bail;
- strings = malloc(string_size);
- if (!strings) {
- pcfError("pcfGetProperties(): Couldn't allocate strings (%d)\n", string_size);
- goto Bail;
- }
- FontFileRead(file, strings, string_size);
- if (IS_EOF(file)) goto Bail;
- position += string_size;
- for (i = 0; i < nprops; i++) {
- props[i].name = MakeAtom(strings + props[i].name,
- strlen(strings + props[i].name), TRUE);
- if (isStringProp[i]) {
- props[i].value = MakeAtom(strings + props[i].value,
- strlen(strings + props[i].value), TRUE);
- }
- }
- free(strings);
- pFontInfo->isStringProp = isStringProp;
- pFontInfo->props = props;
- pFontInfo->nprops = nprops;
- return TRUE;
-Bail:
- free(isStringProp);
- free(props);
- return FALSE;
-}
-
-
-/*
- * pcfReadAccel
- *
- * Fill in the accelerator information from the font file; used
- * to read both BDF_ACCELERATORS and old style ACCELERATORS
- */
-
-static Bool
-pcfGetAccel(FontInfoPtr pFontInfo, FontFilePtr file,
- PCFTablePtr tables, int ntables, CARD32 type)
-{
- CARD32 format;
- CARD32 size;
-
- if (!pcfSeekToType(file, tables, ntables, type, &format, &size) ||
- IS_EOF(file))
- goto Bail;
- format = pcfGetLSB32(file);
- if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
- !PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS))
- {
- goto Bail;
- }
- pFontInfo->noOverlap = pcfGetINT8(file, format);
- pFontInfo->constantMetrics = pcfGetINT8(file, format);
- pFontInfo->terminalFont = pcfGetINT8(file, format);
- pFontInfo->constantWidth = pcfGetINT8(file, format);
- pFontInfo->inkInside = pcfGetINT8(file, format);
- pFontInfo->inkMetrics = pcfGetINT8(file, format);
- pFontInfo->drawDirection = pcfGetINT8(file, format);
- pFontInfo->anamorphic = FALSE;
- pFontInfo->cachable = TRUE;
- /* natural alignment */ pcfGetINT8(file, format);
- pFontInfo->fontAscent = pcfGetINT32(file, format);
- pFontInfo->fontDescent = pcfGetINT32(file, format);
- pFontInfo->maxOverlap = pcfGetINT32(file, format);
- if (IS_EOF(file)) goto Bail;
- if (!pcfGetMetric(file, format, &pFontInfo->minbounds))
- goto Bail;
- if (!pcfGetMetric(file, format, &pFontInfo->maxbounds))
- goto Bail;
- if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
- if (!pcfGetMetric(file, format, &pFontInfo->ink_minbounds))
- goto Bail;
- if (!pcfGetMetric(file, format, &pFontInfo->ink_maxbounds))
- goto Bail;
- } else {
- pFontInfo->ink_minbounds = pFontInfo->minbounds;
- pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
- }
- return TRUE;
-Bail:
- return FALSE;
-}
-
-int
-pcfReadFont(FontPtr pFont, FontFilePtr file,
- int bit, int byte, int glyph, int scan)
-{
- CARD32 format;
- CARD32 size;
- BitmapFontPtr bitmapFont = 0;
- int i;
- PCFTablePtr tables = 0;
- int ntables;
- int nmetrics;
- int nbitmaps;
- int sizebitmaps;
- int nink_metrics;
- CharInfoPtr metrics = 0;
- xCharInfo *ink_metrics = 0;
- char *bitmaps = 0;
- CharInfoPtr **encoding = 0;
- int nencoding = 0;
- int encodingOffset;
- CARD32 bitmapSizes[GLYPHPADOPTIONS];
- CARD32 *offsets = 0;
- Bool hasBDFAccelerators;
-
- pFont->info.nprops = 0;
- pFont->info.props = 0;
- if (!(tables = pcfReadTOC(file, &ntables)))
- goto Bail;
-
- /* properties */
-
- if (!pcfGetProperties(&pFont->info, file, tables, ntables))
- goto Bail;
-
- /* Use the old accelerators if no BDF accelerators are in the file */
-
- hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
- if (!hasBDFAccelerators)
- if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_ACCELERATORS))
- goto Bail;
-
- /* metrics */
-
- if (!pcfSeekToType(file, tables, ntables, PCF_METRICS, &format, &size)) {
- goto Bail;
- }
- format = pcfGetLSB32(file);
- if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
- !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
- goto Bail;
- }
- if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
- nmetrics = pcfGetINT32(file, format);
- else
- nmetrics = pcfGetINT16(file, format);
- if (IS_EOF(file)) goto Bail;
- if (nmetrics < 0 || nmetrics > INT32_MAX / sizeof(CharInfoRec)) {
- pcfError("pcfReadFont(): invalid file format\n");
- goto Bail;
- }
- metrics = malloc(nmetrics * sizeof(CharInfoRec));
- if (!metrics) {
- pcfError("pcfReadFont(): Couldn't allocate metrics (%d*%d)\n", nmetrics, sizeof(CharInfoRec));
- goto Bail;
- }
- for (i = 0; i < nmetrics; i++)
- if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
- if (!pcfGetMetric(file, format, &(metrics + i)->metrics))
- goto Bail;
- } else {
- if (!pcfGetCompressedMetric(file, format, &(metrics + i)->metrics))
- goto Bail;
- }
-
- /* bitmaps */
-
- if (!pcfSeekToType(file, tables, ntables, PCF_BITMAPS, &format, &size))
- goto Bail;
- format = pcfGetLSB32(file);
- if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
- goto Bail;
-
- nbitmaps = pcfGetINT32(file, format);
- if (nbitmaps != nmetrics || IS_EOF(file))
- goto Bail;
- /* nmetrics is already ok, so nbitmap also is */
- offsets = malloc(nbitmaps * sizeof(CARD32));
- if (!offsets) {
- pcfError("pcfReadFont(): Couldn't allocate offsets (%d*%d)\n", nbitmaps, sizeof(CARD32));
- goto Bail;
- }
- for (i = 0; i < nbitmaps; i++) {
- offsets[i] = pcfGetINT32(file, format);
- if (IS_EOF(file)) goto Bail;
- }
-
- for (i = 0; i < GLYPHPADOPTIONS; i++) {
- bitmapSizes[i] = pcfGetINT32(file, format);
- if (IS_EOF(file)) goto Bail;
- if (bitmapSizes[i] < 0) goto Bail;
- }
-
- sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX(format)];
- /* guard against completely empty font */
- bitmaps = malloc(sizebitmaps ? sizebitmaps : 1);
- if (!bitmaps) {
- pcfError("pcfReadFont(): Couldn't allocate bitmaps (%d)\n", sizebitmaps ? sizebitmaps : 1);
- goto Bail;
- }
- FontFileRead(file, bitmaps, sizebitmaps);
- if (IS_EOF(file)) goto Bail;
- position += sizebitmaps;
-
- if (PCF_BIT_ORDER(format) != bit)
- BitOrderInvert((unsigned char *)bitmaps, sizebitmaps);
- if ((PCF_BYTE_ORDER(format) == PCF_BIT_ORDER(format)) != (bit == byte)) {
- switch (bit == byte ? PCF_SCAN_UNIT(format) : scan) {
- case 1:
- break;
- case 2:
- TwoByteSwap((unsigned char *)bitmaps, sizebitmaps);
- break;
- case 4:
- FourByteSwap((unsigned char *)bitmaps, sizebitmaps);
- break;
- }
- }
- if (PCF_GLYPH_PAD(format) != glyph) {
- char *padbitmaps;
- int sizepadbitmaps;
- int old,
- new;
- xCharInfo *metric;
-
- sizepadbitmaps = bitmapSizes[PCF_SIZE_TO_INDEX(glyph)];
- padbitmaps = malloc(sizepadbitmaps);
- if (!padbitmaps) {
- pcfError("pcfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
- goto Bail;
- }
- new = 0;
- for (i = 0; i < nbitmaps; i++) {
- old = offsets[i];
- metric = &metrics[i].metrics;
- offsets[i] = new;
- new += RepadBitmap(bitmaps + old, padbitmaps + new,
- PCF_GLYPH_PAD(format), glyph,
- metric->rightSideBearing - metric->leftSideBearing,
- metric->ascent + metric->descent);
- }
- free(bitmaps);
- bitmaps = padbitmaps;
- }
- for (i = 0; i < nbitmaps; i++)
- metrics[i].bits = bitmaps + offsets[i];
-
- free(offsets);
- offsets = NULL;
-
- /* ink metrics ? */
-
- ink_metrics = NULL;
- if (pcfSeekToType(file, tables, ntables, PCF_INK_METRICS, &format, &size)) {
- format = pcfGetLSB32(file);
- if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
- !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
- goto Bail;
- }
- if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
- nink_metrics = pcfGetINT32(file, format);
- else
- nink_metrics = pcfGetINT16(file, format);
- if (IS_EOF(file)) goto Bail;
- if (nink_metrics != nmetrics)
- goto Bail;
- /* nmetrics already checked */
- ink_metrics = malloc(nink_metrics * sizeof(xCharInfo));
- if (!ink_metrics) {
- pcfError("pcfReadFont(): Couldn't allocate ink_metrics (%d*%d)\n", nink_metrics, sizeof(xCharInfo));
- goto Bail;
- }
- for (i = 0; i < nink_metrics; i++)
- if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
- if (!pcfGetMetric(file, format, ink_metrics + i))
- goto Bail;
- } else {
- if (!pcfGetCompressedMetric(file, format, ink_metrics + i))
- goto Bail;
- }
- }
-
- /* encoding */
-
- if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
- goto Bail;
- format = pcfGetLSB32(file);
- if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
- goto Bail;
-
- pFont->info.firstCol = pcfGetINT16(file, format);
- pFont->info.lastCol = pcfGetINT16(file, format);
- pFont->info.firstRow = pcfGetINT16(file, format);
- pFont->info.lastRow = pcfGetINT16(file, format);
- pFont->info.defaultCh = pcfGetINT16(file, format);
- if (IS_EOF(file)) goto Bail;
- if (pFont->info.firstCol > pFont->info.lastCol ||
- pFont->info.firstRow > pFont->info.lastRow ||
- pFont->info.lastCol-pFont->info.firstCol > 255) goto Bail;
-
- nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
- (pFont->info.lastRow - pFont->info.firstRow + 1);
-
- encoding = calloc(NUM_SEGMENTS(nencoding), sizeof(CharInfoPtr*));
- if (!encoding) {
- pcfError("pcfReadFont(): Couldn't allocate encoding (%d*%d)\n", nencoding, sizeof(CharInfoPtr));
- goto Bail;
- }
-
- pFont->info.allExist = TRUE;
- for (i = 0; i < nencoding; i++) {
- encodingOffset = pcfGetINT16(file, format);
- if (IS_EOF(file)) goto Bail;
- if (encodingOffset == 0xFFFF) {
- pFont->info.allExist = FALSE;
- } else {
- if(!encoding[SEGMENT_MAJOR(i)]) {
- encoding[SEGMENT_MAJOR(i)]=
- calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr));
- if(!encoding[SEGMENT_MAJOR(i)])
- goto Bail;
- }
- ACCESSENCODINGL(encoding, i) = metrics + encodingOffset;
- }
- }
-
- /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
-
- if (hasBDFAccelerators)
- if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_BDF_ACCELERATORS))
- goto Bail;
-
- bitmapFont = malloc(sizeof *bitmapFont);
- if (!bitmapFont) {
- pcfError("pcfReadFont(): Couldn't allocate bitmapFont (%d)\n", sizeof *bitmapFont);
- goto Bail;
- }
-
- bitmapFont->version_num = PCF_FILE_VERSION;
- bitmapFont->num_chars = nmetrics;
- bitmapFont->num_tables = ntables;
- bitmapFont->metrics = metrics;
- bitmapFont->ink_metrics = ink_metrics;
- bitmapFont->bitmaps = bitmaps;
- bitmapFont->encoding = encoding;
- bitmapFont->pDefault = (CharInfoPtr) 0;
- if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
- unsigned int r,
- c,
- cols;
-
- r = pFont->info.defaultCh >> 8;
- c = pFont->info.defaultCh & 0xFF;
- if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
- pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
- cols = pFont->info.lastCol - pFont->info.firstCol + 1;
- r = r - pFont->info.firstRow;
- c = c - pFont->info.firstCol;
- bitmapFont->pDefault = ACCESSENCODING(encoding, r * cols + c);
- }
- }
- bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
- pFont->fontPrivate = (pointer) bitmapFont;
- pFont->get_glyphs = bitmapGetGlyphs;
- pFont->get_metrics = bitmapGetMetrics;
- pFont->unload_font = pcfUnloadFont;
- pFont->unload_glyphs = NULL;
- pFont->bit = bit;
- pFont->byte = byte;
- pFont->glyph = glyph;
- pFont->scan = scan;
- free(tables);
- return Successful;
-Bail:
- free(ink_metrics);
- if(encoding) {
- for(i=0; i<NUM_SEGMENTS(nencoding); i++)
- free(encoding[i]);
- }
- free(encoding);
- free(bitmaps);
- free(metrics);
- free(pFont->info.props);
- pFont->info.nprops = 0;
- pFont->info.props = 0;
- free (pFont->info.isStringProp);
- free(bitmapFont);
- free(tables);
- free(offsets);
- return AllocError;
-}
-
-int
-pcfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
-{
- PCFTablePtr tables;
- int ntables;
- CARD32 format;
- CARD32 size;
- int nencoding;
- Bool hasBDFAccelerators;
-
- pFontInfo->isStringProp = NULL;
- pFontInfo->props = NULL;
- pFontInfo->nprops = 0;
-
- if (!(tables = pcfReadTOC(file, &ntables)))
- goto Bail;
-
- /* properties */
-
- if (!pcfGetProperties(pFontInfo, file, tables, ntables))
- goto Bail;
-
- /* Use the old accelerators if no BDF accelerators are in the file */
-
- hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
- if (!hasBDFAccelerators)
- if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_ACCELERATORS))
- goto Bail;
-
- /* encoding */
-
- if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
- goto Bail;
- format = pcfGetLSB32(file);
- if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
- goto Bail;
-
- pFontInfo->firstCol = pcfGetINT16(file, format);
- pFontInfo->lastCol = pcfGetINT16(file, format);
- pFontInfo->firstRow = pcfGetINT16(file, format);
- pFontInfo->lastRow = pcfGetINT16(file, format);
- pFontInfo->defaultCh = pcfGetINT16(file, format);
- if (IS_EOF(file)) goto Bail;
- if (pFontInfo->firstCol > pFontInfo->lastCol ||
- pFontInfo->firstRow > pFontInfo->lastRow ||
- pFontInfo->lastCol-pFontInfo->firstCol > 255) goto Bail;
-
- nencoding = (pFontInfo->lastCol - pFontInfo->firstCol + 1) *
- (pFontInfo->lastRow - pFontInfo->firstRow + 1);
-
- pFontInfo->allExist = TRUE;
- while (nencoding--) {
- if (pcfGetINT16(file, format) == 0xFFFF)
- pFontInfo->allExist = FALSE;
- if (IS_EOF(file)) goto Bail;
- }
- if (IS_EOF(file)) goto Bail;
-
- /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
-
- if (hasBDFAccelerators)
- if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_BDF_ACCELERATORS))
- goto Bail;
-
- free(tables);
- return Successful;
-Bail:
- pFontInfo->nprops = 0;
- free (pFontInfo->props);
- free (pFontInfo->isStringProp);
- free(tables);
- return AllocError;
-}
-
-static void
-pcfUnloadFont(FontPtr pFont)
-{
- BitmapFontPtr bitmapFont;
- int i,nencoding;
-
- bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
- free(bitmapFont->ink_metrics);
- if(bitmapFont->encoding) {
- nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
- (pFont->info.lastRow - pFont->info.firstRow + 1);
- for(i=0; i<NUM_SEGMENTS(nencoding); i++)
- free(bitmapFont->encoding[i]);
- }
- free(bitmapFont->encoding);
- free(bitmapFont->bitmaps);
- free(bitmapFont->metrics);
- free(pFont->info.isStringProp);
- free(pFont->info.props);
- free(bitmapFont);
- DestroyFontRec(pFont);
-}
+/*
+
+Copyright 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/pcf.h>
+
+#ifndef MAX
+#define MAX(a,b) (((a)>(b)) ? a : b)
+#endif
+
+#include <stdarg.h>
+#include <stdint.h>
+
+void
+pcfError(const char* message, ...)
+{
+ va_list args;
+
+ va_start(args, message);
+
+ fprintf(stderr, "PCF Error: ");
+ vfprintf(stderr, message, args);
+ va_end(args);
+}
+
+/* Read PCF font files */
+
+static void pcfUnloadFont ( FontPtr pFont );
+static int position;
+
+
+#define IS_EOF(file) ((file)->eof == BUFFILEEOF)
+
+#define FONT_FILE_GETC_ERR(f) (tmp = FontFileGetc(f), BAIL_ON_EOF)
+
+static int
+pcfGetLSB32(FontFilePtr file)
+{
+ int c;
+
+ c = FontFileGetc(file);
+ c |= FontFileGetc(file) << 8;
+ c |= FontFileGetc(file) << 16;
+ c |= FontFileGetc(file) << 24;
+ position += 4;
+ return c;
+}
+
+static int
+pcfGetINT32(FontFilePtr file, CARD32 format)
+{
+ int c;
+
+ if (PCF_BYTE_ORDER(format) == MSBFirst) {
+ c = FontFileGetc(file) << 24;
+ c |= FontFileGetc(file) << 16;
+ c |= FontFileGetc(file) << 8;
+ c |= FontFileGetc(file);
+ } else {
+ c = FontFileGetc(file);
+ c |= FontFileGetc(file) << 8;
+ c |= FontFileGetc(file) << 16;
+ c |= FontFileGetc(file) << 24;
+ }
+ position += 4;
+ return c;
+}
+
+static int
+pcfGetINT16(FontFilePtr file, CARD32 format)
+{
+ int c;
+
+ if (PCF_BYTE_ORDER(format) == MSBFirst) {
+ c = FontFileGetc(file) << 8;
+ c |= FontFileGetc(file);
+ } else {
+ c = FontFileGetc(file);
+ c |= FontFileGetc(file) << 8;
+ }
+ position += 2;
+ return c;
+}
+
+#define pcfGetINT8(file, format) (position++, FontFileGetc(file))
+
+static PCFTablePtr
+pcfReadTOC(FontFilePtr file, int *countp)
+{
+ CARD32 version;
+ PCFTablePtr tables;
+ int count;
+ int i;
+
+ position = 0;
+ version = pcfGetLSB32(file);
+ if (version != PCF_FILE_VERSION)
+ return (PCFTablePtr) NULL;
+ count = pcfGetLSB32(file);
+ if (IS_EOF(file)) return (PCFTablePtr) NULL;
+ if (count < 0 || count > INT32_MAX / sizeof(PCFTableRec)) {
+ pcfError("pcfReadTOC(): invalid file format\n");
+ return NULL;
+ }
+ tables = malloc(count * sizeof(PCFTableRec));
+ if (!tables) {
+ pcfError("pcfReadTOC(): Couldn't allocate tables (%d*%d)\n", count, sizeof(PCFTableRec));
+ return (PCFTablePtr) NULL;
+ }
+ for (i = 0; i < count; i++) {
+ tables[i].type = pcfGetLSB32(file);
+ tables[i].format = pcfGetLSB32(file);
+ tables[i].size = pcfGetLSB32(file);
+ tables[i].offset = pcfGetLSB32(file);
+ if (IS_EOF(file)) goto Bail;
+ }
+
+ *countp = count;
+ return tables;
+
+ Bail:
+ free(tables);
+ return (PCFTablePtr) NULL;
+}
+
+/*
+ * PCF supports two formats for metrics, both the regular
+ * jumbo size, and 'lite' metrics, which are useful
+ * for most fonts which have even vaguely reasonable
+ * metrics
+ */
+
+static Bool
+pcfGetMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
+{
+ metric->leftSideBearing = pcfGetINT16(file, format);
+ metric->rightSideBearing = pcfGetINT16(file, format);
+ metric->characterWidth = pcfGetINT16(file, format);
+ metric->ascent = pcfGetINT16(file, format);
+ metric->descent = pcfGetINT16(file, format);
+ metric->attributes = pcfGetINT16(file, format);
+ if (IS_EOF(file)) return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+pcfGetCompressedMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
+{
+ metric->leftSideBearing = pcfGetINT8(file, format) - 0x80;
+ metric->rightSideBearing = pcfGetINT8(file, format) - 0x80;
+ metric->characterWidth = pcfGetINT8(file, format) - 0x80;
+ metric->ascent = pcfGetINT8(file, format) - 0x80;
+ metric->descent = pcfGetINT8(file, format) - 0x80;
+ metric->attributes = 0;
+ if (IS_EOF(file)) return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * Position the file to the begining of the specified table
+ * in the font file
+ */
+static Bool
+pcfSeekToType(FontFilePtr file, PCFTablePtr tables, int ntables,
+ CARD32 type, CARD32 *formatp, CARD32 *sizep)
+{
+ int i;
+
+ for (i = 0; i < ntables; i++)
+ if (tables[i].type == type) {
+ if (position > tables[i].offset)
+ return FALSE;
+ if (!FontFileSkip(file, tables[i].offset - position))
+ return FALSE;
+ position = tables[i].offset;
+ *sizep = tables[i].size;
+ *formatp = tables[i].format;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static Bool
+pcfHasType (PCFTablePtr tables, int ntables, CARD32 type)
+{
+ int i;
+
+ for (i = 0; i < ntables; i++)
+ if (tables[i].type == type)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * pcfGetProperties
+ *
+ * Reads the font properties from the font file, filling in the FontInfo rec
+ * supplied. Used by by both ReadFont and ReadFontInfo routines.
+ */
+
+static Bool
+pcfGetProperties(FontInfoPtr pFontInfo, FontFilePtr file,
+ PCFTablePtr tables, int ntables)
+{
+ FontPropPtr props = 0;
+ int nprops;
+ char *isStringProp = 0;
+ CARD32 format;
+ int i;
+ CARD32 size;
+ int string_size;
+ char *strings;
+
+ /* font properties */
+
+ if (!pcfSeekToType(file, tables, ntables, PCF_PROPERTIES, &format, &size))
+ goto Bail;
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ goto Bail;
+ nprops = pcfGetINT32(file, format);
+ if (nprops <= 0 || nprops > INT32_MAX / sizeof(FontPropRec)) {
+ pcfError("pcfGetProperties(): invalid nprops value (%d)\n", nprops);
+ goto Bail;
+ }
+ if (IS_EOF(file)) goto Bail;
+ props = malloc(nprops * sizeof(FontPropRec));
+ if (!props) {
+ pcfError("pcfGetProperties(): Couldn't allocate props (%d*%d)\n", nprops, sizeof(FontPropRec));
+ goto Bail;
+ }
+ isStringProp = malloc(nprops * sizeof(char));
+ if (!isStringProp) {
+ pcfError("pcfGetProperties(): Couldn't allocate isStringProp (%d*%d)\n", nprops, sizeof(char));
+ goto Bail;
+ }
+ for (i = 0; i < nprops; i++) {
+ props[i].name = pcfGetINT32(file, format);
+ isStringProp[i] = pcfGetINT8(file, format);
+ props[i].value = pcfGetINT32(file, format);
+ if (props[i].name < 0
+ || (isStringProp[i] != 0 && isStringProp[i] != 1)
+ || (isStringProp[i] && props[i].value < 0)) {
+ pcfError("pcfGetProperties(): invalid file format %d %d %d\n",
+ props[i].name, isStringProp[i], props[i].value);
+ goto Bail;
+ }
+ if (IS_EOF(file)) goto Bail;
+ }
+ /* pad the property array */
+ /*
+ * clever here - nprops is the same as the number of odd-units read, as
+ * only isStringProp are odd length
+ */
+ if (nprops & 3)
+ {
+ i = 4 - (nprops & 3);
+ (void)FontFileSkip(file, i);
+ position += i;
+ }
+ if (IS_EOF(file)) goto Bail;
+ string_size = pcfGetINT32(file, format);
+ if (string_size < 0) goto Bail;
+ if (IS_EOF(file)) goto Bail;
+ strings = malloc(string_size);
+ if (!strings) {
+ pcfError("pcfGetProperties(): Couldn't allocate strings (%d)\n", string_size);
+ goto Bail;
+ }
+ FontFileRead(file, strings, string_size);
+ if (IS_EOF(file)) goto Bail;
+ position += string_size;
+ for (i = 0; i < nprops; i++) {
+ props[i].name = MakeAtom(strings + props[i].name,
+ strlen(strings + props[i].name), TRUE);
+ if (isStringProp[i]) {
+ props[i].value = MakeAtom(strings + props[i].value,
+ strlen(strings + props[i].value), TRUE);
+ }
+ }
+ free(strings);
+ pFontInfo->isStringProp = isStringProp;
+ pFontInfo->props = props;
+ pFontInfo->nprops = nprops;
+ return TRUE;
+Bail:
+ free(isStringProp);
+ free(props);
+ return FALSE;
+}
+
+
+/*
+ * pcfReadAccel
+ *
+ * Fill in the accelerator information from the font file; used
+ * to read both BDF_ACCELERATORS and old style ACCELERATORS
+ */
+
+static Bool
+pcfGetAccel(FontInfoPtr pFontInfo, FontFilePtr file,
+ PCFTablePtr tables, int ntables, CARD32 type)
+{
+ CARD32 format;
+ CARD32 size;
+
+ if (!pcfSeekToType(file, tables, ntables, type, &format, &size) ||
+ IS_EOF(file))
+ goto Bail;
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
+ !PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS))
+ {
+ goto Bail;
+ }
+ pFontInfo->noOverlap = pcfGetINT8(file, format);
+ pFontInfo->constantMetrics = pcfGetINT8(file, format);
+ pFontInfo->terminalFont = pcfGetINT8(file, format);
+ pFontInfo->constantWidth = pcfGetINT8(file, format);
+ pFontInfo->inkInside = pcfGetINT8(file, format);
+ pFontInfo->inkMetrics = pcfGetINT8(file, format);
+ pFontInfo->drawDirection = pcfGetINT8(file, format);
+ pFontInfo->anamorphic = FALSE;
+ pFontInfo->cachable = TRUE;
+ /* natural alignment */ pcfGetINT8(file, format);
+ pFontInfo->fontAscent = pcfGetINT32(file, format);
+ pFontInfo->fontDescent = pcfGetINT32(file, format);
+ pFontInfo->maxOverlap = pcfGetINT32(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (!pcfGetMetric(file, format, &pFontInfo->minbounds))
+ goto Bail;
+ if (!pcfGetMetric(file, format, &pFontInfo->maxbounds))
+ goto Bail;
+ if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
+ if (!pcfGetMetric(file, format, &pFontInfo->ink_minbounds))
+ goto Bail;
+ if (!pcfGetMetric(file, format, &pFontInfo->ink_maxbounds))
+ goto Bail;
+ } else {
+ pFontInfo->ink_minbounds = pFontInfo->minbounds;
+ pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
+ }
+ return TRUE;
+Bail:
+ return FALSE;
+}
+
+int
+pcfReadFont(FontPtr pFont, FontFilePtr file,
+ int bit, int byte, int glyph, int scan)
+{
+ CARD32 format;
+ CARD32 size;
+ BitmapFontPtr bitmapFont = 0;
+ int i;
+ PCFTablePtr tables = 0;
+ int ntables;
+ int nmetrics;
+ int nbitmaps;
+ int sizebitmaps;
+ int nink_metrics;
+ CharInfoPtr metrics = 0;
+ xCharInfo *ink_metrics = 0;
+ char *bitmaps = 0;
+ CharInfoPtr **encoding = 0;
+ int nencoding = 0;
+ int encodingOffset;
+ CARD32 bitmapSizes[GLYPHPADOPTIONS];
+ CARD32 *offsets = 0;
+ Bool hasBDFAccelerators;
+
+ pFont->info.nprops = 0;
+ pFont->info.props = 0;
+ if (!(tables = pcfReadTOC(file, &ntables)))
+ goto Bail;
+
+ /* properties */
+
+ if (!pcfGetProperties(&pFont->info, file, tables, ntables))
+ goto Bail;
+
+ /* Use the old accelerators if no BDF accelerators are in the file */
+
+ hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
+ if (!hasBDFAccelerators)
+ if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_ACCELERATORS))
+ goto Bail;
+
+ /* metrics */
+
+ if (!pcfSeekToType(file, tables, ntables, PCF_METRICS, &format, &size)) {
+ goto Bail;
+ }
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
+ !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
+ goto Bail;
+ }
+ if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ nmetrics = pcfGetINT32(file, format);
+ else
+ nmetrics = pcfGetINT16(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (nmetrics < 0 || nmetrics > INT32_MAX / sizeof(CharInfoRec)) {
+ pcfError("pcfReadFont(): invalid file format\n");
+ goto Bail;
+ }
+ metrics = malloc(nmetrics * sizeof(CharInfoRec));
+ if (!metrics) {
+ pcfError("pcfReadFont(): Couldn't allocate metrics (%d*%d)\n", nmetrics, sizeof(CharInfoRec));
+ goto Bail;
+ }
+ for (i = 0; i < nmetrics; i++)
+ if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
+ if (!pcfGetMetric(file, format, &(metrics + i)->metrics))
+ goto Bail;
+ } else {
+ if (!pcfGetCompressedMetric(file, format, &(metrics + i)->metrics))
+ goto Bail;
+ }
+
+ /* bitmaps */
+
+ if (!pcfSeekToType(file, tables, ntables, PCF_BITMAPS, &format, &size))
+ goto Bail;
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ goto Bail;
+
+ nbitmaps = pcfGetINT32(file, format);
+ if (nbitmaps != nmetrics || IS_EOF(file))
+ goto Bail;
+ /* nmetrics is already ok, so nbitmap also is */
+ offsets = malloc(nbitmaps * sizeof(CARD32));
+ if (!offsets) {
+ pcfError("pcfReadFont(): Couldn't allocate offsets (%d*%d)\n", nbitmaps, sizeof(CARD32));
+ goto Bail;
+ }
+ for (i = 0; i < nbitmaps; i++) {
+ offsets[i] = pcfGetINT32(file, format);
+ if (IS_EOF(file)) goto Bail;
+ }
+
+ for (i = 0; i < GLYPHPADOPTIONS; i++) {
+ bitmapSizes[i] = pcfGetINT32(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (bitmapSizes[i] < 0) goto Bail;
+ }
+
+ sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX(format)];
+ /* guard against completely empty font */
+ bitmaps = malloc(sizebitmaps ? sizebitmaps : 1);
+ if (!bitmaps) {
+ pcfError("pcfReadFont(): Couldn't allocate bitmaps (%d)\n", sizebitmaps ? sizebitmaps : 1);
+ goto Bail;
+ }
+ FontFileRead(file, bitmaps, sizebitmaps);
+ if (IS_EOF(file)) goto Bail;
+ position += sizebitmaps;
+
+ if (PCF_BIT_ORDER(format) != bit)
+ BitOrderInvert((unsigned char *)bitmaps, sizebitmaps);
+ if ((PCF_BYTE_ORDER(format) == PCF_BIT_ORDER(format)) != (bit == byte)) {
+ switch (bit == byte ? PCF_SCAN_UNIT(format) : scan) {
+ case 1:
+ break;
+ case 2:
+ TwoByteSwap((unsigned char *)bitmaps, sizebitmaps);
+ break;
+ case 4:
+ FourByteSwap((unsigned char *)bitmaps, sizebitmaps);
+ break;
+ }
+ }
+ if (PCF_GLYPH_PAD(format) != glyph) {
+ char *padbitmaps;
+ int sizepadbitmaps;
+ int old,
+ new;
+ xCharInfo *metric;
+
+ sizepadbitmaps = bitmapSizes[PCF_SIZE_TO_INDEX(glyph)];
+ padbitmaps = malloc(sizepadbitmaps);
+ if (!padbitmaps) {
+ pcfError("pcfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
+ goto Bail;
+ }
+ new = 0;
+ for (i = 0; i < nbitmaps; i++) {
+ old = offsets[i];
+ metric = &metrics[i].metrics;
+ offsets[i] = new;
+ new += RepadBitmap(bitmaps + old, padbitmaps + new,
+ PCF_GLYPH_PAD(format), glyph,
+ metric->rightSideBearing - metric->leftSideBearing,
+ metric->ascent + metric->descent);
+ }
+ free(bitmaps);
+ bitmaps = padbitmaps;
+ }
+ for (i = 0; i < nbitmaps; i++)
+ metrics[i].bits = bitmaps + offsets[i];
+
+ free(offsets);
+ offsets = NULL;
+
+ /* ink metrics ? */
+
+ ink_metrics = NULL;
+ if (pcfSeekToType(file, tables, ntables, PCF_INK_METRICS, &format, &size)) {
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) &&
+ !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) {
+ goto Bail;
+ }
+ if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ nink_metrics = pcfGetINT32(file, format);
+ else
+ nink_metrics = pcfGetINT16(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (nink_metrics != nmetrics)
+ goto Bail;
+ /* nmetrics already checked */
+ ink_metrics = malloc(nink_metrics * sizeof(xCharInfo));
+ if (!ink_metrics) {
+ pcfError("pcfReadFont(): Couldn't allocate ink_metrics (%d*%d)\n", nink_metrics, sizeof(xCharInfo));
+ goto Bail;
+ }
+ for (i = 0; i < nink_metrics; i++)
+ if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) {
+ if (!pcfGetMetric(file, format, ink_metrics + i))
+ goto Bail;
+ } else {
+ if (!pcfGetCompressedMetric(file, format, ink_metrics + i))
+ goto Bail;
+ }
+ }
+
+ /* encoding */
+
+ if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
+ goto Bail;
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ goto Bail;
+
+ pFont->info.firstCol = pcfGetINT16(file, format);
+ pFont->info.lastCol = pcfGetINT16(file, format);
+ pFont->info.firstRow = pcfGetINT16(file, format);
+ pFont->info.lastRow = pcfGetINT16(file, format);
+ pFont->info.defaultCh = pcfGetINT16(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (pFont->info.firstCol > pFont->info.lastCol ||
+ pFont->info.firstRow > pFont->info.lastRow ||
+ pFont->info.lastCol-pFont->info.firstCol > 255) goto Bail;
+
+ nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
+ (pFont->info.lastRow - pFont->info.firstRow + 1);
+
+ encoding = calloc(NUM_SEGMENTS(nencoding), sizeof(CharInfoPtr*));
+ if (!encoding) {
+ pcfError("pcfReadFont(): Couldn't allocate encoding (%d*%d)\n", nencoding, sizeof(CharInfoPtr));
+ goto Bail;
+ }
+
+ pFont->info.allExist = TRUE;
+ for (i = 0; i < nencoding; i++) {
+ encodingOffset = pcfGetINT16(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (encodingOffset == 0xFFFF) {
+ pFont->info.allExist = FALSE;
+ } else {
+ if(!encoding[SEGMENT_MAJOR(i)]) {
+ encoding[SEGMENT_MAJOR(i)]=
+ calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr));
+ if(!encoding[SEGMENT_MAJOR(i)])
+ goto Bail;
+ }
+ ACCESSENCODINGL(encoding, i) = metrics + encodingOffset;
+ }
+ }
+
+ /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
+
+ if (hasBDFAccelerators)
+ if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_BDF_ACCELERATORS))
+ goto Bail;
+
+ bitmapFont = malloc(sizeof *bitmapFont);
+ if (!bitmapFont) {
+ pcfError("pcfReadFont(): Couldn't allocate bitmapFont (%d)\n", sizeof *bitmapFont);
+ goto Bail;
+ }
+
+ bitmapFont->version_num = PCF_FILE_VERSION;
+ bitmapFont->num_chars = nmetrics;
+ bitmapFont->num_tables = ntables;
+ bitmapFont->metrics = metrics;
+ bitmapFont->ink_metrics = ink_metrics;
+ bitmapFont->bitmaps = bitmaps;
+ bitmapFont->encoding = encoding;
+ bitmapFont->pDefault = (CharInfoPtr) 0;
+ if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
+ unsigned int r,
+ c,
+ cols;
+
+ r = pFont->info.defaultCh >> 8;
+ c = pFont->info.defaultCh & 0xFF;
+ if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
+ pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
+ cols = pFont->info.lastCol - pFont->info.firstCol + 1;
+ r = r - pFont->info.firstRow;
+ c = c - pFont->info.firstCol;
+ bitmapFont->pDefault = ACCESSENCODING(encoding, r * cols + c);
+ }
+ }
+ bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
+ pFont->fontPrivate = (pointer) bitmapFont;
+ pFont->get_glyphs = bitmapGetGlyphs;
+ pFont->get_metrics = bitmapGetMetrics;
+ pFont->unload_font = pcfUnloadFont;
+ pFont->unload_glyphs = NULL;
+ pFont->bit = bit;
+ pFont->byte = byte;
+ pFont->glyph = glyph;
+ pFont->scan = scan;
+ free(tables);
+ return Successful;
+Bail:
+ free(ink_metrics);
+ if(encoding) {
+ for(i=0; i<NUM_SEGMENTS(nencoding); i++)
+ free(encoding[i]);
+ }
+ free(encoding);
+ free(bitmaps);
+ free(metrics);
+ free(pFont->info.props);
+ pFont->info.nprops = 0;
+ pFont->info.props = 0;
+ free (pFont->info.isStringProp);
+ free(bitmapFont);
+ free(tables);
+ free(offsets);
+ return AllocError;
+}
+
+int
+pcfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
+{
+ PCFTablePtr tables;
+ int ntables;
+ CARD32 format;
+ CARD32 size;
+ int nencoding;
+ Bool hasBDFAccelerators;
+
+ pFontInfo->isStringProp = NULL;
+ pFontInfo->props = NULL;
+ pFontInfo->nprops = 0;
+
+ if (!(tables = pcfReadTOC(file, &ntables)))
+ goto Bail;
+
+ /* properties */
+
+ if (!pcfGetProperties(pFontInfo, file, tables, ntables))
+ goto Bail;
+
+ /* Use the old accelerators if no BDF accelerators are in the file */
+
+ hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS);
+ if (!hasBDFAccelerators)
+ if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_ACCELERATORS))
+ goto Bail;
+
+ /* encoding */
+
+ if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size))
+ goto Bail;
+ format = pcfGetLSB32(file);
+ if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT))
+ goto Bail;
+
+ pFontInfo->firstCol = pcfGetINT16(file, format);
+ pFontInfo->lastCol = pcfGetINT16(file, format);
+ pFontInfo->firstRow = pcfGetINT16(file, format);
+ pFontInfo->lastRow = pcfGetINT16(file, format);
+ pFontInfo->defaultCh = pcfGetINT16(file, format);
+ if (IS_EOF(file)) goto Bail;
+ if (pFontInfo->firstCol > pFontInfo->lastCol ||
+ pFontInfo->firstRow > pFontInfo->lastRow ||
+ pFontInfo->lastCol-pFontInfo->firstCol > 255) goto Bail;
+
+ nencoding = (pFontInfo->lastCol - pFontInfo->firstCol + 1) *
+ (pFontInfo->lastRow - pFontInfo->firstRow + 1);
+
+ pFontInfo->allExist = TRUE;
+ while (nencoding--) {
+ if (pcfGetINT16(file, format) == 0xFFFF)
+ pFontInfo->allExist = FALSE;
+ if (IS_EOF(file)) goto Bail;
+ }
+ if (IS_EOF(file)) goto Bail;
+
+ /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
+
+ if (hasBDFAccelerators)
+ if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_BDF_ACCELERATORS))
+ goto Bail;
+
+ free(tables);
+ return Successful;
+Bail:
+ pFontInfo->nprops = 0;
+ free (pFontInfo->props);
+ free (pFontInfo->isStringProp);
+ free(tables);
+ return AllocError;
+}
+
+static void
+pcfUnloadFont(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont;
+ int i,nencoding;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ free(bitmapFont->ink_metrics);
+ if(bitmapFont->encoding) {
+ nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
+ (pFont->info.lastRow - pFont->info.firstRow + 1);
+ for(i=0; i<NUM_SEGMENTS(nencoding); i++)
+ free(bitmapFont->encoding[i]);
+ }
+ free(bitmapFont->encoding);
+ free(bitmapFont->bitmaps);
+ free(bitmapFont->metrics);
+ free(pFont->info.isStringProp);
+ free(pFont->info.props);
+ free(bitmapFont);
+ DestroyFontRec(pFont);
+}
diff --git a/libXfont/src/bitmap/pcfwrite.c b/libXfont/src/bitmap/pcfwrite.c
index 3ac07b359..4c0771e2a 100644
--- a/libXfont/src/bitmap/pcfwrite.c
+++ b/libXfont/src/bitmap/pcfwrite.c
@@ -1,466 +1,466 @@
-/*
-
-Copyright 1990, 1994, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-/*
- * Author: Keith Packard, MIT X Consortium
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <X11/fonts/fntfilst.h>
-#include <X11/fonts/bitmap.h>
-#include <X11/fonts/pcf.h>
-
-/* Write PCF font files */
-
-static CARD32 current_position;
-
-static int
-pcfWrite(FontFilePtr file, char *b, int c)
-{
- current_position += c;
- return FontFileWrite(file, b, c);
-}
-
-static int
-pcfPutLSB32(FontFilePtr file, int c)
-{
- current_position += 4;
- (void) FontFilePutc(c, file);
- (void) FontFilePutc(c >> 8, file);
- (void) FontFilePutc(c >> 16, file);
- return FontFilePutc(c >> 24, file);
-}
-
-static int
-pcfPutINT32(FontFilePtr file, CARD32 format, int c)
-{
- current_position += 4;
- if (PCF_BYTE_ORDER(format) == MSBFirst) {
- (void) FontFilePutc(c >> 24, file);
- (void) FontFilePutc(c >> 16, file);
- (void) FontFilePutc(c >> 8, file);
- return FontFilePutc(c, file);
- } else {
- (void) FontFilePutc(c, file);
- (void) FontFilePutc(c >> 8, file);
- (void) FontFilePutc(c >> 16, file);
- return FontFilePutc(c >> 24, file);
- }
-}
-
-static int
-pcfPutINT16(FontFilePtr file, CARD32 format, int c)
-{
- current_position += 2;
- if (PCF_BYTE_ORDER(format) == MSBFirst) {
- (void) FontFilePutc(c >> 8, file);
- return FontFilePutc(c, file);
- } else {
- (void) FontFilePutc(c, file);
- return FontFilePutc(c >> 8, file);
- }
-}
-
-/*ARGSUSED*/
-static int
-pcfPutINT8(FontFilePtr file, CARD32 format, int c)
-{
- current_position += 1;
- return FontFilePutc(c, file);
-}
-
-static void
-pcfWriteTOC(FontFilePtr file, PCFTablePtr table, int count)
-{
- CARD32 version;
- int i;
-
- version = PCF_FILE_VERSION;
- pcfPutLSB32(file, version);
- pcfPutLSB32(file, count);
- for (i = 0; i < count; i++) {
- pcfPutLSB32(file, table->type);
- pcfPutLSB32(file, table->format);
- pcfPutLSB32(file, table->size);
- pcfPutLSB32(file, table->offset);
- table++;
- }
-}
-
-static void
-pcfPutCompressedMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
-{
- pcfPutINT8(file, format, metric->leftSideBearing + 0x80);
- pcfPutINT8(file, format, metric->rightSideBearing + 0x80);
- pcfPutINT8(file, format, metric->characterWidth + 0x80);
- pcfPutINT8(file, format, metric->ascent + 0x80);
- pcfPutINT8(file, format, metric->descent + 0x80);
-}
-
-static void
-pcfPutMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
-{
- pcfPutINT16(file, format, metric->leftSideBearing);
- pcfPutINT16(file, format, metric->rightSideBearing);
- pcfPutINT16(file, format, metric->characterWidth);
- pcfPutINT16(file, format, metric->ascent);
- pcfPutINT16(file, format, metric->descent);
- pcfPutINT16(file, format, metric->attributes);
-}
-
-static void
-pcfPutBitmap(FontFilePtr file, CARD32 format, CharInfoPtr pCI)
-{
- int count;
- unsigned char *bits;
-
- count = BYTES_FOR_GLYPH(pCI, PCF_GLYPH_PAD(format));
- bits = (unsigned char *) pCI->bits;
- current_position += count;
- while (count--)
- FontFilePutc(*bits++, file);
-}
-
-static void
-pcfPutAccel(FontFilePtr file, CARD32 format, FontInfoPtr pFontInfo)
-{
- pcfPutINT8(file, format, pFontInfo->noOverlap);
- pcfPutINT8(file, format, pFontInfo->constantMetrics);
- pcfPutINT8(file, format, pFontInfo->terminalFont);
- pcfPutINT8(file, format, pFontInfo->constantWidth);
- pcfPutINT8(file, format, pFontInfo->inkInside);
- pcfPutINT8(file, format, pFontInfo->inkMetrics);
- pcfPutINT8(file, format, pFontInfo->drawDirection);
- pcfPutINT8(file, format, 0);
- pcfPutINT32(file, format, pFontInfo->fontAscent);
- pcfPutINT32(file, format, pFontInfo->fontDescent);
- pcfPutINT32(file, format, pFontInfo->maxOverlap);
- pcfPutMetric(file, format, &pFontInfo->minbounds);
- pcfPutMetric(file, format, &pFontInfo->maxbounds);
- if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
- pcfPutMetric(file, format, &pFontInfo->ink_minbounds);
- pcfPutMetric(file, format, &pFontInfo->ink_maxbounds);
- }
-}
-
-#define S32 4
-#define S16 2
-#define S8 1
-
-#define Pad(s) (RoundUp(s) - (s))
-#define RoundUp(s) (((s) + 3) & ~3)
-
-#define Compressable(i) (-128 <= (i) && (i) <= 127)
-
-#define CanCompressMetric(m) (Compressable((m)->leftSideBearing) && \
- Compressable((m)->rightSideBearing) && \
- Compressable((m)->characterWidth) && \
- Compressable((m)->ascent) && \
- Compressable((m)->descent) && \
- (m)->attributes == 0)
-
-#define CanCompressMetrics(min,max) (CanCompressMetric(min) && CanCompressMetric(max))
-
-static char *
-pcfNameForAtom(Atom a)
-{
- return NameForAtom(a);
-}
-
-int
-pcfWriteFont(FontPtr pFont, FontFilePtr file)
-{
- PCFTableRec tables[32],
- *table;
- CARD32 mask,
- bit;
- int ntables;
- int size;
- CARD32 format;
- int i;
- int cur_table;
- int prop_string_size;
- int glyph_string_size;
- xCharInfo *minbounds,
- *maxbounds;
- xCharInfo *ink_minbounds,
- *ink_maxbounds;
- BitmapFontPtr bitmapFont;
- int nencodings = 0;
- int header_size;
- FontPropPtr offsetProps;
- int prop_pad = 0;
- char *atom_name;
- int glyph;
- CARD32 offset;
-
- bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
- if (bitmapFont->bitmapExtra) {
- minbounds = &bitmapFont->bitmapExtra->info.minbounds;
- maxbounds = &bitmapFont->bitmapExtra->info.maxbounds;
- ink_minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds;
- ink_maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds;
- } else {
- minbounds = &pFont->info.minbounds;
- maxbounds = &pFont->info.maxbounds;
- ink_minbounds = &pFont->info.ink_minbounds;
- ink_maxbounds = &pFont->info.ink_maxbounds;
- }
- offsetProps = malloc(pFont->info.nprops * sizeof(FontPropRec));
- if (!offsetProps) {
- pcfError("pcfWriteFont(): Couldn't allocate offsetProps (%d*%d)", pFont->info.nprops, sizeof(FontPropRec));
- return AllocError;
- }
- prop_string_size = 0;
- for (i = 0; i < pFont->info.nprops; i++) {
- offsetProps[i].name = prop_string_size;
- prop_string_size += strlen(pcfNameForAtom(pFont->info.props[i].name)) + 1;
- if (pFont->info.isStringProp[i]) {
- offsetProps[i].value = prop_string_size;
- prop_string_size += strlen(pcfNameForAtom(pFont->info.props[i].value)) + 1;
- } else
- offsetProps[i].value = pFont->info.props[i].value;
- }
- format = PCF_FORMAT(pFont->bit, pFont->byte, pFont->glyph, pFont->scan);
- mask = 0xFFFFFFF;
- ntables = 0;
- table = tables;
- while (mask) {
- bit = lowbit(mask);
- mask &= ~bit;
- table->type = bit;
- switch (bit) {
- case PCF_PROPERTIES:
- table->format = PCF_DEFAULT_FORMAT | format;
- size = S32 + S32 + (S32 + S8 + S32) * pFont->info.nprops;
- prop_pad = Pad(size);
- table->size = RoundUp(size) + S32 +
- RoundUp(prop_string_size);
- table++;
- break;
- case PCF_ACCELERATORS:
- if (bitmapFont->bitmapExtra->info.inkMetrics)
- table->format = PCF_ACCEL_W_INKBOUNDS | format;
- else
- table->format = PCF_DEFAULT_FORMAT | format;
- table->size = 100;
- table++;
- break;
- case PCF_METRICS:
- if (CanCompressMetrics(minbounds, maxbounds)) {
- table->format = PCF_COMPRESSED_METRICS | format;
- size = S32 + S16 + bitmapFont->num_chars * (5 * S8);
- table->size = RoundUp(size);
- } else {
- table->format = PCF_DEFAULT_FORMAT | format;
- table->size = S32 + S32 + bitmapFont->num_chars * (6 * S16);
- }
- table++;
- break;
- case PCF_BITMAPS:
- table->format = PCF_DEFAULT_FORMAT | format;
- size = S32 + S32 + bitmapFont->num_chars * S32 +
- GLYPHPADOPTIONS * S32 +
- bitmapFont->bitmapExtra->bitmapsSizes[PCF_GLYPH_PAD_INDEX(format)];
- table->size = RoundUp(size);
- table++;
- break;
- case PCF_INK_METRICS:
- if (bitmapFont->ink_metrics) {
- if (CanCompressMetrics(ink_minbounds, ink_maxbounds)) {
- table->format = PCF_COMPRESSED_METRICS | format;
- size = S32 + S16 + bitmapFont->num_chars * (5 * S8);
- table->size = RoundUp(size);
- } else {
- table->format = PCF_DEFAULT_FORMAT | format;
- table->size = S32 + S32 + bitmapFont->num_chars * (6 * S16);
- }
- table++;
- }
- break;
- case PCF_BDF_ENCODINGS:
- table->format = PCF_DEFAULT_FORMAT | format;
- nencodings = (pFont->info.lastRow - pFont->info.firstRow + 1) *
- (pFont->info.lastCol - pFont->info.firstCol + 1);
- size = S32 + 5 * S16 + nencodings * S16;
- table->size = RoundUp(size);
- table++;
- break;
- case PCF_SWIDTHS:
- table->format = PCF_DEFAULT_FORMAT | format;
- table->size = S32 + S32 + bitmapFont->num_chars * S32;
- table++;
- break;
- case PCF_GLYPH_NAMES:
- table->format = PCF_DEFAULT_FORMAT | format;
- glyph_string_size = 0;
- for (i = 0; i < bitmapFont->num_chars; i++)
- glyph_string_size += strlen(pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i])) + 1;
- table->size = S32 + S32 + bitmapFont->num_chars * S32 +
- S32 + RoundUp(glyph_string_size);
- table++;
- break;
- case PCF_BDF_ACCELERATORS:
- if (pFont->info.inkMetrics)
- table->format = PCF_ACCEL_W_INKBOUNDS | format;
- else
- table->format = PCF_DEFAULT_FORMAT | format;
- table->size = 100;
- table++;
- break;
- }
- }
- ntables = table - tables;
- offset = 0;
- header_size = S32 + S32 + ntables * (4 * S32);
- offset = header_size;
- for (cur_table = 0, table = tables;
- cur_table < ntables;
- cur_table++, table++) {
- table->offset = offset;
- offset += table->size;
- }
- current_position = 0;
- pcfWriteTOC(file, tables, ntables);
- for (cur_table = 0, table = tables;
- cur_table < ntables;
- cur_table++, table++) {
- if (current_position > table->offset) {
- printf("can't go backwards... %d > %d\n",
- (int)current_position, (int)table->offset);
- free(offsetProps);
- return BadFontName;
- }
- while (current_position < table->offset)
- pcfPutINT8(file, format, '\0');
- pcfPutLSB32(file, table->format);
- switch (table->type) {
- case PCF_PROPERTIES:
- pcfPutINT32(file, format, pFont->info.nprops);
- for (i = 0; i < pFont->info.nprops; i++) {
- pcfPutINT32(file, format, offsetProps[i].name);
- pcfPutINT8(file, format, pFont->info.isStringProp[i]);
- pcfPutINT32(file, format, offsetProps[i].value);
- }
- for (i = 0; i < prop_pad; i++)
- pcfPutINT8(file, format, 0);
- pcfPutINT32(file, format, prop_string_size);
- for (i = 0; i < pFont->info.nprops; i++) {
- atom_name = pcfNameForAtom(pFont->info.props[i].name);
- pcfWrite(file, atom_name, strlen(atom_name) + 1);
- if (pFont->info.isStringProp[i]) {
- atom_name = pcfNameForAtom(pFont->info.props[i].value);
- pcfWrite(file, atom_name, strlen(atom_name) + 1);
- }
- }
- break;
- case PCF_ACCELERATORS:
- pcfPutAccel(file, table->format, &bitmapFont->bitmapExtra->info);
- break;
- case PCF_METRICS:
- if (PCF_FORMAT_MATCH(table->format, PCF_COMPRESSED_METRICS)) {
- pcfPutINT16(file, format, bitmapFont->num_chars);
- for (i = 0; i < bitmapFont->num_chars; i++)
- pcfPutCompressedMetric(file, format, &bitmapFont->metrics[i].metrics);
- } else {
- pcfPutINT32(file, format, bitmapFont->num_chars);
- for (i = 0; i < bitmapFont->num_chars; i++)
- pcfPutMetric(file, format, &bitmapFont->metrics[i].metrics);
- }
- break;
- case PCF_BITMAPS:
- pcfPutINT32(file, format, bitmapFont->num_chars);
- glyph = PCF_GLYPH_PAD(format);
- offset = 0;
- for (i = 0; i < bitmapFont->num_chars; i++) {
- pcfPutINT32(file, format, offset);
- offset += BYTES_FOR_GLYPH(&bitmapFont->metrics[i], glyph);
- }
- for (i = 0; i < GLYPHPADOPTIONS; i++) {
- pcfPutINT32(file, format,
- bitmapFont->bitmapExtra->bitmapsSizes[i]);
- }
- for (i = 0; i < bitmapFont->num_chars; i++)
- pcfPutBitmap(file, format, &bitmapFont->metrics[i]);
- break;
- case PCF_INK_METRICS:
- if (PCF_FORMAT_MATCH(table->format, PCF_COMPRESSED_METRICS)) {
- pcfPutINT16(file, format, bitmapFont->num_chars);
- for (i = 0; i < bitmapFont->num_chars; i++)
- pcfPutCompressedMetric(file, format, &bitmapFont->ink_metrics[i]);
- } else {
- pcfPutINT32(file, format, bitmapFont->num_chars);
- for (i = 0; i < bitmapFont->num_chars; i++)
- pcfPutMetric(file, format, &bitmapFont->ink_metrics[i]);
- }
- break;
- case PCF_BDF_ENCODINGS:
- pcfPutINT16(file, format, pFont->info.firstCol);
- pcfPutINT16(file, format, pFont->info.lastCol);
- pcfPutINT16(file, format, pFont->info.firstRow);
- pcfPutINT16(file, format, pFont->info.lastRow);
- pcfPutINT16(file, format, pFont->info.defaultCh);
- for (i = 0; i < nencodings; i++) {
- if (ACCESSENCODING(bitmapFont->encoding,i))
- pcfPutINT16(file, format,
- ACCESSENCODING(bitmapFont->encoding, i) -
- bitmapFont->metrics);
- else
- pcfPutINT16(file, format, 0xFFFF);
- }
- break;
- case PCF_SWIDTHS:
- pcfPutINT32(file, format, bitmapFont->num_chars);
- for (i = 0; i < bitmapFont->num_chars; i++)
- pcfPutINT32(file, format, bitmapFont->bitmapExtra->sWidths[i]);
- break;
- case PCF_GLYPH_NAMES:
- pcfPutINT32(file, format, bitmapFont->num_chars);
- offset = 0;
- for (i = 0; i < bitmapFont->num_chars; i++) {
- pcfPutINT32(file, format, offset);
- offset += strlen(pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i])) + 1;
- }
- pcfPutINT32(file, format, offset);
- for (i = 0; i < bitmapFont->num_chars; i++) {
- atom_name = pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i]);
- pcfWrite(file, atom_name, strlen(atom_name) + 1);
- }
- break;
- case PCF_BDF_ACCELERATORS:
- pcfPutAccel(file, table->format, &pFont->info);
- break;
- }
- }
-
- free(offsetProps);
- return Successful;
-}
+/*
+
+Copyright 1990, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include <X11/fonts/pcf.h>
+
+/* Write PCF font files */
+
+static CARD32 current_position;
+
+static int
+pcfWrite(FontFilePtr file, char *b, int c)
+{
+ current_position += c;
+ return FontFileWrite(file, b, c);
+}
+
+static int
+pcfPutLSB32(FontFilePtr file, int c)
+{
+ current_position += 4;
+ (void) FontFilePutc(c, file);
+ (void) FontFilePutc(c >> 8, file);
+ (void) FontFilePutc(c >> 16, file);
+ return FontFilePutc(c >> 24, file);
+}
+
+static int
+pcfPutINT32(FontFilePtr file, CARD32 format, int c)
+{
+ current_position += 4;
+ if (PCF_BYTE_ORDER(format) == MSBFirst) {
+ (void) FontFilePutc(c >> 24, file);
+ (void) FontFilePutc(c >> 16, file);
+ (void) FontFilePutc(c >> 8, file);
+ return FontFilePutc(c, file);
+ } else {
+ (void) FontFilePutc(c, file);
+ (void) FontFilePutc(c >> 8, file);
+ (void) FontFilePutc(c >> 16, file);
+ return FontFilePutc(c >> 24, file);
+ }
+}
+
+static int
+pcfPutINT16(FontFilePtr file, CARD32 format, int c)
+{
+ current_position += 2;
+ if (PCF_BYTE_ORDER(format) == MSBFirst) {
+ (void) FontFilePutc(c >> 8, file);
+ return FontFilePutc(c, file);
+ } else {
+ (void) FontFilePutc(c, file);
+ return FontFilePutc(c >> 8, file);
+ }
+}
+
+/*ARGSUSED*/
+static int
+pcfPutINT8(FontFilePtr file, CARD32 format, int c)
+{
+ current_position += 1;
+ return FontFilePutc(c, file);
+}
+
+static void
+pcfWriteTOC(FontFilePtr file, PCFTablePtr table, int count)
+{
+ CARD32 version;
+ int i;
+
+ version = PCF_FILE_VERSION;
+ pcfPutLSB32(file, version);
+ pcfPutLSB32(file, count);
+ for (i = 0; i < count; i++) {
+ pcfPutLSB32(file, table->type);
+ pcfPutLSB32(file, table->format);
+ pcfPutLSB32(file, table->size);
+ pcfPutLSB32(file, table->offset);
+ table++;
+ }
+}
+
+static void
+pcfPutCompressedMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
+{
+ pcfPutINT8(file, format, metric->leftSideBearing + 0x80);
+ pcfPutINT8(file, format, metric->rightSideBearing + 0x80);
+ pcfPutINT8(file, format, metric->characterWidth + 0x80);
+ pcfPutINT8(file, format, metric->ascent + 0x80);
+ pcfPutINT8(file, format, metric->descent + 0x80);
+}
+
+static void
+pcfPutMetric(FontFilePtr file, CARD32 format, xCharInfo *metric)
+{
+ pcfPutINT16(file, format, metric->leftSideBearing);
+ pcfPutINT16(file, format, metric->rightSideBearing);
+ pcfPutINT16(file, format, metric->characterWidth);
+ pcfPutINT16(file, format, metric->ascent);
+ pcfPutINT16(file, format, metric->descent);
+ pcfPutINT16(file, format, metric->attributes);
+}
+
+static void
+pcfPutBitmap(FontFilePtr file, CARD32 format, CharInfoPtr pCI)
+{
+ int count;
+ unsigned char *bits;
+
+ count = BYTES_FOR_GLYPH(pCI, PCF_GLYPH_PAD(format));
+ bits = (unsigned char *) pCI->bits;
+ current_position += count;
+ while (count--)
+ FontFilePutc(*bits++, file);
+}
+
+static void
+pcfPutAccel(FontFilePtr file, CARD32 format, FontInfoPtr pFontInfo)
+{
+ pcfPutINT8(file, format, pFontInfo->noOverlap);
+ pcfPutINT8(file, format, pFontInfo->constantMetrics);
+ pcfPutINT8(file, format, pFontInfo->terminalFont);
+ pcfPutINT8(file, format, pFontInfo->constantWidth);
+ pcfPutINT8(file, format, pFontInfo->inkInside);
+ pcfPutINT8(file, format, pFontInfo->inkMetrics);
+ pcfPutINT8(file, format, pFontInfo->drawDirection);
+ pcfPutINT8(file, format, 0);
+ pcfPutINT32(file, format, pFontInfo->fontAscent);
+ pcfPutINT32(file, format, pFontInfo->fontDescent);
+ pcfPutINT32(file, format, pFontInfo->maxOverlap);
+ pcfPutMetric(file, format, &pFontInfo->minbounds);
+ pcfPutMetric(file, format, &pFontInfo->maxbounds);
+ if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) {
+ pcfPutMetric(file, format, &pFontInfo->ink_minbounds);
+ pcfPutMetric(file, format, &pFontInfo->ink_maxbounds);
+ }
+}
+
+#define S32 4
+#define S16 2
+#define S8 1
+
+#define Pad(s) (RoundUp(s) - (s))
+#define RoundUp(s) (((s) + 3) & ~3)
+
+#define Compressable(i) (-128 <= (i) && (i) <= 127)
+
+#define CanCompressMetric(m) (Compressable((m)->leftSideBearing) && \
+ Compressable((m)->rightSideBearing) && \
+ Compressable((m)->characterWidth) && \
+ Compressable((m)->ascent) && \
+ Compressable((m)->descent) && \
+ (m)->attributes == 0)
+
+#define CanCompressMetrics(min,max) (CanCompressMetric(min) && CanCompressMetric(max))
+
+static char *
+pcfNameForAtom(Atom a)
+{
+ return NameForAtom(a);
+}
+
+int
+pcfWriteFont(FontPtr pFont, FontFilePtr file)
+{
+ PCFTableRec tables[32],
+ *table;
+ CARD32 mask,
+ bit;
+ int ntables;
+ int size;
+ CARD32 format;
+ int i;
+ int cur_table;
+ int prop_string_size;
+ int glyph_string_size;
+ xCharInfo *minbounds,
+ *maxbounds;
+ xCharInfo *ink_minbounds,
+ *ink_maxbounds;
+ BitmapFontPtr bitmapFont;
+ int nencodings = 0;
+ int header_size;
+ FontPropPtr offsetProps;
+ int prop_pad = 0;
+ char *atom_name;
+ int glyph;
+ CARD32 offset;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ if (bitmapFont->bitmapExtra) {
+ minbounds = &bitmapFont->bitmapExtra->info.minbounds;
+ maxbounds = &bitmapFont->bitmapExtra->info.maxbounds;
+ ink_minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds;
+ ink_maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds;
+ } else {
+ minbounds = &pFont->info.minbounds;
+ maxbounds = &pFont->info.maxbounds;
+ ink_minbounds = &pFont->info.ink_minbounds;
+ ink_maxbounds = &pFont->info.ink_maxbounds;
+ }
+ offsetProps = malloc(pFont->info.nprops * sizeof(FontPropRec));
+ if (!offsetProps) {
+ pcfError("pcfWriteFont(): Couldn't allocate offsetProps (%d*%d)", pFont->info.nprops, sizeof(FontPropRec));
+ return AllocError;
+ }
+ prop_string_size = 0;
+ for (i = 0; i < pFont->info.nprops; i++) {
+ offsetProps[i].name = prop_string_size;
+ prop_string_size += strlen(pcfNameForAtom(pFont->info.props[i].name)) + 1;
+ if (pFont->info.isStringProp[i]) {
+ offsetProps[i].value = prop_string_size;
+ prop_string_size += strlen(pcfNameForAtom(pFont->info.props[i].value)) + 1;
+ } else
+ offsetProps[i].value = pFont->info.props[i].value;
+ }
+ format = PCF_FORMAT(pFont->bit, pFont->byte, pFont->glyph, pFont->scan);
+ mask = 0xFFFFFFF;
+ ntables = 0;
+ table = tables;
+ while (mask) {
+ bit = lowbit(mask);
+ mask &= ~bit;
+ table->type = bit;
+ switch (bit) {
+ case PCF_PROPERTIES:
+ table->format = PCF_DEFAULT_FORMAT | format;
+ size = S32 + S32 + (S32 + S8 + S32) * pFont->info.nprops;
+ prop_pad = Pad(size);
+ table->size = RoundUp(size) + S32 +
+ RoundUp(prop_string_size);
+ table++;
+ break;
+ case PCF_ACCELERATORS:
+ if (bitmapFont->bitmapExtra->info.inkMetrics)
+ table->format = PCF_ACCEL_W_INKBOUNDS | format;
+ else
+ table->format = PCF_DEFAULT_FORMAT | format;
+ table->size = 100;
+ table++;
+ break;
+ case PCF_METRICS:
+ if (CanCompressMetrics(minbounds, maxbounds)) {
+ table->format = PCF_COMPRESSED_METRICS | format;
+ size = S32 + S16 + bitmapFont->num_chars * (5 * S8);
+ table->size = RoundUp(size);
+ } else {
+ table->format = PCF_DEFAULT_FORMAT | format;
+ table->size = S32 + S32 + bitmapFont->num_chars * (6 * S16);
+ }
+ table++;
+ break;
+ case PCF_BITMAPS:
+ table->format = PCF_DEFAULT_FORMAT | format;
+ size = S32 + S32 + bitmapFont->num_chars * S32 +
+ GLYPHPADOPTIONS * S32 +
+ bitmapFont->bitmapExtra->bitmapsSizes[PCF_GLYPH_PAD_INDEX(format)];
+ table->size = RoundUp(size);
+ table++;
+ break;
+ case PCF_INK_METRICS:
+ if (bitmapFont->ink_metrics) {
+ if (CanCompressMetrics(ink_minbounds, ink_maxbounds)) {
+ table->format = PCF_COMPRESSED_METRICS | format;
+ size = S32 + S16 + bitmapFont->num_chars * (5 * S8);
+ table->size = RoundUp(size);
+ } else {
+ table->format = PCF_DEFAULT_FORMAT | format;
+ table->size = S32 + S32 + bitmapFont->num_chars * (6 * S16);
+ }
+ table++;
+ }
+ break;
+ case PCF_BDF_ENCODINGS:
+ table->format = PCF_DEFAULT_FORMAT | format;
+ nencodings = (pFont->info.lastRow - pFont->info.firstRow + 1) *
+ (pFont->info.lastCol - pFont->info.firstCol + 1);
+ size = S32 + 5 * S16 + nencodings * S16;
+ table->size = RoundUp(size);
+ table++;
+ break;
+ case PCF_SWIDTHS:
+ table->format = PCF_DEFAULT_FORMAT | format;
+ table->size = S32 + S32 + bitmapFont->num_chars * S32;
+ table++;
+ break;
+ case PCF_GLYPH_NAMES:
+ table->format = PCF_DEFAULT_FORMAT | format;
+ glyph_string_size = 0;
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ glyph_string_size += strlen(pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i])) + 1;
+ table->size = S32 + S32 + bitmapFont->num_chars * S32 +
+ S32 + RoundUp(glyph_string_size);
+ table++;
+ break;
+ case PCF_BDF_ACCELERATORS:
+ if (pFont->info.inkMetrics)
+ table->format = PCF_ACCEL_W_INKBOUNDS | format;
+ else
+ table->format = PCF_DEFAULT_FORMAT | format;
+ table->size = 100;
+ table++;
+ break;
+ }
+ }
+ ntables = table - tables;
+ offset = 0;
+ header_size = S32 + S32 + ntables * (4 * S32);
+ offset = header_size;
+ for (cur_table = 0, table = tables;
+ cur_table < ntables;
+ cur_table++, table++) {
+ table->offset = offset;
+ offset += table->size;
+ }
+ current_position = 0;
+ pcfWriteTOC(file, tables, ntables);
+ for (cur_table = 0, table = tables;
+ cur_table < ntables;
+ cur_table++, table++) {
+ if (current_position > table->offset) {
+ printf("can't go backwards... %d > %d\n",
+ (int)current_position, (int)table->offset);
+ free(offsetProps);
+ return BadFontName;
+ }
+ while (current_position < table->offset)
+ pcfPutINT8(file, format, '\0');
+ pcfPutLSB32(file, table->format);
+ switch (table->type) {
+ case PCF_PROPERTIES:
+ pcfPutINT32(file, format, pFont->info.nprops);
+ for (i = 0; i < pFont->info.nprops; i++) {
+ pcfPutINT32(file, format, offsetProps[i].name);
+ pcfPutINT8(file, format, pFont->info.isStringProp[i]);
+ pcfPutINT32(file, format, offsetProps[i].value);
+ }
+ for (i = 0; i < prop_pad; i++)
+ pcfPutINT8(file, format, 0);
+ pcfPutINT32(file, format, prop_string_size);
+ for (i = 0; i < pFont->info.nprops; i++) {
+ atom_name = pcfNameForAtom(pFont->info.props[i].name);
+ pcfWrite(file, atom_name, strlen(atom_name) + 1);
+ if (pFont->info.isStringProp[i]) {
+ atom_name = pcfNameForAtom(pFont->info.props[i].value);
+ pcfWrite(file, atom_name, strlen(atom_name) + 1);
+ }
+ }
+ break;
+ case PCF_ACCELERATORS:
+ pcfPutAccel(file, table->format, &bitmapFont->bitmapExtra->info);
+ break;
+ case PCF_METRICS:
+ if (PCF_FORMAT_MATCH(table->format, PCF_COMPRESSED_METRICS)) {
+ pcfPutINT16(file, format, bitmapFont->num_chars);
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ pcfPutCompressedMetric(file, format, &bitmapFont->metrics[i].metrics);
+ } else {
+ pcfPutINT32(file, format, bitmapFont->num_chars);
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ pcfPutMetric(file, format, &bitmapFont->metrics[i].metrics);
+ }
+ break;
+ case PCF_BITMAPS:
+ pcfPutINT32(file, format, bitmapFont->num_chars);
+ glyph = PCF_GLYPH_PAD(format);
+ offset = 0;
+ for (i = 0; i < bitmapFont->num_chars; i++) {
+ pcfPutINT32(file, format, offset);
+ offset += BYTES_FOR_GLYPH(&bitmapFont->metrics[i], glyph);
+ }
+ for (i = 0; i < GLYPHPADOPTIONS; i++) {
+ pcfPutINT32(file, format,
+ bitmapFont->bitmapExtra->bitmapsSizes[i]);
+ }
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ pcfPutBitmap(file, format, &bitmapFont->metrics[i]);
+ break;
+ case PCF_INK_METRICS:
+ if (PCF_FORMAT_MATCH(table->format, PCF_COMPRESSED_METRICS)) {
+ pcfPutINT16(file, format, bitmapFont->num_chars);
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ pcfPutCompressedMetric(file, format, &bitmapFont->ink_metrics[i]);
+ } else {
+ pcfPutINT32(file, format, bitmapFont->num_chars);
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ pcfPutMetric(file, format, &bitmapFont->ink_metrics[i]);
+ }
+ break;
+ case PCF_BDF_ENCODINGS:
+ pcfPutINT16(file, format, pFont->info.firstCol);
+ pcfPutINT16(file, format, pFont->info.lastCol);
+ pcfPutINT16(file, format, pFont->info.firstRow);
+ pcfPutINT16(file, format, pFont->info.lastRow);
+ pcfPutINT16(file, format, pFont->info.defaultCh);
+ for (i = 0; i < nencodings; i++) {
+ if (ACCESSENCODING(bitmapFont->encoding,i))
+ pcfPutINT16(file, format,
+ ACCESSENCODING(bitmapFont->encoding, i) -
+ bitmapFont->metrics);
+ else
+ pcfPutINT16(file, format, 0xFFFF);
+ }
+ break;
+ case PCF_SWIDTHS:
+ pcfPutINT32(file, format, bitmapFont->num_chars);
+ for (i = 0; i < bitmapFont->num_chars; i++)
+ pcfPutINT32(file, format, bitmapFont->bitmapExtra->sWidths[i]);
+ break;
+ case PCF_GLYPH_NAMES:
+ pcfPutINT32(file, format, bitmapFont->num_chars);
+ offset = 0;
+ for (i = 0; i < bitmapFont->num_chars; i++) {
+ pcfPutINT32(file, format, offset);
+ offset += strlen(pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i])) + 1;
+ }
+ pcfPutINT32(file, format, offset);
+ for (i = 0; i < bitmapFont->num_chars; i++) {
+ atom_name = pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i]);
+ pcfWrite(file, atom_name, strlen(atom_name) + 1);
+ }
+ break;
+ case PCF_BDF_ACCELERATORS:
+ pcfPutAccel(file, table->format, &pFont->info);
+ break;
+ }
+ }
+
+ free(offsetProps);
+ return Successful;
+}
diff --git a/libXfont/src/bitmap/snfread.c b/libXfont/src/bitmap/snfread.c
index d003cc5a5..d0b0dfe3c 100644
--- a/libXfont/src/bitmap/snfread.c
+++ b/libXfont/src/bitmap/snfread.c
@@ -1,508 +1,508 @@
-/************************************************************************
-Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-************************************************************************/
-
-/*
-
-Copyright 1994, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <ctype.h>
-#include <X11/fonts/fntfilst.h>
-#include <X11/fonts/bitmap.h>
-#include "snfstr.h"
-
-#include <stdarg.h>
-
-static void
-snfError(const char* message, ...)
-{
- va_list args;
-
- va_start(args, message);
-
- fprintf(stderr, "SNF Error: ");
- vfprintf(stderr, message, args);
- va_end(args);
-}
-
-static void snfUnloadFont(FontPtr pFont);
-
-static int
-snfReadCharInfo(FontFilePtr file, CharInfoPtr charInfo, char *base)
-{
- snfCharInfoRec snfCharInfo;
-
-#define Width(m) ((m).rightSideBearing - (m).leftSideBearing)
-#define Height(m) ((m).ascent + (m).descent)
-
- if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
- sizeof(snfCharInfo)) {
- return BadFontName;
- }
- charInfo->metrics = snfCharInfo.metrics;
- if (snfCharInfo.exists)
- charInfo->bits = base + snfCharInfo.byteOffset;
- else
- charInfo->bits = 0;
- return Successful;
-}
-
-static int
-snfReadxCharInfo(FontFilePtr file, xCharInfo *charInfo)
-{
- snfCharInfoRec snfCharInfo;
-
- if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
- sizeof(snfCharInfo)) {
- return BadFontName;
- }
- *charInfo = snfCharInfo.metrics;
- return Successful;
-}
-
-static void
-snfCopyInfo(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo)
-{
- pFontInfo->firstCol = snfInfo->firstCol;
- pFontInfo->lastCol = snfInfo->lastCol;
- pFontInfo->firstRow = snfInfo->firstRow;
- pFontInfo->lastRow = snfInfo->lastRow;
- pFontInfo->defaultCh = snfInfo->chDefault;
- pFontInfo->noOverlap = snfInfo->noOverlap;
- pFontInfo->terminalFont = snfInfo->terminalFont;
- pFontInfo->constantMetrics = snfInfo->constantMetrics;
- pFontInfo->constantWidth = snfInfo->constantWidth;
- pFontInfo->inkInside = snfInfo->inkInside;
- pFontInfo->inkMetrics = snfInfo->inkMetrics;
- pFontInfo->allExist = snfInfo->allExist;
- pFontInfo->drawDirection = snfInfo->drawDirection;
- pFontInfo->anamorphic = FALSE;
- pFontInfo->cachable = TRUE;
- pFontInfo->maxOverlap = 0;
- pFontInfo->minbounds = snfInfo->minbounds.metrics;
- pFontInfo->maxbounds = snfInfo->maxbounds.metrics;
- pFontInfo->fontAscent = snfInfo->fontAscent;
- pFontInfo->fontDescent = snfInfo->fontDescent;
- pFontInfo->nprops = snfInfo->nProps;
-}
-
-static int
-snfReadProps(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo, FontFilePtr file)
-{
- char *strings;
- FontPropPtr pfp;
- snfFontPropPtr psnfp;
- char *propspace;
- int bytestoalloc;
- int i;
-
- bytestoalloc = snfInfo->nProps * sizeof(snfFontPropRec) +
- BYTESOFSTRINGINFO(snfInfo);
- propspace = malloc(bytestoalloc);
- if (!propspace) {
- snfError("snfReadProps(): Couldn't allocate propspace (%d)\n", bytestoalloc);
- return AllocError;
- }
-
- if (FontFileRead(file, propspace, bytestoalloc) != bytestoalloc) {
- free(propspace);
- return BadFontName;
- }
- psnfp = (snfFontPropPtr) propspace;
-
- strings = propspace + BYTESOFPROPINFO(snfInfo);
-
- for (i = 0, pfp = pFontInfo->props; i < snfInfo->nProps; i++, pfp++, psnfp++) {
- pfp->name = MakeAtom(&strings[psnfp->name],
- (unsigned) strlen(&strings[psnfp->name]), 1);
- pFontInfo->isStringProp[i] = psnfp->indirect;
- if (psnfp->indirect)
- pfp->value = (INT32) MakeAtom(&strings[psnfp->value],
- (unsigned) strlen(&strings[psnfp->value]), 1);
- else
- pfp->value = psnfp->value;
- }
-
- free(propspace);
- return Successful;
-}
-
-static int
-snfReadHeader(snfFontInfoPtr snfInfo, FontFilePtr file)
-{
- if (FontFileRead(file, (char *) snfInfo, sizeof *snfInfo) != sizeof *snfInfo)
- return BadFontName;
-
- if (snfInfo->version1 != FONT_FILE_VERSION ||
- snfInfo->version2 != FONT_FILE_VERSION)
- return BadFontName;
- return Successful;
-}
-
-static int snf_set;
-static int snf_bit, snf_byte, snf_glyph, snf_scan;
-
-void
-SnfSetFormat (int bit, int byte, int glyph, int scan)
-{
- snf_bit = bit;
- snf_byte = byte;
- snf_glyph = glyph;
- snf_scan = scan;
- snf_set = 1;
-}
-
-static void
-SnfGetFormat (int *bit, int *byte, int *glyph, int *scan)
-{
- if (!snf_set)
- FontDefaultFormat (&snf_bit, &snf_byte, &snf_glyph, &snf_scan);
- *bit = snf_bit;
- *byte = snf_byte;
- *glyph = snf_glyph;
- *scan = snf_scan;
-}
-
-int
-snfReadFont(FontPtr pFont, FontFilePtr file,
- int bit, int byte, int glyph, int scan)
-{
- snfFontInfoRec fi;
- unsigned bytestoalloc;
- int i, j;
- char *fontspace;
- BitmapFontPtr bitmapFont;
- int num_chars;
- int bitmapsSize;
- int ret;
- int metrics_off;
- int encoding_off;
- int props_off;
- int isStringProp_off;
- int ink_off;
- char *bitmaps;
- int def_bit, def_byte, def_glyph, def_scan;
-
- ret = snfReadHeader(&fi, file);
- if (ret != Successful)
- return ret;
-
- SnfGetFormat (&def_bit, &def_byte, &def_glyph, &def_scan);
-
- /*
- * we'll allocate one chunk of memory and split it among the various parts
- * of the font:
- *
- * BitmapFontRec CharInfoRec's Glyphs Encoding DIX Properties Ink CharInfoRec's
- *
- * If the glyphpad is not the same as the font file, then the glyphs
- * are allocated separately, to be later realloc'ed when we know
- * how big to make them.
- */
-
- bitmapsSize = BYTESOFGLYPHINFO(&fi);
- num_chars = n2dChars(&fi);
- bytestoalloc = sizeof(BitmapFontRec); /* bitmapFont */
- metrics_off = bytestoalloc;
- bytestoalloc += num_chars * sizeof(CharInfoRec); /* metrics */
- encoding_off = bytestoalloc;
- bytestoalloc += NUM_SEGMENTS(num_chars) * sizeof(CharInfoPtr**);
- /* encoding */
- props_off = bytestoalloc;
- bytestoalloc += fi.nProps * sizeof(FontPropRec); /* props */
- isStringProp_off = bytestoalloc;
- bytestoalloc += fi.nProps * sizeof(char); /* isStringProp */
- bytestoalloc = (bytestoalloc + 3) & ~3;
- ink_off = bytestoalloc;
- if (fi.inkMetrics)
- bytestoalloc += num_chars * sizeof(xCharInfo); /* ink_metrics */
-
- fontspace = malloc(bytestoalloc);
- if (!fontspace) {
- snfError("snfReadFont(): Couldn't allocate fontspace (%d)\n", bytestoalloc);
- return AllocError;
- }
- bitmaps = malloc (bitmapsSize);
- if (!bitmaps)
- {
- snfError("snfReadFont(): Couldn't allocate bitmaps (%d)\n", bitmapsSize);
- free (fontspace);
- return AllocError;
- }
- /*
- * now fix up pointers
- */
-
- bitmapFont = (BitmapFontPtr) fontspace;
- bitmapFont->num_chars = num_chars;
- bitmapFont->metrics = (CharInfoPtr) (fontspace + metrics_off);
- bitmapFont->encoding = (CharInfoPtr **) (fontspace + encoding_off);
- bitmapFont->bitmaps = bitmaps;
- bitmapFont->pDefault = NULL;
- bitmapFont->bitmapExtra = NULL;
- pFont->info.props = (FontPropPtr) (fontspace + props_off);
- pFont->info.isStringProp = (char *) (fontspace + isStringProp_off);
- if (fi.inkMetrics)
- bitmapFont->ink_metrics = (xCharInfo *) (fontspace + ink_off);
- else
- bitmapFont->ink_metrics = 0;
-
- /*
- * read the CharInfo
- */
-
- ret = Successful;
- memset(bitmapFont->encoding, 0,
- NUM_SEGMENTS(num_chars)*sizeof(CharInfoPtr*));
- for (i = 0; ret == Successful && i < num_chars; i++) {
- ret = snfReadCharInfo(file, &bitmapFont->metrics[i], bitmaps);
- if (bitmapFont->metrics[i].bits) {
- if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
- bitmapFont->encoding[SEGMENT_MAJOR(i)]=
- calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr));
- if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
- ret = AllocError;
- break;
- }
- }
- ACCESSENCODINGL(bitmapFont->encoding,i) = &bitmapFont->metrics[i];
- }
- }
-
- if (ret != Successful) {
- free(bitmaps);
- if(bitmapFont->encoding) {
- for(j=0; j<SEGMENT_MAJOR(i); j++)
- free(bitmapFont->encoding[i]);
- }
- free(fontspace);
- return ret;
- }
- /*
- * read the glyphs
- */
-
- if (FontFileRead(file, bitmaps, bitmapsSize) != bitmapsSize) {
- free(bitmaps);
- free(fontspace);
- return BadFontName;
- }
-
- if (def_bit != bit)
- BitOrderInvert((unsigned char *)bitmaps, bitmapsSize);
- if ((def_byte == def_bit) != (bit == byte)) {
- switch (bit == byte ? def_scan : scan) {
- case 1:
- break;
- case 2:
- TwoByteSwap((unsigned char *)bitmaps, bitmapsSize);
- break;
- case 4:
- FourByteSwap((unsigned char *)bitmaps, bitmapsSize);
- break;
- }
- }
- if (def_glyph != glyph) {
- char *padbitmaps;
- int sizepadbitmaps;
- int sizechar;
- CharInfoPtr metric;
-
- sizepadbitmaps = 0;
- metric = bitmapFont->metrics;
- for (i = 0; i < num_chars; i++)
- {
- if (metric->bits)
- sizepadbitmaps += BYTES_FOR_GLYPH(metric,glyph);
- metric++;
- }
- padbitmaps = malloc(sizepadbitmaps);
- if (!padbitmaps) {
- snfError("snfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
- free (bitmaps);
- free (fontspace);
- return AllocError;
- }
- metric = bitmapFont->metrics;
- bitmapFont->bitmaps = padbitmaps;
- for (i = 0; i < num_chars; i++) {
- sizechar = RepadBitmap(metric->bits, padbitmaps,
- def_glyph, glyph,
- metric->metrics.rightSideBearing -
- metric->metrics.leftSideBearing,
- metric->metrics.ascent + metric->metrics.descent);
- metric->bits = padbitmaps;
- padbitmaps += sizechar;
- metric++;
- }
- free(bitmaps);
- }
-
- /* now read and atom'ize properties */
-
- ret = snfReadProps(&fi, &pFont->info, file);
- if (ret != Successful) {
- free(fontspace);
- return ret;
- }
- snfCopyInfo(&fi, &pFont->info);
-
- /* finally, read the ink metrics if the exist */
-
- if (fi.inkMetrics) {
- ret = Successful;
- ret = snfReadxCharInfo(file, &pFont->info.ink_minbounds);
- ret = snfReadxCharInfo(file, &pFont->info.ink_maxbounds);
- for (i = 0; ret == Successful && i < num_chars; i++)
- ret = snfReadxCharInfo(file, &bitmapFont->ink_metrics[i]);
- if (ret != Successful) {
- free(fontspace);
- return ret;
- }
- } else {
- pFont->info.ink_minbounds = pFont->info.minbounds;
- pFont->info.ink_maxbounds = pFont->info.maxbounds;
- }
-
- if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
- unsigned int r,
- c,
- cols;
-
- r = pFont->info.defaultCh >> 8;
- c = pFont->info.defaultCh & 0xFF;
- if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
- pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
- cols = pFont->info.lastCol - pFont->info.firstCol + 1;
- r = r - pFont->info.firstRow;
- c = c - pFont->info.firstCol;
- bitmapFont->pDefault = &bitmapFont->metrics[r * cols + c];
- }
- }
- bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
- pFont->fontPrivate = (pointer) bitmapFont;
- pFont->get_glyphs = bitmapGetGlyphs;
- pFont->get_metrics = bitmapGetMetrics;
- pFont->unload_font = snfUnloadFont;
- pFont->unload_glyphs = NULL;
- pFont->bit = bit;
- pFont->byte = byte;
- pFont->glyph = glyph;
- pFont->scan = scan;
- return Successful;
-}
-
-int
-snfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
-{
- int ret;
- snfFontInfoRec fi;
- int bytestoskip;
- int num_chars;
-
- ret = snfReadHeader(&fi, file);
- if (ret != Successful)
- return ret;
- snfCopyInfo(&fi, pFontInfo);
-
- pFontInfo->props = malloc(fi.nProps * sizeof(FontPropRec));
- if (!pFontInfo->props) {
- snfError("snfReadFontInfo(): Couldn't allocate props (%d*%d)\n", fi.nProps, sizeof(FontPropRec));
- return AllocError;
- }
- pFontInfo->isStringProp = malloc(fi.nProps * sizeof(char));
- if (!pFontInfo->isStringProp) {
- snfError("snfReadFontInfo(): Couldn't allocate isStringProp (%d*%d)\n", fi.nProps, sizeof(char));
- free(pFontInfo->props);
- return AllocError;
- }
- num_chars = n2dChars(&fi);
- bytestoskip = num_chars * sizeof(snfCharInfoRec); /* charinfos */
- bytestoskip += BYTESOFGLYPHINFO(&fi);
- (void)FontFileSkip(file, bytestoskip);
-
- ret = snfReadProps(&fi, pFontInfo, file);
- if (ret != Successful) {
- free(pFontInfo->props);
- free(pFontInfo->isStringProp);
- return ret;
- }
- if (fi.inkMetrics) {
- ret = snfReadxCharInfo(file, &pFontInfo->ink_minbounds);
- if (ret != Successful) {
- free(pFontInfo->props);
- free(pFontInfo->isStringProp);
- return ret;
- }
- ret = snfReadxCharInfo(file, &pFontInfo->ink_maxbounds);
- if (ret != Successful) {
- free(pFontInfo->props);
- free(pFontInfo->isStringProp);
- return ret;
- }
- } else {
- pFontInfo->ink_minbounds = pFontInfo->minbounds;
- pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
- }
- return Successful;
-
-}
-
-static void
-snfUnloadFont(FontPtr pFont)
-{
- BitmapFontPtr bitmapFont;
-
- bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
- free (bitmapFont->bitmaps);
- free (bitmapFont);
- DestroyFontRec (pFont);
-}
-
+/************************************************************************
+Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+************************************************************************/
+
+/*
+
+Copyright 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/bitmap.h>
+#include "snfstr.h"
+
+#include <stdarg.h>
+
+static void
+snfError(const char* message, ...)
+{
+ va_list args;
+
+ va_start(args, message);
+
+ fprintf(stderr, "SNF Error: ");
+ vfprintf(stderr, message, args);
+ va_end(args);
+}
+
+static void snfUnloadFont(FontPtr pFont);
+
+static int
+snfReadCharInfo(FontFilePtr file, CharInfoPtr charInfo, char *base)
+{
+ snfCharInfoRec snfCharInfo;
+
+#define Width(m) ((m).rightSideBearing - (m).leftSideBearing)
+#define Height(m) ((m).ascent + (m).descent)
+
+ if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
+ sizeof(snfCharInfo)) {
+ return BadFontName;
+ }
+ charInfo->metrics = snfCharInfo.metrics;
+ if (snfCharInfo.exists)
+ charInfo->bits = base + snfCharInfo.byteOffset;
+ else
+ charInfo->bits = 0;
+ return Successful;
+}
+
+static int
+snfReadxCharInfo(FontFilePtr file, xCharInfo *charInfo)
+{
+ snfCharInfoRec snfCharInfo;
+
+ if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) !=
+ sizeof(snfCharInfo)) {
+ return BadFontName;
+ }
+ *charInfo = snfCharInfo.metrics;
+ return Successful;
+}
+
+static void
+snfCopyInfo(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo)
+{
+ pFontInfo->firstCol = snfInfo->firstCol;
+ pFontInfo->lastCol = snfInfo->lastCol;
+ pFontInfo->firstRow = snfInfo->firstRow;
+ pFontInfo->lastRow = snfInfo->lastRow;
+ pFontInfo->defaultCh = snfInfo->chDefault;
+ pFontInfo->noOverlap = snfInfo->noOverlap;
+ pFontInfo->terminalFont = snfInfo->terminalFont;
+ pFontInfo->constantMetrics = snfInfo->constantMetrics;
+ pFontInfo->constantWidth = snfInfo->constantWidth;
+ pFontInfo->inkInside = snfInfo->inkInside;
+ pFontInfo->inkMetrics = snfInfo->inkMetrics;
+ pFontInfo->allExist = snfInfo->allExist;
+ pFontInfo->drawDirection = snfInfo->drawDirection;
+ pFontInfo->anamorphic = FALSE;
+ pFontInfo->cachable = TRUE;
+ pFontInfo->maxOverlap = 0;
+ pFontInfo->minbounds = snfInfo->minbounds.metrics;
+ pFontInfo->maxbounds = snfInfo->maxbounds.metrics;
+ pFontInfo->fontAscent = snfInfo->fontAscent;
+ pFontInfo->fontDescent = snfInfo->fontDescent;
+ pFontInfo->nprops = snfInfo->nProps;
+}
+
+static int
+snfReadProps(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo, FontFilePtr file)
+{
+ char *strings;
+ FontPropPtr pfp;
+ snfFontPropPtr psnfp;
+ char *propspace;
+ int bytestoalloc;
+ int i;
+
+ bytestoalloc = snfInfo->nProps * sizeof(snfFontPropRec) +
+ BYTESOFSTRINGINFO(snfInfo);
+ propspace = malloc(bytestoalloc);
+ if (!propspace) {
+ snfError("snfReadProps(): Couldn't allocate propspace (%d)\n", bytestoalloc);
+ return AllocError;
+ }
+
+ if (FontFileRead(file, propspace, bytestoalloc) != bytestoalloc) {
+ free(propspace);
+ return BadFontName;
+ }
+ psnfp = (snfFontPropPtr) propspace;
+
+ strings = propspace + BYTESOFPROPINFO(snfInfo);
+
+ for (i = 0, pfp = pFontInfo->props; i < snfInfo->nProps; i++, pfp++, psnfp++) {
+ pfp->name = MakeAtom(&strings[psnfp->name],
+ (unsigned) strlen(&strings[psnfp->name]), 1);
+ pFontInfo->isStringProp[i] = psnfp->indirect;
+ if (psnfp->indirect)
+ pfp->value = (INT32) MakeAtom(&strings[psnfp->value],
+ (unsigned) strlen(&strings[psnfp->value]), 1);
+ else
+ pfp->value = psnfp->value;
+ }
+
+ free(propspace);
+ return Successful;
+}
+
+static int
+snfReadHeader(snfFontInfoPtr snfInfo, FontFilePtr file)
+{
+ if (FontFileRead(file, (char *) snfInfo, sizeof *snfInfo) != sizeof *snfInfo)
+ return BadFontName;
+
+ if (snfInfo->version1 != FONT_FILE_VERSION ||
+ snfInfo->version2 != FONT_FILE_VERSION)
+ return BadFontName;
+ return Successful;
+}
+
+static int snf_set;
+static int snf_bit, snf_byte, snf_glyph, snf_scan;
+
+void
+SnfSetFormat (int bit, int byte, int glyph, int scan)
+{
+ snf_bit = bit;
+ snf_byte = byte;
+ snf_glyph = glyph;
+ snf_scan = scan;
+ snf_set = 1;
+}
+
+static void
+SnfGetFormat (int *bit, int *byte, int *glyph, int *scan)
+{
+ if (!snf_set)
+ FontDefaultFormat (&snf_bit, &snf_byte, &snf_glyph, &snf_scan);
+ *bit = snf_bit;
+ *byte = snf_byte;
+ *glyph = snf_glyph;
+ *scan = snf_scan;
+}
+
+int
+snfReadFont(FontPtr pFont, FontFilePtr file,
+ int bit, int byte, int glyph, int scan)
+{
+ snfFontInfoRec fi;
+ unsigned bytestoalloc;
+ int i, j;
+ char *fontspace;
+ BitmapFontPtr bitmapFont;
+ int num_chars;
+ int bitmapsSize;
+ int ret;
+ int metrics_off;
+ int encoding_off;
+ int props_off;
+ int isStringProp_off;
+ int ink_off;
+ char *bitmaps;
+ int def_bit, def_byte, def_glyph, def_scan;
+
+ ret = snfReadHeader(&fi, file);
+ if (ret != Successful)
+ return ret;
+
+ SnfGetFormat (&def_bit, &def_byte, &def_glyph, &def_scan);
+
+ /*
+ * we'll allocate one chunk of memory and split it among the various parts
+ * of the font:
+ *
+ * BitmapFontRec CharInfoRec's Glyphs Encoding DIX Properties Ink CharInfoRec's
+ *
+ * If the glyphpad is not the same as the font file, then the glyphs
+ * are allocated separately, to be later realloc'ed when we know
+ * how big to make them.
+ */
+
+ bitmapsSize = BYTESOFGLYPHINFO(&fi);
+ num_chars = n2dChars(&fi);
+ bytestoalloc = sizeof(BitmapFontRec); /* bitmapFont */
+ metrics_off = bytestoalloc;
+ bytestoalloc += num_chars * sizeof(CharInfoRec); /* metrics */
+ encoding_off = bytestoalloc;
+ bytestoalloc += NUM_SEGMENTS(num_chars) * sizeof(CharInfoPtr**);
+ /* encoding */
+ props_off = bytestoalloc;
+ bytestoalloc += fi.nProps * sizeof(FontPropRec); /* props */
+ isStringProp_off = bytestoalloc;
+ bytestoalloc += fi.nProps * sizeof(char); /* isStringProp */
+ bytestoalloc = (bytestoalloc + 3) & ~3;
+ ink_off = bytestoalloc;
+ if (fi.inkMetrics)
+ bytestoalloc += num_chars * sizeof(xCharInfo); /* ink_metrics */
+
+ fontspace = malloc(bytestoalloc);
+ if (!fontspace) {
+ snfError("snfReadFont(): Couldn't allocate fontspace (%d)\n", bytestoalloc);
+ return AllocError;
+ }
+ bitmaps = malloc (bitmapsSize);
+ if (!bitmaps)
+ {
+ snfError("snfReadFont(): Couldn't allocate bitmaps (%d)\n", bitmapsSize);
+ free (fontspace);
+ return AllocError;
+ }
+ /*
+ * now fix up pointers
+ */
+
+ bitmapFont = (BitmapFontPtr) fontspace;
+ bitmapFont->num_chars = num_chars;
+ bitmapFont->metrics = (CharInfoPtr) (fontspace + metrics_off);
+ bitmapFont->encoding = (CharInfoPtr **) (fontspace + encoding_off);
+ bitmapFont->bitmaps = bitmaps;
+ bitmapFont->pDefault = NULL;
+ bitmapFont->bitmapExtra = NULL;
+ pFont->info.props = (FontPropPtr) (fontspace + props_off);
+ pFont->info.isStringProp = (char *) (fontspace + isStringProp_off);
+ if (fi.inkMetrics)
+ bitmapFont->ink_metrics = (xCharInfo *) (fontspace + ink_off);
+ else
+ bitmapFont->ink_metrics = 0;
+
+ /*
+ * read the CharInfo
+ */
+
+ ret = Successful;
+ memset(bitmapFont->encoding, 0,
+ NUM_SEGMENTS(num_chars)*sizeof(CharInfoPtr*));
+ for (i = 0; ret == Successful && i < num_chars; i++) {
+ ret = snfReadCharInfo(file, &bitmapFont->metrics[i], bitmaps);
+ if (bitmapFont->metrics[i].bits) {
+ if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
+ bitmapFont->encoding[SEGMENT_MAJOR(i)]=
+ calloc(BITMAP_FONT_SEGMENT_SIZE, sizeof(CharInfoPtr));
+ if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) {
+ ret = AllocError;
+ break;
+ }
+ }
+ ACCESSENCODINGL(bitmapFont->encoding,i) = &bitmapFont->metrics[i];
+ }
+ }
+
+ if (ret != Successful) {
+ free(bitmaps);
+ if(bitmapFont->encoding) {
+ for(j=0; j<SEGMENT_MAJOR(i); j++)
+ free(bitmapFont->encoding[i]);
+ }
+ free(fontspace);
+ return ret;
+ }
+ /*
+ * read the glyphs
+ */
+
+ if (FontFileRead(file, bitmaps, bitmapsSize) != bitmapsSize) {
+ free(bitmaps);
+ free(fontspace);
+ return BadFontName;
+ }
+
+ if (def_bit != bit)
+ BitOrderInvert((unsigned char *)bitmaps, bitmapsSize);
+ if ((def_byte == def_bit) != (bit == byte)) {
+ switch (bit == byte ? def_scan : scan) {
+ case 1:
+ break;
+ case 2:
+ TwoByteSwap((unsigned char *)bitmaps, bitmapsSize);
+ break;
+ case 4:
+ FourByteSwap((unsigned char *)bitmaps, bitmapsSize);
+ break;
+ }
+ }
+ if (def_glyph != glyph) {
+ char *padbitmaps;
+ int sizepadbitmaps;
+ int sizechar;
+ CharInfoPtr metric;
+
+ sizepadbitmaps = 0;
+ metric = bitmapFont->metrics;
+ for (i = 0; i < num_chars; i++)
+ {
+ if (metric->bits)
+ sizepadbitmaps += BYTES_FOR_GLYPH(metric,glyph);
+ metric++;
+ }
+ padbitmaps = malloc(sizepadbitmaps);
+ if (!padbitmaps) {
+ snfError("snfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps);
+ free (bitmaps);
+ free (fontspace);
+ return AllocError;
+ }
+ metric = bitmapFont->metrics;
+ bitmapFont->bitmaps = padbitmaps;
+ for (i = 0; i < num_chars; i++) {
+ sizechar = RepadBitmap(metric->bits, padbitmaps,
+ def_glyph, glyph,
+ metric->metrics.rightSideBearing -
+ metric->metrics.leftSideBearing,
+ metric->metrics.ascent + metric->metrics.descent);
+ metric->bits = padbitmaps;
+ padbitmaps += sizechar;
+ metric++;
+ }
+ free(bitmaps);
+ }
+
+ /* now read and atom'ize properties */
+
+ ret = snfReadProps(&fi, &pFont->info, file);
+ if (ret != Successful) {
+ free(fontspace);
+ return ret;
+ }
+ snfCopyInfo(&fi, &pFont->info);
+
+ /* finally, read the ink metrics if the exist */
+
+ if (fi.inkMetrics) {
+ ret = Successful;
+ ret = snfReadxCharInfo(file, &pFont->info.ink_minbounds);
+ ret = snfReadxCharInfo(file, &pFont->info.ink_maxbounds);
+ for (i = 0; ret == Successful && i < num_chars; i++)
+ ret = snfReadxCharInfo(file, &bitmapFont->ink_metrics[i]);
+ if (ret != Successful) {
+ free(fontspace);
+ return ret;
+ }
+ } else {
+ pFont->info.ink_minbounds = pFont->info.minbounds;
+ pFont->info.ink_maxbounds = pFont->info.maxbounds;
+ }
+
+ if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) {
+ unsigned int r,
+ c,
+ cols;
+
+ r = pFont->info.defaultCh >> 8;
+ c = pFont->info.defaultCh & 0xFF;
+ if (pFont->info.firstRow <= r && r <= pFont->info.lastRow &&
+ pFont->info.firstCol <= c && c <= pFont->info.lastCol) {
+ cols = pFont->info.lastCol - pFont->info.firstCol + 1;
+ r = r - pFont->info.firstRow;
+ c = c - pFont->info.firstCol;
+ bitmapFont->pDefault = &bitmapFont->metrics[r * cols + c];
+ }
+ }
+ bitmapFont->bitmapExtra = (BitmapExtraPtr) 0;
+ pFont->fontPrivate = (pointer) bitmapFont;
+ pFont->get_glyphs = bitmapGetGlyphs;
+ pFont->get_metrics = bitmapGetMetrics;
+ pFont->unload_font = snfUnloadFont;
+ pFont->unload_glyphs = NULL;
+ pFont->bit = bit;
+ pFont->byte = byte;
+ pFont->glyph = glyph;
+ pFont->scan = scan;
+ return Successful;
+}
+
+int
+snfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file)
+{
+ int ret;
+ snfFontInfoRec fi;
+ int bytestoskip;
+ int num_chars;
+
+ ret = snfReadHeader(&fi, file);
+ if (ret != Successful)
+ return ret;
+ snfCopyInfo(&fi, pFontInfo);
+
+ pFontInfo->props = malloc(fi.nProps * sizeof(FontPropRec));
+ if (!pFontInfo->props) {
+ snfError("snfReadFontInfo(): Couldn't allocate props (%d*%d)\n", fi.nProps, sizeof(FontPropRec));
+ return AllocError;
+ }
+ pFontInfo->isStringProp = malloc(fi.nProps * sizeof(char));
+ if (!pFontInfo->isStringProp) {
+ snfError("snfReadFontInfo(): Couldn't allocate isStringProp (%d*%d)\n", fi.nProps, sizeof(char));
+ free(pFontInfo->props);
+ return AllocError;
+ }
+ num_chars = n2dChars(&fi);
+ bytestoskip = num_chars * sizeof(snfCharInfoRec); /* charinfos */
+ bytestoskip += BYTESOFGLYPHINFO(&fi);
+ (void)FontFileSkip(file, bytestoskip);
+
+ ret = snfReadProps(&fi, pFontInfo, file);
+ if (ret != Successful) {
+ free(pFontInfo->props);
+ free(pFontInfo->isStringProp);
+ return ret;
+ }
+ if (fi.inkMetrics) {
+ ret = snfReadxCharInfo(file, &pFontInfo->ink_minbounds);
+ if (ret != Successful) {
+ free(pFontInfo->props);
+ free(pFontInfo->isStringProp);
+ return ret;
+ }
+ ret = snfReadxCharInfo(file, &pFontInfo->ink_maxbounds);
+ if (ret != Successful) {
+ free(pFontInfo->props);
+ free(pFontInfo->isStringProp);
+ return ret;
+ }
+ } else {
+ pFontInfo->ink_minbounds = pFontInfo->minbounds;
+ pFontInfo->ink_maxbounds = pFontInfo->maxbounds;
+ }
+ return Successful;
+
+}
+
+static void
+snfUnloadFont(FontPtr pFont)
+{
+ BitmapFontPtr bitmapFont;
+
+ bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
+ free (bitmapFont->bitmaps);
+ free (bitmapFont);
+ DestroyFontRec (pFont);
+}
+
diff --git a/libXfont/src/bitmap/snfstr.h b/libXfont/src/bitmap/snfstr.h
index 148bb1fcc..89372669e 100644
--- a/libXfont/src/bitmap/snfstr.h
+++ b/libXfont/src/bitmap/snfstr.h
@@ -1,182 +1,182 @@
-/***********************************************************
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-/*
-
-Copyright 1994, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-*/
-
-#ifndef SNFSTR_H
-#define SNFSTR_H 1
-
-#include <X11/fonts/fntfilio.h>
-
-/*-
- * This file describes the Server Natural Font format.
- * SNF fonts are both CPU-dependent and frame buffer bit order dependent.
- * This file is used by:
- * 1) the server, to hold font information read out of font files.
- * 2) font converters
- *
- * Each font file contains the following
- * data structures, with no padding in-between.
- *
- * 1) The XFONTINFO structure
- * hand-padded to a two-short boundary.
- * maxbounds.byteoffset is the total number of bytes in the
- * glpyh array
- * maxbounds.bitOffset is thetotal width of the unpadded font
- *
- * 2) The XCHARINFO array
- * indexed directly with character codes, both on disk
- * and in memory.
- *
- * 3) Character glyphs
- * padded in the server-natural way, and
- * ordered in the device-natural way.
- * End of glyphs padded to 32-bit boundary.
- *
- * 4) nProps font properties
- *
- * 5) a sequence of null-terminated strings, for font properties
- */
-
-#define FONT_FILE_VERSION 4
-
-typedef struct _snfFontProp {
- CARD32 name; /* offset of string */
- INT32 value; /* number or offset of string */
- Bool indirect; /* value is a string offset */
-} snfFontPropRec;
-
-/*
- * the following macro definitions describe a font file image in memory
- */
-#define ADDRCharInfoRec( pfi) \
- ((snfCharInfoRec *) &(pfi)[1])
-
-#define ADDRCHARGLYPHS( pfi) \
- (((char *) &(pfi)[1]) + BYTESOFCHARINFO(pfi))
-
-/*
- * pad out glyphs to a CARD32 boundary
- */
-#define ADDRXFONTPROPS( pfi) \
- ((snfFontPropRec *) ((char *)ADDRCHARGLYPHS( pfi) + BYTESOFGLYPHINFO(pfi)))
-
-#define ADDRSTRINGTAB( pfi) \
- ((char *)ADDRXFONTPROPS( pfi) + BYTESOFPROPINFO(pfi))
-
-#define n2dChars(pfi) (((pfi)->lastRow - (pfi)->firstRow + 1) * \
- ((pfi)->lastCol - (pfi)->firstCol + 1))
-#define BYTESOFFONTINFO(pfi) (sizeof(snfFontInfoRec))
-#define BYTESOFCHARINFO(pfi) (sizeof(snfCharInfoRec) * n2dChars(pfi))
-#define BYTESOFPROPINFO(pfi) (sizeof(snfFontPropRec) * (pfi)->nProps)
-#define BYTESOFSTRINGINFO(pfi) ((pfi)->lenStrings)
-#define BYTESOFGLYPHINFO(pfi) (((pfi)->maxbounds.byteOffset+3) & ~0x3)
-#define BYTESOFINKINFO(pfi) (sizeof(snfCharInfoRec) * n2dChars(pfi))
-
-typedef struct _snfFontProp *snfFontPropPtr;
-typedef struct _snfCharInfo *snfCharInfoPtr;
-typedef struct _snfFontInfo *snfFontInfoPtr;
-
-typedef struct _snfCharInfo {
- xCharInfo metrics; /* info preformatted for Queries */
- unsigned byteOffset:24; /* byte offset of the raster from pGlyphs */
- unsigned exists:1; /* true iff glyph exists for this char */
- unsigned pad:7; /* must be zero for now */
-} snfCharInfoRec;
-
-typedef struct _snfFontInfo {
- unsigned int version1; /* version stamp */
- unsigned int allExist;
- unsigned int drawDirection;
- unsigned int noOverlap; /* true if:
- * max(rightSideBearing-characterWidth) <=
- * minbounds->metrics.leftSideBearing */
- unsigned int constantMetrics;
- unsigned int terminalFont; /* Should be deprecated! true if: constant
- * metrics && leftSideBearing == 0 &&
- * rightSideBearing == characterWidth &&
- * ascent == fontAscent && descent ==
- * fontDescent */
- unsigned int linear:1; /* true if firstRow == lastRow */
- unsigned int constantWidth:1; /* true if
- * minbounds->metrics.characterWidth
- * ==
- * maxbounds->metrics.characterWidth */
- unsigned int inkInside:1; /* true if for all defined glyphs:
- * leftSideBearing >= 0 && rightSideBearing <=
- * characterWidth && -fontDescent <= ascent <=
- * fontAscent && -fontAscent <= descent <=
- * fontDescent */
- unsigned int inkMetrics:1; /* ink metrics != bitmap metrics */
- /* used with terminalFont */
- /* see font's pInk{CI,Min,Max} */
- unsigned int padding:28;
- unsigned int firstCol;
- unsigned int lastCol;
- unsigned int firstRow;
- unsigned int lastRow;
- unsigned int nProps;
- unsigned int lenStrings; /* length in bytes of string table */
- unsigned int chDefault; /* default character */
- int fontDescent; /* minimum for quality typography */
- int fontAscent; /* minimum for quality typography */
- snfCharInfoRec minbounds; /* MIN of glyph metrics over all chars */
- snfCharInfoRec maxbounds; /* MAX of glyph metrics over all chars */
- unsigned int pixDepth; /* intensity bits per pixel */
- unsigned int glyphSets; /* number of sets of glyphs, for sub-pixel
- * positioning */
- unsigned int version2; /* version stamp double-check */
-} snfFontInfoRec;
-
-extern void SnfSetFormat ( int bit, int byte, int glyph, int scan );
-extern int snfReadFont ( FontPtr pFont, FontFilePtr file,
- int bit, int byte, int glyph, int scan );
-extern int snfReadFontInfo ( FontInfoPtr pFontInfo, FontFilePtr file );
-
-#endif /* SNFSTR_H */
+/***********************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/*
+
+Copyright 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifndef SNFSTR_H
+#define SNFSTR_H 1
+
+#include <X11/fonts/fntfilio.h>
+
+/*-
+ * This file describes the Server Natural Font format.
+ * SNF fonts are both CPU-dependent and frame buffer bit order dependent.
+ * This file is used by:
+ * 1) the server, to hold font information read out of font files.
+ * 2) font converters
+ *
+ * Each font file contains the following
+ * data structures, with no padding in-between.
+ *
+ * 1) The XFONTINFO structure
+ * hand-padded to a two-short boundary.
+ * maxbounds.byteoffset is the total number of bytes in the
+ * glpyh array
+ * maxbounds.bitOffset is thetotal width of the unpadded font
+ *
+ * 2) The XCHARINFO array
+ * indexed directly with character codes, both on disk
+ * and in memory.
+ *
+ * 3) Character glyphs
+ * padded in the server-natural way, and
+ * ordered in the device-natural way.
+ * End of glyphs padded to 32-bit boundary.
+ *
+ * 4) nProps font properties
+ *
+ * 5) a sequence of null-terminated strings, for font properties
+ */
+
+#define FONT_FILE_VERSION 4
+
+typedef struct _snfFontProp {
+ CARD32 name; /* offset of string */
+ INT32 value; /* number or offset of string */
+ Bool indirect; /* value is a string offset */
+} snfFontPropRec;
+
+/*
+ * the following macro definitions describe a font file image in memory
+ */
+#define ADDRCharInfoRec( pfi) \
+ ((snfCharInfoRec *) &(pfi)[1])
+
+#define ADDRCHARGLYPHS( pfi) \
+ (((char *) &(pfi)[1]) + BYTESOFCHARINFO(pfi))
+
+/*
+ * pad out glyphs to a CARD32 boundary
+ */
+#define ADDRXFONTPROPS( pfi) \
+ ((snfFontPropRec *) ((char *)ADDRCHARGLYPHS( pfi) + BYTESOFGLYPHINFO(pfi)))
+
+#define ADDRSTRINGTAB( pfi) \
+ ((char *)ADDRXFONTPROPS( pfi) + BYTESOFPROPINFO(pfi))
+
+#define n2dChars(pfi) (((pfi)->lastRow - (pfi)->firstRow + 1) * \
+ ((pfi)->lastCol - (pfi)->firstCol + 1))
+#define BYTESOFFONTINFO(pfi) (sizeof(snfFontInfoRec))
+#define BYTESOFCHARINFO(pfi) (sizeof(snfCharInfoRec) * n2dChars(pfi))
+#define BYTESOFPROPINFO(pfi) (sizeof(snfFontPropRec) * (pfi)->nProps)
+#define BYTESOFSTRINGINFO(pfi) ((pfi)->lenStrings)
+#define BYTESOFGLYPHINFO(pfi) (((pfi)->maxbounds.byteOffset+3) & ~0x3)
+#define BYTESOFINKINFO(pfi) (sizeof(snfCharInfoRec) * n2dChars(pfi))
+
+typedef struct _snfFontProp *snfFontPropPtr;
+typedef struct _snfCharInfo *snfCharInfoPtr;
+typedef struct _snfFontInfo *snfFontInfoPtr;
+
+typedef struct _snfCharInfo {
+ xCharInfo metrics; /* info preformatted for Queries */
+ unsigned byteOffset:24; /* byte offset of the raster from pGlyphs */
+ unsigned exists:1; /* true iff glyph exists for this char */
+ unsigned pad:7; /* must be zero for now */
+} snfCharInfoRec;
+
+typedef struct _snfFontInfo {
+ unsigned int version1; /* version stamp */
+ unsigned int allExist;
+ unsigned int drawDirection;
+ unsigned int noOverlap; /* true if:
+ * max(rightSideBearing-characterWidth) <=
+ * minbounds->metrics.leftSideBearing */
+ unsigned int constantMetrics;
+ unsigned int terminalFont; /* Should be deprecated! true if: constant
+ * metrics && leftSideBearing == 0 &&
+ * rightSideBearing == characterWidth &&
+ * ascent == fontAscent && descent ==
+ * fontDescent */
+ unsigned int linear:1; /* true if firstRow == lastRow */
+ unsigned int constantWidth:1; /* true if
+ * minbounds->metrics.characterWidth
+ * ==
+ * maxbounds->metrics.characterWidth */
+ unsigned int inkInside:1; /* true if for all defined glyphs:
+ * leftSideBearing >= 0 && rightSideBearing <=
+ * characterWidth && -fontDescent <= ascent <=
+ * fontAscent && -fontAscent <= descent <=
+ * fontDescent */
+ unsigned int inkMetrics:1; /* ink metrics != bitmap metrics */
+ /* used with terminalFont */
+ /* see font's pInk{CI,Min,Max} */
+ unsigned int padding:28;
+ unsigned int firstCol;
+ unsigned int lastCol;
+ unsigned int firstRow;
+ unsigned int lastRow;
+ unsigned int nProps;
+ unsigned int lenStrings; /* length in bytes of string table */
+ unsigned int chDefault; /* default character */
+ int fontDescent; /* minimum for quality typography */
+ int fontAscent; /* minimum for quality typography */
+ snfCharInfoRec minbounds; /* MIN of glyph metrics over all chars */
+ snfCharInfoRec maxbounds; /* MAX of glyph metrics over all chars */
+ unsigned int pixDepth; /* intensity bits per pixel */
+ unsigned int glyphSets; /* number of sets of glyphs, for sub-pixel
+ * positioning */
+ unsigned int version2; /* version stamp double-check */
+} snfFontInfoRec;
+
+extern void SnfSetFormat ( int bit, int byte, int glyph, int scan );
+extern int snfReadFont ( FontPtr pFont, FontFilePtr file,
+ int bit, int byte, int glyph, int scan );
+extern int snfReadFontInfo ( FontInfoPtr pFontInfo, FontFilePtr file );
+
+#endif /* SNFSTR_H */