diff options
author | Keith Packard <keithp@keithp.com> | 2015-05-26 13:44:07 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2015-05-26 13:44:07 -0700 |
commit | 067417178c7adcf48a7a08c08a4d3dab67c9eaeb (patch) | |
tree | b9ab144efe92b9cd9138933feef9f5eb1c2b65c0 | |
parent | cccbb54288fd5f8498170ae4fd84c8d9fa55cf84 (diff) |
render: Eliminate temporary mask when drawing glyphsglamor-keithp
The temporary mask was supposed to do a better job when drawing glyphs
sharing pixels than just drawing them one at a time. However, the way
it was defined assumed that the glyphs didn't actually overlap, and
the computational cost for this minor adjustment is quite high.
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | render/glyph.c | 147 |
1 files changed, 18 insertions, 129 deletions
diff --git a/render/glyph.c b/render/glyph.c index f3310db12..39245fa49 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -494,53 +494,6 @@ FreeGlyphSet(void *value, XID gid) 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) void @@ -576,111 +529,47 @@ miGlyphs(CARD8 op, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, - INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs) + 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; + int x = 0, y = 0; + + /* Align source pattern with origin of first glyph */ + if (nlist) { + xSrc -= list->xOff; + ySrc -= list->yOff; } while (nlist--) { + int n = list->len; x += list->xOff; y += list->yOff; - n = list->len; while (n--) { - glyph = *glyphs++; - pPicture = GetGlyphPicture(glyph, pScreen); + GlyphPtr glyph = *glyphs++; - if (pPicture) { - 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 { + if (glyph->info.width && glyph->info.height) { + PicturePtr pPicture = GetGlyphPicture(glyph, pScreen); + + if (pPicture) { CompositePicture(op, pSrc, pPicture, pDst, - xSrc + (x - glyph->info.x) - xDst, - ySrc + (y - glyph->info.y) - yDst, + xSrc + (x - glyph->info.x), + ySrc + (y - glyph->info.y), 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((void *) pMask, (XID) 0); - (*pScreen->DestroyPixmap) (pMaskPixmap); - } } PicturePtr GetGlyphPicture(GlyphPtr glyph, ScreenPtr pScreen) |