diff options
author | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2007-10-25 12:19:30 -0400 |
---|---|---|
committer | Eamon Walsh <ewalsh@moss-charon.epoch.ncsc.mil> | 2007-10-25 12:19:30 -0400 |
commit | b633d54b94d746d26e13014634d9f63bbb7e8f7d (patch) | |
tree | 4832d035672164284ff8698d5875e9d5435f494a /render | |
parent | 4b05f19cb9e42d8c8eff5ca4e463f5bc2a05433d (diff) | |
parent | 48ca5961caee62f2980017a6bdc96a1b4c747727 (diff) |
Merge branch 'master' into XACE-SELINUX
Conflicts:
GL/glx/glxscreens.c
hw/xnest/Screen.c
render/glyph.c
render/glyphstr.h
render/render.c
Diffstat (limited to 'render')
-rw-r--r-- | render/Makefile.am | 1 | ||||
-rw-r--r-- | render/glyph.c | 332 | ||||
-rw-r--r-- | render/glyphstr.h | 26 | ||||
-rw-r--r-- | render/miglyph.c | 255 | ||||
-rw-r--r-- | render/mipict.c | 2 | ||||
-rw-r--r-- | render/mipict.h | 6 | ||||
-rw-r--r-- | render/picture.c | 18 | ||||
-rw-r--r-- | render/picture.h | 2 | ||||
-rw-r--r-- | render/picturestr.h | 2 | ||||
-rw-r--r-- | render/render.c | 156 |
10 files changed, 438 insertions, 362 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 cb1534d6e..bb7c880d3 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -26,6 +26,9 @@ #include <dix-config.h> #endif +#include <stddef.h> +#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 @@ -93,6 +97,7 @@ FreeGlyphPrivates (GlyphPtr glyph) } dixFreePrivates(glyph->devPrivates); + glyph->devPrivates = NULL; } void @@ -114,7 +119,6 @@ GlyphUninit (ScreenPtr pScreen) { (*ps->UnrealizeGlyph) (pScreen, glyph); FreeGlyphPrivates(glyph); - glyph->devPrivates = NULL; } } } @@ -141,7 +145,10 @@ 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 elt, step, s; GlyphPtr glyph; @@ -172,7 +179,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; } @@ -189,17 +196,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); - - hash = 0; - while (n--) - hash ^= *bits++; - return hash; + 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; + + 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 @@ -240,6 +277,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++) @@ -250,8 +288,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) @@ -263,9 +302,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); } FreeGlyphPrivates(glyph); @@ -277,13 +320,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; @@ -298,10 +342,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++; } @@ -354,7 +398,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; @@ -366,25 +410,27 @@ 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); - } - - FreeGlyphPrivates(glyph); - xfree (glyph); - return 0; - } + goto bail; } } return glyph; + +bail: + while (i--) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps) + (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); + } + + FreeGlyphPrivates(glyph); + xfree (glyph); + return 0; } Bool @@ -428,7 +474,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; @@ -510,3 +556,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) + +/* Stub ABI compatibility for mi*Glyph, should go away */ +_X_EXPORT void +miGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr list, + GlyphPtr *glyphs) +{ + CompositeGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, + glyphs); +} + +Bool +miRealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ + return TRUE; +} + +void +miUnrealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ +} + +_X_EXPORT void +CompositeGlyphs (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; + + ValidatePicture (pSrc); + ValidatePicture (pDst); + + 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); + 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 e89f34e59..67b21fe63 100644 --- a/render/glyphstr.h +++ b/render/glyphstr.h @@ -40,13 +40,16 @@ #define GlyphFormatNum 5 typedef struct _Glyph { - CARD32 refcnt; + CARD32 refcnt; PrivateRec *devPrivates; - CARD32 size; /* info + bitmap */ - xGlyphInfo info; - /* bits follow */ + 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; @@ -98,10 +101,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.c b/render/mipict.c index 87dccbbda..5aad676f5 100644 --- a/render/mipict.c +++ b/render/mipict.c @@ -636,7 +636,7 @@ miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats) /* MI rendering routines */ ps->Composite = 0; /* requires DDX support */ - ps->Glyphs = miGlyphs; + ps->Glyphs = NULL; ps->CompositeRects = miCompositeRects; ps->Trapezoids = miTrapezoids; ps->Triangles = miTriangles; 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/picture.c b/render/picture.c index 049274e9f..35e2a28b3 100644 --- a/render/picture.c +++ b/render/picture.c @@ -1673,24 +1673,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 5444e519c..4dfa94402 100644 --- a/render/picturestr.h +++ b/render/picturestr.h @@ -342,7 +342,7 @@ typedef struct _PictureScreen { ValidatePictureProcPtr ValidatePicture; CompositeProcPtr Composite; - GlyphsProcPtr Glyphs; + GlyphsProcPtr Glyphs; /* unused */ CompositeRectsProcPtr CompositeRects; DestroyWindowProcPtr DestroyWindow; diff --git a/render/render.c b/render/render.c index fe50dd28e..b9ac45e96 100644 --- a/render/render.c +++ b/render/render.c @@ -1170,24 +1170,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; + int i, screen; + PicturePtr pSrc = NULL, pDst = NULL; + PixmapPtr pSrcPix = NULL, pDstPix = NULL; + CARD32 component_alpha; REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); err = dixLookupResource((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, @@ -1203,11 +1210,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; } @@ -1220,58 +1231,133 @@ 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); + + 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; |