diff options
Diffstat (limited to 'libXfont/src/bitmap')
-rw-r--r-- | libXfont/src/bitmap/bdfread.c | 1910 | ||||
-rw-r--r-- | libXfont/src/bitmap/bdfutils.c | 672 | ||||
-rw-r--r-- | libXfont/src/bitmap/bitmap.c | 314 | ||||
-rw-r--r-- | libXfont/src/bitmap/bitmapfunc.c | 510 | ||||
-rw-r--r-- | libXfont/src/bitmap/bitmaputil.c | 454 | ||||
-rw-r--r-- | libXfont/src/bitmap/bitscale.c | 3386 | ||||
-rw-r--r-- | libXfont/src/bitmap/fontink.c | 432 | ||||
-rw-r--r-- | libXfont/src/bitmap/makefile | 16 | ||||
-rw-r--r-- | libXfont/src/bitmap/pcfread.c | 1560 | ||||
-rw-r--r-- | libXfont/src/bitmap/pcfwrite.c | 932 | ||||
-rw-r--r-- | libXfont/src/bitmap/snfread.c | 1016 | ||||
-rw-r--r-- | libXfont/src/bitmap/snfstr.h | 364 |
12 files changed, 5792 insertions, 5774 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 cf16bffed..cf22a4593 100644 --- a/libXfont/src/bitmap/bitscale.c +++ b/libXfont/src/bitmap/bitscale.c @@ -1,1691 +1,1695 @@ -/* - -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); - - if (propCount && (!props || !isStringProp)) - { - font->info.nprops = 0; - font->info.props = (FontPropPtr)0; - font->info.isStringProp = (char *)0; - bitmapUnloadScalable(font); - return AllocError; - } - - font->info.props = props; - font->info.nprops = propCount; - font->info.isStringProp = isStringProp; - - *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);
+
+ if (propCount && (!props || !isStringProp))
+ {
+ font->info.nprops = 0;
+ font->info.props = (FontPropPtr)0;
+ font->info.isStringProp = (char *)0;
+ bitmapUnloadScalable(font);
+ return AllocError;
+ }
+
+ font->info.props = props;
+ font->info.nprops = propCount;
+ font->info.isStringProp = isStringProp;
+
+ *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 */
|