void exaGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs) { PixmapPtr pMaskPixmap = 0; PicturePtr pMask = NULL; ScreenPtr pScreen = pDst->pDrawable->pScreen; int width = 0, height = 0; int x, y; int first_xOff = list->xOff, first_yOff = list->yOff; int n; GlyphPtr glyph; int error; BoxRec extents = { 0, 0, 0, 0 }; CARD32 component_alpha; ExaGlyphBuffer buffer; if (maskFormat) { ExaScreenPriv(pScreen); 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; if (maskFormat->depth == 1) { PictFormatPtr a8Format = PictureMatchFormat(pScreen, 8, PICT_a8); if (a8Format) maskFormat = a8Format; } 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 || (!component_alpha && pExaScr->info->CheckComposite && !(*pExaScr->info->CheckComposite) (PictOpAdd, pSrc, NULL, pMask))) { PictFormatPtr argbFormat; (*pScreen->DestroyPixmap) (pMaskPixmap); if (!pMask) return; /* The driver can't seem to composite to a8, let's try argb (but * without component-alpha) */ FreePicture((pointer) pMask, (XID) 0); argbFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8); if (argbFormat) maskFormat = argbFormat; pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth, CREATE_PIXMAP_USAGE_SCRATCH); if (!pMaskPixmap) return; pMask = CreatePicture(0, &pMaskPixmap->drawable, maskFormat, 0, 0, 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 { x = 0; y = 0; } buffer.count = 0; buffer.mask = NULL; while (nlist--) { x += list->xOff; y += list->yOff; n = list->len; while (n--) { glyph = *glyphs++; if (glyph->info.width > 0 && glyph->info.height > 0) { /* pGlyph->info.{x,y} compensate for empty space in the glyph. */ if (maskFormat) { if (exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask, 0, 0, 0, 0, x - glyph->info.x, y - glyph->info.y) == ExaGlyphNeedFlush) { exaGlyphsToMask(pMask, &buffer); exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask, 0, 0, 0, 0, x - glyph->info.x, y - glyph->info.y); } } else { if (exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst, xSrc + (x - glyph->info.x) - first_xOff, ySrc + (y - glyph->info.y) - first_yOff, 0, 0, x - glyph->info.x, y - glyph->info.y) == ExaGlyphNeedFlush) { exaGlyphsToDst(pSrc, pDst, &buffer); exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst, xSrc + (x - glyph->info.x) - first_xOff, ySrc + (y - glyph->info.y) - first_yOff, 0, 0, x - glyph->info.x, y - glyph->info.y); } } } x += glyph->info.xOff; y += glyph->info.yOff; } list++; } if (buffer.count) { if (maskFormat) exaGlyphsToMask(pMask, &buffer); else exaGlyphsToDst(pSrc, pDst, &buffer); } if (maskFormat) { x = extents.x1; y = extents.y1; CompositePicture(op, pSrc, pMask, pDst, xSrc + x - first_xOff, ySrc + y - first_yOff, 0, 0, x, y, width, height); FreePicture((pointer) pMask, (XID) 0); (*pScreen->DestroyPixmap) (pMaskPixmap); } }
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 (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 { 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); } }