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;
|
||
|
}
|