home *** CD-ROM | disk | FTP | other *** search
- /* $Header: scale.c,v 1.20 91/01/10 20:09:48 rws Exp $ */
-
- /*
- * Copyright 1990 Massachusetts Institute of Technology
- *
- * 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, and that the name of M.I.T. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. M.I.T. makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
- * 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.
- *
- */
-
- #include "Xos.h"
- #include "X.h"
- #include "Xmd.h"
- #include "Xproto.h"
- #include "dixfont.h"
- #include "dixfontstr.h"
- #include "font.h"
- #include "fontstruct.h"
- #include "snfstruct.h"
- #include "os.h"
- #include "osstruct.h"
- #include "misc.h"
- #include "fontdir.h"
-
- #define MAXFNAMELEN 1024
-
- extern FontFile FindFontFile();
- extern Atom MakeAtom();
-
- typedef struct _scalables {
- int pixel, point, x, y, width;
- } Scalables;
-
- enum scaleType {
- atom, pixel_size, point_size, resolution_x, resolution_y, average_width,
- scaledX, scaledY, unscaled, scaledXoverY, uncomputed
- };
-
- typedef struct _fontProp {
- char *name;
- Atom atom;
- enum scaleType type;
- } fontProp;
-
-
- static unsigned long fontGeneration=0; /* initialization flag */
-
- static FontTable scaledFonts = (FontTable)NULL;
-
- 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, atom,
- "FONT", 0, atom
- };
- #define NPROPS ((sizeof(fontNamePropTable) / sizeof(fontProp)) - 1)
-
- 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,
- "ITALIC_ANGLE", 0, unscaled,
- "CAP_HEIGHT", 0, scaledY,
- "X_HEIGHT", 0, scaledY,
- "RELATIVE_SETWIDTH", 0, unscaled,
- "RELATIVE_WEIGHT", 0, unscaled,
- "WEIGHT", 0, scaledXoverY,
- "DESTINATION", 0, unscaled
- };
-
- static void initFontPropTable()
- {
- 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);
- }
-
- static char *
- GetInt(ptr, val)
- char *ptr;
- int *val;
- {
- ptr++;
- if (*ptr == '*')
- {
- *val = -1;
- ptr++;
- }
- else
- for (*val = 0; *ptr >= '0' && *ptr <= '9'; )
- *val = *val * 10 + *ptr++ - '0';
- if (*ptr == '-')
- return ptr;
- return (char *)NULL;
- }
-
- static Bool
- ParseXLFDName(fname, vals, subst)
- char *fname;
- register Scalables *vals;
- char subst;
- {
- register char *ptr;
- register char *ptr1, *ptr2, *ptr3, *ptr4;
-
- if (!(*fname == '-') || /* foundry */
- !(ptr = index(fname+1, '-')) || /* family_name */
- !(ptr = index(ptr+1, '-')) || /* weight_name */
- !(ptr = index(ptr+1, '-')) || /* slant */
- !(ptr = index(ptr+1, '-')) || /* setwidth_name */
- !(ptr = index(ptr+1, '-')) || /* add_style_name */
- !(ptr1 = ptr = index(ptr+1, '-')) || /* pixel_size */
- !(ptr = GetInt(ptr, &vals->pixel)) ||
- !(ptr = GetInt(ptr, &vals->point)) || /* point_size */
- !(ptr = GetInt(ptr, &vals->x)) || /* resolution_x */
- !(ptr2 = ptr = GetInt(ptr, &vals->y)) || /* resolution_y */
- !(ptr3 = ptr = index(ptr+1, '-')) || /* spacing */
- !(ptr4 = ptr = GetInt(ptr, &vals->width)) || /* average_width */
- !(ptr = index(ptr+1, '-')) || /* charset_registry */
- index(ptr+1, '-')) /* charset_encoding */
- return FALSE;
- if (subst)
- {
- ptr = ptr1 + 1;
- *ptr++ = subst;
- *ptr++ = '-';
- *ptr++ = subst;
- *ptr++ = '-';
- *ptr++ = subst;
- *ptr++ = '-';
- *ptr++ = subst;
- bcopy(ptr2, ptr, ptr3 - ptr2 + 1);
- ptr += ptr3 - ptr2 + 1;
- *ptr++ = subst;
- strcpy(ptr, ptr4);
- }
- return TRUE;
- }
-
- static void
- ComputeScaleFactors(from, to, dx, dy)
- Scalables *from, *to;
- double *dx, *dy;
- {
- /* compute scale factors */
- *dy = ((double) to->point * to->y) / (from->point * from->y);
- *dx = (((double)(to->x * from->y)) / (to->y * from->x)) * *dy;
- if (to->width > 0)
- *dx = to->width / (from->width * *dx);
- }
-
- #define SCORE(m,s) \
- if (m >= 1.0) { \
- if ((m == 1.0) || (m == 2.0)) \
- score += (4 * s); \
- else if (m < minfrac) \
- score += (1 * s); \
- else if (m < 2.0) \
- score += (3 * s); \
- else \
- score += (2 * s); \
- } else { \
- m = 1/m; \
- if (m < minfrac) \
- score += (1 * s); \
- else \
- score += (2 * s); \
- }
-
- static Bool
- FindBestToScale(fname, vals, best)
- char *fname;
- register Scalables *vals, *best;
- {
- register FontPathPtr fpr;
- Scalables temp;
- int best_path;
- register int i;
- int best_score, score;
- double dx, dy, best_dx, best_dy, minfrac;
-
- /* find all matching fonts */
- fpr = ExpandFontNamePattern((unsigned)strlen(fname), fname, 65535);
- if (!fpr)
- return False;
- /* find the best match */
- best_score = 0;
- for (i = 0; i < fpr->npaths; i++)
- {
- if (!ParseXLFDName(fpr->paths[i], &temp, '\0'))
- continue;
- if ((temp.pixel <= 0) || (temp.point <= 0) ||
- (temp.x <= 0) || (temp.y <= 0))
- continue;
- ComputeScaleFactors(&temp, vals, &dx, &dy);
- minfrac = (double)(3 * temp.pixel);
- minfrac = (minfrac + 4.0) / minfrac;
- score = 0;
- SCORE(dy, 10);
- SCORE(dx, 1);
- if ((score > best_score) ||
- ((score == best_score) &&
- ((dy < best_dy) || ((dy == best_dy) && (dx < best_dx))))) {
- best_path = i;
- best_score = score;
- best_dx = dx;
- best_dy = dy;
- *best = temp;
- }
- }
- if (best_score)
- strcpy(fname, fpr->paths[best_path]);
- FreeFontRecord(fpr);
- return (best_score != 0);
- }
-
- static int computeProps(pf, npf, nprops, xfactor, yfactor)
- DIXFontProp * pf;
- DIXFontProp * npf;
- unsigned int nprops;
- double xfactor, yfactor;
- {
- int n;
- int count;
- fontProp* t;
-
- for (count=0; nprops > 0; nprops--, pf++) {
- 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 = xfactor * pf->value;
- break;
- case scaledY:
- npf->value = yfactor * pf->value;
- break;
- case unscaled:
- npf->value = pf->value;
- break;
- case scaledXoverY:
- npf->value = pf->value * (xfactor / yfactor);
- }
- npf->name = pf->name;
- npf++;
- count++;
- }
- return count;
- }
-
- static int ComputeScaledProperties(font, canonname, vals, dx, dy,
- scalename, tmpProps)
- FontPtr font; /* the font to be scaled */
- char * canonname; /* canonical name of the scaled font */
- Scalables *vals;
- double dx, dy; /* scale factors in x and y directions */
- char * scalename; /* returns XLFD name of the scaled font */
- DIXFontProp *tmpProps; /* returns properties; preallocated */
- {
- int n;
- unsigned len;
- char *ptr1, *ptr2, *ptr3, *ptr4;
- DIXFontProp *fp;
- fontProp *fpt;
-
- if (fontGeneration != serverGeneration) {
- initFontPropTable();
- fontGeneration = serverGeneration;
- }
- ptr2 = canonname;
- ptr4 = scalename;
- for (fp=tmpProps, fpt=fontNamePropTable, n=NPROPS; n; fp++, fpt++, n--) {
-
- *ptr4 = '-';
- ptr1 = ptr2+1;
- if (*ptr1 == '-')
- ptr2 = ptr1;
- else {
- if (n > 1)
- ptr2 = index(ptr1+1, '-');
- else
- ptr2 = index(ptr1+1, '\0');
- }
- ptr3 = ptr4+1;
-
- switch (fpt->type) {
- case atom:
- len = ptr2 - ptr1;
- strncpy(ptr3, ptr1, len);
- fp->value = MakeAtom(ptr3, len, TRUE);
- break;
- case pixel_size:
- sprintf(ptr3, "%d", vals->pixel);
- len = strlen(ptr3);
- fp->value = vals->pixel;
- break;
- case point_size:
- sprintf(ptr3, "%d", vals->point);
- len = strlen(ptr3);
- fp->value = vals->point;
- break;
- case resolution_x:
- sprintf(ptr3, "%d", vals->x);
- len = strlen(ptr3);
- fp->value = vals->x;
- break;
- case resolution_y:
- sprintf(ptr3, "%d", vals->y);
- len = strlen(ptr3);
- fp->value = vals->y;
- break;
- case average_width:
- sprintf(ptr3, "%d", vals->width);
- len = strlen(ptr3);
- fp->value = vals->width;
- break;
- }
- ptr4 = ptr3 + len;
- fp->name = fpt->atom;
- }
- *ptr4 = '\0';
- fp->name = fpt->atom;
- fp->value = MakeAtom(scalename, (unsigned)(ptr4 - scalename), TRUE);
-
- n = NPROPS + 1;
- n += computeProps(font->pFP, tmpProps + n, font->pFI->nProps, dx, dy);
- return n;
- }
-
- /*
- * ScaleFont
- * returns a pointer to the new scaled font, or NULL (due to BadAlloc).
- */
- static FontPtr
- ScaleFont(opf, widthMult, heightMult, props, propCount)
- FontPtr opf; /* originating font */
- double widthMult; /* glyphs width scale factor */
- double heightMult; /* glyphs height scale factor */
- DIXFontProp* props; /* some of the new properties */
- int propCount; /* count of new properties */
- {
- FontPtr pf;
- FontInfoPtr pfi, opfi;
- CharInfoPtr pci, opci;
- int nchars; /* how many characters in the font */
- int newWidth, newHeight;
- unsigned glyphBytesOffset;
- unsigned bytestoalloc, bytestoink, bytestoprops, bytestoglyphs;
- char * fontspace;
- int * scratch;
- static void ScaleBitmap();
-
- /* Allocate a new Font struct in one chunk of memory.
- *
- * FontRec pf
- * FontInfoRec pf->pFI
- * CharInfoRec's pf->pCI[i]
- * Glyphs pf->pGlyphs[i] not necessarily the same i
- * DIX Properties pf->pFP
- * Ink CharInfoRec's pf->pInkCI, pf->pInkMin, pf->pInkMax
- */
- opfi = opf->pFI;
- bytestoalloc = sizeof (FontRec);
- bytestoalloc += BYTESOFFONTINFO(opfi);
- bytestoalloc += BYTESOFCHARINFO(opfi);
- bytestoglyphs = bytestoalloc;
- nchars = n2dChars(opfi);
- for (opci=opf->pCI; nchars; opci++, nchars--)
- if (opci->exists) {
- newWidth = GLYPHWIDTHPIXELS(opci) * widthMult;
- newHeight = GLYPHHEIGHTPIXELS(opci) * heightMult;
- bytestoalloc += PADGLYPHWIDTHBYTES(newWidth) * newHeight;
- }
- nchars = n2dChars(opfi);
- bytestoprops = bytestoalloc;
- bytestoalloc += propCount * sizeof (DIXFontProp);
- bytestoink = bytestoalloc;
- if (opfi->inkMetrics) bytestoalloc += BYTESOFINKINFO(opfi);
-
- /* allocate the new font structure */
-
- if (! (fontspace = (char *) xalloc(bytestoalloc)))
- return (FontPtr) NULL;
-
- /* set up pointers into the new font space */
-
- pf = (FontPtr) fontspace;
- pfi = pf->pFI = (FontInfoPtr) (fontspace + sizeof(FontRec));
- *pfi = *opfi;
- pfi->nProps = propCount;
-
- pf->pCI = ADDRCharInfoRec(pfi);
- pf->pGlyphs = (char *) (fontspace + bytestoglyphs);
- bzero(pf->pGlyphs, (bytestoprops - bytestoglyphs));
-
- /* Copy over the scaled XLFD properties */
-
- pf->pFP = (DIXFontProp *) (fontspace + bytestoprops);
- bcopy((char *)props, (char *)pf->pFP, propCount * sizeof(DIXFontProp));
-
- if (pfi->inkMetrics) {
- pf->pInkMin = (CharInfoPtr)(fontspace + bytestoink);
- pf->pInkMax = pf->pInkMin + 1;
- pf->pInkCI = pf->pInkMax + 1;
- } else {
- pf->pInkMin = &pfi->minbounds;
- pf->pInkMax = &pfi->maxbounds;
- pf->pInkCI = pf->pCI;
- }
-
- /* FontRec */
-
- pf->osPrivate = opf->osPrivate;
- pf->fileType = opf->fileType;
- pf->refcnt = 0;
-
- /* FontInfo
- * fontDescent
- * fontAscent
- * minbounds
- * maxbounds
- * -- everything else was copied from the original font, above.
- */
-
- pfi->fontDescent *= heightMult;
- pfi->fontAscent *= heightMult;
- pfi->minbounds.metrics.leftSideBearing = MAXSHORT;
- pfi->minbounds.metrics.rightSideBearing = MAXSHORT;
- pfi->minbounds.metrics.ascent = MAXSHORT;
- pfi->minbounds.metrics.descent = MAXSHORT;
- pfi->minbounds.metrics.characterWidth = opf->pCI->metrics.characterWidth;
-
- pfi->maxbounds.metrics.leftSideBearing = MINSHORT;
- pfi->maxbounds.metrics.rightSideBearing = MINSHORT;
- pfi->maxbounds.metrics.ascent = MINSHORT;
- pfi->maxbounds.metrics.descent = MINSHORT;
- pfi->maxbounds.metrics.characterWidth = opf->pCI->metrics.characterWidth;
-
- /* For each character, set the per-character metrics, scale the glyph,
- * and check per-font minbounds and maxbounds character information.
- */
-
- /* Allocate the scratch space for the glyph scaling routine. */
- if (! (scratch = (int *)
- ALLOCATE_LOCAL((int) ((opfi->maxbounds.metrics.rightSideBearing -
- opfi->minbounds.metrics.leftSideBearing)
- * widthMult * sizeof(int))))) {
- xfree(fontspace);
- return (FontPtr) NULL;
- }
-
- glyphBytesOffset = 0;
- pci = pf->pCI;
- for (opci = opf->pCI; nchars; pci++, opci++, --nchars) {
- int width, height;
-
- if (! (pci->exists = opci->exists))
- continue;
-
- /* Determine current and new width and height */
-
- width = GLYPHWIDTHPIXELS(opci);
- height = GLYPHHEIGHTPIXELS(opci);
- newWidth = width * widthMult;
- newHeight = height * heightMult;
-
- /* Scale the glyph */
-
- ScaleBitmap(&(opf->pGlyphs[(int) opci->byteOffset]), width,
- height, &(pf->pGlyphs[(int) glyphBytesOffset]), newWidth,
- newHeight, scratch);
-
- pci->byteOffset = glyphBytesOffset;
- glyphBytesOffset += (PADGLYPHWIDTHBYTES(newWidth) * newHeight);
-
- /* Scale the character metrics */
-
- pci->metrics.leftSideBearing = (opci->metrics.leftSideBearing *
- widthMult);
- pci->metrics.rightSideBearing = newWidth +
- pci->metrics.leftSideBearing;
- pci->metrics.ascent = opci->metrics.ascent * heightMult;
- pci->metrics.descent = newHeight - pci->metrics.ascent;
- pci->metrics.characterWidth = opci->metrics.characterWidth * widthMult;
- pci->metrics.attributes = opci->metrics.attributes;
-
- #define MINMAX(field) \
- if (pfi->minbounds.metrics.field > pci->metrics.field) \
- pfi->minbounds.metrics.field = pci->metrics.field; \
- if (pfi->maxbounds.metrics.field < pci->metrics.field) \
- pfi->maxbounds.metrics.field = pci->metrics.field
-
- MINMAX(leftSideBearing);
- MINMAX(rightSideBearing);
- MINMAX(ascent);
- MINMAX(descent);
- MINMAX(characterWidth);
- #undef MINMAX
-
- }
- pci = pf->pCI;
- DEALLOCATE_LOCAL((char *) scratch);
-
- /* Check and set ink metrics */
- if (pfi->inkMetrics) {
- CharInfoPtr pci;
- int n;
- n = (bytestoalloc - bytestoink) / sizeof(CharInfoRec);
- bcopy(opf->pInkMin, pf->pInkMin, n);
- for (pci=pf->pInkMin; n; n--, pci++) {
- if (pci->exists) {
- pci->metrics.leftSideBearing *= widthMult;
- pci->metrics.rightSideBearing *= widthMult;
- pci->metrics.ascent *= heightMult;
- pci->metrics.descent *= heightMult;
- pci->metrics.characterWidth *= widthMult;
- }
- }
- }
- return pf;
- }
-
- static int lcm(a, b) /* least common multiple */
- int a, b;
- {
- register int m;
- register int larger, smaller;
-
- m = larger = max(a, b);
- smaller = min(a, b);
-
- while (m % smaller)
- m += larger;
- return m;
- }
-
- static void ScaleBitmap(bitmap, width, height,
- newBitmap, newWidth, newHeight, scratch)
- char * bitmap; /* padded bitmap to be scaled */
- int width; /* unpadded width of bitmap in bits */
- int height; /* unpadded height of bitmap in bits */
- char * newBitmap; /* allocated, zero'ed, padded memory */
- int newWidth; /* unpadded width of new bitmap in bits */
- int newHeight; /* unpadded height of new bitmap in bits */
- int * scratch; /* scratch memory: newWidth * sizeof int */
- {
- int kcounter; /* 0 <= kcounter <= k */
- int lcounter; /* 0 <= lcounter <= l */
- int kkcounter; /* 0 <= kkcounter <= kk */
- int llcounter; /* 0 <= llcounter <= ll */
- int newBit; /* newBitmap column index, by bits */
- int * acc; /* pseudonym for scratch */
- int bitValue; /* tmp variable */
- int dataByte;
- char * dataBytePointer;
- char * saveDataBytePointer;
-
- /* The following variables have constant values, once assigned. */
-
- int virtualWidth; /* unpadded bit width of the virtual bitmap */
- int virtualHeight; /* unpadded bit height of the virtual bitmap */
- int k; /* horizontal bit copies in virtualBitmap */
- int l; /* vertical bit copies in virtualBitmap */
- int kk; /* horiz. virtual bits in a newBitmap bit */
- int ll; /* vertical virtual bits in a newBitmap bit */
- int threshold;
- int padWidth; /* actual width in bytes of pad in bitmap */
- int newPadWidth;
-
- if (!newWidth || !newHeight)
- return;
-
- padWidth = PADGLYPHWIDTHBYTES(width) - ((width + 7) >> 3);
- newPadWidth = PADGLYPHWIDTHBYTES(newWidth) - ((newWidth + 7) >> 3);
- virtualWidth = lcm(width, newWidth);
- virtualHeight = lcm(height, newHeight);
- k = virtualWidth / width;
- l = virtualHeight / height;
- kk = virtualWidth / newWidth;
- ll = virtualHeight / newHeight;
- threshold = kk * ll;
-
- saveDataBytePointer = bitmap;
- newBitmap--;
- lcounter = l;
- for (; newHeight; newHeight--, newBitmap += newPadWidth) {
-
- newBit = newWidth;
- acc = scratch;
- do
- *acc++ = threshold;
- while (--newBit);
-
- llcounter = ll;
- while (llcounter) {
- int bit; /* index into glyph row, indicating a bit */
- int row_dup; /* row duplication count from source */
- int kdup;
- int kkdup;
-
- if (! lcounter) {
- lcounter = l;
- dataBytePointer += padWidth;
- saveDataBytePointer = dataBytePointer;
- } else
- dataBytePointer = saveDataBytePointer;
-
- if ((row_dup = llcounter) > lcounter)
- row_dup = lcounter;
- lcounter -= row_dup;
- llcounter -= row_dup;
- row_dup <<= 1;
-
- bit = 1;
- kdup = k * row_dup;
- kkdup = kk * row_dup;
- kcounter = 0;
- newBit = newWidth;
- acc = scratch;
- do {
- int tmp = 0;
- kkcounter = kkdup;
- if (! kcounter) {
- /* advance to the next column of the source bitmap */
- kcounter = kdup;
- if (! (--bit)) {
- bit = 8;
- dataByte = *dataBytePointer++;
- }
- /* extract the appropriate bit from source bitmap */
- #if (BITMAP_BIT_ORDER == LSBFirst)
- bitValue = dataByte & 1;
- dataByte >>= 1;
- #else
- bitValue = dataByte & 128;
- dataByte <<= 1;
- #endif
- }
- while ((kkcounter -= kcounter) > 0) {
- if (bitValue)
- tmp += kcounter;
- /* advance to the next column of the source bitmap */
- kcounter = kdup;
- if (! (--bit)) {
- bit = 8;
- dataByte = *dataBytePointer++;
- }
- /* extract the appropriate bit from source bitmap */
- #if (BITMAP_BIT_ORDER == LSBFirst)
- bitValue = dataByte & 1;
- dataByte >>= 1;
- #else
- bitValue = dataByte & 128;
- dataByte <<= 1;
- #endif
- }
- if (bitValue)
- tmp += kcounter + kkcounter;
- kcounter = -kkcounter;
- *acc++ -= tmp;
- }
- while (--newBit);
- }
- /* Set the appropriate bits in newBitmap, based on the count of bits
- * set in the virtual bitmap which map to a single bit in the new
- * bitmap, and based on the knowing the constant number of bits in
- * the virtual bitmap which map to a bit in the new bitmap.
- */
- acc=scratch;
-
- #if (BITMAP_BIT_ORDER == LSBFirst)
- bitValue=128;
- #else
- bitValue=1;
- #endif
- newBit = newWidth;
- do {
- #if (BITMAP_BIT_ORDER == LSBFirst)
- if ((bitValue <<= 1) == 256) {
- bitValue = 0x1;
- newBitmap++;
- }
- #else
- if (! (bitValue >>= 1)) {
- bitValue = 128;
- newBitmap++;
- }
- #endif
- if (*acc++ < 0)
- *newBitmap |= bitValue;
- } while (--newBit);
- }
- }
-
- /*
- * exported interfaces
- */
-
- FontFile
- FindScaledFont(path, fontname, table)
- FontPathPtr path;
- char *fontname;
- FontTable *table;
- {
- #if (BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER)
- return NullFontFile; /* XXX we don't deal with this case yet */
- #else
- char fname[MAXFNAMELEN];
- FontFile ff;
- Scalables vals;
- register int i;
- Bool found;
- Scalables best;
- FontPtr font = NullFont;
- FontPtr scaled_font;
- double dx, dy;
- FontTable tmptab;
- DIXFontProp *tmpProps;
- int propCount;
- char canonname[1024];
- char scalename[1024];
-
- *table = scaledFonts;
- /* first see if we already have it */
- i = FindNameInFontTable(scaledFonts, fontname, &found);
- if (found) {
- ff = &scaledFonts->file.ff[scaledFonts->name.fn[i].u.index];
- if (ff->private)
- return ff;
- }
- strcpy(fname, fontname);
- /* make sure it is a valid XLFD name, and get canonical form */
- if (!ParseXLFDName(fname, &vals, '0') ||
- !vals.pixel || !vals.point || !vals.x || !vals.y || !vals.width ||
- ((vals.pixel < 0) && (vals.point < 0)))
- return NullFontFile;
- if ((vals.point > 0) && (vals.y > 0))
- {
- best.pixel = (vals.point * vals.y * 10) / 7227;
- if (vals.pixel < 0)
- vals.pixel = best.pixel;
- else if ((best.pixel < vals.pixel - 1) ||
- (best.pixel > vals.pixel + 1))
- return NullFontFile;
- }
- else if (vals.pixel > 0)
- {
- if (vals.point > 0)
- vals.y = (vals.pixel * 7227) / (vals.point * 10);
- else if (vals.y > 0)
- vals.point = (vals.pixel * 7227) / (vals.y * 10);
- }
- if (vals.x < 0)
- vals.x = vals.y;
- if (found) {
- /* get values of font to scale */
- if (!ParseXLFDName(ff->name, &best, '\0'))
- return NullFontFile;
- strcpy(canonname, scaledFonts->name.fn[i].name);
- } else {
- /* make sure the canonical form exists */
- FontPathPtr fpr;
-
- fpr = ExpandFontNamePattern((unsigned)strlen(fname), fname, 1);
- if (!fpr)
- return NullFontFile;
- if (!fpr->npaths)
- {
- FreeFontRecord(fpr);
- return NullFontFile;
- }
- strcpy(canonname, fpr->paths[0]);
- FreeFontRecord(fpr);
- ff = FindFontFile (path, canonname, 0, FALSE, &tmptab);
- if (!ff || !ff->alias)
- return NullFontFile;
- strcpy(fname, ff->name);
- /* get the wildcard form */
- if (!ParseXLFDName(fname, &best, '*'))
- return NullFontFile;
- }
- if (vals.y < 0)
- {
- if (best.y <= 0)
- return NullFontFile;
- vals.y = best.y;
- if (vals.point < 0)
- vals.point = (vals.pixel * 7227) / (vals.y * 10);
- else
- vals.pixel = (vals.point * vals.y * 10) / 7227;
- if (vals.x < 0)
- vals.x = vals.y;
- }
- if (found)
- font = FontFileLoad(ff->name, (unsigned)strlen(ff->name));
- else if (FindBestToScale(fname, &vals, &best))
- font = FontFileLoad(fname, (unsigned)strlen(fname));
- if (!font)
- return NullFontFile;
- ComputeScaleFactors(&best, &vals, &dx, &dy);
- if (vals.width < 0)
- vals.width = best.width * dx;
- /* prepare font properties for the new font */
- tmpProps = (DIXFontProp *)
- ALLOCATE_LOCAL(sizeof(DIXFontProp) *
- (sizeof(fontNamePropTable) / sizeof(fontProp) +
- sizeof(fontPropTable) / sizeof(fontProp)));
- if (!tmpProps)
- return (FontFile) NULL;
- propCount = ComputeScaledProperties(font, canonname, &vals, dx, dy,
- scalename, tmpProps);
- /* compute the scaled font */
- scaled_font = ScaleFont(font, dx, dy, tmpProps, propCount);
- DEALLOCATE_LOCAL(tmpProps);
- /* do not need the base font any more */
- if (!font->refcnt)
- FontUnload(font);
- if (!scaled_font)
- return NullFontFile;
- /* enter into the table if new */
- if (!found) {
- i = AddFileEntry(scaledFonts, fname, True);
- if (i >= 0) {
- ff = &scaledFonts->file.ff[i];
- i = AddVerifiedNameEntry(scaledFonts, scalename, i);
- }
- if (i <= 0) {
- FontUnload(scaled_font);
- return NullFontFile;
- }
- }
- ff->private = (Opaque) scaled_font;
- scaled_font->osPrivate = (pointer) ff;
- return ff;
- #endif
- }
-
- void
- FreeScaledFonts()
- {
- register FontTable table = scaledFonts;
- register int i;
- register FontPtr font;
-
- if (table) {
- for (i = 0; i < table->file.used; i++) {
- if (font = (FontPtr) table->file.ff[i].private)
- font->osPrivate = NULL;
- }
- FreeFontTable(table);
- }
- scaledFonts = MakeFontTable("", 10);
- }
-
-