diff options
Diffstat (limited to 'nx-X11/programs/Xserver/render/glyph.c')
-rw-r--r-- | nx-X11/programs/Xserver/render/glyph.c | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/render/glyph.c b/nx-X11/programs/Xserver/render/glyph.c index 2ef1087e7..d3bfae760 100644 --- a/nx-X11/programs/Xserver/render/glyph.c +++ b/nx-X11/programs/Xserver/render/glyph.c @@ -42,6 +42,7 @@ #include "servermd.h" #include "picturestr.h" #include "glyphstr.h" +#include "mipict.h" #include <stdint.h> @@ -489,3 +490,209 @@ FreeGlyphSet (void *value, } return Success; } + +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 +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); +} + +#ifndef NXAGENT_SERVER +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; + + 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; + } + 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, + (void *) (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, + (void *) (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((void *) 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((void *) pMask, (XID) 0); + (*pScreen->DestroyPixmap) (pMaskPixmap); + } +} +#endif |