743 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			743 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Copyright © 2004 David Reveman
 | 
						|
 *
 | 
						|
 * 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
 | 
						|
 * David Reveman not be used in advertising or publicity pertaining to
 | 
						|
 * distribution of the software without specific, written prior permission.
 | 
						|
 * David Reveman makes no representations about the suitability of this
 | 
						|
 * software for any purpose. It is provided "as is" without express or
 | 
						|
 * implied warranty.
 | 
						|
 *
 | 
						|
 * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
						|
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
 | 
						|
 * NO EVENT SHALL DAVID REVEMAN 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"
 | 
						|
#include "gcstruct.h"
 | 
						|
#include "fb.h"
 | 
						|
 | 
						|
Bool
 | 
						|
xglFill (DrawablePtr	pDrawable,
 | 
						|
	 GCPtr		pGC,
 | 
						|
	 xglGeometryPtr pGeometry,
 | 
						|
	 int		x,
 | 
						|
	 int		y,
 | 
						|
	 int		width,
 | 
						|
	 int		height,
 | 
						|
	 BoxPtr		pBox,
 | 
						|
	 int		nBox)
 | 
						|
{
 | 
						|
    XGL_GC_PRIV (pGC);
 | 
						|
 | 
						|
    switch (pGC->fillStyle) {
 | 
						|
    case FillSolid:
 | 
						|
	if (xglSolid (pDrawable,
 | 
						|
		      pGCPriv->op, pGCPriv->fg,
 | 
						|
		      pGeometry,
 | 
						|
		      x, y,
 | 
						|
		      width, height,
 | 
						|
		      pBox, nBox))
 | 
						|
	    return TRUE;
 | 
						|
	break;
 | 
						|
    case FillStippled:
 | 
						|
    case FillOpaqueStippled:
 | 
						|
	break;
 | 
						|
    case FillTiled:
 | 
						|
	if (xglTile (pDrawable,
 | 
						|
		     pGCPriv->op, pGC->tile.pixmap,
 | 
						|
		     -(pGC->patOrg.x + pDrawable->x),
 | 
						|
		     -(pGC->patOrg.y + pDrawable->y),
 | 
						|
		     pGeometry,
 | 
						|
		     x, y,
 | 
						|
		     width, height,
 | 
						|
		     pBox, nBox))
 | 
						|
	    return TRUE;
 | 
						|
	break;
 | 
						|
    }
 | 
						|
 | 
						|
    return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
xglFillBox (DrawablePtr pDrawable,
 | 
						|
	    GCPtr	pGC,
 | 
						|
	    int		x,
 | 
						|
	    int		y,
 | 
						|
	    int		width,
 | 
						|
	    int		height,
 | 
						|
	    BoxPtr	pBox,
 | 
						|
	    int		nBox)
 | 
						|
{
 | 
						|
    if (!nBox)
 | 
						|
	return;
 | 
						|
 | 
						|
    if (!xglFill (pDrawable, pGC, NULL, x, y, width, height, pBox, nBox))
 | 
						|
    {
 | 
						|
	RegionRec region;
 | 
						|
 | 
						|
	XGL_DRAWABLE_PIXMAP (pDrawable);
 | 
						|
	XGL_PIXMAP_PRIV (pPixmap);
 | 
						|
 | 
						|
	if (!xglMapPixmapBits (pPixmap))
 | 
						|
	    FatalError (XGL_SW_FAILURE_STRING);
 | 
						|
 | 
						|
	switch (pGC->fillStyle) {
 | 
						|
	case FillSolid:
 | 
						|
	    break;
 | 
						|
	case FillStippled:
 | 
						|
	case FillOpaqueStippled:
 | 
						|
	    if (!xglSyncBits (&pGC->stipple->drawable, NullBox))
 | 
						|
		FatalError (XGL_SW_FAILURE_STRING);
 | 
						|
	    break;
 | 
						|
	case FillTiled:
 | 
						|
	    if (!xglSyncBits (&pGC->tile.pixmap->drawable, NullBox))
 | 
						|
		FatalError (XGL_SW_FAILURE_STRING);
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
 | 
						|
	pPixmapPriv->damageBox = miEmptyBox;
 | 
						|
 | 
						|
	while (nBox--)
 | 
						|
	{
 | 
						|
	    fbFill (pDrawable, pGC,
 | 
						|
		    pBox->x1, pBox->y1,
 | 
						|
		    pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
 | 
						|
 | 
						|
	    REGION_INIT (pDrawable->pScreen, ®ion, pBox, 1);
 | 
						|
	    xglAddSurfaceDamage (pDrawable, ®ion);
 | 
						|
	    REGION_UNINIT (pDrawable->pScreen, ®ion);
 | 
						|
 | 
						|
	    pBox++;
 | 
						|
	}
 | 
						|
    } else
 | 
						|
	xglAddCurrentBitDamage (pDrawable);
 | 
						|
}
 | 
						|
 | 
						|
#define N_STACK_BOX 1024
 | 
						|
 | 
						|
static BoxPtr
 | 
						|
xglMoreBoxes (BoxPtr stackBox,
 | 
						|
	      BoxPtr heapBox,
 | 
						|
	      int    nBoxes)
 | 
						|
{
 | 
						|
    Bool stack = !heapBox;
 | 
						|
 | 
						|
    heapBox = xrealloc (heapBox, sizeof (BoxRec) * nBoxes);
 | 
						|
    if (!heapBox)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
    if (stack)
 | 
						|
	memcpy (heapBox, stackBox, sizeof (BoxRec) * N_STACK_BOX);
 | 
						|
 | 
						|
    return heapBox;
 | 
						|
}
 | 
						|
 | 
						|
#define ADD_BOX(pBox, nBox, stackBox, heapBox, size, box)	\
 | 
						|
    {								\
 | 
						|
	if ((nBox) == (size))					\
 | 
						|
	{							\
 | 
						|
	    (size) *= 2;					\
 | 
						|
	    (heapBox) = xglMoreBoxes (stackBox, heapBox, size);	\
 | 
						|
	    if (heapBox)					\
 | 
						|
	    {							\
 | 
						|
		(pBox) = (heapBox) + (nBox);			\
 | 
						|
		*(pBox)++ = (box);				\
 | 
						|
		(nBox)++;					\
 | 
						|
	    }							\
 | 
						|
	}							\
 | 
						|
	else							\
 | 
						|
	{							\
 | 
						|
	    *(pBox)++ = (box);					\
 | 
						|
	    (nBox)++;						\
 | 
						|
	}							\
 | 
						|
    }
 | 
						|
 | 
						|
void
 | 
						|
xglFillRect (DrawablePtr pDrawable,
 | 
						|
	     GCPtr	 pGC,
 | 
						|
	     int	 nrect,
 | 
						|
	     xRectangle  *prect)
 | 
						|
{
 | 
						|
    RegionPtr pClip = pGC->pCompositeClip;
 | 
						|
    BoxPtr    pClipBox;
 | 
						|
    BoxPtr    pExtent = REGION_EXTENTS (pGC->pScreen, pClip);
 | 
						|
    BoxRec    part, full;
 | 
						|
    BoxPtr    heapBox = NULL;
 | 
						|
    BoxRec    stackBox[N_STACK_BOX];
 | 
						|
    int       size = N_STACK_BOX;
 | 
						|
    BoxPtr    pBox = stackBox;
 | 
						|
    int	      nClip, nBox = 0;
 | 
						|
 | 
						|
    while (nrect--)
 | 
						|
    {
 | 
						|
	full.x1 = prect->x + pDrawable->x;
 | 
						|
	full.y1 = prect->y + pDrawable->y;
 | 
						|
	full.x2 = full.x1 + (int) prect->width;
 | 
						|
	full.y2 = full.y1 + (int) prect->height;
 | 
						|
 | 
						|
	prect++;
 | 
						|
 | 
						|
	if (full.x1 < pExtent->x1)
 | 
						|
	    full.x1 = pExtent->x1;
 | 
						|
	if (full.y1 < pExtent->y1)
 | 
						|
	    full.y1 = pExtent->y1;
 | 
						|
	if (full.x2 > pExtent->x2)
 | 
						|
	    full.x2 = pExtent->x2;
 | 
						|
	if (full.y2 > pExtent->y2)
 | 
						|
	    full.y2 = pExtent->y2;
 | 
						|
 | 
						|
	if (full.x1 >= full.x2 || full.y1 >= full.y2)
 | 
						|
	    continue;
 | 
						|
 | 
						|
	nClip = REGION_NUM_RECTS (pClip);
 | 
						|
	if (nClip == 1)
 | 
						|
	{
 | 
						|
	    ADD_BOX (pBox, nBox, stackBox, heapBox, size, full);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
	    pClipBox = REGION_RECTS (pClip);
 | 
						|
	    while (nClip--)
 | 
						|
	    {
 | 
						|
		part = *pClipBox++;
 | 
						|
 | 
						|
		if (part.x1 < full.x1)
 | 
						|
		    part.x1 = full.x1;
 | 
						|
		if (part.y1 < full.y1)
 | 
						|
		    part.y1 = full.y1;
 | 
						|
		if (part.x2 > full.x2)
 | 
						|
		    part.x2 = full.x2;
 | 
						|
		if (part.y2 > full.y2)
 | 
						|
		    part.y2 = full.y2;
 | 
						|
 | 
						|
		if (part.x1 < part.x2 && part.y1 < part.y2)
 | 
						|
		    ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    xglFillBox (pDrawable, pGC,
 | 
						|
		pExtent->x1, pExtent->y1,
 | 
						|
		pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
 | 
						|
		(heapBox) ? heapBox : stackBox, nBox);
 | 
						|
 | 
						|
    if (heapBox)
 | 
						|
	xfree (heapBox);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
xglFillSpan (DrawablePtr pDrawable,
 | 
						|
	     GCPtr	 pGC,
 | 
						|
	     int	 n,
 | 
						|
	     DDXPointPtr ppt,
 | 
						|
	     int	 *pwidth)
 | 
						|
{
 | 
						|
    RegionPtr pClip = pGC->pCompositeClip;
 | 
						|
    BoxPtr    pClipBox;
 | 
						|
    BoxPtr    pExtent = REGION_EXTENTS (pGC->pScreen, pClip);
 | 
						|
    BoxRec    part, full;
 | 
						|
    BoxPtr    heapBox = NULL;
 | 
						|
    BoxRec    stackBox[N_STACK_BOX];
 | 
						|
    int       size = N_STACK_BOX;
 | 
						|
    BoxPtr    pBox = stackBox;
 | 
						|
    int	      nClip, nBox = 0;
 | 
						|
 | 
						|
    while (n--)
 | 
						|
    {
 | 
						|
	full.x1 = ppt->x;
 | 
						|
	full.y1 = ppt->y;
 | 
						|
	full.x2 = full.x1 + *pwidth;
 | 
						|
	full.y2 = full.y1 + 1;
 | 
						|
 | 
						|
	pwidth++;
 | 
						|
	ppt++;
 | 
						|
 | 
						|
	if (full.x1 < pExtent->x1)
 | 
						|
	    full.x1 = pExtent->x1;
 | 
						|
	if (full.y1 < pExtent->y1)
 | 
						|
	    full.y1 = pExtent->y1;
 | 
						|
	if (full.x2 > pExtent->x2)
 | 
						|
	    full.x2 = pExtent->x2;
 | 
						|
	if (full.y2 > pExtent->y2)
 | 
						|
	    full.y2 = pExtent->y2;
 | 
						|
 | 
						|
	if (full.x1 >= full.x2 || full.y1 >= full.y2)
 | 
						|
	    continue;
 | 
						|
 | 
						|
	nClip = REGION_NUM_RECTS (pClip);
 | 
						|
	if (nClip == 1)
 | 
						|
	{
 | 
						|
	    ADD_BOX (pBox, nBox, stackBox, heapBox, size, full);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
	    pClipBox = REGION_RECTS (pClip);
 | 
						|
	    while (nClip--)
 | 
						|
	    {
 | 
						|
		part = *pClipBox++;
 | 
						|
 | 
						|
		if (part.x1 < full.x1)
 | 
						|
		    part.x1 = full.x1;
 | 
						|
		if (part.y1 < full.y1)
 | 
						|
		    part.y1 = full.y1;
 | 
						|
		if (part.x2 > full.x2)
 | 
						|
		    part.x2 = full.x2;
 | 
						|
		if (part.y2 > full.y2)
 | 
						|
		    part.y2 = full.y2;
 | 
						|
 | 
						|
		if (part.x1 < part.x2 && part.y1 < part.y2)
 | 
						|
		    ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    xglFillBox (pDrawable, pGC,
 | 
						|
		pExtent->x1, pExtent->y1,
 | 
						|
		pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
 | 
						|
		(heapBox) ? heapBox : stackBox, nBox);
 | 
						|
 | 
						|
    if (heapBox)
 | 
						|
	xfree (heapBox);
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
xglFillLine (DrawablePtr pDrawable,
 | 
						|
	     GCPtr       pGC,
 | 
						|
	     int	 mode,
 | 
						|
	     int	 npt,
 | 
						|
	     DDXPointPtr ppt)
 | 
						|
{
 | 
						|
    RegionPtr	   pClip = pGC->pCompositeClip;
 | 
						|
    BoxPtr	   pExtent = REGION_EXTENTS (pGC->pScreen, pClip);
 | 
						|
    Bool	   coincidentEndpoints = FALSE;
 | 
						|
    Bool	   horizontalAndVertical = TRUE;
 | 
						|
    DDXPointPtr    pptTmp;
 | 
						|
    int		   nptTmp;
 | 
						|
    DDXPointRec    pt;
 | 
						|
    xglGeometryPtr pGeometry;
 | 
						|
 | 
						|
    XGL_SCREEN_PRIV (pGC->pScreen);
 | 
						|
 | 
						|
    if (npt < 2)
 | 
						|
	return TRUE;
 | 
						|
 | 
						|
    pt = *ppt;
 | 
						|
 | 
						|
    nptTmp = npt - 1;
 | 
						|
    pptTmp = ppt + 1;
 | 
						|
 | 
						|
    if (mode == CoordModePrevious)
 | 
						|
    {
 | 
						|
	while (nptTmp--)
 | 
						|
	{
 | 
						|
	    if (pptTmp->x && pptTmp->y)
 | 
						|
		horizontalAndVertical = FALSE;
 | 
						|
 | 
						|
	    pt.x += pptTmp->x;
 | 
						|
	    pt.y += pptTmp->y;
 | 
						|
 | 
						|
	    pptTmp++;
 | 
						|
	}
 | 
						|
 | 
						|
	if (pt.x == ppt->x && pt.y == ppt->y)
 | 
						|
	    coincidentEndpoints = TRUE;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
	while (nptTmp--)
 | 
						|
	{
 | 
						|
	    if (pptTmp->x != pt.x && pptTmp->y != pt.y)
 | 
						|
	    {
 | 
						|
		horizontalAndVertical = FALSE;
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
 | 
						|
	    pt = *pptTmp++;
 | 
						|
	}
 | 
						|
 | 
						|
	if (ppt[npt - 1].x == ppt->x && ppt[npt - 1].y == ppt->y)
 | 
						|
	    coincidentEndpoints = TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
    if (horizontalAndVertical)
 | 
						|
    {
 | 
						|
	BoxPtr pClipBox;
 | 
						|
	BoxRec part, full;
 | 
						|
	BoxPtr heapBox = NULL;
 | 
						|
	BoxRec stackBox[N_STACK_BOX];
 | 
						|
	int    size = N_STACK_BOX;
 | 
						|
	BoxPtr pBox = stackBox;
 | 
						|
	int    nClip, nBox = 0;
 | 
						|
	int    dx, dy;
 | 
						|
 | 
						|
	pt = *ppt;
 | 
						|
 | 
						|
	ppt++;
 | 
						|
	npt--;
 | 
						|
 | 
						|
	while (npt--)
 | 
						|
	{
 | 
						|
	    if (mode == CoordModePrevious)
 | 
						|
	    {
 | 
						|
		dx = ppt->x;
 | 
						|
		dy = ppt->y;
 | 
						|
	    }
 | 
						|
	    else
 | 
						|
	    {
 | 
						|
		dx = ppt->x - pt.x;
 | 
						|
		dy = ppt->y - pt.y;
 | 
						|
	    }
 | 
						|
 | 
						|
	    if (dx)
 | 
						|
	    {
 | 
						|
		if (dx > 0)
 | 
						|
		{
 | 
						|
		    full.x1 = pt.x + pDrawable->x;
 | 
						|
 | 
						|
		    if (npt || coincidentEndpoints)
 | 
						|
			full.x2 = full.x1 + dx;
 | 
						|
		    else
 | 
						|
			full.x2 = full.x1 + dx + 1;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
		    full.x2 = pt.x + pDrawable->x + 1;
 | 
						|
 | 
						|
		    if (npt || coincidentEndpoints)
 | 
						|
			full.x1 = full.x2 + dx;
 | 
						|
		    else
 | 
						|
			full.x1 = full.x2 + dx - 1;
 | 
						|
		}
 | 
						|
 | 
						|
		full.y1 = pt.y + pDrawable->y;
 | 
						|
		full.y2 = full.y1 + 1;
 | 
						|
	    }
 | 
						|
	    else
 | 
						|
	    {
 | 
						|
		if (dy > 0)
 | 
						|
		{
 | 
						|
		    full.y1 = pt.y + pDrawable->y;
 | 
						|
 | 
						|
		    if (npt || coincidentEndpoints)
 | 
						|
			full.y2 = full.y1 + dy;
 | 
						|
		    else
 | 
						|
			full.y2 = full.y1 + dy + 1;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
		    full.y2 = pt.y + pDrawable->y + 1;
 | 
						|
 | 
						|
		    if (npt || coincidentEndpoints)
 | 
						|
			full.y1 = full.y2 + dy;
 | 
						|
		    else
 | 
						|
			full.y1 = full.y2 + dy - 1;
 | 
						|
		}
 | 
						|
 | 
						|
		full.x1 = pt.x + pDrawable->x;
 | 
						|
		full.x2 = full.x1 + 1;
 | 
						|
	    }
 | 
						|
 | 
						|
	    pt.x += dx;
 | 
						|
	    pt.y += dy;
 | 
						|
 | 
						|
	    ppt++;
 | 
						|
 | 
						|
	    if (full.x1 < pExtent->x1)
 | 
						|
		full.x1 = pExtent->x1;
 | 
						|
	    if (full.y1 < pExtent->y1)
 | 
						|
		full.y1 = pExtent->y1;
 | 
						|
	    if (full.x2 > pExtent->x2)
 | 
						|
		full.x2 = pExtent->x2;
 | 
						|
	    if (full.y2 > pExtent->y2)
 | 
						|
		full.y2 = pExtent->y2;
 | 
						|
 | 
						|
	    if (full.x1 >= full.x2 || full.y1 >= full.y2)
 | 
						|
		continue;
 | 
						|
 | 
						|
	    nClip = REGION_NUM_RECTS (pClip);
 | 
						|
	    if (nClip == 1)
 | 
						|
	    {
 | 
						|
		ADD_BOX (pBox, nBox, stackBox, heapBox, size, full);
 | 
						|
	    }
 | 
						|
	    else
 | 
						|
	    {
 | 
						|
		pClipBox = REGION_RECTS (pClip);
 | 
						|
		while (nClip--)
 | 
						|
		{
 | 
						|
		    part = *pClipBox++;
 | 
						|
 | 
						|
		    if (part.x1 < full.x1)
 | 
						|
			part.x1 = full.x1;
 | 
						|
		    if (part.y1 < full.y1)
 | 
						|
			part.y1 = full.y1;
 | 
						|
		    if (part.x2 > full.x2)
 | 
						|
			part.x2 = full.x2;
 | 
						|
		    if (part.y2 > full.y2)
 | 
						|
			part.y2 = full.y2;
 | 
						|
 | 
						|
		    if (part.x1 < part.x2 && part.y1 < part.y2)
 | 
						|
			ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	}
 | 
						|
 | 
						|
	xglFillBox (pDrawable, pGC,
 | 
						|
		    pExtent->x1, pExtent->y1,
 | 
						|
		    pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
 | 
						|
		    (heapBox) ? heapBox : stackBox, nBox);
 | 
						|
 | 
						|
	if (heapBox)
 | 
						|
	    xfree (heapBox);
 | 
						|
 | 
						|
	return TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!pScreenPriv->lines)
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    if (coincidentEndpoints)
 | 
						|
	npt--;
 | 
						|
 | 
						|
    pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, npt);
 | 
						|
 | 
						|
    GEOMETRY_ADD_LINE (pGC->pScreen, pGeometry,
 | 
						|
		       coincidentEndpoints, mode, npt, ppt);
 | 
						|
 | 
						|
    if (coincidentEndpoints)
 | 
						|
	GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINE_LOOP);
 | 
						|
    else
 | 
						|
	GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINE_STRIP);
 | 
						|
 | 
						|
    /* Lines need a 0.5 translate */
 | 
						|
    GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);
 | 
						|
 | 
						|
    GEOMETRY_TRANSLATE (pGeometry, pDrawable->x, pDrawable->y);
 | 
						|
 | 
						|
    pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
 | 
						|
 | 
						|
    if (xglFill (pDrawable, pGC, pGeometry,
 | 
						|
		 pExtent->x1, pExtent->y1,
 | 
						|
		 pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
 | 
						|
		 REGION_RECTS (pGC->pCompositeClip),
 | 
						|
		 REGION_NUM_RECTS (pGC->pCompositeClip)))
 | 
						|
    {
 | 
						|
	xglAddCurrentBitDamage (pDrawable);
 | 
						|
	return TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
    return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
xglFillSegment (DrawablePtr pDrawable,
 | 
						|
		GCPtr	    pGC,
 | 
						|
		int	    nSegInit,
 | 
						|
		xSegment    *pSegInit)
 | 
						|
{
 | 
						|
    RegionPtr	   pClip = pGC->pCompositeClip;
 | 
						|
    BoxPtr	   pExtent = REGION_EXTENTS (pGC->pScreen, pClip);
 | 
						|
    Bool	   horizontalAndVertical = TRUE;
 | 
						|
    xglGeometryPtr pGeometry;
 | 
						|
    xSegment	   *pSeg;
 | 
						|
    int		   nSeg;
 | 
						|
 | 
						|
    XGL_SCREEN_PRIV (pGC->pScreen);
 | 
						|
 | 
						|
    if (nSegInit < 1)
 | 
						|
	return TRUE;
 | 
						|
 | 
						|
    pSeg = pSegInit;
 | 
						|
    nSeg = nSegInit;
 | 
						|
    while (nSeg--)
 | 
						|
    {
 | 
						|
	if (pSeg->x1 != pSeg->x2 && pSeg->y1 != pSeg->y2)
 | 
						|
	    horizontalAndVertical = FALSE;
 | 
						|
 | 
						|
	pSeg++;
 | 
						|
    }
 | 
						|
 | 
						|
    if (horizontalAndVertical)
 | 
						|
    {
 | 
						|
	BoxPtr pClipBox;
 | 
						|
	BoxRec part, full;
 | 
						|
	BoxPtr heapBox = NULL;
 | 
						|
	BoxRec stackBox[N_STACK_BOX];
 | 
						|
	int    size = N_STACK_BOX;
 | 
						|
	BoxPtr pBox = stackBox;
 | 
						|
	int    nClip, nBox = 0;
 | 
						|
 | 
						|
	while (nSegInit--)
 | 
						|
	{
 | 
						|
	    if (pSegInit->x1 != pSegInit->x2)
 | 
						|
	    {
 | 
						|
		if (pSegInit->x1 < pSegInit->x2)
 | 
						|
		{
 | 
						|
		    full.x1 = pSegInit->x1;
 | 
						|
		    full.x2 = pSegInit->x2;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
		    full.x1 = pSegInit->x2;
 | 
						|
		    full.x2 = pSegInit->x1;
 | 
						|
		}
 | 
						|
 | 
						|
		full.x1 += pDrawable->x;
 | 
						|
		full.x2 += pDrawable->x + 1;
 | 
						|
		full.y1  = pSegInit->y1 + pDrawable->y;
 | 
						|
		full.y2  = full.y1 + 1;
 | 
						|
	    }
 | 
						|
	    else
 | 
						|
	    {
 | 
						|
		if (pSegInit->y1 < pSegInit->y2)
 | 
						|
		{
 | 
						|
		    full.y1 = pSegInit->y1;
 | 
						|
		    full.y2 = pSegInit->y2;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
		    full.y1 = pSegInit->y2;
 | 
						|
		    full.y2 = pSegInit->y1;
 | 
						|
		}
 | 
						|
 | 
						|
		full.y1 += pDrawable->y;
 | 
						|
		full.y2 += pDrawable->y + 1;
 | 
						|
		full.x1  = pSegInit->x1 + pDrawable->x;
 | 
						|
		full.x2  = full.x1 + 1;
 | 
						|
	    }
 | 
						|
 | 
						|
	    pSegInit++;
 | 
						|
 | 
						|
	    if (full.x1 < pExtent->x1)
 | 
						|
		full.x1 = pExtent->x1;
 | 
						|
	    if (full.y1 < pExtent->y1)
 | 
						|
		full.y1 = pExtent->y1;
 | 
						|
	    if (full.x2 > pExtent->x2)
 | 
						|
		full.x2 = pExtent->x2;
 | 
						|
	    if (full.y2 > pExtent->y2)
 | 
						|
		full.y2 = pExtent->y2;
 | 
						|
 | 
						|
	    if (full.x1 >= full.x2 || full.y1 >= full.y2)
 | 
						|
		continue;
 | 
						|
 | 
						|
	    nClip = REGION_NUM_RECTS (pClip);
 | 
						|
	    if (nClip == 1)
 | 
						|
	    {
 | 
						|
		ADD_BOX (pBox, nBox, stackBox, heapBox, size, full);
 | 
						|
	    }
 | 
						|
	    else
 | 
						|
	    {
 | 
						|
		pClipBox = REGION_RECTS (pClip);
 | 
						|
		while (nClip--)
 | 
						|
		{
 | 
						|
		    part = *pClipBox++;
 | 
						|
 | 
						|
		    if (part.x1 < full.x1)
 | 
						|
			part.x1 = full.x1;
 | 
						|
		    if (part.y1 < full.y1)
 | 
						|
			part.y1 = full.y1;
 | 
						|
		    if (part.x2 > full.x2)
 | 
						|
			part.x2 = full.x2;
 | 
						|
		    if (part.y2 > full.y2)
 | 
						|
			part.y2 = full.y2;
 | 
						|
 | 
						|
		    if (part.x1 < part.x2 && part.y1 < part.y2)
 | 
						|
			ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	}
 | 
						|
 | 
						|
	xglFillBox (pDrawable, pGC,
 | 
						|
		    pExtent->x1, pExtent->y1,
 | 
						|
		    pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
 | 
						|
		    (heapBox) ? heapBox : stackBox, nBox);
 | 
						|
 | 
						|
	if (heapBox)
 | 
						|
	    xfree (heapBox);
 | 
						|
 | 
						|
	return TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!pScreenPriv->lines)
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, 2 * nSegInit);
 | 
						|
 | 
						|
    GEOMETRY_ADD_SEGMENT (pGC->pScreen, pGeometry, nSegInit, pSegInit);
 | 
						|
 | 
						|
    /* Line segments need 0.5 translate */
 | 
						|
    GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);
 | 
						|
    GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINES);
 | 
						|
 | 
						|
    GEOMETRY_TRANSLATE (pGeometry, pDrawable->x, pDrawable->y);
 | 
						|
 | 
						|
    if (xglFill (pDrawable, pGC, pGeometry,
 | 
						|
		 pExtent->x1, pExtent->y1,
 | 
						|
		 pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
 | 
						|
		 REGION_RECTS (pGC->pCompositeClip),
 | 
						|
		 REGION_NUM_RECTS (pGC->pCompositeClip)))
 | 
						|
    {
 | 
						|
	xglAddCurrentBitDamage (pDrawable);
 | 
						|
	return TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
    return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
xglFillGlyph (DrawablePtr  pDrawable,
 | 
						|
	      GCPtr	   pGC,
 | 
						|
	      int	   x,
 | 
						|
	      int	   y,
 | 
						|
	      unsigned int nGlyph,
 | 
						|
	      CharInfoPtr  *ppci,
 | 
						|
	      pointer      pglyphBase)
 | 
						|
{
 | 
						|
    BoxPtr	   pExtent;
 | 
						|
    xglGeometryRec geometry;
 | 
						|
 | 
						|
    if (nGlyph < 1)
 | 
						|
	return TRUE;
 | 
						|
 | 
						|
    pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
 | 
						|
 | 
						|
    x += pDrawable->x;
 | 
						|
    y += pDrawable->y;
 | 
						|
 | 
						|
    GEOMETRY_INIT (pDrawable->pScreen, &geometry,
 | 
						|
		   GLITZ_GEOMETRY_TYPE_BITMAP,
 | 
						|
		   GEOMETRY_USAGE_SYSMEM, 0);
 | 
						|
 | 
						|
    GEOMETRY_FOR_GLYPH (pDrawable->pScreen,
 | 
						|
			&geometry,
 | 
						|
			nGlyph,
 | 
						|
			ppci,
 | 
						|
			pglyphBase);
 | 
						|
 | 
						|
    GEOMETRY_TRANSLATE (&geometry, x, y);
 | 
						|
 | 
						|
    if (xglFill (pDrawable, pGC, &geometry,
 | 
						|
		 pExtent->x1, pExtent->y1,
 | 
						|
		 pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
 | 
						|
		 REGION_RECTS (pGC->pCompositeClip),
 | 
						|
		 REGION_NUM_RECTS (pGC->pCompositeClip)))
 | 
						|
    {
 | 
						|
	GEOMETRY_UNINIT (&geometry);
 | 
						|
	xglAddCurrentBitDamage (pDrawable);
 | 
						|
	return TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
    GEOMETRY_UNINIT (&geometry);
 | 
						|
    return FALSE;
 | 
						|
}
 |