diff options
Diffstat (limited to 'xorg-server/hw/xgl/xglglyph.c')
-rw-r--r-- | xorg-server/hw/xgl/xglglyph.c | 1170 |
1 files changed, 0 insertions, 1170 deletions
diff --git a/xorg-server/hw/xgl/xglglyph.c b/xorg-server/hw/xgl/xglglyph.c deleted file mode 100644 index c1a484ac0..000000000 --- a/xorg-server/hw/xgl/xglglyph.c +++ /dev/null @@ -1,1170 +0,0 @@ -/* - * Copyright © 2005 Novell, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without - * fee, provided that the above copyright notice appear in all copies - * and that both that copyright notice and this permission notice - * appear in supporting documentation, and that the name of - * Novell, Inc. not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior permission. - * Novell, Inc. makes no representations about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - * - * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN - * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author: David Reveman <davidr@novell.com> - */ - -#include "xgl.h" - -#ifdef RENDER -#include "gcstruct.h" -#include "picturestr.h" - -#define BITMAP_CACHE_SIZE 256000 -#define BITMAP_CACHE_MAX_LEVEL ~0 -#define BITMAP_CACHE_MAX_SIZE 512 - -#define TEXTURE_CACHE_SIZE 512 -#define TEXTURE_CACHE_MAX_LEVEL 64 -#define TEXTURE_CACHE_MAX_HEIGHT 72 -#define TEXTURE_CACHE_MAX_WIDTH 72 - -#define NEXT_GLYPH_SERIAL_NUMBER ((++glyphSerialNumber) > MAX_SERIAL_NUM ? \ - (glyphSerialNumber = 1): glyphSerialNumber) - -#define GLYPH_GET_AREA_PRIV(pArea) \ - ((xglGlyphAreaPtr) (pArea)->devPrivate.ptr) - -#define GLYPH_AREA_PRIV(pArea) \ - xglGlyphAreaPtr pAreaPriv = GLYPH_GET_AREA_PRIV (pArea) - -#define NEEDS_COMPONENT(f) (PICT_FORMAT_A (f) != 0 && PICT_FORMAT_RGB (f) != 0) - -#define WRITE_VEC2(ptr, _x, _y) \ - *(ptr)++ = (_x); \ - *(ptr)++ = (_y) - -#define WRITE_BOX(ptr, _vx1, _vy1, _vx2, _vy2, box) \ - WRITE_VEC2 (ptr, _vx1, _vy1); \ - WRITE_VEC2 (ptr, (box).x1, (box).y2); \ - WRITE_VEC2 (ptr, _vx2, _vy1); \ - WRITE_VEC2 (ptr, (box).x2, (box).y2); \ - WRITE_VEC2 (ptr, _vx2, _vy2); \ - WRITE_VEC2 (ptr, (box).x2, (box).y1); \ - WRITE_VEC2 (ptr, _vx1, _vy2); \ - WRITE_VEC2 (ptr, (box).x1, (box).y1) - -typedef union _xglGlyphList { - glitz_short_t *s; - glitz_float_t *f; -} xglGlyphListRec, *xglGlyphListPtr; - -typedef struct _xglGlyphArray { - int lastX, lastY; -} xglGlyphArrayRec, *xglGlyphArrayPtr; - -typedef union _xglGlyphVertexData { - xglGlyphArrayRec array; - xglGlyphListRec list; -} xglGlyphVertexDataRec, *xglGlyphVertexDataPtr; - -typedef struct _xglGlyphOp { - GlyphListPtr pLists; - int listLen; - GlyphPtr *ppGlyphs; - int nGlyphs; - int xOff; - int yOff; - Bool noCache; -} xglGlyphOpRec, *xglGlyphOpPtr; - -unsigned long glyphSerialNumber = 0; - -xglAreaRec zeroSizeArea = { - 0, 0, - 0, 0, - 0, 0, - { NULL, NULL, NULL, NULL }, NULL, - (pointer) 0, - { 0 } -}; - -static Bool -xglGlyphCreate (xglAreaPtr pArea) -{ - return TRUE; -} - -static Bool -xglGlyphMoveIn (xglAreaPtr pArea, - pointer closure) -{ - xglGlyphCachePtr pCache = (xglGlyphCachePtr) pArea->pRoot->closure; - GlyphPtr pGlyph = (GlyphPtr) closure; - - XGL_GLYPH_PRIV (pCache->pScreen, pGlyph); - - pGlyphPriv->pArea = pArea; - - return TRUE; -} - -static void -xglGlyphMoveOut (xglAreaPtr pArea, - pointer closure) -{ - xglGlyphCachePtr pCache = (xglGlyphCachePtr) pArea->pRoot->closure; - GlyphPtr pGlyph = (GlyphPtr) closure; - - XGL_GLYPH_PRIV (pCache->pScreen, pGlyph); - - pGlyphPriv->pArea = NULL; -} - -static int -xglGlyphCompareScore (xglAreaPtr pArea, - pointer closure1, - pointer closure2) -{ - GLYPH_AREA_PRIV (pArea); - - if (pAreaPriv->serial == glyphSerialNumber) - return 1; - - return -1; -} - -static const xglAreaFuncsRec xglGlyphAreaFuncs = { - xglGlyphCreate, - xglGlyphMoveIn, - xglGlyphMoveOut, - xglGlyphCompareScore -}; - -Bool -xglRealizeGlyph (ScreenPtr pScreen, - GlyphPtr pGlyph) -{ - PictureScreenPtr pPictureScreen = GetPictureScreen (pScreen); - Bool ret; - - XGL_SCREEN_PRIV (pScreen); - XGL_GLYPH_PRIV (pScreen, pGlyph); - - XGL_PICTURE_SCREEN_UNWRAP (RealizeGlyph); - ret = (*pPictureScreen->RealizeGlyph) (pScreen, pGlyph); - XGL_PICTURE_SCREEN_WRAP (RealizeGlyph, xglRealizeGlyph); - - pGlyphPriv->pArea = NULL; - - return ret; -} - -void -xglUnrealizeGlyph (ScreenPtr pScreen, - GlyphPtr pGlyph) -{ - PictureScreenPtr pPictureScreen = GetPictureScreen (pScreen); - - XGL_SCREEN_PRIV (pScreen); - XGL_GLYPH_PRIV (pScreen, pGlyph); - - XGL_PICTURE_SCREEN_UNWRAP (UnrealizeGlyph); - (*pPictureScreen->UnrealizeGlyph) (pScreen, pGlyph); - XGL_PICTURE_SCREEN_WRAP (UnrealizeGlyph, xglUnrealizeGlyph); - - if (pGlyphPriv->pArea && pGlyphPriv->pArea->width) - xglWithdrawArea (pGlyphPriv->pArea); -} - -Bool -xglInitGlyphCache (xglGlyphCachePtr pCache, - ScreenPtr pScreen, - PictFormatPtr format) -{ - XGL_SCREEN_PRIV (pScreen); - - pCache->depth = format->depth; - - if (!pScreenPriv->pSolidAlpha) - { - xglCreateSolidAlphaPicture (pScreen); - if (!pScreenPriv->pSolidAlpha) - return FALSE; - } - - if (pCache->depth == 1) - { - int stride; - - GEOMETRY_INIT (pScreen, &pCache->u.geometry, - GLITZ_GEOMETRY_TYPE_VERTEX, - GEOMETRY_USAGE_STATIC, BITMAP_CACHE_SIZE); - GEOMETRY_SET_VERTEX_DATA_TYPE (&pCache->u.geometry, - pScreenPriv->geometryDataType); - - stride = pCache->u.geometry.f.vertex.bytes_per_vertex; - if (!xglRootAreaInit (&pCache->rootArea, - BITMAP_CACHE_MAX_LEVEL, - BITMAP_CACHE_SIZE / (stride * 4), - 0, sizeof (xglGlyphAreaRec), - (xglAreaFuncsPtr) &xglGlyphAreaFuncs, - (pointer) pCache)) - { - GEOMETRY_UNINIT (&pCache->u.geometry); - return FALSE; - } - } - else - { - - xglGlyphTexturePtr pTexture = &pCache->u.texture; - glitz_surface_t *mask; - glitz_surface_attributes_t attr; - glitz_vertex_format_t *vertex; - xglVisualPtr pVisual; - - pVisual = xglFindVisualWithDepth (pScreen, format->depth); - if (!pVisual) - return FALSE; - - if (!xglRootAreaInit (&pCache->rootArea, - TEXTURE_CACHE_MAX_LEVEL, - TEXTURE_CACHE_SIZE, TEXTURE_CACHE_SIZE, - sizeof (xglGlyphAreaRec), - (xglAreaFuncsPtr) &xglGlyphAreaFuncs, - (pointer) pCache)) - return FALSE; - - if (pScreenPriv->geometryDataType == GEOMETRY_DATA_TYPE_SHORT) - { - attr.unnormalized = 1; - mask = glitz_surface_create (pScreenPriv->drawable, - pVisual->format.surface, - TEXTURE_CACHE_SIZE, - TEXTURE_CACHE_SIZE, - GLITZ_SURFACE_UNNORMALIZED_MASK, - &attr); - } - else - mask = NULL; - - if (!mask) - { - mask = glitz_surface_create (pScreenPriv->drawable, - pVisual->format.surface, - TEXTURE_CACHE_SIZE, - TEXTURE_CACHE_SIZE, - 0, NULL); - if (!mask) - return FALSE; - - pTexture->geometryDataType = GEOMETRY_DATA_TYPE_FLOAT; - } - else - pTexture->geometryDataType = GEOMETRY_DATA_TYPE_SHORT; - - if (NEEDS_COMPONENT (format->format)) - glitz_surface_set_component_alpha (mask, 1); - - pTexture->pMask = xglCreateDevicePicture (mask); - if (!pTexture->pMask) - return FALSE; - - vertex = &pCache->u.texture.format.vertex; - vertex->primitive = GLITZ_PRIMITIVE_QUADS; - vertex->mask.size = GLITZ_COORDINATE_SIZE_XY; - vertex->attributes = GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK; - - if (pTexture->geometryDataType == GEOMETRY_DATA_TYPE_FLOAT) - { - vertex->type = GLITZ_DATA_TYPE_FLOAT; - vertex->bytes_per_vertex = sizeof (glitz_float_t) * 4; - vertex->mask.offset = sizeof (glitz_float_t) * 2; - vertex->mask.type = GLITZ_DATA_TYPE_FLOAT; - } - else - { - vertex->type = GLITZ_DATA_TYPE_SHORT; - vertex->bytes_per_vertex = sizeof (glitz_short_t) * 4; - vertex->mask.offset = sizeof (glitz_short_t) * 2; - vertex->mask.type = GLITZ_DATA_TYPE_SHORT; - } - - pTexture->pixel.fourcc = GLITZ_FOURCC_RGB; - pTexture->pixel.masks = pVisual->pPixel->masks; - pTexture->pixel.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP; - pTexture->pixel.bytes_per_line = 0; - pTexture->pixel.xoffset = 0; - pTexture->pixel.skip_lines = 0; - } - - pCache->pScreen = pScreen; - - return TRUE; -} - -void -xglFiniGlyphCache (xglGlyphCachePtr pCache) -{ - if (pCache->pScreen) - { - xglRootAreaFini (&pCache->rootArea); - - if (pCache->depth == 1) - { - GEOMETRY_UNINIT (&pCache->u.geometry); - } - else - { - if (pCache->u.texture.pMask) - FreePicture ((pointer) pCache->u.texture.pMask, 0); - } - - pCache->pScreen = NULL; - } -} - -static xglAreaPtr -xglCacheGlyph (xglGlyphCachePtr pCache, - GlyphPtr pGlyph) -{ - ScreenPtr pScreen = pCache->pScreen; - - XGL_GLYPH_PRIV (pScreen, pGlyph); - - if (pCache->depth == 1) - { - PixmapPtr pPixmap; - RegionPtr pRegion; - int nBox; - - pPixmap = GetScratchPixmapHeader (pScreen, - pGlyph->info.width, - pGlyph->info.height, - pCache->depth, pCache->depth, 0, - (pointer) (pGlyph + 1)); - if (!pPixmap) - return NULL; - - (*pScreen->ModifyPixmapHeader) (pPixmap, - pGlyph->info.width, - pGlyph->info.height, - 0, 0, -1, (pointer) (pGlyph + 1)); - - pRegion = (*pScreen->BitmapToRegion) (pPixmap); - FreeScratchPixmapHeader (pPixmap); - - if (!pRegion) - return NULL; - - nBox = REGION_NUM_RECTS (pRegion); - if (nBox > BITMAP_CACHE_MAX_SIZE) - { - REGION_DESTROY (pScreen, pRegion); - return NULL; - } - - if (nBox > 0) - { - /* Find available area */ - if (!xglFindArea (pCache->rootArea.pArea, nBox, 0, - FALSE, (pointer) pGlyph)) - { - /* Kicking out area with lower score */ - xglFindArea (pCache->rootArea.pArea, nBox, 0, - TRUE, (pointer) pGlyph); - } - - if (pGlyphPriv->pArea) - { - int stride; - - GLYPH_AREA_PRIV (pGlyphPriv->pArea); - - pAreaPriv->serial = glyphSerialNumber; - pAreaPriv->u.range.first = pGlyphPriv->pArea->x * 4; - pAreaPriv->u.range.count = nBox * 4; - - stride = pCache->u.geometry.f.vertex.bytes_per_vertex; - GEOMETRY_ADD_REGION_AT (pScreen, &pCache->u.geometry, pRegion, - pGlyphPriv->pArea->x * stride * 4); - } - } else - pGlyphPriv->pArea = &zeroSizeArea; - - REGION_DESTROY (pScreen, pRegion); - } - else - { - xglGlyphTexturePtr pTexture = &pCache->u.texture; - - if (pGlyph->info.width > TEXTURE_CACHE_MAX_WIDTH || - pGlyph->info.height > TEXTURE_CACHE_MAX_HEIGHT) - return NULL; - - if (pGlyph->info.width > 0 && pGlyph->info.height > 0) - { - glitz_buffer_t *buffer; - - buffer = glitz_buffer_create_for_data (pGlyph + 1); - if (!buffer) - return NULL; - - /* Find available area */ - if (!xglFindArea (pCache->rootArea.pArea, - pGlyph->info.width, pGlyph->info.height, - FALSE, (pointer) pGlyph)) - { - /* Kicking out area with lower score */ - xglFindArea (pCache->rootArea.pArea, - pGlyph->info.width, pGlyph->info.height, - TRUE, (pointer) pGlyph); - } - - if (pGlyphPriv->pArea) - { - glitz_surface_t *surface; - glitz_point_fixed_t p1, p2; - glitz_pixel_format_t pixel; - - GLYPH_AREA_PRIV (pGlyphPriv->pArea); - - pixel = pTexture->pixel; - pixel.bytes_per_line = - PixmapBytePad (pGlyph->info.width, pCache->depth); - - surface = pTexture->pMask->pSourcePict->source.devPrivate.ptr; - - glitz_set_pixels (surface, - pGlyphPriv->pArea->x, - pGlyphPriv->pArea->y, - pGlyph->info.width, - pGlyph->info.height, - &pixel, - buffer); - - p1.x = pGlyphPriv->pArea->x << 16; - p1.y = pGlyphPriv->pArea->y << 16; - p2.x = (pGlyphPriv->pArea->x + pGlyph->info.width) << 16; - p2.y = (pGlyphPriv->pArea->y + pGlyph->info.height) << 16; - - glitz_surface_translate_point (surface, &p1, &p1); - glitz_surface_translate_point (surface, &p2, &p2); - - pAreaPriv->serial = glyphSerialNumber; - if (pTexture->geometryDataType) - { - pAreaPriv->u.box.fBox.x1 = FIXED_TO_FLOAT (p1.x); - pAreaPriv->u.box.fBox.y1 = FIXED_TO_FLOAT (p1.y); - pAreaPriv->u.box.fBox.x2 = FIXED_TO_FLOAT (p2.x); - pAreaPriv->u.box.fBox.y2 = FIXED_TO_FLOAT (p2.y); - } - else - { - pAreaPriv->u.box.sBox.x1 = p1.x >> 16; - pAreaPriv->u.box.sBox.y1 = p1.y >> 16; - pAreaPriv->u.box.sBox.x2 = p2.x >> 16; - pAreaPriv->u.box.sBox.y2 = p2.y >> 16; - } - } - glitz_buffer_destroy (buffer); - } else - pGlyphPriv->pArea = &zeroSizeArea; - } - - return pGlyphPriv->pArea; -} - -static void -xglUncachedGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - xglGlyphOpPtr pOp) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PicturePtr pPicture = NULL; - PixmapPtr pPixmap = NULL; - xglGlyphCachePtr pCache; - int depth = pOp->pLists->format->depth; - GlyphPtr glyph; - INT16 xOff, yOff; - xglGlyphPtr pGlyphPriv; - xglAreaPtr pArea; - Bool usingCache = !pOp->noCache; - - XGL_SCREEN_PRIV (pScreen); - - pCache = &pScreenPriv->glyphCache[depth]; - if (usingCache) - { - if (!pCache->pScreen) - { - if (!xglInitGlyphCache (pCache, pScreen, pOp->pLists->format)) - usingCache = FALSE; - } - } - - while (pOp->nGlyphs) - { - glyph = *pOp->ppGlyphs; - - if (!pOp->listLen) - { - pOp->pLists++; - pOp->listLen = pOp->pLists->len; - pOp->xOff += pOp->pLists->xOff; - pOp->yOff += pOp->pLists->yOff; - } - - xOff = pOp->xOff; - yOff = pOp->yOff; - - if (usingCache) - { - pGlyphPriv = XGL_GET_GLYPH_PRIV (pScreen, glyph); - pArea = pGlyphPriv->pArea; - if (pSrc) - { - if (!pArea) - pArea = xglCacheGlyph (pCache, glyph); - - if (pArea) - break; - } - } else - pArea = NULL; - - pOp->listLen--; - pOp->nGlyphs--; - pOp->ppGlyphs++; - - pOp->xOff += glyph->info.xOff; - pOp->yOff += glyph->info.yOff; - - if (pArea) - continue; - - if (!pPicture) - { - XID componentAlpha; - int error; - - pPixmap = GetScratchPixmapHeader (pScreen, - glyph->info.width, - glyph->info.height, - depth, depth, - 0, (pointer) (glyph + 1)); - if (!pPixmap) - return; - - componentAlpha = NEEDS_COMPONENT (pOp->pLists->format->format); - pPicture = CreatePicture (0, &pPixmap->drawable, - pOp->pLists->format, - CPComponentAlpha, &componentAlpha, - serverClient, &error); - if (!pPicture) - { - FreeScratchPixmapHeader (pPixmap); - return; - } - } - - (*pScreen->ModifyPixmapHeader) (pPixmap, - glyph->info.width, glyph->info.height, - 0, 0, -1, (pointer) (glyph + 1)); - pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - - if (pSrc) - CompositePicture (op, - pSrc, - pPicture, - pDst, - xSrc + (xOff - glyph->info.x), - ySrc + (yOff - glyph->info.y), - 0, 0, - xOff - glyph->info.x, - yOff - glyph->info.y, - glyph->info.width, - glyph->info.height); - else - CompositePicture (PictOpAdd, - pPicture, - NULL, - pDst, - 0, 0, - 0, 0, - xOff - glyph->info.x, - yOff - glyph->info.y, - glyph->info.width, - glyph->info.height); - } - - if (pPicture) - { - FreeScratchPixmapHeader (pPixmap); - FreePicture ((pointer) pPicture, 0); - } -} - -static Bool -xglCachedGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - xglGlyphOpPtr pOp) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; - xglGlyphOpRec opSave = *pOp; - xglGlyphCachePtr pCache; - xglGlyphVertexDataRec vData; - xglGeometryPtr pGeometry; - GlyphPtr glyph; - xglGlyphPtr pGlyphPriv; - xglAreaPtr pArea; - xglGlyphAreaPtr pGlyphArea; - BoxRec extents; - INT16 xOff, yOff, x1, x2, y1, y2; - int depth = pOp->pLists->format->depth; - int i, remaining = pOp->nGlyphs; - int nGlyph = 0; - PicturePtr pMaskPicture = NULL; - - XGL_SCREEN_PRIV (pScreen); - - pCache = &pScreenPriv->glyphCache[depth]; - if (!pCache->pScreen) - { - if (!xglInitGlyphCache (pCache, pScreen, pOp->pLists->format)) - { - pOp->noCache = TRUE; - return 1; - } - } - - /* update serial number for all glyphs already in cache so that - we don't accidentally replace one. */ - for (i = 0; i < pOp->nGlyphs; i++) - { - pGlyphPriv = XGL_GET_GLYPH_PRIV (pScreen, pOp->ppGlyphs[i]); - pArea = pGlyphPriv->pArea; - if (pArea && pArea->width) - GLYPH_GET_AREA_PRIV (pArea)->serial = glyphSerialNumber; - } - - for (i = 0; i < pOp->nGlyphs; i++) - { - pGlyphPriv = XGL_GET_GLYPH_PRIV (pScreen, pOp->ppGlyphs[i]); - pArea = pGlyphPriv->pArea; - if (!pArea) - pArea = xglCacheGlyph (pCache, pOp->ppGlyphs[i]); - - if (pArea) - { - if (pArea->width) - nGlyph++; - } - else if (pSrc) - break; - } - - if (nGlyph) - { - if (depth == 1) - { - glitz_multi_array_t *multiArray; - - pGeometry = &pCache->u.geometry; - pGeometry->xOff = pGeometry->yOff = 0; - - multiArray = glitz_multi_array_create (nGlyph); - if (!multiArray) - return 1; - - GEOMETRY_SET_MULTI_ARRAY (pGeometry, multiArray); - glitz_multi_array_destroy (multiArray); - - vData.array.lastX = 0; - vData.array.lastY = 0; - } - else - { - i = 4 * pCache->u.texture.format.vertex.bytes_per_vertex * nGlyph; - pGeometry = xglGetScratchGeometryWithSize (pScreen, i); - - pGeometry->f = pCache->u.texture.format; - pGeometry->type = GLITZ_GEOMETRY_TYPE_VERTEX; - pMaskPicture = pCache->u.texture.pMask; - - vData.list.s = glitz_buffer_map (pGeometry->buffer, - GLITZ_BUFFER_ACCESS_WRITE_ONLY); - } - } else - pGeometry = NULL; - - extents.x1 = MAXSHORT; - extents.y1 = MAXSHORT; - extents.x2 = MINSHORT; - extents.y2 = MINSHORT; - - while (pOp->nGlyphs) - { - glyph = *pOp->ppGlyphs; - - if (!pOp->listLen) - { - pOp->pLists++; - pOp->listLen = pOp->pLists->len; - pOp->xOff += pOp->pLists->xOff; - pOp->yOff += pOp->pLists->yOff; - } - - xOff = pOp->xOff; - yOff = pOp->yOff; - - pGlyphPriv = XGL_GET_GLYPH_PRIV (pScreen, glyph); - pArea = pGlyphPriv->pArea; - if (!pArea && pSrc) - break; - - pOp->listLen--; - pOp->nGlyphs--; - pOp->ppGlyphs++; - - pOp->xOff += glyph->info.xOff; - pOp->yOff += glyph->info.yOff; - - if (!pArea) - continue; - - x1 = xOff - glyph->info.x; - x2 = x1 + glyph->info.width; - if (x1 < extents.x1) - extents.x1 = x1; - if (x2 > extents.x2) - extents.x2 = x2; - - y1 = yOff - glyph->info.y; - y2 = y1 + glyph->info.height; - if (y1 < extents.y1) - extents.y1 = y1; - if (y2 > extents.y2) - extents.y2 = y2; - - if (pArea->width) - { - pGlyphArea = GLYPH_GET_AREA_PRIV (pArea); - if (depth == 1) - { - glitz_multi_array_add (pGeometry->array, - pGlyphArea->u.range.first, 2, - pGlyphArea->u.range.count, - (x1 - vData.array.lastX) << 16, - (y1 - vData.array.lastY) << 16); - vData.array.lastX = x1; - vData.array.lastY = y1; - } - else - { - if (pCache->u.texture.geometryDataType) - { - WRITE_BOX (vData.list.f, x1, y1, x2, y2, - pGlyphArea->u.box.fBox); - } - else - { - WRITE_BOX (vData.list.s, x1, y1, x2, y2, - pGlyphArea->u.box.sBox); - } - } - } - remaining--; - } - - NEXT_GLYPH_SERIAL_NUMBER; - - if (nGlyph) - { - if (depth != 1) - { - glitz_buffer_unmap (pGeometry->buffer); - pGeometry->count = nGlyph * 4; - } - - xSrc += extents.x1; - ySrc += extents.y1; - - if (!pSrc) - { - op = PictOpAdd; - pSrc = pScreenPriv->pSolidAlpha; - - if (remaining) - *pOp = opSave; - } - - GEOMETRY_TRANSLATE (pGeometry, - pDst->pDrawable->x, - pDst->pDrawable->y); - - if (xglCompositeGeneral (op, - pSrc, - pMaskPicture, - pDst, - pGeometry, - xSrc, ySrc, - 0, 0, - pDst->pDrawable->x + extents.x1, - pDst->pDrawable->y + extents.y1, - extents.x2 - extents.x1, - extents.y2 - extents.y1)) - { - xglAddCurrentBitDamage (pDst->pDrawable); - return remaining; - } - - remaining = ~0; - *pOp = opSave; - pOp->noCache = TRUE; - } - else - { - if (remaining) - { - *pOp = opSave; - pOp->noCache = TRUE; - } - } - - return remaining; -} - -static Bool -xglGlyphExtents (PicturePtr pDst, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs, - BoxPtr extents) -{ - GlyphPtr glyph; - BoxRec line; - int x1, x2, y1, y2; - int n; - int x; - int y; - Bool overlap = FALSE; - - x = 0; - y = 0; - - extents->x1 = MAXSHORT; - extents->x2 = MINSHORT; - extents->y1 = MAXSHORT; - extents->y2 = MINSHORT; - - while (!list->len) - { - if (--nlist) - { - x += list->xOff; - y += list->yOff; - list++; - } - else - { - return FALSE; - } - } - - glyph = *glyphs; - x1 = (x + list->xOff) - glyph->info.x; - if (x1 < MINSHORT) - x1 = MINSHORT; - y1 = (y + list->yOff) - glyph->info.y; - if (y1 < MINSHORT) - y1 = MINSHORT; - - line.x1 = x1; - line.x2 = x1; - line.y1 = y1; - line.y2 = y1; - - 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 >= line.x2) - { - line.x2 = x2; - if (y1 < line.y1) - line.y1 = y1; - if (y2 > line.y2) - line.y2 = y2; - } - else if (x2 <= line.x1) - { - line.x1 = x1; - if (y1 < line.y1) - line.y1 = y1; - if (y2 > line.y2) - line.y2 = y2; - } - else - { - if (line.y1 >= extents->y2) - { - extents->y2 = line.y2; - if (line.y1 < extents->y1) - extents->y1 = line.y1; - } - else if (line.y2 <= extents->y1) - { - extents->y1 = line.y1; - if (line.y2 > extents->y2) - extents->y2 = line.y2; - } - else - { - if (line.y1 < extents->y1) - extents->y1 = line.y1; - if (line.y2 > extents->y2) - extents->y2 = line.y2; - - overlap = TRUE; - } - - if (line.x1 < extents->x1) - extents->x1 = line.x1; - if (line.x2 > extents->x2) - extents->x2 = line.x2; - - line.x1 = x1; - line.y1 = y1; - line.x2 = x2; - line.y2 = y2; - } - - x += glyph->info.xOff; - y += glyph->info.yOff; - } - } - - if (line.y1 >= extents->y2) - { - extents->y2 = line.y2; - if (line.y1 < extents->y1) - extents->y1 = line.y1; - } - else if (line.y2 <= extents->y1) - { - extents->y1 = line.y1; - if (line.y2 > extents->y2) - extents->y2 = line.y2; - } - else - { - if (line.y1 < extents->y1) - extents->y1 = line.y1; - if (line.y2 > extents->y2) - extents->y2 = line.y2; - - overlap = TRUE; - } - - if (line.x1 < extents->x1) - extents->x1 = line.x1; - if (line.x2 > extents->x2) - extents->x2 = line.x2; - - xglPictureClipExtents (pDst, extents); - - return overlap; -} - -/* returns 0 if all glyph lists don't have the same format */ -static CARD32 -xglGlyphListFormatId (GlyphListPtr list, - int nlist) -{ - CARD32 id = list->format->id; - - nlist--; - list++; - - while (nlist--) - { - if (list->format->id != id) - return 0; - - list++; - } - - return id; -} - -void -xglGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PicturePtr pMask = NULL, pSrcPicture, pDstPicture; - BoxRec extents; - xglGlyphOpRec glyphOp; - int xDst = list->xOff, yDst = list->yOff; - int overlap; - int target; - - overlap = xglGlyphExtents (pDst, nlist, list, glyphs, &extents); - if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) - return; - - target = xglPrepareTarget (pDst->pDrawable); - - if (op != PictOpAdd && maskFormat && - (!target || overlap || op != PictOpOver || - xglGlyphListFormatId (list, nlist) != maskFormat->id)) - { - PixmapPtr pPixmap; - XID componentAlpha; - GCPtr pGC; - xRectangle rect; - int error; - - rect.x = 0; - rect.y = 0; - rect.width = extents.x2 - extents.x1; - rect.height = extents.y2 - extents.y1; - - pPixmap = (*pScreen->CreatePixmap) (pScreen, - rect.width, rect.height, - maskFormat->depth, - CREATE_PIXMAP_USAGE_SCRATCH); - if (!pPixmap) - return; - - componentAlpha = NEEDS_COMPONENT (maskFormat->format); - pMask = CreatePicture (0, &pPixmap->drawable, - maskFormat, CPComponentAlpha, &componentAlpha, - serverClient, &error); - if (!pMask) - { - (*pScreen->DestroyPixmap) (pPixmap); - return; - } - - if (!target) - { - /* make sure we don't do accelerated drawing to mask */ - xglSetPixmapVisual (pPixmap, NULL); - } - - ValidatePicture (pMask); - pGC = GetScratchGC (pPixmap->drawable.depth, pScreen); - ValidateGC (&pPixmap->drawable, pGC); - (*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &rect); - FreeScratchGC (pGC); - - (*pScreen->DestroyPixmap) (pPixmap); - - target = xglPrepareTarget (pMask->pDrawable); - - glyphOp.xOff = -extents.x1; - glyphOp.yOff = -extents.y1; - pSrcPicture = NULL; - pDstPicture = pMask; - } - else - { - glyphOp.xOff = 0; - glyphOp.yOff = 0; - pSrcPicture = pSrc; - pDstPicture = pDst; - } - - glyphOp.ppGlyphs = glyphs; - glyphOp.noCache = !target; - - while (nlist--) - { - glyphOp.xOff += list->xOff; - glyphOp.yOff += list->yOff; - glyphOp.listLen = list->len; - glyphOp.nGlyphs = list->len; - glyphOp.pLists = list++; - - for (; nlist; nlist--, list++) - { - if (list->format->id != glyphOp.pLists->format->id) - break; - - glyphOp.nGlyphs += list->len; - } - - while (glyphOp.nGlyphs) - { - if (glyphOp.noCache || xglCachedGlyphs (op, - pSrcPicture, - pDstPicture, - xSrc - xDst, ySrc - yDst, - &glyphOp)) - xglUncachedGlyphs (op, - pSrcPicture, - pDstPicture, - xSrc - xDst, ySrc - yDst, - &glyphOp); - } - } - - if (pMask) - { - CompositePicture (op, pSrc, pMask, pDst, - xSrc + extents.x1 - xDst, - ySrc + extents.y1 - yDst, - 0, 0, - extents.x1, extents.y1, - extents.x2 - extents.x1, - extents.y2 - extents.y1); - - FreePicture ((pointer) pMask, (XID) 0); - } -} - -#endif |