diff options
Diffstat (limited to 'render')
-rw-r--r-- | render/Makefile.am | 1 | ||||
-rw-r--r-- | render/glyph.c | 330 | ||||
-rw-r--r-- | render/glyphstr.h | 28 | ||||
-rw-r--r-- | render/miglyph.c | 255 | ||||
-rw-r--r-- | render/mipict.h | 6 | ||||
-rw-r--r-- | render/mirect.c | 4 | ||||
-rw-r--r-- | render/mitrap.c | 2 | ||||
-rw-r--r-- | render/mitri.c | 8 | ||||
-rw-r--r-- | render/picture.c | 66 | ||||
-rw-r--r-- | render/picture.h | 2 | ||||
-rw-r--r-- | render/picturestr.h | 6 | ||||
-rw-r--r-- | render/render.c | 204 |
12 files changed, 495 insertions, 417 deletions
diff --git a/render/Makefile.am b/render/Makefile.am index 830778a92..e53c7c746 100644 --- a/render/Makefile.am +++ b/render/Makefile.am @@ -6,7 +6,6 @@ librender_la_SOURCES = \ animcur.c \ filter.c \ glyph.c \ - miglyph.c \ miindex.c \ mipict.c \ mirect.c \ diff --git a/render/glyph.c b/render/glyph.c index 583a52ba3..e1dc0bc99 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -26,6 +26,9 @@ #include <dix-config.h> #endif +#include <stddef.h> /* buggy openssl/sha.h wants size_t */ +#include <openssl/sha.h> + #include "misc.h" #include "scrnintstr.h" #include "os.h" @@ -41,6 +44,7 @@ #include "servermd.h" #include "picturestr.h" #include "glyphstr.h" +#include "mipict.h" /* * From Knuth -- a good choice for hash/rehash values is p, p-2 where @@ -412,7 +416,10 @@ _GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr) } 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; GlyphPtr glyph; @@ -443,7 +450,7 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) } else if (s == signature && (!match || - memcmp (&compare->info, &glyph->info, compare->size) == 0)) + memcmp (glyph->sha1, sha1, 20) == 0)) { break; } @@ -460,17 +467,47 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) return gr; } -CARD32 -HashGlyph (GlyphPtr glyph) +int +HashGlyph (xGlyphInfo *gi, + CARD8 *bits, + unsigned long size, + unsigned char sha1[20]) { - CARD32 *bits = (CARD32 *) &(glyph->info); - CARD32 hash; - int n = glyph->size / sizeof (CARD32); + SHA_CTX ctx; + int success; + + success = SHA1_Init (&ctx); + if (! success) + return BadAlloc; + + 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; - hash = 0; - while (n--) - hash ^= *bits++; - return hash; + 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 @@ -511,6 +548,7 @@ FreeGlyph (GlyphPtr glyph, int format) GlyphRefPtr gr; int i; int first; + CARD32 signature; first = -1; for (i = 0; i < globalGlyphs[format].hashSet->size; i++) @@ -521,8 +559,9 @@ FreeGlyph (GlyphPtr glyph, int format) first = i; } - gr = FindGlyphRef (&globalGlyphs[format], - HashGlyph (glyph), TRUE, glyph); + signature = *(CARD32 *) glyph->sha1; + gr = FindGlyphRef (&globalGlyphs[format], signature, + TRUE, glyph->sha1); if (gr - globalGlyphs[format].table != first) DuplicateRef (glyph, "Found wrong one"); if (gr->glyph && gr->glyph != DeletedGlyph) @@ -534,9 +573,13 @@ FreeGlyph (GlyphPtr glyph, int format) 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) - (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); + (*ps->UnrealizeGlyph) (pScreen, glyph); } if (glyph->devPrivates) @@ -549,13 +592,14 @@ void AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) { GlyphRefPtr gr; - CARD32 hash; + CARD32 signature; CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global"); /* Locate existing matching glyph */ - hash = HashGlyph (glyph); - gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph); - if (gr->glyph && gr->glyph != DeletedGlyph) + signature = *(CARD32 *) glyph->sha1; + gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], signature, + TRUE, glyph->sha1); + if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph) { PictureScreenPtr ps; int i; @@ -571,10 +615,10 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) xfree (glyph); glyph = gr->glyph; } - else + else if (gr->glyph != glyph) { gr->glyph = glyph; - gr->signature = hash; + gr->signature = signature; globalGlyphs[glyphSet->fdepth].tableEntries++; } @@ -627,7 +671,7 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth) GlyphPtr glyph; int i; - size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]); + size = screenInfo.numScreens * sizeof (PicturePtr); glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec)); if (!glyph) return 0; @@ -648,26 +692,28 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth) for (i = 0; i < screenInfo.numScreens; i++) { ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps) { if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph)) - { - 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; - } + goto bail; } } 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 @@ -711,7 +757,7 @@ ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global) if (glyph && glyph != DeletedGlyph) { s = hash->table[i].signature; - gr = FindGlyphRef (&newHash, s, global, glyph); + gr = FindGlyphRef (&newHash, s, global, glyph->sha1); gr->signature = s; gr->glyph = glyph; ++newHash.tableEntries; @@ -801,3 +847,215 @@ FreeGlyphSet (pointer value, } return Success; } + +static void +GlyphExtents (int nlist, + GlyphListPtr list, + GlyphPtr *glyphs, + BoxPtr extents) +{ + int x1, x2, y1, y2; + int n; + GlyphPtr glyph; + int x, y; + + x = 0; + y = 0; + extents->x1 = MAXSHORT; + extents->x2 = MINSHORT; + extents->y1 = MAXSHORT; + extents->y2 = MINSHORT; + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + list++; + while (n--) + { + glyph = *glyphs++; + x1 = x - glyph->info.x; + if (x1 < MINSHORT) + x1 = MINSHORT; + y1 = y - glyph->info.y; + if (y1 < MINSHORT) + y1 = MINSHORT; + x2 = x1 + glyph->info.width; + if (x2 > MAXSHORT) + x2 = MAXSHORT; + y2 = y1 + glyph->info.height; + if (y2 > MAXSHORT) + y2 = MAXSHORT; + if (x1 < extents->x1) + extents->x1 = x1; + if (x2 > extents->x2) + extents->x2 = x2; + if (y1 < extents->y1) + extents->y1 = y1; + if (y2 > extents->y2) + extents->y2 = y2; + x += glyph->info.xOff; + y += glyph->info.yOff; + } + } +} + +#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) + +_X_EXPORT void +CompositeGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr lists, + GlyphPtr *glyphs) +{ + PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); + + ValidatePicture (pSrc); + ValidatePicture (pDst); + (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs); +} + +Bool +miRealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ + return TRUE; +} + +void +miUnrealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ +} + +_X_EXPORT void +miGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr list, + GlyphPtr *glyphs) +{ + PicturePtr pPicture; + PixmapPtr pMaskPixmap = 0; + PicturePtr pMask; + ScreenPtr pScreen = pDst->pDrawable->pScreen; + int width = 0, height = 0; + int x, y; + int xDst = list->xOff, yDst = list->yOff; + int n; + GlyphPtr glyph; + int error; + BoxRec extents = {0, 0, 0, 0}; + CARD32 component_alpha; + + if (maskFormat) + { + GCPtr pGC; + xRectangle rect; + + GlyphExtents (nlist, list, glyphs, &extents); + + if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) + return; + width = extents.x2 - extents.x1; + height = extents.y2 - extents.y1; + pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, + maskFormat->depth, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!pMaskPixmap) + return; + component_alpha = NeedsComponent(maskFormat->format); + pMask = CreatePicture (0, &pMaskPixmap->drawable, + maskFormat, CPComponentAlpha, &component_alpha, + serverClient, &error); + if (!pMask) + { + (*pScreen->DestroyPixmap) (pMaskPixmap); + return; + } + pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); + ValidateGC (&pMaskPixmap->drawable, pGC); + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); + FreeScratchGC (pGC); + x = -extents.x1; + y = -extents.y1; + } + else + { + pMask = pDst; + x = 0; + y = 0; + } + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + while (n--) + { + glyph = *glyphs++; + pPicture = GlyphPicture (glyph)[pScreen->myNum]; + + if (maskFormat) + { + CompositePicture (PictOpAdd, + pPicture, + None, + pMask, + 0, 0, + 0, 0, + x - glyph->info.x, + y - glyph->info.y, + glyph->info.width, + glyph->info.height); + } + else + { + CompositePicture (op, + pSrc, + pPicture, + pDst, + xSrc + (x - glyph->info.x) - xDst, + ySrc + (y - glyph->info.y) - yDst, + 0, 0, + x - glyph->info.x, + y - glyph->info.y, + glyph->info.width, + glyph->info.height); + } + + x += glyph->info.xOff; + y += glyph->info.yOff; + } + list++; + } + if (maskFormat) + { + x = extents.x1; + y = extents.y1; + CompositePicture (op, + pSrc, + pMask, + pDst, + xSrc + x - xDst, + ySrc + y - yDst, + 0, 0, + x, y, + width, height); + FreePicture ((pointer) pMask, (XID) 0); + (*pScreen->DestroyPixmap) (pMaskPixmap); + } +} diff --git a/render/glyphstr.h b/render/glyphstr.h index 22150deee..c6ab5aa11 100644 --- a/render/glyphstr.h +++ b/render/glyphstr.h @@ -39,13 +39,16 @@ #define GlyphFormatNum 5 typedef struct _Glyph { - CARD32 refcnt; - DevUnion *devPrivates; - CARD32 size; /* info + bitmap */ - xGlyphInfo info; - /* bits follow */ + CARD32 refcnt; + DevUnion *devPrivates; + unsigned char sha1[20]; + CARD32 size; /* info + bitmap */ + xGlyphInfo info; + /* per-screen pixmaps follow */ } GlyphRec, *GlyphPtr; +#define GlyphPicture(glyph) ((PicturePtr *) ((glyph) + 1)) + typedef struct _GlyphRef { CARD32 signature; GlyphPtr glyph; @@ -127,10 +130,19 @@ GlyphHashSetPtr FindGlyphHashSet (CARD32 filled); GlyphRefPtr -FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare); +FindGlyphRef (GlyphHashPtr hash, + CARD32 signature, + Bool match, + unsigned char sha1[20]); -CARD32 -HashGlyph (GlyphPtr glyph); +GlyphPtr +FindGlyphByHash (unsigned char sha1[20], int format); + +int +HashGlyph (xGlyphInfo *gi, + CARD8 *bits, + unsigned long size, + unsigned char sha1[20]); void FreeGlyph (GlyphPtr glyph, int format); diff --git a/render/miglyph.c b/render/miglyph.c deleted file mode 100644 index 7968c90ea..000000000 --- a/render/miglyph.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * - * Copyright © 2000 SuSE, Inc. - * - * 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 SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * 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. - * - * Author: Keith Packard, SuSE, Inc. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include "scrnintstr.h" -#include "gcstruct.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "mi.h" -#include "picturestr.h" -#include "mipict.h" - -Bool -miRealizeGlyph (ScreenPtr pScreen, - GlyphPtr glyph) -{ - return TRUE; -} - -void -miUnrealizeGlyph (ScreenPtr pScreen, - GlyphPtr glyph) -{ -} - -_X_EXPORT void -miGlyphExtents (int nlist, - GlyphListPtr list, - GlyphPtr *glyphs, - BoxPtr extents) -{ - int x1, x2, y1, y2; - int n; - GlyphPtr glyph; - int x, y; - - x = 0; - y = 0; - extents->x1 = MAXSHORT; - extents->x2 = MINSHORT; - extents->y1 = MAXSHORT; - extents->y2 = MINSHORT; - while (nlist--) - { - x += list->xOff; - y += list->yOff; - n = list->len; - list++; - while (n--) - { - glyph = *glyphs++; - x1 = x - glyph->info.x; - if (x1 < MINSHORT) - x1 = MINSHORT; - y1 = y - glyph->info.y; - if (y1 < MINSHORT) - y1 = MINSHORT; - x2 = x1 + glyph->info.width; - if (x2 > MAXSHORT) - x2 = MAXSHORT; - y2 = y1 + glyph->info.height; - if (y2 > MAXSHORT) - y2 = MAXSHORT; - if (x1 < extents->x1) - extents->x1 = x1; - if (x2 > extents->x2) - extents->x2 = x2; - if (y1 < extents->y1) - extents->y1 = y1; - if (y2 > extents->y2) - extents->y2 = y2; - x += glyph->info.xOff; - y += glyph->info.yOff; - } - } -} - -#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) - -_X_EXPORT void -miGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs) -{ - PixmapPtr pPixmap = 0; - PicturePtr pPicture; - PixmapPtr pMaskPixmap = 0; - PicturePtr pMask; - ScreenPtr pScreen = pDst->pDrawable->pScreen; - int width = 0, height = 0; - int x, y; - int xDst = list->xOff, yDst = list->yOff; - int n; - GlyphPtr glyph; - int error; - BoxRec extents; - CARD32 component_alpha; - - if (maskFormat) - { - GCPtr pGC; - xRectangle rect; - - miGlyphExtents (nlist, list, glyphs, &extents); - - if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) - return; - width = extents.x2 - extents.x1; - height = extents.y2 - extents.y1; - pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth); - if (!pMaskPixmap) - return; - component_alpha = NeedsComponent(maskFormat->format); - pMask = CreatePicture (0, &pMaskPixmap->drawable, - maskFormat, CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pMask) - { - (*pScreen->DestroyPixmap) (pMaskPixmap); - return; - } - pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); - ValidateGC (&pMaskPixmap->drawable, pGC); - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); - FreeScratchGC (pGC); - x = -extents.x1; - y = -extents.y1; - } - else - { - pMask = pDst; - x = 0; - y = 0; - } - pPicture = 0; - while (nlist--) - { - x += list->xOff; - y += list->yOff; - n = list->len; - while (n--) - { - glyph = *glyphs++; - if (!pPicture) - { - 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) - { - CompositePicture (PictOpAdd, - pPicture, - None, - pMask, - 0, 0, - 0, 0, - x - glyph->info.x, - y - glyph->info.y, - glyph->info.width, - glyph->info.height); - } - else - { - CompositePicture (op, - pSrc, - pPicture, - pDst, - xSrc + (x - glyph->info.x) - xDst, - ySrc + (y - glyph->info.y) - yDst, - 0, 0, - x - glyph->info.x, - y - glyph->info.y, - glyph->info.width, - glyph->info.height); - } - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - if (pPicture) - { - FreeScratchPixmapHeader (pPixmap); - FreePicture ((pointer) pPicture, 0); - pPicture = 0; - pPixmap = 0; - } - } - if (maskFormat) - { - x = extents.x1; - y = extents.y1; - CompositePicture (op, - pSrc, - pMask, - pDst, - xSrc + x - xDst, - ySrc + y - yDst, - 0, 0, - x, y, - width, height); - FreePicture ((pointer) pMask, (XID) 0); - (*pScreen->DestroyPixmap) (pMaskPixmap); - } -} diff --git a/render/mipict.h b/render/mipict.h index bd7c23f4b..60baf7f66 100644 --- a/render/mipict.h +++ b/render/mipict.h @@ -120,12 +120,6 @@ miUnrealizeGlyph (ScreenPtr pScreen, GlyphPtr glyph); void -miGlyphExtents (int nlist, - GlyphListPtr list, - GlyphPtr *glyphs, - BoxPtr extents); - -void miGlyphs (CARD8 op, PicturePtr pSrc, PicturePtr pDst, diff --git a/render/mirect.c b/render/mirect.c index 87767a76c..464df51c1 100644 --- a/render/mirect.c +++ b/render/mirect.c @@ -135,8 +135,8 @@ miCompositeRects (CARD8 op, if (!rgbaFormat) goto bail1; - pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1, - rgbaFormat->depth); + pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1, rgbaFormat->depth, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) goto bail2; diff --git a/render/mitrap.c b/render/mitrap.c index c6188061c..8bdc8a8d0 100644 --- a/render/mitrap.c +++ b/render/mitrap.c @@ -61,7 +61,7 @@ miCreateAlphaPicture (ScreenPtr pScreen, } pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, - pPictFormat->depth); + pPictFormat->depth, 0); if (!pPixmap) return 0; pGC = GetScratchGC (pPixmap->drawable.depth, pScreen); diff --git a/render/mitri.c b/render/mitri.c index 374e2fdc7..a92c19b7e 100644 --- a/render/mitri.c +++ b/render/mitri.c @@ -144,7 +144,7 @@ miTriStrip (CARD8 op, if (npoint < 3) return; ntri = npoint - 2; - tris = ALLOCATE_LOCAL (ntri * sizeof (xTriangle)); + tris = xalloc (ntri * sizeof (xTriangle)); if (!tris) return; for (tri = tris; npoint >= 3; npoint--, points++, tri++) @@ -154,7 +154,7 @@ miTriStrip (CARD8 op, tri->p3 = points[2]; } (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); - DEALLOCATE_LOCAL (tris); + xfree (tris); } void @@ -176,7 +176,7 @@ miTriFan (CARD8 op, if (npoint < 3) return; ntri = npoint - 2; - tris = ALLOCATE_LOCAL (ntri * sizeof (xTriangle)); + tris = xalloc (ntri * sizeof (xTriangle)); if (!tris) return; first = points++; @@ -187,5 +187,5 @@ miTriFan (CARD8 op, tri->p3 = points[1]; } (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris); - DEALLOCATE_LOCAL (tris); + xfree (tris); } diff --git a/render/picture.c b/render/picture.c index 5ddd68ce3..a7e40f994 100644 --- a/render/picture.c +++ b/render/picture.c @@ -452,6 +452,28 @@ PictureFindVisual (ScreenPtr pScreen, VisualID visual) } Bool +PictureInitIndexedFormat(ScreenPtr pScreen, PictFormatPtr format) +{ + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + + if (format->type != PictTypeIndexed || format->index.pColormap) + return TRUE; + + if (format->index.vid == pScreen->rootVisual) { + format->index.pColormap = + (ColormapPtr) LookupIDByType(pScreen->defColormap, RT_COLORMAP); + } else { + VisualPtr pVisual = PictureFindVisual(pScreen, format->index.vid); + if (!CreateColormap(FakeClientID (0), pScreen, pVisual, + &format->index.pColormap, AllocNone, 0)) + return FALSE; + } + if (!ps->InitIndexed(pScreen, format)) + return FALSE; + return TRUE; +} + +static Bool PictureInitIndexedFormats (ScreenPtr pScreen) { PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); @@ -463,30 +485,8 @@ PictureInitIndexedFormats (ScreenPtr pScreen) format = ps->formats; nformat = ps->nformats; while (nformat--) - { - if (format->type == PictTypeIndexed && !format->index.pColormap) - { - if (format->index.vid == pScreen->rootVisual) - format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap, - RT_COLORMAP); - else - { - VisualPtr pVisual; - - pVisual = PictureFindVisual (pScreen, format->index.vid); - if (CreateColormap (FakeClientID (0), pScreen, - pVisual, - &format->index.pColormap, AllocNone, - 0) != Success) - { - return FALSE; - } - } - if (!(*ps->InitIndexed) (pScreen, format)) - return FALSE; - } - format++; - } + if (!PictureInitIndexedFormat(pScreen, format++)) + return FALSE; return TRUE; } @@ -1768,24 +1768,6 @@ CompositePicture (CARD8 op, } void -CompositeGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr lists, - GlyphPtr *glyphs) -{ - PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); - - ValidatePicture (pSrc); - ValidatePicture (pDst); - (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs); -} - -void CompositeRects (CARD8 op, PicturePtr pDst, xRenderColor *color, diff --git a/render/picture.h b/render/picture.h index 563a81b43..e8a098cd9 100644 --- a/render/picture.h +++ b/render/picture.h @@ -115,7 +115,7 @@ typedef enum _PictFormatShort { /* 1bpp formats */ PICT_a1 = PIXMAN_a1, - PICT_g1 = PIXMAN_g1, + PICT_g1 = PIXMAN_g1 } PictFormatShort; /* diff --git a/render/picturestr.h b/render/picturestr.h index 01572ec48..b2e180f11 100644 --- a/render/picturestr.h +++ b/render/picturestr.h @@ -24,8 +24,8 @@ #ifndef _PICTURESTR_H_ #define _PICTURESTR_H_ -#include "glyphstr.h" #include "scrnintstr.h" +#include "glyphstr.h" #include "resource.h" typedef struct _DirectFormat { @@ -345,7 +345,7 @@ typedef struct _PictureScreen { ValidatePictureProcPtr ValidatePicture; CompositeProcPtr Composite; - GlyphsProcPtr Glyphs; + GlyphsProcPtr Glyphs; /* unused */ CompositeRectsProcPtr CompositeRects; DestroyWindowProcPtr DestroyWindow; @@ -449,7 +449,7 @@ void PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef); Bool -PictureInitIndexedFormats (ScreenPtr pScreen); +PictureInitIndexedFormat (ScreenPtr pScreen, PictFormatPtr format); Bool PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel); diff --git a/render/render.c b/render/render.c index caaa2781c..3a9d24a02 100644 --- a/render/render.c +++ b/render/render.c @@ -1080,24 +1080,31 @@ ProcRenderFreeGlyphSet (ClientPtr client) } typedef struct _GlyphNew { - Glyph id; - GlyphPtr glyph; + Glyph id; + GlyphPtr glyph; + Bool found; + unsigned char sha1[20]; } GlyphNewRec, *GlyphNewPtr; +#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) + static int ProcRenderAddGlyphs (ClientPtr client) { GlyphSetPtr glyphSet; REQUEST(xRenderAddGlyphsReq); GlyphNewRec glyphsLocal[NLOCALGLYPH]; - GlyphNewPtr glyphsBase, glyphs; - GlyphPtr glyph; + GlyphNewPtr glyphsBase, glyphs, glyph_new; int remain, nglyphs; CARD32 *gids; xGlyphInfo *gi; CARD8 *bits; int size; int err = BadAlloc; + int i, screen; + PicturePtr pSrc = NULL, pDst = NULL; + PixmapPtr pSrcPix = NULL, pDstPix = NULL; + CARD32 component_alpha; REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client, @@ -1114,11 +1121,15 @@ ProcRenderAddGlyphs (ClientPtr client) if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec)) return BadAlloc; - if (nglyphs <= NLOCALGLYPH) + component_alpha = NeedsComponent (glyphSet->format->format); + + if (nglyphs <= NLOCALGLYPH) { + memset (glyphsLocal, 0, sizeof (glyphsLocal)); glyphsBase = glyphsLocal; + } else { - glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec)); + glyphsBase = (GlyphNewPtr) Xcalloc (nglyphs * sizeof (GlyphNewRec)); if (!glyphsBase) return BadAlloc; } @@ -1131,58 +1142,134 @@ ProcRenderAddGlyphs (ClientPtr client) gi = (xGlyphInfo *) (gids + nglyphs); bits = (CARD8 *) (gi + nglyphs); remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs; - while (remain >= 0 && nglyphs) + for (i = 0; i < nglyphs; i++) { - glyph = AllocateGlyph (gi, glyphSet->fdepth); - if (!glyph) - { - err = BadAlloc; - goto bail; - } - - glyphs->glyph = glyph; - glyphs->id = *gids; - - size = glyph->size - sizeof (xGlyphInfo); + glyph_new = &glyphs[i]; + size = gi[i].height * PixmapBytePad (gi[i].width, + glyphSet->format->depth); if (remain < size) 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, + CREATE_PIMXAP_USAGE_GLYPH_PICTURE); + + 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) size += 4 - (size & 3); bits += size; remain -= size; - gi++; - gids++; - glyphs++; - nglyphs--; } - if (nglyphs || remain) + if (remain || i < nglyphs) { err = BadLength; goto bail; } - nglyphs = stuff->nglyphs; if (!ResizeGlyphSet (glyphSet, nglyphs)) { err = BadAlloc; goto bail; } - glyphs = glyphsBase; - while (nglyphs--) { - AddGlyph (glyphSet, glyphs->glyph, glyphs->id); - glyphs++; - } + for (i = 0; i < nglyphs; i++) + AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id); if (glyphsBase != glyphsLocal) Xfree (glyphsBase); return client->noClientException; bail: - while (glyphs != glyphsBase) - { - --glyphs; - xfree (glyphs->glyph); - } + if (pSrc) + FreePicture ((pointer) pSrc, 0); + if (pSrcPix) + FreeScratchPixmapHeader (pSrcPix); + for (i = 0; i < nglyphs; i++) + if (glyphs[i].glyph && ! glyphs[i].found) + xfree (glyphs[i].glyph); if (glyphsBase != glyphsLocal) Xfree (glyphsBase); return err; @@ -1322,7 +1409,7 @@ ProcRenderCompositeGlyphs (ClientPtr client) glyphsBase = glyphsLocal; else { - glyphsBase = (GlyphPtr *) ALLOCATE_LOCAL (nglyph * sizeof (GlyphPtr)); + glyphsBase = (GlyphPtr *) xalloc (nglyph * sizeof (GlyphPtr)); if (!glyphsBase) return BadAlloc; } @@ -1330,7 +1417,7 @@ ProcRenderCompositeGlyphs (ClientPtr client) listsBase = listsLocal; else { - listsBase = (GlyphListPtr) ALLOCATE_LOCAL (nlist * sizeof (GlyphListRec)); + listsBase = (GlyphListPtr) xalloc (nlist * sizeof (GlyphListRec)); if (!listsBase) return BadAlloc; } @@ -1355,9 +1442,9 @@ ProcRenderCompositeGlyphs (ClientPtr client) { client->errorValue = gs; if (glyphsBase != glyphsLocal) - DEALLOCATE_LOCAL (glyphsBase); + xfree (glyphsBase); if (listsBase != listsLocal) - DEALLOCATE_LOCAL (listsBase); + xfree (listsBase); return RenderErrBase + BadGlyphSet; } } @@ -1411,9 +1498,9 @@ ProcRenderCompositeGlyphs (ClientPtr client) glyphsBase); if (glyphsBase != glyphsLocal) - DEALLOCATE_LOCAL (glyphsBase); + xfree (glyphsBase); if (listsBase != listsLocal) - DEALLOCATE_LOCAL (listsBase); + xfree (listsBase); return client->noClientException; } @@ -1550,7 +1637,8 @@ ProcRenderCreateCursor (ClientPtr client) xfree (mskbits); return (BadImplementation); } - pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32); + pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32, + CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) { xfree (argbbits); @@ -2877,7 +2965,7 @@ PanoramiXRenderFillRectangles (ClientPtr client) RenderErrBase + BadPicture); extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq); if (extra_len && - (extra = (char *) ALLOCATE_LOCAL (extra_len))) + (extra = (char *) xalloc (extra_len))) { memcpy (extra, stuff + 1, extra_len); FOR_NSCREENS_FORWARD(j) { @@ -2903,7 +2991,7 @@ PanoramiXRenderFillRectangles (ClientPtr client) result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client); if(result != Success) break; } - DEALLOCATE_LOCAL(extra); + xfree(extra); } return result; @@ -2928,7 +3016,7 @@ PanoramiXRenderTrapezoids(ClientPtr client) extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq); if (extra_len && - (extra = (char *) ALLOCATE_LOCAL (extra_len))) { + (extra = (char *) xalloc (extra_len))) { memcpy (extra, stuff + 1, extra_len); FOR_NSCREENS_FORWARD(j) { @@ -2965,7 +3053,7 @@ PanoramiXRenderTrapezoids(ClientPtr client) if(result != Success) break; } - DEALLOCATE_LOCAL(extra); + xfree(extra); } return result; @@ -2990,7 +3078,7 @@ PanoramiXRenderTriangles(ClientPtr client) extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq); if (extra_len && - (extra = (char *) ALLOCATE_LOCAL (extra_len))) { + (extra = (char *) xalloc (extra_len))) { memcpy (extra, stuff + 1, extra_len); FOR_NSCREENS_FORWARD(j) { @@ -3023,7 +3111,7 @@ PanoramiXRenderTriangles(ClientPtr client) if(result != Success) break; } - DEALLOCATE_LOCAL(extra); + xfree(extra); } return result; @@ -3048,7 +3136,7 @@ PanoramiXRenderTriStrip(ClientPtr client) extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq); if (extra_len && - (extra = (char *) ALLOCATE_LOCAL (extra_len))) { + (extra = (char *) xalloc (extra_len))) { memcpy (extra, stuff + 1, extra_len); FOR_NSCREENS_FORWARD(j) { @@ -3077,7 +3165,7 @@ PanoramiXRenderTriStrip(ClientPtr client) if(result != Success) break; } - DEALLOCATE_LOCAL(extra); + xfree(extra); } return result; @@ -3102,7 +3190,7 @@ PanoramiXRenderTriFan(ClientPtr client) extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq); if (extra_len && - (extra = (char *) ALLOCATE_LOCAL (extra_len))) { + (extra = (char *) xalloc (extra_len))) { memcpy (extra, stuff + 1, extra_len); FOR_NSCREENS_FORWARD(j) { @@ -3131,7 +3219,7 @@ PanoramiXRenderTriFan(ClientPtr client) if(result != Success) break; } - DEALLOCATE_LOCAL(extra); + xfree(extra); } return result; @@ -3156,7 +3244,7 @@ PanoramiXRenderColorTrapezoids(ClientPtr client) extra_len = (client->req_len << 2) - sizeof (xRenderColorTrapezoidsReq); if (extra_len && - (extra = (char *) ALLOCATE_LOCAL (extra_len))) { + (extra = (char *) xalloc (extra_len))) { memcpy (extra, stuff + 1, extra_len); FOR_NSCREENS_FORWARD(j) { @@ -3177,7 +3265,7 @@ PanoramiXRenderColorTrapezoids(ClientPtr client) if(result != Success) break; } - DEALLOCATE_LOCAL(extra); + xfree(extra); } return result; @@ -3200,7 +3288,7 @@ PanoramiXRenderColorTriangles(ClientPtr client) extra_len = (client->req_len << 2) - sizeof (xRenderColorTrianglesReq); if (extra_len && - (extra = (char *) ALLOCATE_LOCAL (extra_len))) { + (extra = (char *) xalloc (extra_len))) { memcpy (extra, stuff + 1, extra_len); FOR_NSCREENS_FORWARD(j) { @@ -3221,7 +3309,7 @@ PanoramiXRenderColorTriangles(ClientPtr client) if(result != Success) break; } - DEALLOCATE_LOCAL(extra); + xfree(extra); } return result; @@ -3244,7 +3332,7 @@ PanoramiXRenderAddTraps (ClientPtr client) RenderErrBase + BadPicture); extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq); if (extra_len && - (extra = (char *) ALLOCATE_LOCAL (extra_len))) + (extra = (char *) xalloc (extra_len))) { memcpy (extra, stuff + 1, extra_len); x_off = stuff->xOff; @@ -3261,7 +3349,7 @@ PanoramiXRenderAddTraps (ClientPtr client) result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client); if(result != Success) break; } - DEALLOCATE_LOCAL(extra); + xfree(extra); } return result; |