[PATCH 5/5] render: Eliminate temporary mask when drawing glyphs
Keith Packard
keithp at keithp.com
Tue May 26 13:47:55 PDT 2015
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 at keithp.com>
---
render/glyph.c | 147 +++++++--------------------------------------------------
1 file changed, 18 insertions(+), 129 deletions(-)
diff --git a/render/glyph.c b/render/glyph.c
index f3310db..39245fa 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)
--
2.1.4
More information about the xorg-devel
mailing list