Пример #1
0
int
__glXDisp_UseXFont(__GLXclientState * cl, GLbyte * pc)
{
    ClientPtr client = cl->client;
    xGLXUseXFontReq *req;
    FontPtr pFont;
    GLuint currentListIndex;
    __GLXcontext *cx;
    int error;

    REQUEST_SIZE_MATCH(xGLXUseXFontReq);

    req = (xGLXUseXFontReq *) pc;
    cx = __glXForceCurrent(cl, req->contextTag, &error);
    if (!cx) {
        return error;
    }

    CALL_GetIntegerv(GET_DISPATCH(),
                     (GL_LIST_INDEX, (GLint *) &currentListIndex));
    if (currentListIndex != 0) {
        /*
         ** A display list is currently being made.  It is an error
         ** to try to make a font during another lists construction.
         */
        client->errorValue = cx->id;
        return __glXError(GLXBadContextState);
    }

    /*
     ** Font can actually be either the ID of a font or the ID of a GC
     ** containing a font.
     */

    error = dixLookupFontable(&pFont, req->font, client, DixReadAccess);
    if (error != Success)
        return error;

    return MakeBitmapsFromFont(pFont, req->first, req->count, req->listBase);
}
Пример #2
0
static int
ProcXF86BigfontQueryFont(
    ClientPtr client)
{
    FontPtr pFont;
    REQUEST(xXF86BigfontQueryFontReq);
    CARD32 stuff_flags;
    xCharInfo* pmax;
    xCharInfo* pmin;
    int nCharInfos;
    int shmid;
#ifdef HAS_SHM
    ShmDescPtr pDesc = NULL;
#else
#define pDesc 0
#endif
    xCharInfo* pCI;
    CARD16* pIndex2UniqIndex;
    CARD16* pUniqIndex2Index;
    CARD32 nUniqCharInfos;

#if 0
    REQUEST_SIZE_MATCH(xXF86BigfontQueryFontReq);
#else
    switch (client->req_len) {
	case 2: /* client with version 1.0 libX11 */
	    stuff_flags = (LocalClient(client) && !client->swapped ? XF86Bigfont_FLAGS_Shm : 0);
	    break;
	case 3: /* client with version 1.1 libX11 */
	    stuff_flags = stuff->flags;
	    break;
	default:
	    return BadLength;
    }
#endif
    if (dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess) != Success)
	return BadFont;    /* procotol spec says only error is BadFont */

    pmax = FONTINKMAX(pFont);
    pmin = FONTINKMIN(pFont);
    nCharInfos =
       (pmax->rightSideBearing == pmin->rightSideBearing
        && pmax->leftSideBearing == pmin->leftSideBearing
        && pmax->descent == pmin->descent
        && pmax->ascent == pmin->ascent
        && pmax->characterWidth == pmin->characterWidth)
       ? 0 : N2dChars(pFont);
    shmid = -1;
    pCI = NULL;
    pIndex2UniqIndex = NULL;
    pUniqIndex2Index = NULL;
    nUniqCharInfos = 0;

    if (nCharInfos > 0) {
#ifdef HAS_SHM
	if (!badSysCall)
	    pDesc = (ShmDescPtr) FontGetPrivate(pFont, FontShmdescIndex);
	if (pDesc) {
	    pCI = (xCharInfo *) pDesc->attach_addr;
	    if (stuff_flags & XF86Bigfont_FLAGS_Shm)
		shmid = pDesc->shmid;
	} else {
	    if (stuff_flags & XF86Bigfont_FLAGS_Shm && !badSysCall)
		pDesc = shmalloc(nCharInfos * sizeof(xCharInfo)
				 + sizeof(CARD32));
	    if (pDesc) {
		pCI = (xCharInfo *) pDesc->attach_addr;
		shmid = pDesc->shmid;
	    } else {
#endif
		pCI = malloc(nCharInfos * sizeof(xCharInfo));
		if (!pCI)
		    return BadAlloc;
#ifdef HAS_SHM
	    }
#endif
	    /* Fill nCharInfos starting at pCI. */
	    {
		xCharInfo* prCI = pCI;
		int ninfos = 0;
		int ncols = pFont->info.lastCol - pFont->info.firstCol + 1;
		int row;
		for (row = pFont->info.firstRow;
		     row <= pFont->info.lastRow && ninfos < nCharInfos;
		     row++) {
		    unsigned char chars[512];
		    xCharInfo* tmpCharInfos[256];
		    unsigned long count;
		    int col;
		    unsigned long i;
		    i = 0;
		    for (col = pFont->info.firstCol;
			 col <= pFont->info.lastCol;
			 col++) {
			chars[i++] = row;
			chars[i++] = col;
		    }
		    (*pFont->get_metrics) (pFont, ncols, chars, TwoD16Bit,
					   &count, tmpCharInfos);
		    for (i = 0; i < count && ninfos < nCharInfos; i++) {
			*prCI++ = *tmpCharInfos[i];
			ninfos++;
		    }
		}
	    }
#ifdef HAS_SHM
	    if (pDesc && !badSysCall) {
		*(CARD32 *)(pCI + nCharInfos) = signature;
		if (!FontSetPrivate(pFont, FontShmdescIndex, pDesc)) {
		    shmdealloc(pDesc);
		    return BadAlloc;
		}
	    }
	}
#endif
	if (shmid == -1) {
	    /* Cannot use shared memory, so remove-duplicates the xCharInfos
	       using a temporary hash table. */
	    /* Note that CARD16 is suitable as index type, because
	       nCharInfos <= 0x10000. */
	    CARD32 hashModulus;
	    CARD16* pHash2UniqIndex;
	    CARD16* pUniqIndex2NextUniqIndex;
	    CARD32 NextIndex;
	    CARD32 NextUniqIndex;
	    CARD16* tmp;
	    CARD32 i, j;

	    hashModulus = 67;
	    if (hashModulus > nCharInfos+1)
		hashModulus = nCharInfos+1;

	    tmp = malloc((4*nCharInfos+1) * sizeof(CARD16));
	    if (!tmp) {
		if (!pDesc) free(pCI);
		return BadAlloc;
	    }
	    pIndex2UniqIndex = tmp;
		/* nCharInfos elements */
	    pUniqIndex2Index = tmp + nCharInfos;
		/* max. nCharInfos elements */
	    pUniqIndex2NextUniqIndex = tmp + 2*nCharInfos;
		/* max. nCharInfos elements */
	    pHash2UniqIndex = tmp + 3*nCharInfos;
		/* hashModulus (<= nCharInfos+1) elements */

	    /* Note that we can use 0xffff as end-of-list indicator, because
	       even if nCharInfos = 0x10000, 0xffff can not occur as valid
	       entry before the last element has been inserted. And once the
	       last element has been inserted, we don't need the hash table
	       any more. */
	    for (j = 0; j < hashModulus; j++)
		pHash2UniqIndex[j] = (CARD16)(-1);

	    NextUniqIndex = 0;
	    for (NextIndex = 0; NextIndex < nCharInfos; NextIndex++) {
		xCharInfo* p = &pCI[NextIndex];
		CARD32 hashCode = hashCI(p) % hashModulus;
		for (i = pHash2UniqIndex[hashCode];
		     i != (CARD16)(-1);
		     i = pUniqIndex2NextUniqIndex[i]) {
		    j = pUniqIndex2Index[i];
		    if (pCI[j].leftSideBearing == p->leftSideBearing
			&& pCI[j].rightSideBearing == p->rightSideBearing
			&& pCI[j].characterWidth == p->characterWidth
			&& pCI[j].ascent == p->ascent
			&& pCI[j].descent == p->descent
			&& pCI[j].attributes == p->attributes)
			break;
		}
		if (i != (CARD16)(-1)) {
		    /* Found *p at Index j, UniqIndex i */
		    pIndex2UniqIndex[NextIndex] = i;
		} else {
		    /* Allocate a new entry in the Uniq table */
		    if (hashModulus <= 2*NextUniqIndex
			&& hashModulus < nCharInfos+1) {
			/* Time to increate hash table size */
			hashModulus = 2*hashModulus+1;
			if (hashModulus > nCharInfos+1)
			    hashModulus = nCharInfos+1;
			for (j = 0; j < hashModulus; j++)
			    pHash2UniqIndex[j] = (CARD16)(-1);
			for (i = 0; i < NextUniqIndex; i++)
			    pUniqIndex2NextUniqIndex[i] = (CARD16)(-1);
			for (i = 0; i < NextUniqIndex; i++) {
			    j = pUniqIndex2Index[i];
			    p = &pCI[j];
			    hashCode = hashCI(p) % hashModulus;
			    pUniqIndex2NextUniqIndex[i] = pHash2UniqIndex[hashCode];
			    pHash2UniqIndex[hashCode] = i;
			}
			p = &pCI[NextIndex];
			hashCode = hashCI(p) % hashModulus;
		    }
		    i = NextUniqIndex++;
		    pUniqIndex2NextUniqIndex[i] = pHash2UniqIndex[hashCode];
		    pHash2UniqIndex[hashCode] = i;
		    pUniqIndex2Index[i] = NextIndex;
		    pIndex2UniqIndex[NextIndex] = i;
		}
	    }
	    nUniqCharInfos = NextUniqIndex;
	    /* fprintf(stderr, "font metrics: nCharInfos = %d, nUniqCharInfos = %d, hashModulus = %d\n", nCharInfos, nUniqCharInfos, hashModulus); */
	}
    }

    {
	int nfontprops = pFont->info.nprops;
	int rlength =
	   sizeof(xXF86BigfontQueryFontReply)
	   + nfontprops * sizeof(xFontProp)
	   + (nCharInfos > 0 && shmid == -1
	      ? nUniqCharInfos * sizeof(xCharInfo)
	        + (nCharInfos+1)/2 * 2 * sizeof(CARD16)
	      : 0);
	xXF86BigfontQueryFontReply* reply = malloc(rlength);
	char* p;
	if (!reply) {
	    if (nCharInfos > 0) {
		if (shmid == -1) free(pIndex2UniqIndex);
		if (!pDesc) free(pCI);
	    }
	    return BadAlloc;
	}
	reply->type = X_Reply;
	reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
	reply->sequenceNumber = client->sequence;
	reply->minBounds = pFont->info.ink_minbounds;
	reply->maxBounds = pFont->info.ink_maxbounds;
	reply->minCharOrByte2 = pFont->info.firstCol;
	reply->maxCharOrByte2 = pFont->info.lastCol;
	reply->defaultChar = pFont->info.defaultCh;
	reply->nFontProps = pFont->info.nprops;
	reply->drawDirection = pFont->info.drawDirection;
	reply->minByte1 = pFont->info.firstRow;
	reply->maxByte1 = pFont->info.lastRow;
	reply->allCharsExist = pFont->info.allExist;
	reply->fontAscent = pFont->info.fontAscent;
	reply->fontDescent = pFont->info.fontDescent;
	reply->nCharInfos = nCharInfos;
        reply->nUniqCharInfos = nUniqCharInfos;
	reply->shmid = shmid;
	reply->shmsegoffset = 0;
	if (client->swapped) {
	    char tmp;
	    swaps(&reply->sequenceNumber, tmp);
	    swapl(&reply->length, tmp);
	    swapCharInfo(&reply->minBounds);
	    swapCharInfo(&reply->maxBounds);
	    swaps(&reply->minCharOrByte2, tmp);
	    swaps(&reply->maxCharOrByte2, tmp);
	    swaps(&reply->defaultChar, tmp);
	    swaps(&reply->nFontProps, tmp);
	    swaps(&reply->fontAscent, tmp);
	    swaps(&reply->fontDescent, tmp);
	    swapl(&reply->nCharInfos, tmp);
	    swapl(&reply->nUniqCharInfos, tmp);
	    swapl(&reply->shmid, tmp);
	    swapl(&reply->shmsegoffset, tmp);
	}
	p = (char*) &reply[1];
	{
	    FontPropPtr pFP;
	    xFontProp* prFP;
	    int i;
	    for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) p;
		 i < nfontprops;
		 i++, pFP++, prFP++) {
		prFP->name = pFP->name;
		prFP->value = pFP->value;
		if (client->swapped) {
		    char tmp;
		    swapl(&prFP->name, tmp);
		    swapl(&prFP->value, tmp);
		}
	    }
	    p = (char*) prFP;
	}
	if (nCharInfos > 0 && shmid == -1) {
	    xCharInfo* pci;
	    CARD16* ps;
	    int i, j;
	    pci = (xCharInfo*) p;
	    for (i = 0; i < nUniqCharInfos; i++, pci++) {
		*pci = pCI[pUniqIndex2Index[i]];
		if (client->swapped)
		    swapCharInfo(pci);
	    }
	    ps = (CARD16*) pci;
	    for (j = 0; j < nCharInfos; j++, ps++) {
		*ps = pIndex2UniqIndex[j];
		if (client->swapped) {
		    char tmp;
		    swaps(ps, tmp);
		}
	    }
	}
	WriteToClient(client, rlength, (char *)reply);
	free(reply);
	if (nCharInfos > 0) {
	    if (shmid == -1) free(pIndex2UniqIndex);
	    if (!pDesc) free(pCI);
	}
	return Success;
    }
}