⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitscale.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 = (CharInfoPtr) xalloc(nchars * sizeof(CharInfoRec));    if (!bitmapFont->metrics)	goto bail;    bitmapFont->encoding = (CharInfoPtr *) xalloc(nchars * sizeof(CharInfoPtr));    if (!bitmapFont->encoding)	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. */    inkindex1 = 0;    pci = bitmapFont->metrics;    for (i = 0; i < nchars; i++)    {	if (opci = obitmapFont->encoding[inkindex2 = 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)		{		    bitmapFont->encoding[i] = 0;		    continue;		}	    }	    if (opci->metrics.leftSideBearing == 0 &&		opci->metrics.rightSideBearing == 0 &&		opci->metrics.ascent == 0 &&		opci->metrics.descent == 0 &&		opci->metrics.characterWidth == 0)	    {		bitmapFont->encoding[i] = 0;		continue;	    }	    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++;	}	else	    bitmapFont->encoding[i] = 0;    }    /*     * 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++)    {	CharInfoRec temppci;	if ((pci = bitmapFont->encoding[i]) &&	    (opci = obitmapFont->encoding[OLDINDEX(i)]))	{	    pci = bitmapFont->encoding[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 = bitmapFont->encoding[r * cols + c];	}    }    *newWidthMult = xmult;    *newHeightMult = ymult;    return pf;bail:    if (pf)	xfree(pf);    if (bitmapFont) {	xfree(bitmapFont->metrics);	xfree(bitmapFont->ink_metrics);	xfree(bitmapFont->bitmaps);	xfree(bitmapFont->encoding);    }    return NULL;}static intlcm(a, b)			/* least common multiple */    int         a,                b;{    register int m;    register int larger,                smaller;    if (a > b) {	m = larger = a;	smaller = b;    } else {	m = larger = b;	smaller = a;    }    while (m % smaller)	m += larger;    return m;}static voidScaleBitmap(pFont, opci, pci, inv_xform, widthMult, heightMult)    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, *thisrow, *nextrow, pixmult;    int		box_x, box_y;    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 =		(unsigned char *)xalloc((width + 1) * (height + 1));	    if (char_grayscale)	    {		diffusion_workspace =		    (INT32 *)xalloc((newWidth + 2) * 2 * sizeof(int));		if (!diffusion_workspace)		{		    xfree(char_grayscale);		    char_grayscale = (unsigned char *)0;		}		/* Initialize our error diffusion workspace for later use */		bzero((char *)diffusion_workspace + sizeof(INT32),		      (newWidth + 3) * sizeof(int));		thisrow = diffusion_workspace + 1;		nextrow = diffusion_workspace + newWidth + 3;	    }	}    }    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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -