[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