aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xgl/xglglyph.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xgl/xglglyph.c')
-rw-r--r--xorg-server/hw/xgl/xglglyph.c1170
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