Merge branch 'glyph-pixmaps'

Conflicts:

	configure.ac
	exa/exa_render.c
This commit is contained in:
Eric Anholt 2007-10-02 12:14:04 -07:00
commit 439edc768e
7 changed files with 231 additions and 210 deletions

View File

@ -631,7 +631,7 @@ else
fi fi
REQUIRED_MODULES="[randrproto >= 1.2] $RENDERPROTO [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto [xproto >= 7.0.9] xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]" REQUIRED_MODULES="[randrproto >= 1.2] $RENDERPROTO [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto [xproto >= 7.0.9] xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]"
REQUIRED_LIBS="xfont xau fontenc [pixman-1 >= 0.9.5]" REQUIRED_LIBS="xfont xau fontenc [pixman-1 >= 0.9.5] openssl"
dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config

View File

@ -53,6 +53,7 @@
#include "fboverlay.h" #include "fboverlay.h"
#ifdef RENDER #ifdef RENDER
#include "fbpict.h" #include "fbpict.h"
#include "glyphstr.h"
#endif #endif
#include "damage.h" #include "damage.h"

View File

@ -1081,7 +1081,6 @@ exaGlyphs (CARD8 op,
GlyphPtr *glyphs) GlyphPtr *glyphs)
{ {
ExaScreenPriv (pDst->pDrawable->pScreen); ExaScreenPriv (pDst->pDrawable->pScreen);
PixmapPtr pPixmap = NULL;
PicturePtr pPicture; PicturePtr pPicture;
PixmapPtr pMaskPixmap = NULL; PixmapPtr pMaskPixmap = NULL;
PicturePtr pMask; PicturePtr pMask;
@ -1171,8 +1170,6 @@ exaGlyphs (CARD8 op,
{ {
GCPtr pGC = NULL; GCPtr pGC = NULL;
int maxwidth = 0, maxheight = 0, i; int maxwidth = 0, maxheight = 0, i;
ExaMigrationRec pixmaps[1];
PixmapPtr pScratchPixmap = NULL;
x += list->xOff; x += list->xOff;
y += list->yOff; y += list->yOff;
@ -1196,38 +1193,9 @@ exaGlyphs (CARD8 op,
continue; continue;
} }
/* Create the (real) temporary pixmap to store the current glyph in */
pPixmap = (*pScreen->CreatePixmap) (pScreen, maxwidth, maxheight,
list->format->depth);
if (!pPixmap)
return;
/* Create a temporary picture to wrap the temporary pixmap, so it can be
* used as a source for Composite.
*/
component_alpha = NeedsComponent(list->format->format);
pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
CPComponentAlpha, &component_alpha,
serverClient, &error);
if (!pPicture) {
(*pScreen->DestroyPixmap) (pPixmap);
return;
}
ValidatePicture(pPicture);
/* Give the temporary pixmap an initial kick towards the screen, so
* it'll stick there.
*/
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pPixmap;
pixmaps[0].pReg = NULL;
exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL);
while (n--) while (n--)
{ {
GlyphPtr glyph = *glyphs++; GlyphPtr glyph = *glyphs++;
pointer glyphdata = (pointer) (glyph + 1);
DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable; DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable;
x1 = x - glyph->info.x; x1 = x - glyph->info.x;
@ -1237,69 +1205,9 @@ exaGlyphs (CARD8 op,
(x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0) (x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0)
goto nextglyph; goto nextglyph;
(*pScreen->ModifyPixmapHeader) (pScratchPixmap, /* The glyph already has a Picture ready for us to use. */
glyph->info.width, pPicture = GlyphPicture (glyph)[pScreen->myNum];
glyph->info.height, ValidatePicture(pPicture);
0, 0, -1, glyphdata);
/* Copy the glyph data into the proper pixmap instead of a fake.
* First we try to use UploadToScreen, if we can, then we fall back
* to a plain exaCopyArea in case of failure.
*/
if (pExaScr->info->UploadToScreen &&
exaPixmapIsOffscreen(pPixmap) &&
(*pExaScr->info->UploadToScreen) (pPixmap, 0, 0,
glyph->info.width,
glyph->info.height,
glyphdata,
PixmapBytePad(glyph->info.width,
list->format->depth)))
{
exaMarkSync (pScreen);
} else {
/* Set up the scratch pixmap/GC for doing a CopyArea. */
if (pScratchPixmap == NULL) {
/* Get a scratch pixmap to wrap the original glyph data */
pScratchPixmap = GetScratchPixmapHeader (pScreen,
glyph->info.width,
glyph->info.height,
list->format->depth,
list->format->depth,
-1, glyphdata);
if (!pScratchPixmap) {
FreePicture(pPicture, 0);
(*pScreen->DestroyPixmap) (pPixmap);
return;
}
/* Get a scratch GC with which to copy the glyph data from
* scratch to temporary
*/
pGC = GetScratchGC (list->format->depth, pScreen);
ValidateGC (&pPixmap->drawable, pGC);
} else {
(*pScreen->ModifyPixmapHeader) (pScratchPixmap,
glyph->info.width,
glyph->info.height,
0, 0, -1, glyphdata);
pScratchPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
}
#ifdef MITSHM
if (pExaScr->info->PrepareComposite)
exaShmPutImage(&pPixmap->drawable, pGC,
pPixmap->drawable.depth, ZPixmap,
glyph->info.width, glyph->info.height, 0, 0,
glyph->info.width, glyph->info.height, 0, 0,
glyphdata);
else
#endif
exaCopyArea (&pScratchPixmap->drawable, &pPixmap->drawable, pGC,
0, 0, glyph->info.width, glyph->info.height, 0, 0);
}
exaPixmapDirty (pPixmap, 0, 0,
glyph->info.width, glyph->info.height);
if (maskFormat) if (maskFormat)
{ {
@ -1315,6 +1223,7 @@ exaGlyphs (CARD8 op,
0, 0, x1, y1, glyph->info.width, 0, 0, x1, y1, glyph->info.width,
glyph->info.height); glyph->info.height);
} }
nextglyph: nextglyph:
x += glyph->info.xOff; x += glyph->info.xOff;
y += glyph->info.yOff; y += glyph->info.yOff;
@ -1322,10 +1231,6 @@ nextglyph:
list++; list++;
if (pGC != NULL) if (pGC != NULL)
FreeScratchGC (pGC); FreeScratchGC (pGC);
FreePicture ((pointer) pPicture, 0);
(*pScreen->DestroyPixmap) (pPixmap);
if (pScratchPixmap != NULL)
FreeScratchPixmapHeader (pScratchPixmap);
} }
if (maskFormat) if (maskFormat)
{ {

View File

@ -26,6 +26,8 @@
#include <dix-config.h> #include <dix-config.h>
#endif #endif
#include <openssl/sha.h>
#include "misc.h" #include "misc.h"
#include "scrnintstr.h" #include "scrnintstr.h"
#include "os.h" #include "os.h"
@ -412,7 +414,10 @@ _GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr)
} }
GlyphRefPtr GlyphRefPtr
FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) FindGlyphRef (GlyphHashPtr hash,
CARD32 signature,
Bool match,
unsigned char sha1[20])
{ {
CARD32 elt, step, s; CARD32 elt, step, s;
GlyphPtr glyph; GlyphPtr glyph;
@ -443,7 +448,7 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
} }
else if (s == signature && else if (s == signature &&
(!match || (!match ||
memcmp (&compare->info, &glyph->info, compare->size) == 0)) memcmp (glyph->sha1, sha1, 20) == 0))
{ {
break; break;
} }
@ -460,17 +465,47 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
return gr; return gr;
} }
CARD32 int
HashGlyph (GlyphPtr glyph) HashGlyph (xGlyphInfo *gi,
CARD8 *bits,
unsigned long size,
unsigned char sha1[20])
{ {
CARD32 *bits = (CARD32 *) &(glyph->info); SHA_CTX ctx;
CARD32 hash; int success;
int n = glyph->size / sizeof (CARD32);
hash = 0; success = SHA1_Init (&ctx);
while (n--) if (! success)
hash ^= *bits++; return BadAlloc;
return hash;
success = SHA1_Update (&ctx, gi, sizeof (xGlyphInfo));
if (! success)
return BadAlloc;
success = SHA1_Update (&ctx, bits, size);
if (! success)
return BadAlloc;
success = SHA1_Final (sha1, &ctx);
if (! success)
return BadAlloc;
return Success;
}
GlyphPtr
FindGlyphByHash (unsigned char sha1[20], int format)
{
GlyphRefPtr gr;
CARD32 signature = *(CARD32 *) sha1;
gr = FindGlyphRef (&globalGlyphs[format],
signature, TRUE, sha1);
if (gr->glyph && gr->glyph != DeletedGlyph)
return gr->glyph;
else
return NULL;
} }
#ifdef CHECK_DUPLICATES #ifdef CHECK_DUPLICATES
@ -511,6 +546,7 @@ FreeGlyph (GlyphPtr glyph, int format)
GlyphRefPtr gr; GlyphRefPtr gr;
int i; int i;
int first; int first;
CARD32 signature;
first = -1; first = -1;
for (i = 0; i < globalGlyphs[format].hashSet->size; i++) for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
@ -521,8 +557,9 @@ FreeGlyph (GlyphPtr glyph, int format)
first = i; first = i;
} }
gr = FindGlyphRef (&globalGlyphs[format], signature = *(CARD32 *) glyph->sha1;
HashGlyph (glyph), TRUE, glyph); gr = FindGlyphRef (&globalGlyphs[format], signature,
TRUE, glyph->sha1);
if (gr - globalGlyphs[format].table != first) if (gr - globalGlyphs[format].table != first)
DuplicateRef (glyph, "Found wrong one"); DuplicateRef (glyph, "Found wrong one");
if (gr->glyph && gr->glyph != DeletedGlyph) if (gr->glyph && gr->glyph != DeletedGlyph)
@ -534,9 +571,13 @@ FreeGlyph (GlyphPtr glyph, int format)
for (i = 0; i < screenInfo.numScreens; i++) for (i = 0; i < screenInfo.numScreens; i++)
{ {
ps = GetPictureScreenIfSet (screenInfo.screens[i]); ScreenPtr pScreen = screenInfo.screens[i];
FreePicture ((pointer) GlyphPicture (glyph)[i], 0);
ps = GetPictureScreenIfSet (pScreen);
if (ps) if (ps)
(*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); (*ps->UnrealizeGlyph) (pScreen, glyph);
} }
if (glyph->devPrivates) if (glyph->devPrivates)
@ -549,13 +590,14 @@ void
AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
{ {
GlyphRefPtr gr; GlyphRefPtr gr;
CARD32 hash; CARD32 signature;
CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global"); CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
/* Locate existing matching glyph */ /* Locate existing matching glyph */
hash = HashGlyph (glyph); signature = *(CARD32 *) glyph->sha1;
gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph); gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], signature,
if (gr->glyph && gr->glyph != DeletedGlyph) TRUE, glyph->sha1);
if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph)
{ {
PictureScreenPtr ps; PictureScreenPtr ps;
int i; int i;
@ -571,10 +613,10 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
xfree (glyph); xfree (glyph);
glyph = gr->glyph; glyph = gr->glyph;
} }
else else if (gr->glyph != glyph)
{ {
gr->glyph = glyph; gr->glyph = glyph;
gr->signature = hash; gr->signature = signature;
globalGlyphs[glyphSet->fdepth].tableEntries++; globalGlyphs[glyphSet->fdepth].tableEntries++;
} }
@ -627,7 +669,7 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
GlyphPtr glyph; GlyphPtr glyph;
int i; int i;
size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]); size = screenInfo.numScreens * sizeof (PicturePtr);
glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec)); glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
if (!glyph) if (!glyph)
return 0; return 0;
@ -648,26 +690,28 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
for (i = 0; i < screenInfo.numScreens; i++) for (i = 0; i < screenInfo.numScreens; i++)
{ {
ps = GetPictureScreenIfSet (screenInfo.screens[i]); ps = GetPictureScreenIfSet (screenInfo.screens[i]);
if (ps) if (ps)
{ {
if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph)) if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph))
{ goto bail;
while (i--)
{
ps = GetPictureScreenIfSet (screenInfo.screens[i]);
if (ps)
(*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph);
}
if (glyph->devPrivates)
xfree (glyph->devPrivates);
xfree (glyph);
return 0;
}
} }
} }
return glyph; return glyph;
bail:
while (i--)
{
ps = GetPictureScreenIfSet (screenInfo.screens[i]);
if (ps)
(*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph);
}
if (glyph->devPrivates)
xfree (glyph->devPrivates);
xfree (glyph);
return 0;
} }
Bool Bool
@ -711,7 +755,7 @@ ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
if (glyph && glyph != DeletedGlyph) if (glyph && glyph != DeletedGlyph)
{ {
s = hash->table[i].signature; s = hash->table[i].signature;
gr = FindGlyphRef (&newHash, s, global, glyph); gr = FindGlyphRef (&newHash, s, global, glyph->sha1);
gr->signature = s; gr->signature = s;
gr->glyph = glyph; gr->glyph = glyph;
++newHash.tableEntries; ++newHash.tableEntries;

View File

@ -39,13 +39,16 @@
#define GlyphFormatNum 5 #define GlyphFormatNum 5
typedef struct _Glyph { typedef struct _Glyph {
CARD32 refcnt; CARD32 refcnt;
DevUnion *devPrivates; DevUnion *devPrivates;
CARD32 size; /* info + bitmap */ unsigned char sha1[20];
xGlyphInfo info; CARD32 size; /* info + bitmap */
/* bits follow */ xGlyphInfo info;
/* per-screen pixmaps follow */
} GlyphRec, *GlyphPtr; } GlyphRec, *GlyphPtr;
#define GlyphPicture(glyph) ((PicturePtr *) ((glyph) + 1))
typedef struct _GlyphRef { typedef struct _GlyphRef {
CARD32 signature; CARD32 signature;
GlyphPtr glyph; GlyphPtr glyph;
@ -127,10 +130,19 @@ GlyphHashSetPtr
FindGlyphHashSet (CARD32 filled); FindGlyphHashSet (CARD32 filled);
GlyphRefPtr GlyphRefPtr
FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare); FindGlyphRef (GlyphHashPtr hash,
CARD32 signature,
Bool match,
unsigned char sha1[20]);
CARD32 GlyphPtr
HashGlyph (GlyphPtr glyph); FindGlyphByHash (unsigned char sha1[20], int format);
int
HashGlyph (xGlyphInfo *gi,
CARD8 *bits,
unsigned long size,
unsigned char sha1[20]);
void void
FreeGlyph (GlyphPtr glyph, int format); FreeGlyph (GlyphPtr glyph, int format);

View File

@ -112,7 +112,7 @@ miGlyphs (CARD8 op,
GlyphListPtr list, GlyphListPtr list,
GlyphPtr *glyphs) GlyphPtr *glyphs)
{ {
PixmapPtr pPixmap = 0; PixmapPtr pPixmap;
PicturePtr pPicture; PicturePtr pPicture;
PixmapPtr pMaskPixmap = 0; PixmapPtr pMaskPixmap = 0;
PicturePtr pMask; PicturePtr pMask;
@ -166,7 +166,6 @@ miGlyphs (CARD8 op,
x = 0; x = 0;
y = 0; y = 0;
} }
pPicture = 0;
while (nlist--) while (nlist--)
{ {
x += list->xOff; x += list->xOff;
@ -175,28 +174,8 @@ miGlyphs (CARD8 op,
while (n--) while (n--)
{ {
glyph = *glyphs++; glyph = *glyphs++;
if (!pPicture) pPicture = GlyphPicture (glyph)[pScreen->myNum];
{
pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height,
list->format->depth,
list->format->depth,
0, (pointer) (glyph + 1));
if (!pPixmap)
return;
component_alpha = NeedsComponent(list->format->format);
pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
CPComponentAlpha, &component_alpha,
serverClient, &error);
if (!pPicture)
{
FreeScratchPixmapHeader (pPixmap);
return;
}
}
(*pScreen->ModifyPixmapHeader) (pPixmap,
glyph->info.width, glyph->info.height,
0, 0, -1, (pointer) (glyph + 1));
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
if (maskFormat) if (maskFormat)
{ {
CompositePicture (PictOpAdd, CompositePicture (PictOpAdd,
@ -224,17 +203,11 @@ miGlyphs (CARD8 op,
glyph->info.width, glyph->info.width,
glyph->info.height); glyph->info.height);
} }
x += glyph->info.xOff; x += glyph->info.xOff;
y += glyph->info.yOff; y += glyph->info.yOff;
} }
list++; list++;
if (pPicture)
{
FreeScratchPixmapHeader (pPixmap);
FreePicture ((pointer) pPicture, 0);
pPicture = 0;
pPixmap = 0;
}
} }
if (maskFormat) if (maskFormat)
{ {

View File

@ -1080,24 +1080,31 @@ ProcRenderFreeGlyphSet (ClientPtr client)
} }
typedef struct _GlyphNew { typedef struct _GlyphNew {
Glyph id; Glyph id;
GlyphPtr glyph; GlyphPtr glyph;
Bool found;
unsigned char sha1[20];
} GlyphNewRec, *GlyphNewPtr; } GlyphNewRec, *GlyphNewPtr;
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
static int static int
ProcRenderAddGlyphs (ClientPtr client) ProcRenderAddGlyphs (ClientPtr client)
{ {
GlyphSetPtr glyphSet; GlyphSetPtr glyphSet;
REQUEST(xRenderAddGlyphsReq); REQUEST(xRenderAddGlyphsReq);
GlyphNewRec glyphsLocal[NLOCALGLYPH]; GlyphNewRec glyphsLocal[NLOCALGLYPH];
GlyphNewPtr glyphsBase, glyphs; GlyphNewPtr glyphsBase, glyphs, glyph_new;
GlyphPtr glyph;
int remain, nglyphs; int remain, nglyphs;
CARD32 *gids; CARD32 *gids;
xGlyphInfo *gi; xGlyphInfo *gi;
CARD8 *bits; CARD8 *bits;
int size; int size;
int err = BadAlloc; int err = BadAlloc;
int i, screen;
PicturePtr pSrc = NULL, pDst = NULL;
PixmapPtr pSrcPix = NULL, pDstPix = NULL;
CARD32 component_alpha;
REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client, glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
@ -1114,11 +1121,15 @@ ProcRenderAddGlyphs (ClientPtr client)
if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec)) if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
return BadAlloc; return BadAlloc;
if (nglyphs <= NLOCALGLYPH) component_alpha = NeedsComponent (glyphSet->format->format);
if (nglyphs <= NLOCALGLYPH) {
memset (glyphsLocal, 0, sizeof (glyphsLocal));
glyphsBase = glyphsLocal; glyphsBase = glyphsLocal;
}
else else
{ {
glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec)); glyphsBase = (GlyphNewPtr) Xcalloc (nglyphs * sizeof (GlyphNewRec));
if (!glyphsBase) if (!glyphsBase)
return BadAlloc; return BadAlloc;
} }
@ -1131,58 +1142,133 @@ ProcRenderAddGlyphs (ClientPtr client)
gi = (xGlyphInfo *) (gids + nglyphs); gi = (xGlyphInfo *) (gids + nglyphs);
bits = (CARD8 *) (gi + nglyphs); bits = (CARD8 *) (gi + nglyphs);
remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs; remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
while (remain >= 0 && nglyphs) for (i = 0; i < nglyphs; i++)
{ {
glyph = AllocateGlyph (gi, glyphSet->fdepth); glyph_new = &glyphs[i];
if (!glyph) size = gi[i].height * PixmapBytePad (gi[i].width,
{ glyphSet->format->depth);
err = BadAlloc;
goto bail;
}
glyphs->glyph = glyph;
glyphs->id = *gids;
size = glyph->size - sizeof (xGlyphInfo);
if (remain < size) if (remain < size)
break; break;
memcpy ((CARD8 *) (glyph + 1), bits, size);
err = HashGlyph (&gi[i], bits, size, glyph_new->sha1);
if (err)
goto bail;
glyph_new->glyph = FindGlyphByHash (glyph_new->sha1,
glyphSet->fdepth);
if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph)
{
glyph_new->found = TRUE;
}
else
{
GlyphPtr glyph;
glyph_new->found = FALSE;
glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth);
if (! glyph)
{
err = BadAlloc;
goto bail;
}
for (screen = 0; screen < screenInfo.numScreens; screen++)
{
int width = gi[i].width;
int height = gi[i].height;
int depth = glyphSet->format->depth;
ScreenPtr pScreen;
int error;
pScreen = screenInfo.screens[screen];
pSrcPix = GetScratchPixmapHeader (pScreen,
width, height,
depth, depth,
-1, bits);
if (! pSrcPix)
{
err = BadAlloc;
goto bail;
}
pSrc = CreatePicture (0, &pSrcPix->drawable,
glyphSet->format, 0, NULL,
serverClient, &error);
if (! pSrc)
{
err = BadAlloc;
goto bail;
}
pDstPix = (pScreen->CreatePixmap) (pScreen,
width, height, depth);
GlyphPicture (glyph)[screen] = pDst =
CreatePicture (0, &pDstPix->drawable,
glyphSet->format,
CPComponentAlpha, &component_alpha,
serverClient, &error);
/* The picture takes a reference to the pixmap, so we
drop ours. */
(pScreen->DestroyPixmap) (pDstPix);
if (! pDst)
{
err = BadAlloc;
goto bail;
}
CompositePicture (PictOpSrc,
pSrc,
None,
pDst,
0, 0,
0, 0,
0, 0,
width, height);
FreePicture ((pointer) pSrc, 0);
pSrc = NULL;
FreeScratchPixmapHeader (pSrcPix);
pSrcPix = NULL;
}
memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20);
}
glyph_new->id = gids[i];
if (size & 3) if (size & 3)
size += 4 - (size & 3); size += 4 - (size & 3);
bits += size; bits += size;
remain -= size; remain -= size;
gi++;
gids++;
glyphs++;
nglyphs--;
} }
if (nglyphs || remain) if (remain || i < nglyphs)
{ {
err = BadLength; err = BadLength;
goto bail; goto bail;
} }
nglyphs = stuff->nglyphs;
if (!ResizeGlyphSet (glyphSet, nglyphs)) if (!ResizeGlyphSet (glyphSet, nglyphs))
{ {
err = BadAlloc; err = BadAlloc;
goto bail; goto bail;
} }
glyphs = glyphsBase; for (i = 0; i < nglyphs; i++)
while (nglyphs--) { AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id);
AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
glyphs++;
}
if (glyphsBase != glyphsLocal) if (glyphsBase != glyphsLocal)
Xfree (glyphsBase); Xfree (glyphsBase);
return client->noClientException; return client->noClientException;
bail: bail:
while (glyphs != glyphsBase) if (pSrc)
{ FreePicture ((pointer) pSrc, 0);
--glyphs; if (pSrcPix)
xfree (glyphs->glyph); FreeScratchPixmapHeader (pSrcPix);
} for (i = 0; i < nglyphs; i++)
if (glyphs[i].glyph && ! glyphs[i].found)
xfree (glyphs[i].glyph);
if (glyphsBase != glyphsLocal) if (glyphsBase != glyphsLocal)
Xfree (glyphsBase); Xfree (glyphsBase);
return err; return err;