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

📄 fontutil.c

📁 unix vnc 协议源码. VNC是一款远程控制工具软件.
💻 C
字号:
/* $XConsortium: fontutil.c /main/11 1996/09/12 10:08:59 kaleb $ *//* $XFree86: xc/lib/font/util/fontutil.c,v 3.1 1996/12/23 06:02:33 dawes Exp $ *//*Copyright (c) 1991  X ConsortiumPermission is hereby granted, free of charge, to any person obtaininga copy of this software and associated documentation files (the"Software"), to deal in the Software without restriction, includingwithout limitation the rights to use, copy, modify, merge, publish,distribute, sublicense, and/or sell copies of the Software, and topermit persons to whom the Software is furnished to do so, subject tothe following conditions:The above copyright notice and this permission notice shall be includedin all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESSOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OFMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OROTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OROTHER DEALINGS IN THE SOFTWARE.Except as contained in this notice, the name of the X Consortium shallnot be used in advertising or otherwise to promote the sale, use orother dealings in this Software without prior written authorizationfrom the X Consortium.*//* * Author:  Keith Packard, MIT X Consortium */#include    "fontmisc.h"#include    "fontstruct.h"#include    "FSproto.h"/* Define global here...  doesn't hurt the servers, and avoids   unresolved references in font clients.  */static int defaultGlyphCachingMode = DEFAULT_GLYPH_CACHING_MODE;int glyphCachingMode = DEFAULT_GLYPH_CACHING_MODE;voidGetGlyphs(font, count, chars, fontEncoding, glyphcount, glyphs)    FontPtr     font;    unsigned long count;    unsigned char *chars;    FontEncoding fontEncoding;    unsigned long *glyphcount;	/* RETURN */    CharInfoPtr *glyphs;	/* RETURN */{    (*font->get_glyphs) (font, count, chars, fontEncoding, glyphcount, glyphs);}#define MIN(a,b)    ((a)<(b)?(a):(b))#define MAX(a,b)    ((a)>(b)?(a):(b))voidQueryGlyphExtents(pFont, charinfo, count, info)    FontPtr     pFont;    CharInfoPtr *charinfo;    unsigned long count;    ExtentInfoRec *info;{    register unsigned long i;    xCharInfo  *pCI;    info->drawDirection = pFont->info.drawDirection;    info->fontAscent = pFont->info.fontAscent;    info->fontDescent = pFont->info.fontDescent;    if (count != 0) {	pCI = &((*charinfo)->metrics); charinfo++;	/* ignore nonexisting characters when calculating text extents */	if ( !((pCI->characterWidth == 0)	       && (pCI->rightSideBearing == 0)	       && (pCI->leftSideBearing == 0)	       && (pCI->ascent == 0)	       && (pCI->descent == 0)) ) {	    info->overallAscent = pCI->ascent;	    info->overallDescent = pCI->descent;	    info->overallLeft = pCI->leftSideBearing;	    info->overallRight = pCI->rightSideBearing;	    info->overallWidth = pCI->characterWidth;	}	if (pFont->info.constantMetrics && pFont->info.noOverlap) {	    info->overallWidth *= count;	    info->overallRight += (info->overallWidth -				   pCI->characterWidth);	} else {	    for (i = 1; i < count; i++) {		pCI = &((*charinfo)->metrics); charinfo++;		/* ignore nonexisting characters when calculating extents */		if ( !((pCI->characterWidth == 0)		       && (pCI->rightSideBearing == 0)		       && (pCI->leftSideBearing == 0)		       && (pCI->ascent == 0)		       && (pCI->descent == 0)) ) {		    info->overallAscent = MAX(					      info->overallAscent,					      pCI->ascent);		    info->overallDescent = MAX(					       info->overallDescent,					       pCI->descent);		    info->overallLeft = MIN(					    info->overallLeft,					    info->overallWidth + pCI->leftSideBearing);		    info->overallRight = MAX(					     info->overallRight,					     info->overallWidth + pCI->rightSideBearing);		    /*		     * yes, this order is correct; overallWidth IS incremented		     * last		     */		    info->overallWidth += pCI->characterWidth;		}	    }	}    } else {	info->overallAscent = 0;	info->overallDescent = 0;	info->overallWidth = 0;	info->overallLeft = 0;	info->overallRight = 0;    }}BoolQueryTextExtents(pFont, count, chars, info)    FontPtr     pFont;    unsigned long count;    unsigned char *chars;    ExtentInfoRec *info;{    xCharInfo     **charinfo;    unsigned long   n;    FontEncoding    encoding;    int             cm;    int             i;    unsigned long   t;    xCharInfo      *defaultChar = 0;    unsigned char   defc[2];    int             firstReal;    charinfo = (xCharInfo **) xalloc(count * sizeof(xCharInfo *));    if (!charinfo)	return FALSE;    encoding = TwoD16Bit;    if (pFont->info.lastRow == 0)	encoding = Linear16Bit;    (*pFont->get_metrics) (pFont, count, chars, encoding, &n, charinfo);    /* Do default character substitution as get_metrics doesn't */#define IsNonExistentChar(ci) (!(ci) || \			       (ci)->ascent == 0 && \			       (ci)->descent == 0 && \			       (ci)->leftSideBearing == 0 && \			       (ci)->rightSideBearing == 0 && \			       (ci)->characterWidth == 0)    firstReal = n;    defc[0] = pFont->info.defaultCh >> 8;    defc[1] = pFont->info.defaultCh;    (*pFont->get_metrics) (pFont, 1, defc, encoding, &t, &defaultChar);    if (IsNonExistentChar (defaultChar))	defaultChar = 0;    for (i = 0; i < n; i++)    {	if (IsNonExistentChar (charinfo[i]))	{	    if (!defaultChar)		continue;	    charinfo[i] = defaultChar;	}	if (firstReal == n)	    firstReal = i;    }    cm = pFont->info.constantMetrics;    pFont->info.constantMetrics = FALSE;    QueryGlyphExtents(pFont, charinfo + firstReal, n - firstReal, info);    pFont->info.constantMetrics = cm;    xfree(charinfo);    return TRUE;}BoolParseGlyphCachingMode(str)    char       *str;{    if (!strcmp(str, "none")) defaultGlyphCachingMode = CACHING_OFF;    else if (!strcmp(str, "all")) defaultGlyphCachingMode = CACHE_ALL_GLYPHS;    else if (!strcmp(str, "16")) defaultGlyphCachingMode = CACHE_16_BIT_GLYPHS;    else return FALSE;    return TRUE;}voidInitGlyphCaching(){    /* Set glyphCachingMode to the mode the server hopes to       support.  DDX drivers that do not support the requested level       of glyph caching can call SetGlyphCachingMode to lower the       level of support.     */    glyphCachingMode = defaultGlyphCachingMode;}/* ddxen can call SetGlyphCachingMode to inform us of what level of glyph * caching they can support. */voidSetGlyphCachingMode(newmode)    int newmode;{    if ( (glyphCachingMode > newmode) && (newmode >= 0) )	glyphCachingMode = newmode;}#define range_alloc_granularity 16#define mincharp(p) ((p)->min_char_low + ((p)->min_char_high << 8))#define maxcharp(p) ((p)->max_char_low + ((p)->max_char_high << 8))/* add_range(): Add range to a list of ranges, with coalescence */intadd_range(newrange, nranges, range, charset_subset)fsRange *newrange;int *nranges;fsRange **range;Bool charset_subset;{    int first, last, middle;    unsigned long keymin, keymax;    unsigned long ptrmin, ptrmax;    fsRange *ptr, *ptr1, *ptr2, *endptr;    /* There are two different ways to treat ranges:       1) Charset subsetting (support of the HP XLFD enhancements), in	  which a range of 0x1234,0x3456 means all numbers between	  0x1234 and 0x3456, and in which min and max might be swapped.       2) Row/column ranges, in which a range of 0x1234,0x3456 means the	  ranges 0x1234-0x1256, 0x1334-0x1356, ...  , 0x3434-0x3456.	  This is for support of glyph caching.       The choice of treatment is selected with the "charset_subset"       flag */    /* If newrange covers multiple rows; break up the rows */    if (!charset_subset && newrange->min_char_high != newrange->max_char_high)    {	int i, err;	fsRange temprange;	for (i = newrange->min_char_high;	     i <= newrange->max_char_high;	     i++)	{	    temprange.min_char_low = newrange->min_char_low;	    temprange.max_char_low = newrange->max_char_low;	    temprange.min_char_high = temprange.max_char_high = i;	    err = add_range(&temprange, nranges, range, charset_subset);	    if (err != Successful) break;	}	return err;    }    keymin = mincharp(newrange);    keymax = maxcharp(newrange);    if (charset_subset && keymin > keymax)    {	unsigned long temp = keymin;	keymin = keymax;	keymax = temp;    }    /* add_range() maintains a sorted list; this makes possible coalescence       and binary searches */    /* Binary search for a range with which the new range can merge */    first = middle = 0;    last = *nranges - 1;    while (last >= first)    {	middle = (first + last) / 2;	ptr = (*range) + middle;	ptrmin = mincharp(ptr);	ptrmax = maxcharp(ptr);	if (ptrmin > 0 && keymax < ptrmin - 1) last = middle - 1;	else if (keymin > ptrmax + 1) first = middle + 1;	else if (!charset_subset)	{	    /* We might have a range with which to merge... IF the	       result doesn't cross rows */	    if (newrange->min_char_high != ptr->min_char_high)		last = first - 1;	/* Force adding a new range */	    break;	}	else break;	/* We have at least one range with which we can merge */    }    if (last < first)    {	/* Search failed; we need to add a new range to the list. */	/* Grow the list if necessary */	if (*nranges == 0 || *range == (fsRange *)0)	{	    *range = (fsRange *)xalloc(range_alloc_granularity *				       SIZEOF(fsRange));	    *nranges = 0;	}	else if (!(*nranges % range_alloc_granularity))	{	    *range = (fsRange *)xrealloc((char *)*range,					  (*nranges + range_alloc_granularity) *					  SIZEOF(fsRange));	}	/* If alloc failed, just return a null list */	if (*range == (fsRange *)0)	{	    *nranges = 0;	    return AllocError;	}	/* Should new entry go *at* or *after* ptr? */	ptr = (*range) + middle;	if (middle < *nranges && keymin > ptrmin) ptr++;	/* after */	/* Open up a space for our new range */	memmove((char *)(ptr + 1),		(char *)ptr,		(char *)(*range + *nranges) - (char *)ptr);	/* Insert the new range */	ptr->min_char_low = keymin & 0xff;	ptr->min_char_high = keymin >> 8;	ptr->max_char_low = keymax & 0xff;	ptr->max_char_high = keymax >> 8;	/* Update range count */	(*nranges)++;	/* Done */	return Successful;    }    /* Join our new range to that pointed to by "ptr" */    if (keymin < ptrmin)    {	ptr->min_char_low = keymin & 0xff;	ptr->min_char_high = keymin >> 8;    }    if (keymax > ptrmax)    {	ptr->max_char_low = keymax & 0xff;	ptr->max_char_high = keymax >> 8;    }    ptrmin = mincharp(ptr);    ptrmax = maxcharp(ptr);    endptr = *range + *nranges;    for (ptr1 = ptr; ptr1 >= *range; ptr1--)    {	if (ptrmin <= maxcharp(ptr1) + 1)	{	    if (!charset_subset && ptr->min_char_high != ptr1->min_char_high)		break;	    if (ptrmin >= mincharp(ptr1))		ptrmin = mincharp(ptr1);	}	else break;    }    for (ptr2 = ptr; ptr2 < endptr; ptr2++)    {	if (ptr2->min_char_low == 0 &&	    ptr2->min_char_high == 0 ||	    ptrmax >= mincharp(ptr2) - 1)	{	    if (!charset_subset && ptr->min_char_high != ptr2->min_char_high)		break;	    if (ptrmax <= maxcharp(ptr2))		ptrmax = maxcharp(ptr2);	}	else break;    }    /* We need to coalesce ranges between ptr1 and ptr2 exclusive */    ptr1++;    ptr2--;    if (ptr1 != ptr2)    {	memmove(ptr1, ptr2, (char *)endptr - (char *)ptr2);	*nranges -= (ptr2 - ptr1);    }    /* Write the new range into the range list */    ptr1->min_char_low = ptrmin & 0xff;    ptr1->min_char_high = ptrmin >> 8;    ptr1->max_char_low = ptrmax & 0xff;    ptr1->max_char_high = ptrmax >> 8;    return Successful;}

⌨️ 快捷键说明

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