summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-04-21 10:04:00 +1000
committerDave Airlie <airlied@redhat.com>2011-04-21 10:04:00 +1000
commitddeddda20779bd1843503f40f880ca8b785548ef (patch)
tree259bc09247028c825f654867691e0a60ffc515dc
parent08255ec621eff77a9a259234061c482ab39884b5 (diff)
migrate the rest of the mi stuff below the drv boundary.
now impedance has all the GC entry points, and fb points at the drv fallbacks.
-rw-r--r--dix/impedgc.c114
-rw-r--r--dix/impedscrn.c18
-rw-r--r--drv/Makefile.am12
-rw-r--r--drv/drv_mi.h88
-rw-r--r--drv/drvfillarc.c174
-rw-r--r--drv/drvfillarc.h2
-rw-r--r--drv/drvline.h173
-rw-r--r--drv/drvpoly.c123
-rw-r--r--drv/drvpoly.h207
-rw-r--r--drv/drvpolycon.c247
-rw-r--r--drv/drvpolygen.c230
-rw-r--r--drv/drvpolyrect.c187
-rw-r--r--drv/drvpolyseg.c (renamed from drv/mipolyseg.c)0
-rw-r--r--drv/drvpolytext.c130
-rw-r--r--drv/drvpolyutil.c385
-rw-r--r--drv/drvscanfill.h147
-rw-r--r--drv/drvwideline.c2
-rw-r--r--drv/drvzerclip.c630
-rw-r--r--drv/drvzerline.c378
-rw-r--r--fb/fbarc.c4
-rw-r--r--fb/fbbits.c4
-rw-r--r--fb/fbbits.h20
-rw-r--r--fb/fbgc.c14
-rw-r--r--fb/fbseg.c6
-rw-r--r--mi/Makefile.am1
-rw-r--r--mi/mipolyrect.c (renamed from drv/mipolyrect.c)0
26 files changed, 3171 insertions, 125 deletions
diff --git a/dix/impedgc.c b/dix/impedgc.c
index b19997af3..12ad969ca 100644
--- a/dix/impedgc.c
+++ b/dix/impedgc.c
@@ -38,6 +38,7 @@ static void SyncDrvGC(GCPtr pGC, DrvGCPtr pDrvGC, int index)
pDrvGC->joinStyle = pGC->joinStyle;
pDrvGC->capStyle = pGC->capStyle;
pDrvGC->lineWidth = pGC->lineWidth;
+ pDrvGC->font = pGC->font;
if (pGC->stipple)
pDrvGC->stipple = pGC->stipple->gpu[index];
}
@@ -231,6 +232,18 @@ impedPolySegment (DrawablePtr pDrawable,
pDrvGC, nseg, pSegs);
}
+static void
+impedPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *pRects)
+{
+ int i;
+ ProtoPixmapPtr pPixmap = (ProtoPixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ DrvGCPtr pDrvGC;
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+ pDrvGC = pGC->gpu[0];
+ pDrvGC->ops->PolyRectangle(pPixmap->gpu[0], pDrvGC, nrects, pRects);
+}
+
static void impedPolyArc (DrawablePtr pDrawable,
GCPtr pGC,
int narcs,
@@ -250,6 +263,25 @@ static void impedPolyArc (DrawablePtr pDrawable,
pDrvGC->ops->PolyArc(pPixmap->gpu[0], pDrvGC, narcs, parcs);
}
+static void impedFillPolygon( DrawablePtr pDrawable, GCPtr pGC,
+ int shape, int mode,
+ int count, DDXPointPtr pPts)
+{
+ int i;
+ ProtoPixmapPtr pPixmap = (ProtoPixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ DrvGCPtr pDrvGC;
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ for (i = 0; i < count; i++) {
+ pPts[i].x += x_off;
+ pPts[i].y += y_off;
+ }
+ pDrvGC = pGC->gpu[0];
+ pDrvGC->ops->FillPolygon(pPixmap->gpu[0], pDrvGC, shape,
+ mode, count, pPts);
+}
+
static void impedPolyFillRect(DrawablePtr pDrawable,
GCPtr pGC,
int nrectFill,
@@ -265,10 +297,73 @@ static void impedPolyFillRect(DrawablePtr pDrawable,
prectInit[i].y += y_off;
}
pDrvGC = pGC->gpu[0];
- SyncDrvGC(pGC, pDrvGC, 0);
pDrvGC->ops->PolyFillRect(pPixmap->gpu[0], pDrvGC, nrectFill, prectInit);
}
+static void impedPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
+{
+ int i;
+ ProtoPixmapPtr pPixmap = (ProtoPixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ DrvGCPtr pDrvGC;
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ pDrvGC = pGC->gpu[0];
+ pDrvGC->ops->PolyFillArc(pPixmap->gpu[0], pDrvGC, narcs, parcs);
+}
+
+static int
+impedPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars)
+{
+ int i;
+ ProtoPixmapPtr pPixmap = (ProtoPixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ DrvGCPtr pDrvGC;
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ pDrvGC = pGC->gpu[0];
+ return pDrvGC->ops->PolyText8(pPixmap->gpu[0], pDrvGC, x, y, count, chars);
+}
+
+static int
+impedPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars)
+{
+ int i;
+ ProtoPixmapPtr pPixmap = (ProtoPixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ DrvGCPtr pDrvGC;
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ pDrvGC = pGC->gpu[0];
+ return pDrvGC->ops->PolyText16(pPixmap->gpu[0], pDrvGC, x, y, count, chars);
+}
+
+static void
+impedImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars)
+{
+ int i;
+ ProtoPixmapPtr pPixmap = (ProtoPixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ DrvGCPtr pDrvGC;
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ pDrvGC = pGC->gpu[0];
+ pDrvGC->ops->ImageText8(pPixmap->gpu[0], pDrvGC, x, y, count, chars);
+}
+
+static void
+impedImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars)
+{
+ int i;
+ ProtoPixmapPtr pPixmap = (ProtoPixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ DrvGCPtr pDrvGC;
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ pDrvGC = pGC->gpu[0];
+ pDrvGC->ops->ImageText16(pPixmap->gpu[0], pDrvGC, x, y, count, chars);
+}
+
static void
impedPolyGlyphBlt (DrawablePtr pDrawable,
GCPtr pGC,
@@ -290,7 +385,7 @@ impedPolyGlyphBlt (DrawablePtr pDrawable,
ppci, pglyphBase);
}
-void
+static void
impedImageGlyphBlt (DrawablePtr pDrawable,
GCPtr pGC,
int x,
@@ -405,6 +500,7 @@ impedCopyPlaneNtoN (DrawablePtr pSrcDrawable,
upsidedown, bitplane, closure);
}
+
static RegionPtr
impedCopyPlane (DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable,
@@ -472,15 +568,15 @@ const ProtocolGCOps impedGCOps = {
impedPolyPoint,
impedPolyLines,
impedPolySegment,
- miPolyRectangle,
+ impedPolyRectangle,
impedPolyArc,
- miFillPolygon,
+ impedFillPolygon,
impedPolyFillRect,
- miPolyFillArc,
- miPolyText8,
- miPolyText16,
- miImageText8,
- miImageText16,
+ impedPolyFillArc,
+ impedPolyText8,
+ impedPolyText16,
+ impedImageText8,
+ impedImageText16,
impedImageGlyphBlt,
impedPolyGlyphBlt,
impedPushPixels,
diff --git a/dix/impedscrn.c b/dix/impedscrn.c
index f91b1f88a..51322f2b3 100644
--- a/dix/impedscrn.c
+++ b/dix/impedscrn.c
@@ -9,9 +9,11 @@
#include "servermd.h"
#include "imped.h"
-
+#include "drvline.h"
#include "micmap.h"
+DevPrivateKeyRec drvZeroLineScreenKeyRec;
+
static DevPrivateKeyRec impedWinPrivateKeyRec;
static DevPrivateKey
impedGetWinPrivateKey (void) { return &impedWinPrivateKeyRec; }
@@ -303,5 +305,19 @@ impedScreenInit(ScreenPtr pScreen)
/* replace miCloseScreen */
pScreen->CloseScreen = impedCloseScreen;
+ drvSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
return TRUE;
}
+
+
+DevPrivateKeyRec drvZeroLineScreenKeyRec;
+
+void
+drvSetZeroLineBias(ScreenPtr pScreen, unsigned int bias)
+{
+ if (!dixRegisterPrivateKey(&drvZeroLineScreenKeyRec, PRIVATE_SCREEN, 0))
+ return;
+
+ dixSetPrivate(&pScreen->devPrivates, drvZeroLineScreenKey,
+ (unsigned long *)(unsigned long)bias);
+}
diff --git a/drv/Makefile.am b/drv/Makefile.am
index 3666c77ae..dde0d7287 100644
--- a/drv/Makefile.am
+++ b/drv/Makefile.am
@@ -10,14 +10,22 @@ libdrv_la_SOURCES = \
drv_mi.h \
drvarc.c \
mifpolycon.c \
- mipolyseg.c \
- mipolyrect.c \
+ drvpolyseg.c \
+ drvpolyrect.c \
drvspans.c \
drvdash.c \
drvwideline.c \
+ drvfillarc.c\
drvzerarc.c\
drvfpolycon.c\
+ drvpolycon.c\
+ drvpolygen.c\
+ drvpolyutil.c\
+ drvpolytext.c\
drvclear.c\
+ drvzerclip.c\
+ drvzerline.c\
+ drvpoly.c\
drv_gc.c \
drv_pixmap.c \
drv_picture.c
diff --git a/drv/drv_mi.h b/drv/drv_mi.h
index 12aa2f9f5..151399d64 100644
--- a/drv/drv_mi.h
+++ b/drv/drv_mi.h
@@ -18,6 +18,35 @@ extern _X_EXPORT void drvPolyArc(
xArc * /*parcs*/
);
+/* drvpoly.c */
+
+extern _X_EXPORT void drvFillPolygon(
+ PixmapPtr /*dst*/,
+ DrvGCPtr /*pgc*/,
+ int /*shape*/,
+ int /*mode*/,
+ int /*count*/,
+ DDXPointPtr /*pPts*/
+);
+
+/* drvpolycon.c */
+
+extern _X_EXPORT Bool drvFillConvexPoly(
+ PixmapPtr /*dst*/,
+ DrvGCPtr /*pgc*/,
+ int /*count*/,
+ DDXPointPtr /*ptsIn*/
+);
+
+/* drvpolygen.c */
+
+extern _X_EXPORT Bool drvFillGeneralPoly(
+ PixmapPtr /*dst*/,
+ DrvGCPtr /*pgc*/,
+ int /*count*/,
+ DDXPointPtr /*ptsIn*/
+);
+
/* drvpolyrect.c */
@@ -37,6 +66,43 @@ extern _X_EXPORT void drvPolySegment(
xSegment * /*pSegs*/
);
+/* drvpolytext.c */
+
+extern _X_EXPORT int drvPolyText8(
+ PixmapPtr /*pDraw*/,
+ DrvGCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/
+);
+
+extern _X_EXPORT int drvPolyText16(
+ PixmapPtr /*pDraw*/,
+ DrvGCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/
+);
+
+extern _X_EXPORT void drvImageText8(
+ PixmapPtr /*pDraw*/,
+ DrvGCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/
+);
+
+extern _X_EXPORT void drvImageText16(
+ PixmapPtr /*pDraw*/,
+ DrvGCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/
+);
/* drvzerarc.c */
@@ -58,4 +124,26 @@ drvStepDash (
void
drvClearPixmap(PixmapPtr pPixmap, DrvGCPtr pGC);
+
+
+/* mizerline.c */
+
+extern _X_EXPORT void drvZeroLine(
+ PixmapPtr /*dst*/,
+ DrvGCPtr /*pgc*/,
+ int /*mode*/,
+ int /*nptInit*/,
+ DDXPointRec * /*pptInit*/
+);
+
+extern _X_EXPORT void drvZeroDashLine(
+ PixmapPtr /*dst*/,
+ DrvGCPtr /*pgc*/,
+ int /*mode*/,
+ int /*nptInit*/,
+ DDXPointRec * /*pptInit*/
+);
+
+void
+drvPolyFillArc(PixmapPtr pPixmap, DrvGCPtr pGC, int narcs, xArc *parcs);
#endif
diff --git a/drv/drvfillarc.c b/drv/drvfillarc.c
index 6eca13692..38b66c14c 100644
--- a/drv/drvfillarc.c
+++ b/drv/drvfillarc.c
@@ -35,9 +35,9 @@ Author: Bob Scheifler, MIT X Consortium
#include <X11/X.h>
#include <X11/Xprotostr.h>
#include "regionstr.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "mifpoly.h"
+#include "drv_gcstruct.h"
+#include "drv_pixmapstr.h"
+#include "drvfpoly.h"
#include "drv_mi.h"
#include "drvfillarc.h"
@@ -53,7 +53,7 @@ Author: Bob Scheifler, MIT X Consortium
#define Dcos(d) cos((double)d*(M_PI/11520.0))
void
-miFillArcSetup(xArc *arc, miFillArcRec *info)
+drvFillArcSetup(xArc *arc, drvFillArcRec *info)
{
info->y = arc->height >> 1;
info->dy = arc->height & 1;
@@ -106,7 +106,7 @@ miFillArcSetup(xArc *arc, miFillArcRec *info)
}
static void
-miFillArcDSetup(xArc *arc, miFillArcDRec *info)
+drvFillArcDSetup(xArc *arc, drvFillArcDRec *info)
{
/* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
/* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
@@ -136,9 +136,9 @@ miFillArcDSetup(xArc *arc, miFillArcDRec *info)
}
static void
-miGetArcEdge(
+drvGetArcEdge(
xArc *arc,
- miSliceEdgePtr edge,
+ drvSliceEdgePtr edge,
int k,
Bool top,
Bool left )
@@ -185,7 +185,7 @@ miGetArcEdge(
}
static void
-miEllipseAngleToSlope (int angle, int width, int height, int *dxp, int *dyp,
+drvEllipseAngleToSlope (int angle, int width, int height, int *dxp, int *dyp,
double *d_dxp, double *d_dyp)
{
int dx, dy;
@@ -260,17 +260,17 @@ miEllipseAngleToSlope (int angle, int width, int height, int *dxp, int *dyp,
}
static void
-miGetPieEdge(
+drvGetPieEdge(
xArc *arc,
int angle,
- miSliceEdgePtr edge,
+ drvSliceEdgePtr edge,
Bool top,
Bool left )
{
int k;
int dx, dy;
- miEllipseAngleToSlope (angle, arc->width, arc->height, &dx, &dy, 0, 0);
+ drvEllipseAngleToSlope (angle, arc->width, arc->height, &dx, &dy, 0, 0);
if (dy == 0)
{
@@ -301,11 +301,11 @@ miGetPieEdge(
k += dy;
edge->dx = dx << 1;
edge->dy = dy << 1;
- miGetArcEdge(arc, edge, k, top, left);
+ drvGetArcEdge(arc, edge, k, top, left);
}
void
-miFillArcSliceSetup(xArc *arc, miArcSliceRec *slice, GCPtr pGC)
+drvFillArcSliceSetup(xArc *arc, drvArcSliceRec *slice, DrvGCPtr pGC)
{
int angle1, angle2;
@@ -369,9 +369,9 @@ miFillArcSliceSetup(xArc *arc, miArcSliceRec *slice, GCPtr pGC)
slice->min_top_y = arc->height;
}
}
- miGetPieEdge(arc, angle1, &slice->edge1,
+ drvGetPieEdge(arc, angle1, &slice->edge1,
slice->edge1_top, !slice->edge1_top);
- miGetPieEdge(arc, angle2, &slice->edge2,
+ drvGetPieEdge(arc, angle2, &slice->edge2,
slice->edge2_top, slice->edge2_top);
}
else
@@ -509,9 +509,9 @@ miFillArcSliceSetup(xArc *arc, miArcSliceRec *slice, GCPtr pGC)
slice->edge2.dy = slice->edge1.dy;
slice->edge1_top = signdy < 0;
slice->edge2_top = !slice->edge1_top;
- miGetArcEdge(arc, &slice->edge1, k,
+ drvGetArcEdge(arc, &slice->edge1, k,
slice->edge1_top, !slice->edge1_top);
- miGetArcEdge(arc, &slice->edge2, k,
+ drvGetArcEdge(arc, &slice->edge2, k,
slice->edge2_top, slice->edge2_top);
}
}
@@ -523,7 +523,7 @@ miFillArcSliceSetup(xArc *arc, miArcSliceRec *slice, GCPtr pGC)
*wids = slw; \
pts++; \
wids++; \
- if (miFillArcLower(slw)) \
+ if (drvFillArcLower(slw)) \
{ \
pts->x = xorg - x; \
pts->y = yorg + y + dy; \
@@ -532,15 +532,15 @@ miFillArcSliceSetup(xArc *arc, miArcSliceRec *slice, GCPtr pGC)
}
static void
-miFillEllipseI(
- DrawablePtr pDraw,
- GCPtr pGC,
+drvFillEllipseI(
+ PixmapPtr pPixmap,
+ DrvGCPtr pGC,
xArc *arc )
{
int x, y, e;
int yk, xk, ym, xm, dx, dy, xorg, yorg;
int slw;
- miFillArcRec info;
+ drvFillArcRec info;
DDXPointPtr points;
DDXPointPtr pts;
int *widths;
@@ -555,35 +555,35 @@ miFillEllipseI(
free(points);
return;
}
- miFillArcSetup(arc, &info);
- MIFILLARCSETUP();
+ drvFillArcSetup(arc, &info);
+ DRVFILLARCSETUP();
if (pGC->miTranslate)
{
- xorg += pDraw->x;
- yorg += pDraw->y;
+ xorg += 0;
+ yorg += 0;
}
pts = points;
wids = widths;
while (y > 0)
{
- MIFILLARCSTEP(slw);
+ DRVFILLARCSTEP(slw);
ADDSPANS();
}
- (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+ (*pGC->ops->FillSpans)(pPixmap, pGC, pts - points, points, widths, FALSE);
free(widths);
free(points);
}
static void
-miFillEllipseD(
- DrawablePtr pDraw,
- GCPtr pGC,
+drvFillEllipseD(
+ PixmapPtr pPixmap,
+ DrvGCPtr pGC,
xArc *arc )
{
int x, y;
int xorg, yorg, dx, dy, slw;
double e, yk, xk, ym, xm;
- miFillArcDRec info;
+ drvFillArcDRec info;
DDXPointPtr points;
DDXPointPtr pts;
int *widths;
@@ -598,21 +598,21 @@ miFillEllipseD(
free(points);
return;
}
- miFillArcDSetup(arc, &info);
- MIFILLARCSETUP();
+ drvFillArcDSetup(arc, &info);
+ DRVFILLARCSETUP();
if (pGC->miTranslate)
{
- xorg += pDraw->x;
- yorg += pDraw->y;
+ xorg += 0;
+ yorg += 0;
}
pts = points;
wids = widths;
while (y > 0)
{
- MIFILLARCSTEP(slw);
+ DRVFILLARCSTEP(slw);
ADDSPANS();
}
- (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+ (*pGC->ops->FillSpans)(pPixmap, pGC, pts - points, points, widths, FALSE);
free(widths);
free(points);
}
@@ -640,24 +640,24 @@ miFillEllipseD(
}
static void
-miFillArcSliceI(
- DrawablePtr pDraw,
- GCPtr pGC,
+drvFillArcSliceI(
+ PixmapPtr pPixmap,
+ DrvGCPtr pGC,
xArc *arc )
{
int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
int x, y, e;
- miFillArcRec info;
- miArcSliceRec slice;
+ drvFillArcRec info;
+ drvArcSliceRec slice;
int ya, xl, xr, xc;
DDXPointPtr points;
DDXPointPtr pts;
int *widths;
int *wids;
- miFillArcSetup(arc, &info);
- miFillArcSliceSetup(arc, &slice, pGC);
- MIFILLARCSETUP();
+ drvFillArcSetup(arc, &info);
+ drvFillArcSliceSetup(arc, &slice, pGC);
+ DRVFILLARCSETUP();
slw = arc->height;
if (slice.flip_top || slice.flip_bot)
slw += (arc->height >> 1) + 1;
@@ -672,56 +672,56 @@ miFillArcSliceI(
}
if (pGC->miTranslate)
{
- xorg += pDraw->x;
- yorg += pDraw->y;
- slice.edge1.x += pDraw->x;
- slice.edge2.x += pDraw->x;
+ xorg += 0;
+ yorg += 0;
+ slice.edge1.x += 0;
+ slice.edge2.x += 0;
}
pts = points;
wids = widths;
while (y > 0)
{
- MIFILLARCSTEP(slw);
- MIARCSLICESTEP(slice.edge1);
- MIARCSLICESTEP(slice.edge2);
- if (miFillSliceUpper(slice))
+ DRVFILLARCSTEP(slw);
+ DRVARCSLICESTEP(slice.edge1);
+ DRVARCSLICESTEP(slice.edge2);
+ if (drvFillSliceUpper(slice))
{
ya = yorg - y;
- MIARCSLICEUPPER(xl, xr, slice, slw);
+ DRVARCSLICEUPPER(xl, xr, slice, slw);
ADDSLICESPANS(slice.flip_top);
}
- if (miFillSliceLower(slice))
+ if (drvFillSliceLower(slice))
{
ya = yorg + y + dy;
- MIARCSLICELOWER(xl, xr, slice, slw);
+ DRVARCSLICELOWER(xl, xr, slice, slw);
ADDSLICESPANS(slice.flip_bot);
}
}
- (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+ (*pGC->ops->FillSpans)(pPixmap, pGC, pts - points, points, widths, FALSE);
free(widths);
free(points);
}
static void
-miFillArcSliceD(
- DrawablePtr pDraw,
- GCPtr pGC,
+drvFillArcSliceD(
+ PixmapPtr pPixmap,
+ DrvGCPtr pGC,
xArc *arc )
{
int x, y;
int dx, dy, xorg, yorg, slw;
double e, yk, xk, ym, xm;
- miFillArcDRec info;
- miArcSliceRec slice;
+ drvFillArcDRec info;
+ drvArcSliceRec slice;
int ya, xl, xr, xc;
DDXPointPtr points;
DDXPointPtr pts;
int *widths;
int *wids;
- miFillArcDSetup(arc, &info);
- miFillArcSliceSetup(arc, &slice, pGC);
- MIFILLARCSETUP();
+ drvFillArcDSetup(arc, &info);
+ drvFillArcSliceSetup(arc, &slice, pGC);
+ DRVFILLARCSETUP();
slw = arc->height;
if (slice.flip_top || slice.flip_bot)
slw += (arc->height >> 1) + 1;
@@ -736,63 +736,63 @@ miFillArcSliceD(
}
if (pGC->miTranslate)
{
- xorg += pDraw->x;
- yorg += pDraw->y;
- slice.edge1.x += pDraw->x;
- slice.edge2.x += pDraw->x;
+ xorg += 0;
+ yorg += 0;
+ slice.edge1.x += 0;
+ slice.edge2.x += 0;
}
pts = points;
wids = widths;
while (y > 0)
{
- MIFILLARCSTEP(slw);
- MIARCSLICESTEP(slice.edge1);
- MIARCSLICESTEP(slice.edge2);
- if (miFillSliceUpper(slice))
+ DRVFILLARCSTEP(slw);
+ DRVARCSLICESTEP(slice.edge1);
+ DRVARCSLICESTEP(slice.edge2);
+ if (drvFillSliceUpper(slice))
{
ya = yorg - y;
- MIARCSLICEUPPER(xl, xr, slice, slw);
+ DRVARCSLICEUPPER(xl, xr, slice, slw);
ADDSLICESPANS(slice.flip_top);
}
- if (miFillSliceLower(slice))
+ if (drvFillSliceLower(slice))
{
ya = yorg + y + dy;
- MIARCSLICELOWER(xl, xr, slice, slw);
+ DRVARCSLICELOWER(xl, xr, slice, slw);
ADDSLICESPANS(slice.flip_bot);
}
}
- (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+ (*pGC->ops->FillSpans)(pPixmap, pGC, pts - points, points, widths, FALSE);
free(widths);
free(points);
}
-/* MIPOLYFILLARC -- The public entry for the PolyFillArc request.
+/* DRVPOLYFILLARC -- The public entry for the PolyFillArc request.
* Since we don't have to worry about overlapping segments, we can just
* fill each arc as it comes.
*/
void
-miPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs)
+drvPolyFillArc(PixmapPtr pPixmap, DrvGCPtr pGC, int narcs, xArc *parcs)
{
int i;
xArc *arc;
for(i = narcs, arc = parcs; --i >= 0; arc++)
{
- if (miFillArcEmpty(arc))
+ if (drvFillArcEmpty(arc))
continue;
if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE))
{
- if (miCanFillArc(arc))
- miFillEllipseI(pDraw, pGC, arc);
+ if (drvCanFillArc(arc))
+ drvFillEllipseI(pPixmap, pGC, arc);
else
- miFillEllipseD(pDraw, pGC, arc);
+ drvFillEllipseD(pPixmap, pGC, arc);
}
else
{
- if (miCanFillArc(arc))
- miFillArcSliceI(pDraw, pGC, arc);
+ if (drvCanFillArc(arc))
+ drvFillArcSliceI(pPixmap, pGC, arc);
else
- miFillArcSliceD(pDraw, pGC, arc);
+ drvFillArcSliceD(pPixmap, pGC, arc);
}
}
}
diff --git a/drv/drvfillarc.h b/drv/drvfillarc.h
index beead2350..4a33658c9 100644
--- a/drv/drvfillarc.h
+++ b/drv/drvfillarc.h
@@ -184,7 +184,7 @@ extern _X_EXPORT void drvFillArcSetup(
extern _X_EXPORT void drvFillArcSliceSetup(
xArc * /*arc*/,
drvArcSliceRec * /*slice*/,
- GCPtr /*pGC*/
+ DrvGCPtr /*pGC*/
);
#endif /* __DRVFILLARC_H__ */
diff --git a/drv/drvline.h b/drv/drvline.h
new file mode 100644
index 000000000..87196c553
--- /dev/null
+++ b/drv/drvline.h
@@ -0,0 +1,173 @@
+
+/*
+
+Copyright 1994, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+#ifndef MILINE_H
+
+#include "screenint.h"
+#include "privates.h"
+
+/*
+ * Public definitions used for configuring basic pixelization aspects
+ * of the sample implementation line-drawing routines provided in
+ * {mfb,mi,cfb*} at run-time.
+ */
+
+#define XDECREASING 4
+#define YDECREASING 2
+#define YMAJOR 1
+
+#define OCTANT1 (1 << (YDECREASING))
+#define OCTANT2 (1 << (YDECREASING|YMAJOR))
+#define OCTANT3 (1 << (XDECREASING|YDECREASING|YMAJOR))
+#define OCTANT4 (1 << (XDECREASING|YDECREASING))
+#define OCTANT5 (1 << (XDECREASING))
+#define OCTANT6 (1 << (XDECREASING|YMAJOR))
+#define OCTANT7 (1 << (YMAJOR))
+#define OCTANT8 (1 << (0))
+
+#define XMAJOROCTANTS (OCTANT1 | OCTANT4 | OCTANT5 | OCTANT8)
+
+#define DEFAULTZEROLINEBIAS (OCTANT2 | OCTANT3 | OCTANT4 | OCTANT5)
+
+/*
+ * Devices can configure the rendering of routines in mi, mfb, and cfb*
+ * by specifying a thin line bias to be applied to a particular screen
+ * using the following function. The bias parameter is an OR'ing of
+ * the appropriate OCTANT constants defined above to indicate which
+ * octants to bias a line to prefer an axial step when the Bresenham
+ * error term is exactly zero. The octants are mapped as follows:
+ *
+ * \ | /
+ * \ 3 | 2 /
+ * \ | /
+ * 4 \ | / 1
+ * \|/
+ * -----------
+ * /|\
+ * 5 / | \ 8
+ * / | \
+ * / 6 | 7 \
+ * / | \
+ *
+ * For more information, see "Ambiguities in Incremental Line Rastering,"
+ * Jack E. Bresenham, IEEE CG&A, May 1987.
+ */
+
+extern _X_EXPORT void miSetZeroLineBias(
+ ScreenPtr /* pScreen */,
+ unsigned int /* bias */
+);
+
+/*
+ * Private definitions needed for drawing thin (zero width) lines
+ * Used by the mi, mfb, and all cfb* components.
+ */
+
+#define X_AXIS 0
+#define Y_AXIS 1
+
+#define OUT_LEFT 0x08
+#define OUT_RIGHT 0x04
+#define OUT_ABOVE 0x02
+#define OUT_BELOW 0x01
+
+#define OUTCODES(_result, _x, _y, _pbox) \
+ if ( (_x) < (_pbox)->x1) (_result) |= OUT_LEFT; \
+ else if ( (_x) >= (_pbox)->x2) (_result) |= OUT_RIGHT; \
+ if ( (_y) < (_pbox)->y1) (_result) |= OUT_ABOVE; \
+ else if ( (_y) >= (_pbox)->y2) (_result) |= OUT_BELOW;
+
+#define MIOUTCODES(outcode, x, y, xmin, ymin, xmax, ymax) \
+{\
+ if (x < xmin) outcode |= OUT_LEFT;\
+ if (x > xmax) outcode |= OUT_RIGHT;\
+ if (y < ymin) outcode |= OUT_ABOVE;\
+ if (y > ymax) outcode |= OUT_BELOW;\
+}
+
+#define SWAPINT(i, j) \
+{ int _t = i; i = j; j = _t; }
+
+#define SWAPPT(i, j) \
+{ DDXPointRec _t; _t = i; i = j; j = _t; }
+
+#define SWAPINT_PAIR(x1, y1, x2, y2)\
+{ int t = x1; x1 = x2; x2 = t;\
+ t = y1; y1 = y2; y2 = t;\
+}
+
+#define drvGetZeroLineBias(_pScreen) ((unsigned long) (unsigned long*)\
+ dixLookupPrivate(&(_pScreen)->devPrivates, drvZeroLineScreenKey))
+
+#define CalcLineDeltas(_x1,_y1,_x2,_y2,_adx,_ady,_sx,_sy,_SX,_SY,_octant) \
+ (_octant) = 0; \
+ (_sx) = (_SX); \
+ if (((_adx) = (_x2) - (_x1)) < 0) { \
+ (_adx) = -(_adx); \
+ (_sx = -(_sx)); \
+ (_octant) |= XDECREASING; \
+ } \
+ (_sy) = (_SY); \
+ if (((_ady) = (_y2) - (_y1)) < 0) { \
+ (_ady) = -(_ady); \
+ (_sy = -(_sy)); \
+ (_octant) |= YDECREASING; \
+ }
+
+#define SetYMajorOctant(_octant) ((_octant) |= YMAJOR)
+
+#define FIXUP_ERROR(_e, _octant, _bias) \
+ (_e) -= (((_bias) >> (_octant)) & 1)
+
+#define IsXMajorOctant(_octant) (!((_octant) & YMAJOR))
+#define IsYMajorOctant(_octant) ((_octant) & YMAJOR)
+#define IsXDecreasingOctant(_octant) ((_octant) & XDECREASING)
+#define IsYDecreasingOctant(_octant) ((_octant) & YDECREASING)
+
+extern _X_EXPORT DevPrivateKeyRec drvZeroLineScreenKeyRec;
+#define drvZeroLineScreenKey (&drvZeroLineScreenKeyRec)
+
+extern _X_EXPORT int drvZeroClipLine(
+ int /*xmin*/,
+ int /*ymin*/,
+ int /*xmax*/,
+ int /*ymax*/,
+ int * /*new_x1*/,
+ int * /*new_y1*/,
+ int * /*new_x2*/,
+ int * /*new_y2*/,
+ unsigned int /*adx*/,
+ unsigned int /*ady*/,
+ int * /*pt1_clipped*/,
+ int * /*pt2_clipped*/,
+ int /*octant*/,
+ unsigned int /*bias*/,
+ int /*oc1*/,
+ int /*oc2*/
+);
+
+#endif /* MILINE_H */
diff --git a/drv/drvpoly.c b/drv/drvpoly.c
new file mode 100644
index 000000000..012ff5ade
--- /dev/null
+++ b/drv/drvpoly.c
@@ -0,0 +1,123 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/*
+ * mipoly.c
+ *
+ * Written by Brian Kelleher; June 1986
+ *
+ * Draw polygons. This routine translates the point by the
+ * origin if pGC->miTranslate is non-zero, and calls
+ * to the appropriate routine to actually scan convert the
+ * polygon.
+ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "drv_gcstruct.h"
+#include "drv_pixmapstr.h"
+#include "drv_mi.h"
+#include "regionstr.h"
+
+
+void
+drvFillPolygon( PixmapPtr dst, DrvGCPtr pgc,
+ int shape, int mode,
+ int count, DDXPointPtr pPts)
+{
+ int i;
+ int xorg, yorg;
+ DDXPointPtr ppt;
+
+ if (count == 0)
+ return;
+
+ ppt = pPts;
+ if (pgc->miTranslate)
+ {
+ xorg = 0;
+ yorg = 0;
+
+ if (mode == CoordModeOrigin)
+ {
+ for (i = 0; i<count; i++)
+ {
+ ppt->x += xorg;
+ ppt++->y += yorg;
+ }
+ }
+ else
+ {
+ ppt->x += xorg;
+ ppt++->y += yorg;
+ for (i = 1; i<count; i++)
+ {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ ppt++;
+ }
+ }
+ }
+ else
+ {
+ if (mode == CoordModePrevious)
+ {
+ ppt++;
+ for (i = 1; i<count; i++)
+ {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ ppt++;
+ }
+ }
+ }
+ if (shape == Convex)
+ drvFillConvexPoly(dst, pgc, count, pPts);
+ else
+ drvFillGeneralPoly(dst, pgc, count, pPts);
+}
diff --git a/drv/drvpoly.h b/drv/drvpoly.h
new file mode 100644
index 000000000..5a84af9da
--- /dev/null
+++ b/drv/drvpoly.h
@@ -0,0 +1,207 @@
+/*
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+
+/*
+ * fill.h
+ *
+ * Created by Brian Kelleher; Oct 1985
+ *
+ * Include file for filled polygon routines.
+ *
+ * These are the data structures needed to scan
+ * convert regions. Two different scan conversion
+ * methods are available -- the even-odd method, and
+ * the winding number method.
+ * The even-odd rule states that a point is inside
+ * the polygon if a ray drawn from that point in any
+ * direction will pass through an odd number of
+ * path segments.
+ * By the winding number rule, a point is decided
+ * to be inside the polygon if a ray drawn from that
+ * point in any direction passes through a different
+ * number of clockwise and counter-clockwise path
+ * segments.
+ *
+ * These data structures are adapted somewhat from
+ * the algorithm in (Foley/Van Dam) for scan converting
+ * polygons.
+ * The basic algorithm is to start at the top (smallest y)
+ * of the polygon, stepping down to the bottom of
+ * the polygon by incrementing the y coordinate. We
+ * keep a list of edges which the current scanline crosses,
+ * sorted by x. This list is called the Active Edge Table (AET)
+ * As we change the y-coordinate, we update each entry in
+ * in the active edge table to reflect the edges new xcoord.
+ * This list must be sorted at each scanline in case
+ * two edges intersect.
+ * We also keep a data structure known as the Edge Table (ET),
+ * which keeps track of all the edges which the current
+ * scanline has not yet reached. The ET is basically a
+ * list of ScanLineList structures containing a list of
+ * edges which are entered at a given scanline. There is one
+ * ScanLineList per scanline at which an edge is entered.
+ * When we enter a new edge, we move it from the ET to the AET.
+ *
+ * From the AET, we can implement the even-odd rule as in
+ * (Foley/Van Dam).
+ * The winding number rule is a little trickier. We also
+ * keep the EdgeTableEntries in the AET linked by the
+ * nextWETE (winding EdgeTableEntry) link. This allows
+ * the edges to be linked just as before for updating
+ * purposes, but only uses the edges linked by the nextWETE
+ * link as edges representing spans of the polygon to
+ * drawn (as with the even-odd rule).
+ */
+
+/*
+ * for the winding number rule
+ */
+#define CLOCKWISE 1
+#define COUNTERCLOCKWISE -1
+
+typedef struct _EdgeTableEntry {
+ int ymax; /* ycoord at which we exit this edge. */
+ BRESINFO bres; /* Bresenham info to run the edge */
+ struct _EdgeTableEntry *next; /* next in the list */
+ struct _EdgeTableEntry *back; /* for insertion sort */
+ struct _EdgeTableEntry *nextWETE; /* for winding num rule */
+ int ClockWise; /* flag for winding number rule */
+} EdgeTableEntry;
+
+
+typedef struct _ScanLineList{
+ int scanline; /* the scanline represented */
+ EdgeTableEntry *edgelist; /* header node */
+ struct _ScanLineList *next; /* next in the list */
+} ScanLineList;
+
+
+typedef struct {
+ int ymax; /* ymax for the polygon */
+ int ymin; /* ymin for the polygon */
+ ScanLineList scanlines; /* header node */
+} EdgeTable;
+
+
+/*
+ * Here is a struct to help with storage allocation
+ * so we can allocate a big chunk at a time, and then take
+ * pieces from this heap when we need to.
+ */
+#define SLLSPERBLOCK 25
+
+typedef struct _ScanLineListBlock {
+ ScanLineList SLLs[SLLSPERBLOCK];
+ struct _ScanLineListBlock *next;
+} ScanLineListBlock;
+
+/*
+ * number of points to buffer before sending them off
+ * to scanlines() : Must be an even number
+ */
+#define NUMPTSTOBUFFER 200
+
+
+/*
+ *
+ * a few macros for the inner loops of the fill code where
+ * performance considerations don't allow a procedure call.
+ *
+ * Evaluate the given edge at the given scanline.
+ * If the edge has expired, then we leave it and fix up
+ * the active edge table; otherwise, we increment the
+ * x value to be ready for the next scanline.
+ * The winding number rule is in effect, so we must notify
+ * the caller when the edge has been removed so he
+ * can reorder the Winding Active Edge Table.
+ */
+#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \
+ if (pAET->ymax == y) { /* leaving this edge */ \
+ pPrevAET->next = pAET->next; \
+ pAET = pPrevAET->next; \
+ fixWAET = 1; \
+ if (pAET) \
+ pAET->back = pPrevAET; \
+ } \
+ else { \
+ BRESINCRPGONSTRUCT(pAET->bres); \
+ pPrevAET = pAET; \
+ pAET = pAET->next; \
+ } \
+}
+
+
+/*
+ * Evaluate the given edge at the given scanline.
+ * If the edge has expired, then we leave it and fix up
+ * the active edge table; otherwise, we increment the
+ * x value to be ready for the next scanline.
+ * The even-odd rule is in effect.
+ */
+#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \
+ if (pAET->ymax == y) { /* leaving this edge */ \
+ pPrevAET->next = pAET->next; \
+ pAET = pPrevAET->next; \
+ if (pAET) \
+ pAET->back = pPrevAET; \
+ } \
+ else { \
+ BRESINCRPGONSTRUCT(pAET->bres); \
+ pPrevAET = pAET; \
+ pAET = pAET->next; \
+ } \
+}
+
+/* mipolyutil.c */
+
+extern _X_EXPORT Bool drvCreateETandAET(
+ int /*count*/,
+ DDXPointPtr /*pts*/,
+ EdgeTable * /*ET*/,
+ EdgeTableEntry * /*AET*/,
+ EdgeTableEntry * /*pETEs*/,
+ ScanLineListBlock * /*pSLLBlock*/
+);
+
+extern _X_EXPORT void drvloadAET(
+ EdgeTableEntry * /*AET*/,
+ EdgeTableEntry * /*ETEs*/
+);
+
+extern _X_EXPORT void drvcomputeWAET(
+ EdgeTableEntry * /*AET*/
+);
+
+extern _X_EXPORT int drvInsertionSort(
+ EdgeTableEntry * /*AET*/
+);
+
+extern _X_EXPORT void drvFreeStorage(
+ ScanLineListBlock * /*pSLLBlock*/
+);
diff --git a/drv/drvpolycon.c b/drv/drvpolycon.c
new file mode 100644
index 000000000..70b5052ce
--- /dev/null
+++ b/drv/drvpolycon.c
@@ -0,0 +1,247 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "drv_gcstruct.h"
+#include "drv_pixmap.h"
+#include "drv_mi.h"
+#include "drvscanfill.h"
+
+static int getPolyYBounds(DDXPointPtr pts, int n, int *by, int *ty);
+
+/*
+ * convexpoly.c
+ *
+ * Written by Brian Kelleher; Dec. 1985.
+ *
+ * Fill a convex polygon. If the given polygon
+ * is not convex, then the result is undefined.
+ * The algorithm is to order the edges from smallest
+ * y to largest by partitioning the array into a left
+ * edge list and a right edge list. The algorithm used
+ * to traverse each edge is an extension of Bresenham's
+ * line algorithm with y as the major axis.
+ * For a derivation of the algorithm, see the author of
+ * this code.
+ */
+Bool
+drvFillConvexPoly(
+ PixmapPtr pPixmap,
+ DrvGCPtr pgc,
+ int count, /* number of points */
+ DDXPointPtr ptsIn /* the points */
+ )
+{
+ int xl = 0, xr = 0; /* x vals of left and right edges */
+ int dl = 0, dr = 0; /* decision variables */
+ int ml = 0, m1l = 0;/* left edge slope and slope+1 */
+ int mr = 0, m1r = 0; /* right edge slope and slope+1 */
+ int incr1l = 0, incr2l = 0; /* left edge error increments */
+ int incr1r = 0, incr2r = 0; /* right edge error increments */
+ int dy; /* delta y */
+ int y; /* current scanline */
+ int left, right; /* indices to first endpoints */
+ int i; /* loop counter */
+ int nextleft, nextright; /* indices to second endpoints */
+ DDXPointPtr ptsOut, FirstPoint; /* output buffer */
+ int *width, *FirstWidth; /* output buffer */
+ int imin; /* index of smallest vertex (in y) */
+ int ymin; /* y-extents of polygon */
+ int ymax;
+
+ /*
+ * find leftx, bottomy, rightx, topy, and the index
+ * of bottomy. Also translate the points.
+ */
+ imin = getPolyYBounds(ptsIn, count, &ymin, &ymax);
+
+ dy = ymax - ymin + 1;
+ if ((count < 3) || (dy < 0))
+ return TRUE;
+ ptsOut = FirstPoint = malloc(sizeof(DDXPointRec)*dy);
+ width = FirstWidth = malloc(sizeof(int) * dy);
+ if(!FirstPoint || !FirstWidth)
+ {
+ free(FirstWidth);
+ free(FirstPoint);
+ return FALSE;
+ }
+
+ nextleft = nextright = imin;
+ y = ptsIn[nextleft].y;
+
+ /*
+ * loop through all edges of the polygon
+ */
+ do {
+ /*
+ * add a left edge if we need to
+ */
+ if (ptsIn[nextleft].y == y) {
+ left = nextleft;
+
+ /*
+ * find the next edge, considering the end
+ * conditions of the array.
+ */
+ nextleft++;
+ if (nextleft >= count)
+ nextleft = 0;
+
+ /*
+ * now compute all of the random information
+ * needed to run the iterative algorithm.
+ */
+ BRESINITPGON(ptsIn[nextleft].y-ptsIn[left].y,
+ ptsIn[left].x,ptsIn[nextleft].x,
+ xl, dl, ml, m1l, incr1l, incr2l);
+ }
+
+ /*
+ * add a right edge if we need to
+ */
+ if (ptsIn[nextright].y == y) {
+ right = nextright;
+
+ /*
+ * find the next edge, considering the end
+ * conditions of the array.
+ */
+ nextright--;
+ if (nextright < 0)
+ nextright = count-1;
+
+ /*
+ * now compute all of the random information
+ * needed to run the iterative algorithm.
+ */
+ BRESINITPGON(ptsIn[nextright].y-ptsIn[right].y,
+ ptsIn[right].x,ptsIn[nextright].x,
+ xr, dr, mr, m1r, incr1r, incr2r);
+ }
+
+ /*
+ * generate scans to fill while we still have
+ * a right edge as well as a left edge.
+ */
+ i = min(ptsIn[nextleft].y, ptsIn[nextright].y) - y;
+ /* in case we're called with non-convex polygon */
+ if(i < 0)
+ {
+ free(FirstWidth);
+ free(FirstPoint);
+ return TRUE;
+ }
+ while (i-- > 0)
+ {
+ ptsOut->y = y;
+
+ /*
+ * reverse the edges if necessary
+ */
+ if (xl < xr)
+ {
+ *(width++) = xr - xl;
+ (ptsOut++)->x = xl;
+ }
+ else
+ {
+ *(width++) = xl - xr;
+ (ptsOut++)->x = xr;
+ }
+ y++;
+
+ /* increment down the edges */
+ BRESINCRPGON(dl, xl, ml, m1l, incr1l, incr2l);
+ BRESINCRPGON(dr, xr, mr, m1r, incr1r, incr2r);
+ }
+ } while (y != ymax);
+
+ /*
+ * Finally, fill the <remaining> spans
+ */
+ (*pgc->ops->FillSpans)(pPixmap, pgc,
+ ptsOut-FirstPoint,FirstPoint,FirstWidth,
+ 1);
+ free(FirstWidth);
+ free(FirstPoint);
+ return TRUE;
+}
+
+
+/*
+ * Find the index of the point with the smallest y.
+ */
+static int
+getPolyYBounds(DDXPointPtr pts, int n, int *by, int *ty)
+{
+ DDXPointPtr ptMin;
+ int ymin, ymax;
+ DDXPointPtr ptsStart = pts;
+
+ ptMin = pts;
+ ymin = ymax = (pts++)->y;
+
+ while (--n > 0) {
+ if (pts->y < ymin)
+ {
+ ptMin = pts;
+ ymin = pts->y;
+ }
+ if(pts->y > ymax)
+ ymax = pts->y;
+
+ pts++;
+ }
+
+ *by = ymin;
+ *ty = ymax;
+ return ptMin-ptsStart;
+}
diff --git a/drv/drvpolygen.c b/drv/drvpolygen.c
new file mode 100644
index 000000000..98c9aa485
--- /dev/null
+++ b/drv/drvpolygen.c
@@ -0,0 +1,230 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "drv_gcstruct.h"
+#include "drvscanfill.h"
+#include "drvpoly.h"
+#include "drv_pixmap.h"
+#include "drv_mi.h"
+
+/*
+ *
+ * Written by Brian Kelleher; Oct. 1985
+ *
+ * Routine to fill a polygon. Two fill rules are
+ * supported: frWINDING and frEVENODD.
+ *
+ * See fillpoly.h for a complete description of the algorithm.
+ */
+
+Bool
+drvFillGeneralPoly(
+ PixmapPtr pPixmap,
+ DrvGCPtr pgc,
+ int count, /* number of points */
+ DDXPointPtr ptsIn /* the points */
+ )
+{
+ EdgeTableEntry *pAET; /* the Active Edge Table */
+ int y; /* the current scanline */
+ int nPts = 0; /* number of pts in buffer */
+ EdgeTableEntry *pWETE; /* Winding Edge Table */
+ ScanLineList *pSLL; /* Current ScanLineList */
+ DDXPointPtr ptsOut; /* ptr to output buffers */
+ int *width;
+ DDXPointRec FirstPoint[NUMPTSTOBUFFER]; /* the output buffers */
+ int FirstWidth[NUMPTSTOBUFFER];
+ EdgeTableEntry *pPrevAET; /* previous AET entry */
+ EdgeTable ET; /* Edge Table header node */
+ EdgeTableEntry AET; /* Active ET header node */
+ EdgeTableEntry *pETEs; /* Edge Table Entries buff */
+ ScanLineListBlock SLLBlock; /* header for ScanLineList */
+ int fixWAET = 0;
+
+ if (count < 3)
+ return TRUE;
+
+ if(!(pETEs = malloc(sizeof(EdgeTableEntry) * count)))
+ return FALSE;
+ ptsOut = FirstPoint;
+ width = FirstWidth;
+ if (!drvCreateETandAET(count, ptsIn, &ET, &AET, pETEs, &SLLBlock))
+ {
+ free(pETEs);
+ return FALSE;
+ }
+ pSLL = ET.scanlines.next;
+
+ if (pgc->fillRule == EvenOddRule)
+ {
+ /*
+ * for each scanline
+ */
+ for (y = ET.ymin; y < ET.ymax; y++)
+ {
+ /*
+ * Add a new edge to the active edge table when we
+ * get to the next edge.
+ */
+ if (pSLL && y == pSLL->scanline)
+ {
+ drvloadAET(&AET, pSLL->edgelist);
+ pSLL = pSLL->next;
+ }
+ pPrevAET = &AET;
+ pAET = AET.next;
+
+ /*
+ * for each active edge
+ */
+ while (pAET)
+ {
+ ptsOut->x = pAET->bres.minor;
+ ptsOut++->y = y;
+ *width++ = pAET->next->bres.minor - pAET->bres.minor;
+ nPts++;
+
+ /*
+ * send out the buffer when its full
+ */
+ if (nPts == NUMPTSTOBUFFER)
+ {
+ (*pgc->ops->FillSpans)(pPixmap, pgc,
+ nPts, FirstPoint, FirstWidth,
+ 1);
+ ptsOut = FirstPoint;
+ width = FirstWidth;
+ nPts = 0;
+ }
+ EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
+ EVALUATEEDGEEVENODD(pAET, pPrevAET, y);
+ }
+ drvInsertionSort(&AET);
+ }
+ }
+ else /* default to WindingNumber */
+ {
+ /*
+ * for each scanline
+ */
+ for (y = ET.ymin; y < ET.ymax; y++)
+ {
+ /*
+ * Add a new edge to the active edge table when we
+ * get to the next edge.
+ */
+ if (pSLL && y == pSLL->scanline)
+ {
+ drvloadAET(&AET, pSLL->edgelist);
+ drvcomputeWAET(&AET);
+ pSLL = pSLL->next;
+ }
+ pPrevAET = &AET;
+ pAET = AET.next;
+ pWETE = pAET;
+
+ /*
+ * for each active edge
+ */
+ while (pAET)
+ {
+ /*
+ * if the next edge in the active edge table is
+ * also the next edge in the winding active edge
+ * table.
+ */
+ if (pWETE == pAET)
+ {
+ ptsOut->x = pAET->bres.minor;
+ ptsOut++->y = y;
+ *width++ = pAET->nextWETE->bres.minor - pAET->bres.minor;
+ nPts++;
+
+ /*
+ * send out the buffer
+ */
+ if (nPts == NUMPTSTOBUFFER)
+ {
+ (*pgc->ops->FillSpans)(pPixmap, pgc, nPts, FirstPoint,
+ FirstWidth, 1);
+ ptsOut = FirstPoint;
+ width = FirstWidth;
+ nPts = 0;
+ }
+
+ pWETE = pWETE->nextWETE;
+ while (pWETE != pAET)
+ EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
+ pWETE = pWETE->nextWETE;
+ }
+ EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
+ }
+
+ /*
+ * reevaluate the Winding active edge table if we
+ * just had to resort it or if we just exited an edge.
+ */
+ if (drvInsertionSort(&AET) || fixWAET)
+ {
+ drvcomputeWAET(&AET);
+ fixWAET = 0;
+ }
+ }
+ }
+
+ /*
+ * Get any spans that we missed by buffering
+ */
+ (*pgc->ops->FillSpans)(pPixmap, pgc, nPts, FirstPoint, FirstWidth, 1);
+ free(pETEs);
+ drvFreeStorage(SLLBlock.next);
+ return TRUE;
+}
diff --git a/drv/drvpolyrect.c b/drv/drvpolyrect.c
new file mode 100644
index 000000000..55b8e1030
--- /dev/null
+++ b/drv/drvpolyrect.c
@@ -0,0 +1,187 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xprotostr.h>
+#include "regionstr.h"
+#include "drv_gcstruct.h"
+#include "drv_pixmap.h"
+#include "drv_mi.h"
+
+void
+drvPolyRectangle(PixmapPtr pPixmap, DrvGCPtr pGC, int nrects, xRectangle *pRects)
+{
+ int i;
+ xRectangle *pR = pRects;
+ DDXPointRec rect[5];
+ int bound_tmp;
+
+#define MINBOUND(dst,eqn) bound_tmp = eqn; \
+ if (bound_tmp < -32768) \
+ bound_tmp = -32768; \
+ dst = bound_tmp;
+
+#define MAXBOUND(dst,eqn) bound_tmp = eqn; \
+ if (bound_tmp > 32767) \
+ bound_tmp = 32767; \
+ dst = bound_tmp;
+
+#define MAXUBOUND(dst,eqn) bound_tmp = eqn; \
+ if (bound_tmp > 65535) \
+ bound_tmp = 65535; \
+ dst = bound_tmp;
+
+ if (pGC->lineStyle == LineSolid && pGC->joinStyle == JoinMiter &&
+ pGC->lineWidth != 0)
+ {
+ xRectangle *tmp, *t;
+ int ntmp;
+ int offset1, offset2, offset3;
+ int x, y, width, height;
+
+ ntmp = (nrects << 2);
+ offset2 = pGC->lineWidth;
+ offset1 = offset2 >> 1;
+ offset3 = offset2 - offset1;
+ tmp = malloc(ntmp * sizeof (xRectangle));
+ if (!tmp)
+ return;
+ t = tmp;
+ for (i = 0; i < nrects; i++)
+ {
+ x = pR->x;
+ y = pR->y;
+ width = pR->width;
+ height = pR->height;
+ pR++;
+ if (width == 0 && height == 0)
+ {
+ rect[0].x = x;
+ rect[0].y = y;
+ rect[1].x = x;
+ rect[1].y = y;
+ (*pGC->ops->Polylines)(pPixmap, pGC, CoordModeOrigin, 2, rect);
+ }
+ else if (height < offset2 || width < offset1)
+ {
+ if (height == 0)
+ {
+ t->x = x;
+ t->width = width;
+ }
+ else
+ {
+ MINBOUND (t->x, x - offset1)
+ MAXUBOUND (t->width, width + offset2)
+ }
+ if (width == 0)
+ {
+ t->y = y;
+ t->height = height;
+ }
+ else
+ {
+ MINBOUND (t->y, y - offset1)
+ MAXUBOUND (t->height, height + offset2)
+ }
+ t++;
+ }
+ else
+ {
+ MINBOUND(t->x, x - offset1)
+ MINBOUND(t->y, y - offset1)
+ MAXUBOUND(t->width, width + offset2)
+ t->height = offset2;
+ t++;
+ MINBOUND(t->x, x - offset1)
+ MAXBOUND(t->y, y + offset3);
+ t->width = offset2;
+ t->height = height - offset2;
+ t++;
+ MAXBOUND(t->x, x + width - offset1);
+ MAXBOUND(t->y, y + offset3)
+ t->width = offset2;
+ t->height = height - offset2;
+ t++;
+ MINBOUND(t->x, x - offset1)
+ MAXBOUND(t->y, y + height - offset1)
+ MAXUBOUND(t->width, width + offset2)
+ t->height = offset2;
+ t++;
+ }
+ }
+ (*pGC->ops->PolyFillRect) (pPixmap, pGC, t - tmp, tmp);
+ free((pointer) tmp);
+ }
+ else
+ {
+
+ for (i=0; i<nrects; i++)
+ {
+ rect[0].x = pR->x;
+ rect[0].y = pR->y;
+
+ MAXBOUND(rect[1].x, pR->x + (int) pR->width)
+ rect[1].y = rect[0].y;
+
+ rect[2].x = rect[1].x;
+ MAXBOUND(rect[2].y, pR->y + (int) pR->height);
+
+ rect[3].x = rect[0].x;
+ rect[3].y = rect[2].y;
+
+ rect[4].x = rect[0].x;
+ rect[4].y = rect[0].y;
+
+ (*pGC->ops->Polylines)(pPixmap, pGC, CoordModeOrigin, 5, rect);
+ pR++;
+ }
+ }
+}
diff --git a/drv/mipolyseg.c b/drv/drvpolyseg.c
index 1ad354c89..1ad354c89 100644
--- a/drv/mipolyseg.c
+++ b/drv/drvpolyseg.c
diff --git a/drv/drvpolytext.c b/drv/drvpolytext.c
new file mode 100644
index 000000000..d275d7f52
--- /dev/null
+++ b/drv/drvpolytext.c
@@ -0,0 +1,130 @@
+/*******************************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+/*
+ * mipolytext.c - text routines
+ *
+ * Author: haynes
+ * Digital Equipment Corporation
+ * Western Software Laboratory
+ * Date: Thu Feb 5 1987
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "drv_gcstruct.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "drv_mi.h"
+
+int
+drvPolyText8(PixmapPtr pPixmap, DrvGCPtr pGC, int x, int y, int count, char *chars)
+{
+ unsigned long n, i;
+ int w;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
+ Linear8Bit, &n, charinfo);
+ w = 0;
+ for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
+ if (n != 0)
+ (*pGC->ops->PolyGlyphBlt)(
+ pPixmap, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
+ return x+w;
+}
+
+int
+drvPolyText16(PixmapPtr pPixmap, DrvGCPtr pGC, int x, int y, int count, unsigned short *chars)
+{
+ unsigned long n, i;
+ int w;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, charinfo);
+ w = 0;
+ for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
+ if (n != 0)
+ (*pGC->ops->PolyGlyphBlt)(
+ pPixmap, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
+ return x+w;
+}
+
+void
+drvImageText8(PixmapPtr pPixmap, DrvGCPtr pGC, int x, int y, int count, char *chars)
+{
+ unsigned long n;
+ FontPtr font = pGC->font;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(font, (unsigned long)count, (unsigned char *)chars,
+ Linear8Bit, &n, charinfo);
+ if (n !=0 )
+ (*pGC->ops->ImageGlyphBlt)(pPixmap, pGC, x, y, n, charinfo, FONTGLYPHS(font));
+}
+
+void
+drvImageText16(PixmapPtr pPixmap, DrvGCPtr pGC, int x, int y,
+ int count, unsigned short *chars)
+{
+ unsigned long n;
+ FontPtr font = pGC->font;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, charinfo);
+ if (n !=0 )
+ (*pGC->ops->ImageGlyphBlt)(pPixmap, pGC, x, y, n, charinfo, FONTGLYPHS(font));
+}
diff --git a/drv/drvpolyutil.c b/drv/drvpolyutil.c
new file mode 100644
index 000000000..7f7b6628c
--- /dev/null
+++ b/drv/drvpolyutil.c
@@ -0,0 +1,385 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "regionstr.h"
+#include "drv_gc.h"
+#include "drvscanfill.h"
+#include "drvpoly.h"
+#include "misc.h" /* MAXINT */
+
+/*
+ * fillUtils.c
+ *
+ * Written by Brian Kelleher; Oct. 1985
+ *
+ * This module contains all of the utility functions
+ * needed to scan convert a polygon.
+ *
+ */
+
+/*
+ * InsertEdgeInET
+ *
+ * Insert the given edge into the edge table.
+ * First we must find the correct bucket in the
+ * Edge table, then find the right slot in the
+ * bucket. Finally, we can insert it.
+ *
+ */
+static Bool
+drvInsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE, int scanline,
+ ScanLineListBlock **SLLBlock, int *iSLLBlock)
+{
+ EdgeTableEntry *start, *prev;
+ ScanLineList *pSLL, *pPrevSLL;
+ ScanLineListBlock *tmpSLLBlock;
+
+ /*
+ * find the right bucket to put the edge into
+ */
+ pPrevSLL = &ET->scanlines;
+ pSLL = pPrevSLL->next;
+ while (pSLL && (pSLL->scanline < scanline))
+ {
+ pPrevSLL = pSLL;
+ pSLL = pSLL->next;
+ }
+
+ /*
+ * reassign pSLL (pointer to ScanLineList) if necessary
+ */
+ if ((!pSLL) || (pSLL->scanline > scanline))
+ {
+ if (*iSLLBlock > SLLSPERBLOCK-1)
+ {
+ tmpSLLBlock = malloc(sizeof(ScanLineListBlock));
+ if (!tmpSLLBlock)
+ return FALSE;
+ (*SLLBlock)->next = tmpSLLBlock;
+ tmpSLLBlock->next = NULL;
+ *SLLBlock = tmpSLLBlock;
+ *iSLLBlock = 0;
+ }
+ pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
+
+ pSLL->next = pPrevSLL->next;
+ pSLL->edgelist = NULL;
+ pPrevSLL->next = pSLL;
+ }
+ pSLL->scanline = scanline;
+
+ /*
+ * now insert the edge in the right bucket
+ */
+ prev = NULL;
+ start = pSLL->edgelist;
+ while (start && (start->bres.minor < ETE->bres.minor))
+ {
+ prev = start;
+ start = start->next;
+ }
+ ETE->next = start;
+
+ if (prev)
+ prev->next = ETE;
+ else
+ pSLL->edgelist = ETE;
+ return TRUE;
+}
+
+/*
+ * CreateEdgeTable
+ *
+ * This routine creates the edge table for
+ * scan converting polygons.
+ * The Edge Table (ET) looks like:
+ *
+ * EdgeTable
+ * --------
+ * | ymax | ScanLineLists
+ * |scanline|-->------------>-------------->...
+ * -------- |scanline| |scanline|
+ * |edgelist| |edgelist|
+ * --------- ---------
+ * | |
+ * | |
+ * V V
+ * list of ETEs list of ETEs
+ *
+ * where ETE is an EdgeTableEntry data structure,
+ * and there is one ScanLineList per scanline at
+ * which an edge is initially entered.
+ *
+ */
+
+Bool
+drvCreateETandAET(int count, DDXPointPtr pts, EdgeTable *ET, EdgeTableEntry *AET,
+ EdgeTableEntry *pETEs, ScanLineListBlock *pSLLBlock)
+{
+ DDXPointPtr top, bottom;
+ DDXPointPtr PrevPt, CurrPt;
+ int iSLLBlock = 0;
+
+ int dy;
+
+ if (count < 2) return TRUE;
+
+ /*
+ * initialize the Active Edge Table
+ */
+ AET->next = NULL;
+ AET->back = NULL;
+ AET->nextWETE = NULL;
+ AET->bres.minor = MININT;
+
+ /*
+ * initialize the Edge Table.
+ */
+ ET->scanlines.next = NULL;
+ ET->ymax = MININT;
+ ET->ymin = MAXINT;
+ pSLLBlock->next = NULL;
+
+ PrevPt = &pts[count-1];
+
+ /*
+ * for each vertex in the array of points.
+ * In this loop we are dealing with two vertices at
+ * a time -- these make up one edge of the polygon.
+ */
+ while (count--)
+ {
+ CurrPt = pts++;
+
+ /*
+ * find out which point is above and which is below.
+ */
+ if (PrevPt->y > CurrPt->y)
+ {
+ bottom = PrevPt, top = CurrPt;
+ pETEs->ClockWise = 0;
+ }
+ else
+ {
+ bottom = CurrPt, top = PrevPt;
+ pETEs->ClockWise = 1;
+ }
+
+ /*
+ * don't add horizontal edges to the Edge table.
+ */
+ if (bottom->y != top->y)
+ {
+ pETEs->ymax = bottom->y-1; /* -1 so we don't get last scanline */
+
+ /*
+ * initialize integer edge algorithm
+ */
+ dy = bottom->y - top->y;
+ BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres);
+
+ if (!drvInsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock))
+ {
+ drvFreeStorage(pSLLBlock->next);
+ return FALSE;
+ }
+
+ ET->ymax = max(ET->ymax, PrevPt->y);
+ ET->ymin = min(ET->ymin, PrevPt->y);
+ pETEs++;
+ }
+
+ PrevPt = CurrPt;
+ }
+ return TRUE;
+}
+
+/*
+ * loadAET
+ *
+ * This routine moves EdgeTableEntries from the
+ * EdgeTable into the Active Edge Table,
+ * leaving them sorted by smaller x coordinate.
+ *
+ */
+
+void
+drvloadAET(EdgeTableEntry *AET, EdgeTableEntry *ETEs)
+{
+ EdgeTableEntry *pPrevAET;
+ EdgeTableEntry *tmp;
+
+ pPrevAET = AET;
+ AET = AET->next;
+ while (ETEs)
+ {
+ while (AET && (AET->bres.minor < ETEs->bres.minor))
+ {
+ pPrevAET = AET;
+ AET = AET->next;
+ }
+ tmp = ETEs->next;
+ ETEs->next = AET;
+ if (AET)
+ AET->back = ETEs;
+ ETEs->back = pPrevAET;
+ pPrevAET->next = ETEs;
+ pPrevAET = ETEs;
+
+ ETEs = tmp;
+ }
+}
+
+/*
+ * computeWAET
+ *
+ * This routine links the AET by the
+ * nextWETE (winding EdgeTableEntry) link for
+ * use by the winding number rule. The final
+ * Active Edge Table (AET) might look something
+ * like:
+ *
+ * AET
+ * ---------- --------- ---------
+ * |ymax | |ymax | |ymax |
+ * | ... | |... | |... |
+ * |next |->|next |->|next |->...
+ * |nextWETE| |nextWETE| |nextWETE|
+ * --------- --------- ^--------
+ * | | |
+ * V-------------------> V---> ...
+ *
+ */
+void
+drvcomputeWAET(EdgeTableEntry *AET)
+{
+ EdgeTableEntry *pWETE;
+ int inside = 1;
+ int isInside = 0;
+
+ AET->nextWETE = NULL;
+ pWETE = AET;
+ AET = AET->next;
+ while (AET)
+ {
+ if (AET->ClockWise)
+ isInside++;
+ else
+ isInside--;
+
+ if ((!inside && !isInside) ||
+ ( inside && isInside))
+ {
+ pWETE->nextWETE = AET;
+ pWETE = AET;
+ inside = !inside;
+ }
+ AET = AET->next;
+ }
+ pWETE->nextWETE = NULL;
+}
+
+/*
+ * InsertionSort
+ *
+ * Just a simple insertion sort using
+ * pointers and back pointers to sort the Active
+ * Edge Table.
+ *
+ */
+
+int
+drvInsertionSort(EdgeTableEntry *AET)
+{
+ EdgeTableEntry *pETEchase;
+ EdgeTableEntry *pETEinsert;
+ EdgeTableEntry *pETEchaseBackTMP;
+ int changed = 0;
+
+ AET = AET->next;
+ while (AET)
+ {
+ pETEinsert = AET;
+ pETEchase = AET;
+ while (pETEchase->back->bres.minor > AET->bres.minor)
+ pETEchase = pETEchase->back;
+
+ AET = AET->next;
+ if (pETEchase != pETEinsert)
+ {
+ pETEchaseBackTMP = pETEchase->back;
+ pETEinsert->back->next = AET;
+ if (AET)
+ AET->back = pETEinsert->back;
+ pETEinsert->next = pETEchase;
+ pETEchase->back->next = pETEinsert;
+ pETEchase->back = pETEinsert;
+ pETEinsert->back = pETEchaseBackTMP;
+ changed = 1;
+ }
+ }
+ return changed;
+}
+
+/*
+ * Clean up our act.
+ */
+void
+drvFreeStorage(ScanLineListBlock *pSLLBlock)
+{
+ ScanLineListBlock *tmpSLLBlock;
+
+ while (pSLLBlock)
+ {
+ tmpSLLBlock = pSLLBlock->next;
+ free(pSLLBlock);
+ pSLLBlock = tmpSLLBlock;
+ }
+}
diff --git a/drv/drvscanfill.h b/drv/drvscanfill.h
new file mode 100644
index 000000000..e318c45b4
--- /dev/null
+++ b/drv/drvscanfill.h
@@ -0,0 +1,147 @@
+/*
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef SCANFILLINCLUDED
+#define SCANFILLINCLUDED
+/*
+ * scanfill.h
+ *
+ * Written by Brian Kelleher; Jan 1985
+ *
+ * This file contains a few macros to help track
+ * the edge of a filled object. The object is assumed
+ * to be filled in scanline order, and thus the
+ * algorithm used is an extension of Bresenham's line
+ * drawing algorithm which assumes that y is always the
+ * major axis.
+ * Since these pieces of code are the same for any filled shape,
+ * it is more convenient to gather the library in one
+ * place, but since these pieces of code are also in
+ * the inner loops of output primitives, procedure call
+ * overhead is out of the question.
+ * See the author for a derivation if needed.
+ */
+
+
+/*
+ * In scan converting polygons, we want to choose those pixels
+ * which are inside the polygon. Thus, we add .5 to the starting
+ * x coordinate for both left and right edges. Now we choose the
+ * first pixel which is inside the pgon for the left edge and the
+ * first pixel which is outside the pgon for the right edge.
+ * Draw the left pixel, but not the right.
+ *
+ * How to add .5 to the starting x coordinate:
+ * If the edge is moving to the right, then subtract dy from the
+ * error term from the general form of the algorithm.
+ * If the edge is moving to the left, then add dy to the error term.
+ *
+ * The reason for the difference between edges moving to the left
+ * and edges moving to the right is simple: If an edge is moving
+ * to the right, then we want the algorithm to flip immediately.
+ * If it is moving to the left, then we don't want it to flip until
+ * we traverse an entire pixel.
+ */
+#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \
+ int dx; /* local storage */ \
+\
+ /* \
+ * if the edge is horizontal, then it is ignored \
+ * and assumed not to be processed. Otherwise, do this stuff. \
+ */ \
+ if ((dy) != 0) { \
+ xStart = (x1); \
+ dx = (x2) - xStart; \
+ if (dx < 0) { \
+ m = dx / (dy); \
+ m1 = m - 1; \
+ incr1 = -2 * dx + 2 * (dy) * m1; \
+ incr2 = -2 * dx + 2 * (dy) * m; \
+ d = 2 * m * (dy) - 2 * dx - 2 * (dy); \
+ } else { \
+ m = dx / (dy); \
+ m1 = m + 1; \
+ incr1 = 2 * dx - 2 * (dy) * m1; \
+ incr2 = 2 * dx - 2 * (dy) * m; \
+ d = -2 * m * (dy) + 2 * dx; \
+ } \
+ } \
+}
+
+#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \
+ if (m1 > 0) { \
+ if (d > 0) { \
+ minval += m1; \
+ d += incr1; \
+ } \
+ else { \
+ minval += m; \
+ d += incr2; \
+ } \
+ } else {\
+ if (d >= 0) { \
+ minval += m1; \
+ d += incr1; \
+ } \
+ else { \
+ minval += m; \
+ d += incr2; \
+ } \
+ } \
+}
+
+
+/*
+ * This structure contains all of the information needed
+ * to run the bresenham algorithm.
+ * The variables may be hardcoded into the declarations
+ * instead of using this structure to make use of
+ * register declarations.
+ */
+typedef struct {
+ int minor; /* minor axis */
+ int d; /* decision variable */
+ int m, m1; /* slope and slope+1 */
+ int incr1, incr2; /* error increments */
+} BRESINFO;
+
+
+#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \
+ BRESINITPGON(dmaj, min1, min2, bres.minor, bres.d, \
+ bres.m, bres.m1, bres.incr1, bres.incr2)
+
+#define BRESINCRPGONSTRUCT(bres) \
+ BRESINCRPGON(bres.d, bres.minor, bres.m, bres.m1, bres.incr1, bres.incr2)
+
+
+#endif
diff --git a/drv/drvwideline.c b/drv/drvwideline.c
index cfa8d3308..299361bae 100644
--- a/drv/drvwideline.c
+++ b/drv/drvwideline.c
@@ -2082,7 +2082,7 @@ drvWideDash (PixmapPtr pPixmap, DrvGCPtr pGC,
projectRight = FALSE;
dashIndex = 0;
dashOffset = 0;
- miStepDash ((int)pGC->dashOffset, &dashIndex,
+ drvStepDash ((int)pGC->dashOffset, &dashIndex,
pGC->dash, (int)pGC->numInDashList, &dashOffset);
while (--npt)
{
diff --git a/drv/drvzerclip.c b/drv/drvzerclip.c
new file mode 100644
index 000000000..fc16f8b0e
--- /dev/null
+++ b/drv/drvzerclip.c
@@ -0,0 +1,630 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "mi.h"
+#include "miline.h"
+
+/*
+
+The bresenham error equation used in the mi/mfb/cfb line routines is:
+
+ e = error
+ dx = difference in raw X coordinates
+ dy = difference in raw Y coordinates
+ M = # of steps in X direction
+ N = # of steps in Y direction
+ B = 0 to prefer diagonal steps in a given octant,
+ 1 to prefer axial steps in a given octant
+
+ For X major lines:
+ e = 2Mdy - 2Ndx - dx - B
+ -2dx <= e < 0
+
+ For Y major lines:
+ e = 2Ndx - 2Mdy - dy - B
+ -2dy <= e < 0
+
+At the start of the line, we have taken 0 X steps and 0 Y steps,
+so M = 0 and N = 0:
+
+ X major e = 2Mdy - 2Ndx - dx - B
+ = -dx - B
+
+ Y major e = 2Ndx - 2Mdy - dy - B
+ = -dy - B
+
+At the end of the line, we have taken dx X steps and dy Y steps,
+so M = dx and N = dy:
+
+ X major e = 2Mdy - 2Ndx - dx - B
+ = 2dxdy - 2dydx - dx - B
+ = -dx - B
+ Y major e = 2Ndx - 2Mdy - dy - B
+ = 2dydx - 2dxdy - dy - B
+ = -dy - B
+
+Thus, the error term is the same at the start and end of the line.
+
+Let us consider clipping an X coordinate. There are 4 cases which
+represent the two independent cases of clipping the start vs. the
+end of the line and an X major vs. a Y major line. In any of these
+cases, we know the number of X steps (M) and we wish to find the
+number of Y steps (N). Thus, we will solve our error term equation.
+If we are clipping the start of the line, we will find the smallest
+N that satisfies our error term inequality. If we are clipping the
+end of the line, we will find the largest number of Y steps that
+satisfies the inequality. In that case, since we are representing
+the Y steps as (dy - N), we will actually want to solve for the
+smallest N in that equation.
+
+Case 1: X major, starting X coordinate moved by M steps
+
+ -2dx <= 2Mdy - 2Ndx - dx - B < 0
+ 2Ndx <= 2Mdy - dx - B + 2dx 2Ndx > 2Mdy - dx - B
+ 2Ndx <= 2Mdy + dx - B N > (2Mdy - dx - B) / 2dx
+ N <= (2Mdy + dx - B) / 2dx
+
+Since we are trying to find the smallest N that satisfies these
+equations, we should use the > inequality to find the smallest:
+
+ N = floor((2Mdy - dx - B) / 2dx) + 1
+ = floor((2Mdy - dx - B + 2dx) / 2dx)
+ = floor((2Mdy + dx - B) / 2dx)
+
+Case 1b: X major, ending X coordinate moved to M steps
+
+Same derivations as Case 1, but we want the largest N that satisfies
+the equations, so we use the <= inequality:
+
+ N = floor((2Mdy + dx - B) / 2dx)
+
+Case 2: X major, ending X coordinate moved by M steps
+
+ -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
+ -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
+ -2dx <= 2Ndx - 2Mdy - dx - B < 0
+ 2Ndx >= 2Mdy + dx + B - 2dx 2Ndx < 2Mdy + dx + B
+ 2Ndx >= 2Mdy - dx + B N < (2Mdy + dx + B) / 2dx
+ N >= (2Mdy - dx + B) / 2dx
+
+Since we are trying to find the highest number of Y steps that
+satisfies these equations, we need to find the smallest N, so
+we should use the >= inequality to find the smallest:
+
+ N = ceiling((2Mdy - dx + B) / 2dx)
+ = floor((2Mdy - dx + B + 2dx - 1) / 2dx)
+ = floor((2Mdy + dx + B - 1) / 2dx)
+
+Case 2b: X major, starting X coordinate moved to M steps from end
+
+Same derivations as Case 2, but we want the smallest number of Y
+steps, so we want the highest N, so we use the < inequality:
+
+ N = ceiling((2Mdy + dx + B) / 2dx) - 1
+ = floor((2Mdy + dx + B + 2dx - 1) / 2dx) - 1
+ = floor((2Mdy + dx + B + 2dx - 1 - 2dx) / 2dx)
+ = floor((2Mdy + dx + B - 1) / 2dx)
+
+Case 3: Y major, starting X coordinate moved by M steps
+
+ -2dy <= 2Ndx - 2Mdy - dy - B < 0
+ 2Ndx >= 2Mdy + dy + B - 2dy 2Ndx < 2Mdy + dy + B
+ 2Ndx >= 2Mdy - dy + B N < (2Mdy + dy + B) / 2dx
+ N >= (2Mdy - dy + B) / 2dx
+
+Since we are trying to find the smallest N that satisfies these
+equations, we should use the >= inequality to find the smallest:
+
+ N = ceiling((2Mdy - dy + B) / 2dx)
+ = floor((2Mdy - dy + B + 2dx - 1) / 2dx)
+ = floor((2Mdy - dy + B - 1) / 2dx) + 1
+
+Case 3b: Y major, ending X coordinate moved to M steps
+
+Same derivations as Case 3, but we want the largest N that satisfies
+the equations, so we use the < inequality:
+
+ N = ceiling((2Mdy + dy + B) / 2dx) - 1
+ = floor((2Mdy + dy + B + 2dx - 1) / 2dx) - 1
+ = floor((2Mdy + dy + B + 2dx - 1 - 2dx) / 2dx)
+ = floor((2Mdy + dy + B - 1) / 2dx)
+
+Case 4: Y major, ending X coordinate moved by M steps
+
+ -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
+ -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
+ -2dy <= 2Mdy - 2Ndx - dy - B < 0
+ 2Ndx <= 2Mdy - dy - B + 2dy 2Ndx > 2Mdy - dy - B
+ 2Ndx <= 2Mdy + dy - B N > (2Mdy - dy - B) / 2dx
+ N <= (2Mdy + dy - B) / 2dx
+
+Since we are trying to find the highest number of Y steps that
+satisfies these equations, we need to find the smallest N, so
+we should use the > inequality to find the smallest:
+
+ N = floor((2Mdy - dy - B) / 2dx) + 1
+
+Case 4b: Y major, starting X coordinate moved to M steps from end
+
+Same analysis as Case 4, but we want the smallest number of Y steps
+which means the largest N, so we use the <= inequality:
+
+ N = floor((2Mdy + dy - B) / 2dx)
+
+Now let's try the Y coordinates, we have the same 4 cases.
+
+Case 5: X major, starting Y coordinate moved by N steps
+
+ -2dx <= 2Mdy - 2Ndx - dx - B < 0
+ 2Mdy >= 2Ndx + dx + B - 2dx 2Mdy < 2Ndx + dx + B
+ 2Mdy >= 2Ndx - dx + B M < (2Ndx + dx + B) / 2dy
+ M >= (2Ndx - dx + B) / 2dy
+
+Since we are trying to find the smallest M, we use the >= inequality:
+
+ M = ceiling((2Ndx - dx + B) / 2dy)
+ = floor((2Ndx - dx + B + 2dy - 1) / 2dy)
+ = floor((2Ndx - dx + B - 1) / 2dy) + 1
+
+Case 5b: X major, ending Y coordinate moved to N steps
+
+Same derivations as Case 5, but we want the largest M that satisfies
+the equations, so we use the < inequality:
+
+ M = ceiling((2Ndx + dx + B) / 2dy) - 1
+ = floor((2Ndx + dx + B + 2dy - 1) / 2dy) - 1
+ = floor((2Ndx + dx + B + 2dy - 1 - 2dy) / 2dy)
+ = floor((2Ndx + dx + B - 1) / 2dy)
+
+Case 6: X major, ending Y coordinate moved by N steps
+
+ -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
+ -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
+ -2dx <= 2Ndx - 2Mdy - dx - B < 0
+ 2Mdy <= 2Ndx - dx - B + 2dx 2Mdy > 2Ndx - dx - B
+ 2Mdy <= 2Ndx + dx - B M > (2Ndx - dx - B) / 2dy
+ M <= (2Ndx + dx - B) / 2dy
+
+Largest # of X steps means smallest M, so use the > inequality:
+
+ M = floor((2Ndx - dx - B) / 2dy) + 1
+
+Case 6b: X major, starting Y coordinate moved to N steps from end
+
+Same derivations as Case 6, but we want the smallest # of X steps
+which means the largest M, so use the <= inequality:
+
+ M = floor((2Ndx + dx - B) / 2dy)
+
+Case 7: Y major, starting Y coordinate moved by N steps
+
+ -2dy <= 2Ndx - 2Mdy - dy - B < 0
+ 2Mdy <= 2Ndx - dy - B + 2dy 2Mdy > 2Ndx - dy - B
+ 2Mdy <= 2Ndx + dy - B M > (2Ndx - dy - B) / 2dy
+ M <= (2Ndx + dy - B) / 2dy
+
+To find the smallest M, use the > inequality:
+
+ M = floor((2Ndx - dy - B) / 2dy) + 1
+ = floor((2Ndx - dy - B + 2dy) / 2dy)
+ = floor((2Ndx + dy - B) / 2dy)
+
+Case 7b: Y major, ending Y coordinate moved to N steps
+
+Same derivations as Case 7, but we want the largest M that satisfies
+the equations, so use the <= inequality:
+
+ M = floor((2Ndx + dy - B) / 2dy)
+
+Case 8: Y major, ending Y coordinate moved by N steps
+
+ -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
+ -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
+ -2dy <= 2Mdy - 2Ndx - dy - B < 0
+ 2Mdy >= 2Ndx + dy + B - 2dy 2Mdy < 2Ndx + dy + B
+ 2Mdy >= 2Ndx - dy + B M < (2Ndx + dy + B) / 2dy
+ M >= (2Ndx - dy + B) / 2dy
+
+To find the highest X steps, find the smallest M, use the >= inequality:
+
+ M = ceiling((2Ndx - dy + B) / 2dy)
+ = floor((2Ndx - dy + B + 2dy - 1) / 2dy)
+ = floor((2Ndx + dy + B - 1) / 2dy)
+
+Case 8b: Y major, starting Y coordinate moved to N steps from the end
+
+Same derivations as Case 8, but we want to find the smallest # of X
+steps which means the largest M, so we use the < inequality:
+
+ M = ceiling((2Ndx + dy + B) / 2dy) - 1
+ = floor((2Ndx + dy + B + 2dy - 1) / 2dy) - 1
+ = floor((2Ndx + dy + B + 2dy - 1 - 2dy) / 2dy)
+ = floor((2Ndx + dy + B - 1) / 2dy)
+
+So, our equations are:
+
+ 1: X major move x1 to x1+M floor((2Mdy + dx - B) / 2dx)
+ 1b: X major move x2 to x1+M floor((2Mdy + dx - B) / 2dx)
+ 2: X major move x2 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
+ 2b: X major move x1 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
+
+ 3: Y major move x1 to x1+M floor((2Mdy - dy + B - 1) / 2dx) + 1
+ 3b: Y major move x2 to x1+M floor((2Mdy + dy + B - 1) / 2dx)
+ 4: Y major move x2 to x2-M floor((2Mdy - dy - B) / 2dx) + 1
+ 4b: Y major move x1 to x2-M floor((2Mdy + dy - B) / 2dx)
+
+ 5: X major move y1 to y1+N floor((2Ndx - dx + B - 1) / 2dy) + 1
+ 5b: X major move y2 to y1+N floor((2Ndx + dx + B - 1) / 2dy)
+ 6: X major move y2 to y2-N floor((2Ndx - dx - B) / 2dy) + 1
+ 6b: X major move y1 to y2-N floor((2Ndx + dx - B) / 2dy)
+
+ 7: Y major move y1 to y1+N floor((2Ndx + dy - B) / 2dy)
+ 7b: Y major move y2 to y1+N floor((2Ndx + dy - B) / 2dy)
+ 8: Y major move y2 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
+ 8b: Y major move y1 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
+
+We have the following constraints on all of the above terms:
+
+ 0 < M,N <= 2^15 2^15 can be imposed by miZeroClipLine
+ 0 <= dx/dy <= 2^16 - 1
+ 0 <= B <= 1
+
+The floor in all of the above equations can be accomplished with a
+simple C divide operation provided that both numerator and denominator
+are positive.
+
+Since dx,dy >= 0 and since moving an X coordinate implies that dx != 0
+and moving a Y coordinate implies dy != 0, we know that the denominators
+are all > 0.
+
+For all lines, (-B) and (B-1) are both either 0 or -1, depending on the
+bias. Thus, we have to show that the 2MNdxy +/- dxy terms are all >= 1
+or > 0 to prove that the numerators are positive (or zero).
+
+For X Major lines we know that dx > 0 and since 2Mdy is >= 0 due to the
+constraints, the first four equations all have numerators >= 0.
+
+For the second four equations, M > 0, so 2Mdy >= 2dy so (2Mdy - dy) >= dy
+So (2Mdy - dy) > 0, since they are Y major lines. Also, (2Mdy + dy) >= 3dy
+or (2Mdy + dy) > 0. So all of their numerators are >= 0.
+
+For the third set of four equations, N > 0, so 2Ndx >= 2dx so (2Ndx - dx)
+>= dx > 0. Similarly (2Ndx + dx) >= 3dx > 0. So all numerators >= 0.
+
+For the fourth set of equations, dy > 0 and 2Ndx >= 0, so all numerators
+are > 0.
+
+To consider overflow, consider the case of 2 * M,N * dx,dy + dx,dy. This
+is bounded <= 2 * 2^15 * (2^16 - 1) + (2^16 - 1)
+ <= 2^16 * (2^16 - 1) + (2^16 - 1)
+ <= 2^32 - 2^16 + 2^16 - 1
+ <= 2^32 - 1
+Since the (-B) and (B-1) terms are all 0 or -1, the maximum value of
+the numerator is therefore (2^32 - 1), which does not overflow an unsigned
+32 bit variable.
+
+*/
+
+/* Bit codes for the terms of the 16 clipping equations defined below. */
+
+#define T_2NDX (1 << 0)
+#define T_2MDY (0) /* implicit term */
+#define T_DXNOTY (1 << 1)
+#define T_DYNOTX (0) /* implicit term */
+#define T_SUBDXORY (1 << 2)
+#define T_ADDDX (T_DXNOTY) /* composite term */
+#define T_SUBDX (T_DXNOTY | T_SUBDXORY) /* composite term */
+#define T_ADDDY (T_DYNOTX) /* composite term */
+#define T_SUBDY (T_DYNOTX | T_SUBDXORY) /* composite term */
+#define T_BIASSUBONE (1 << 3)
+#define T_SUBBIAS (0) /* implicit term */
+#define T_DIV2DX (1 << 4)
+#define T_DIV2DY (0) /* implicit term */
+#define T_ADDONE (1 << 5)
+
+/* Bit masks defining the 16 equations used in miZeroClipLine. */
+
+#define EQN1 (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
+#define EQN1B (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
+#define EQN2 (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
+#define EQN2B (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
+
+#define EQN3 (T_2MDY | T_SUBDY | T_BIASSUBONE | T_DIV2DX | T_ADDONE)
+#define EQN3B (T_2MDY | T_ADDDY | T_BIASSUBONE | T_DIV2DX)
+#define EQN4 (T_2MDY | T_SUBDY | T_SUBBIAS | T_DIV2DX | T_ADDONE)
+#define EQN4B (T_2MDY | T_ADDDY | T_SUBBIAS | T_DIV2DX)
+
+#define EQN5 (T_2NDX | T_SUBDX | T_BIASSUBONE | T_DIV2DY | T_ADDONE)
+#define EQN5B (T_2NDX | T_ADDDX | T_BIASSUBONE | T_DIV2DY)
+#define EQN6 (T_2NDX | T_SUBDX | T_SUBBIAS | T_DIV2DY | T_ADDONE)
+#define EQN6B (T_2NDX | T_ADDDX | T_SUBBIAS | T_DIV2DY)
+
+#define EQN7 (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
+#define EQN7B (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
+#define EQN8 (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
+#define EQN8B (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
+
+/* drvZeroClipLine
+ *
+ * returns: 1 for partially clipped line
+ * -1 for completely clipped line
+ *
+ */
+int
+drvZeroClipLine(int xmin, int ymin, int xmax, int ymax,
+ int *new_x1, int *new_y1, int *new_x2, int *new_y2,
+ unsigned int adx, unsigned int ady,
+ int *pt1_clipped, int *pt2_clipped,
+ int octant, unsigned int bias,
+ int oc1, int oc2)
+{
+ int swapped = 0;
+ int clipDone = 0;
+ CARD32 utmp = 0;
+ int clip1, clip2;
+ int x1, y1, x2, y2;
+ int x1_orig, y1_orig, x2_orig, y2_orig;
+ int xmajor;
+ int negslope = 0, anchorval = 0;
+ unsigned int eqn = 0;
+
+ x1 = x1_orig = *new_x1;
+ y1 = y1_orig = *new_y1;
+ x2 = x2_orig = *new_x2;
+ y2 = y2_orig = *new_y2;
+
+ clip1 = 0;
+ clip2 = 0;
+
+ xmajor = IsXMajorOctant(octant);
+ bias = ((bias >> octant) & 1);
+
+ while (1)
+ {
+ if ((oc1 & oc2) != 0) /* trivial reject */
+ {
+ clipDone = -1;
+ clip1 = oc1;
+ clip2 = oc2;
+ break;
+ }
+ else if ((oc1 | oc2) == 0) /* trivial accept */
+ {
+ clipDone = 1;
+ if (swapped)
+ {
+ SWAPINT_PAIR(x1, y1, x2, y2);
+ SWAPINT(clip1, clip2);
+ }
+ break;
+ }
+ else /* have to clip */
+ {
+ /* only clip one point at a time */
+ if (oc1 == 0)
+ {
+ SWAPINT_PAIR(x1, y1, x2, y2);
+ SWAPINT_PAIR(x1_orig, y1_orig, x2_orig, y2_orig);
+ SWAPINT(oc1, oc2);
+ SWAPINT(clip1, clip2);
+ swapped = !swapped;
+ }
+
+ clip1 |= oc1;
+ if (oc1 & OUT_LEFT)
+ {
+ negslope = IsYDecreasingOctant(octant);
+ utmp = xmin - x1_orig;
+ if (utmp <= 32767) /* clip based on near endpt */
+ {
+ if (xmajor)
+ eqn = (swapped) ? EQN2 : EQN1;
+ else
+ eqn = (swapped) ? EQN4 : EQN3;
+ anchorval = y1_orig;
+ }
+ else /* clip based on far endpt */
+ {
+ utmp = x2_orig - xmin;
+ if (xmajor)
+ eqn = (swapped) ? EQN1B : EQN2B;
+ else
+ eqn = (swapped) ? EQN3B : EQN4B;
+ anchorval = y2_orig;
+ negslope = !negslope;
+ }
+ x1 = xmin;
+ }
+ else if (oc1 & OUT_ABOVE)
+ {
+ negslope = IsXDecreasingOctant(octant);
+ utmp = ymin - y1_orig;
+ if (utmp <= 32767) /* clip based on near endpt */
+ {
+ if (xmajor)
+ eqn = (swapped) ? EQN6 : EQN5;
+ else
+ eqn = (swapped) ? EQN8 : EQN7;
+ anchorval = x1_orig;
+ }
+ else /* clip based on far endpt */
+ {
+ utmp = y2_orig - ymin;
+ if (xmajor)
+ eqn = (swapped) ? EQN5B : EQN6B;
+ else
+ eqn = (swapped) ? EQN7B : EQN8B;
+ anchorval = x2_orig;
+ negslope = !negslope;
+ }
+ y1 = ymin;
+ }
+ else if (oc1 & OUT_RIGHT)
+ {
+ negslope = IsYDecreasingOctant(octant);
+ utmp = x1_orig - xmax;
+ if (utmp <= 32767) /* clip based on near endpt */
+ {
+ if (xmajor)
+ eqn = (swapped) ? EQN2 : EQN1;
+ else
+ eqn = (swapped) ? EQN4 : EQN3;
+ anchorval = y1_orig;
+ }
+ else /* clip based on far endpt */
+ {
+ /*
+ * Technically since the equations can handle
+ * utmp == 32768, this overflow code isn't
+ * needed since X11 protocol can't generate
+ * a line which goes more than 32768 pixels
+ * to the right of a clip rectangle.
+ */
+ utmp = xmax - x2_orig;
+ if (xmajor)
+ eqn = (swapped) ? EQN1B : EQN2B;
+ else
+ eqn = (swapped) ? EQN3B : EQN4B;
+ anchorval = y2_orig;
+ negslope = !negslope;
+ }
+ x1 = xmax;
+ }
+ else if (oc1 & OUT_BELOW)
+ {
+ negslope = IsXDecreasingOctant(octant);
+ utmp = y1_orig - ymax;
+ if (utmp <= 32767) /* clip based on near endpt */
+ {
+ if (xmajor)
+ eqn = (swapped) ? EQN6 : EQN5;
+ else
+ eqn = (swapped) ? EQN8 : EQN7;
+ anchorval = x1_orig;
+ }
+ else /* clip based on far endpt */
+ {
+ /*
+ * Technically since the equations can handle
+ * utmp == 32768, this overflow code isn't
+ * needed since X11 protocol can't generate
+ * a line which goes more than 32768 pixels
+ * below the bottom of a clip rectangle.
+ */
+ utmp = ymax - y2_orig;
+ if (xmajor)
+ eqn = (swapped) ? EQN5B : EQN6B;
+ else
+ eqn = (swapped) ? EQN7B : EQN8B;
+ anchorval = x2_orig;
+ negslope = !negslope;
+ }
+ y1 = ymax;
+ }
+
+ if (swapped)
+ negslope = !negslope;
+
+ utmp <<= 1; /* utmp = 2N or 2M */
+ if (eqn & T_2NDX)
+ utmp = (utmp * adx);
+ else /* (eqn & T_2MDY) */
+ utmp = (utmp * ady);
+ if (eqn & T_DXNOTY)
+ if (eqn & T_SUBDXORY)
+ utmp -= adx;
+ else
+ utmp += adx;
+ else /* (eqn & T_DYNOTX) */
+ if (eqn & T_SUBDXORY)
+ utmp -= ady;
+ else
+ utmp += ady;
+ if (eqn & T_BIASSUBONE)
+ utmp += bias - 1;
+ else /* (eqn & T_SUBBIAS) */
+ utmp -= bias;
+ if (eqn & T_DIV2DX)
+ utmp /= (adx << 1);
+ else /* (eqn & T_DIV2DY) */
+ utmp /= (ady << 1);
+ if (eqn & T_ADDONE)
+ utmp++;
+
+ if (negslope)
+ utmp = -utmp;
+
+ if (eqn & T_2NDX) /* We are calculating X steps */
+ x1 = anchorval + utmp;
+ else /* else, Y steps */
+ y1 = anchorval + utmp;
+
+ oc1 = 0;
+ MIOUTCODES(oc1, x1, y1, xmin, ymin, xmax, ymax);
+ }
+ }
+
+ *new_x1 = x1;
+ *new_y1 = y1;
+ *new_x2 = x2;
+ *new_y2 = y2;
+
+ *pt1_clipped = clip1;
+ *pt2_clipped = clip2;
+
+ return clipDone;
+}
diff --git a/drv/drvzerline.c b/drv/drvzerline.c
new file mode 100644
index 000000000..275bb3e30
--- /dev/null
+++ b/drv/drvzerline.c
@@ -0,0 +1,378 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "drv_gcstruct.h"
+#include "drv_pixmapstr.h"
+#include "drv_mi.h"
+#include "drvline.h"
+
+/* Draw lineSolid, fillStyle-independent zero width lines.
+ *
+ * Must keep X and Y coordinates in "ints" at least until after they're
+ * translated and clipped to accomodate CoordModePrevious lines with very
+ * large coordinates.
+ *
+ * Draws the same pixels regardless of sign(dx) or sign(dy).
+ *
+ * Ken Whaley
+ *
+ */
+
+/* largest positive value that can fit into a component of a point.
+ * Assumes that the point structure is {type x, y;} where type is
+ * a signed type.
+ */
+#define MAX_COORDINATE ((1 << (((sizeof(DDXPointRec) >> 1) << 3) - 1)) - 1)
+
+#define MI_OUTPUT_POINT(xx, yy)\
+{\
+ if ( !new_span && yy == current_y)\
+ {\
+ if (xx < spans->x)\
+ spans->x = xx;\
+ ++*widths;\
+ }\
+ else\
+ {\
+ ++Nspans;\
+ ++spans;\
+ ++widths;\
+ spans->x = xx;\
+ spans->y = yy;\
+ *widths = 1;\
+ current_y = yy;\
+ new_span = FALSE;\
+ }\
+}
+
+void
+drvZeroLine(
+ PixmapPtr pDraw,
+ DrvGCPtr pGC,
+ int mode, /* Origin or Previous */
+ int npt, /* number of points */
+ DDXPointPtr pptInit)
+{
+ int Nspans, current_y = 0;
+ DDXPointPtr ppt;
+ DDXPointPtr pspanInit, spans;
+ int *pwidthInit, *widths, list_len;
+ int xleft, ytop, xright, ybottom;
+ int new_x1, new_y1, new_x2, new_y2;
+ int x = 0, y = 0, x1, y1, x2, y2, xstart, ystart;
+ int oc1, oc2;
+ int result;
+ int pt1_clipped, pt2_clipped = 0;
+ Bool new_span;
+ int signdx, signdy;
+ int clipdx, clipdy;
+ int width, height;
+ int adx, ady;
+ int octant;
+ unsigned int bias = drvGetZeroLineBias(pDraw->pScreen);
+ int e, e1, e2, e3; /* Bresenham error terms */
+ int length; /* length of lines == # of pixels on major axis */
+
+ xleft = 0;
+ ytop = 0;
+ xright = 0 + pDraw->width - 1;
+ ybottom = 0 + pDraw->height - 1;
+
+ if (!pGC->miTranslate)
+ {
+ /* do everything in drawable-relative coordinates */
+ xleft = 0;
+ ytop = 0;
+ xright -= 0;
+ ybottom -= 0;
+ }
+
+ /* it doesn't matter whether we're in drawable or screen coordinates,
+ * FillSpans simply cannot take starting coordinates outside of the
+ * range of a DDXPointRec component.
+ */
+ if (xright > MAX_COORDINATE)
+ xright = MAX_COORDINATE;
+ if (ybottom > MAX_COORDINATE)
+ ybottom = MAX_COORDINATE;
+
+ /* since we're clipping to the drawable's boundaries & coordinate
+ * space boundaries, we're guaranteed that the larger of width/height
+ * is the longest span we'll need to output
+ */
+ width = xright - xleft + 1;
+ height = ybottom - ytop + 1;
+ list_len = (height >= width) ? height : width;
+ pspanInit = malloc(list_len * sizeof(DDXPointRec));
+ pwidthInit = malloc(list_len * sizeof(int));
+ if (!pspanInit || !pwidthInit)
+ return;
+
+ Nspans = 0;
+ new_span = TRUE;
+ spans = pspanInit - 1;
+ widths = pwidthInit - 1;
+ ppt = pptInit;
+
+ xstart = ppt->x;
+ ystart = ppt->y;
+ if (pGC->miTranslate)
+ {
+ xstart += 0;
+ ystart += 0;
+ }
+
+ /* x2, y2, oc2 copied to x1, y1, oc1 at top of loop to simplify
+ * iteration logic
+ */
+ x2 = xstart;
+ y2 = ystart;
+ oc2 = 0;
+ MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom);
+
+ while (--npt > 0)
+ {
+ if (Nspans > 0)
+ (*pGC->ops->FillSpans)(pDraw, pGC, Nspans, pspanInit,
+ pwidthInit, FALSE);
+ Nspans = 0;
+ new_span = TRUE;
+ spans = pspanInit - 1;
+ widths = pwidthInit - 1;
+
+ x1 = x2;
+ y1 = y2;
+ oc1 = oc2;
+ ++ppt;
+
+ x2 = ppt->x;
+ y2 = ppt->y;
+ if (pGC->miTranslate && (mode != CoordModePrevious))
+ {
+ x2 += 0;
+ y2 += 0;
+ }
+ else if (mode == CoordModePrevious)
+ {
+ x2 += x1;
+ y2 += y1;
+ }
+
+ oc2 = 0;
+ MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom);
+
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
+
+ if (adx > ady)
+ {
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ length = adx; /* don't draw endpoint in main loop */
+
+ FIXUP_ERROR(e, octant, bias);
+
+ new_x1 = x1;
+ new_y1 = y1;
+ new_x2 = x2;
+ new_y2 = y2;
+ pt1_clipped = 0;
+ pt2_clipped = 0;
+
+ if ((oc1 | oc2) != 0)
+ {
+ result = drvZeroClipLine(xleft, ytop, xright, ybottom,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady,
+ &pt1_clipped, &pt2_clipped,
+ octant, bias, oc1, oc2);
+ if (result == -1)
+ continue;
+
+ length = abs(new_x2 - new_x1);
+
+ /* if we've clipped the endpoint, always draw the full length
+ * of the segment, because then the capstyle doesn't matter
+ */
+ if (pt2_clipped)
+ length++;
+
+ if (pt1_clipped)
+ {
+ /* must calculate new error terms */
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ e += (clipdy * e2) + ((clipdx - clipdy) * e1);
+ }
+ }
+
+ /* draw the segment */
+
+ x = new_x1;
+ y = new_y1;
+
+ e3 = e2 - e1;
+ e = e - e1;
+
+ while (length--)
+ {
+ MI_OUTPUT_POINT(x, y);
+ e += e1;
+ if (e >= 0)
+ {
+ y += signdy;
+ e += e3;
+ }
+ x += signdx;
+ }
+ }
+ else /* Y major line */
+ {
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ length = ady; /* don't draw endpoint in main loop */
+
+ SetYMajorOctant(octant);
+ FIXUP_ERROR(e, octant, bias);
+
+ new_x1 = x1;
+ new_y1 = y1;
+ new_x2 = x2;
+ new_y2 = y2;
+ pt1_clipped = 0;
+ pt2_clipped = 0;
+
+ if ((oc1 | oc2) != 0)
+ {
+ result = drvZeroClipLine(xleft, ytop, xright, ybottom,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady,
+ &pt1_clipped, &pt2_clipped,
+ octant, bias, oc1, oc2);
+ if (result == -1)
+ continue;
+
+ length = abs(new_y2 - new_y1);
+
+ /* if we've clipped the endpoint, always draw the full length
+ * of the segment, because then the capstyle doesn't matter
+ */
+ if (pt2_clipped)
+ length++;
+
+ if (pt1_clipped)
+ {
+ /* must calculate new error terms */
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ e += (clipdx * e2) + ((clipdy - clipdx) * e1);
+ }
+ }
+
+ /* draw the segment */
+
+ x = new_x1;
+ y = new_y1;
+
+ e3 = e2 - e1;
+ e = e - e1;
+
+ while (length--)
+ {
+ MI_OUTPUT_POINT(x, y);
+ e += e1;
+ if (e >= 0)
+ {
+ x += signdx;
+ e += e3;
+ }
+ y += signdy;
+ }
+ }
+ }
+
+ /* only do the capnotlast check on the last segment
+ * and only if the endpoint wasn't clipped. And then, if the last
+ * point is the same as the first point, do not draw it, unless the
+ * line is degenerate
+ */
+ if ( (! pt2_clipped) && (pGC->capStyle != CapNotLast) &&
+ (((xstart != x2) || (ystart != y2)) || (ppt == pptInit + 1)))
+ {
+ MI_OUTPUT_POINT(x, y);
+ }
+
+ if (Nspans > 0)
+ (*pGC->ops->FillSpans)(pDraw, pGC, Nspans, pspanInit,
+ pwidthInit, FALSE);
+
+ free(pwidthInit);
+ free(pspanInit);
+}
+
+void
+drvZeroDashLine(
+ PixmapPtr dst,
+ DrvGCPtr pgc,
+ int mode,
+ int nptInit, /* number of points in polyline */
+ DDXPointRec *pptInit /* points in the polyline */
+ )
+{
+ /* XXX kludge until real zero-width dash code is written */
+ pgc->lineWidth = 1;
+ drvWideDash (dst, pgc, mode, nptInit, pptInit);
+ pgc->lineWidth = 0;
+}
diff --git a/fb/fbarc.c b/fb/fbarc.c
index d28125dc8..9831953c7 100644
--- a/fb/fbarc.c
+++ b/fb/fbarc.c
@@ -25,7 +25,7 @@
#endif
#include "fb.h"
-#include "mizerarc.h"
+#include "drvzerarc.h"
#include <limits.h>
typedef void (*FbArc) (FbBits *dst,
@@ -79,7 +79,7 @@ fbPolyArc (PixmapPtr pPixmap,
#endif
while (narcs--)
{
- if (miCanZeroArc (parcs))
+ if (drvCanZeroArc (parcs))
{
box.x1 = parcs->x;
box.y1 = parcs->y;
diff --git a/fb/fbbits.c b/fb/fbbits.c
index 850d1632e..565b9c1b9 100644
--- a/fb/fbbits.c
+++ b/fb/fbbits.c
@@ -25,8 +25,8 @@
#endif
#include "fb.h"
-#include "miline.h"
-#include "mizerarc.h"
+#include "drvline.h"
+#include "drvzerarc.h"
#undef BRESSOLID
#undef BRESDASH
diff --git a/fb/fbbits.h b/fb/fbbits.h
index 4ced7364b..249879dc7 100644
--- a/fb/fbbits.h
+++ b/fb/fbbits.h
@@ -341,7 +341,7 @@ ARC (FbBits *dst,
{
UNIT *bits;
FbStride bitsStride;
- miZeroArcRec info;
+ drvZeroArcRec info;
Bool do360;
int x;
UNIT *yorgp, *yorgop;
@@ -354,12 +354,12 @@ ARC (FbBits *dst,
bitsStride = dstStride * (sizeof (FbBits) / sizeof (UNIT));
andBits = (BITS) and;
xorBits = (BITS) xor;
- do360 = miZeroArcSetup(arc, &info, TRUE);
+ do360 = drvZeroArcSetup(arc, &info, TRUE);
yorgp = bits + ((info.yorg + drawY) * bitsStride);
yorgop = bits + ((info.yorgo + drawY) * bitsStride);
info.xorg = (info.xorg + drawX) * MUL;
info.xorgo = (info.xorgo + drawX) * MUL;
- MIARCSETUP();
+ DRVARCSETUP();
yoffset = y ? bitsStride : 0;
dyoffset = 0;
mask = info.initialMask;
@@ -428,7 +428,7 @@ ARC (FbBits *dst,
ARCRROP(yorghb + xoffset - y * MUL);
}
xoffset += bitsStride;
- MIARCCIRCLESTEP(yoffset += bitsStride;);
+ DRVARCCIRCLESTEP(yoffset += bitsStride;);
}
yorgp -= info.xorg;
yorgop -= info.xorg;
@@ -439,7 +439,7 @@ ARC (FbBits *dst,
{
while (y < info.h || x < info.w)
{
- MIARCOCTANTSHIFT(dyoffset = bitsStride;);
+ DRVARCOCTANTSHIFT(dyoffset = bitsStride;);
if (andBits == 0)
{
ARCCOPY(yorgp + yoffset + info.xorg + x * MUL);
@@ -454,14 +454,14 @@ ARC (FbBits *dst,
ARCRROP(yorgop - yoffset + info.xorgo - x * MUL);
ARCRROP(yorgop - yoffset + info.xorg + x * MUL);
}
- MIARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;);
+ DRVARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;);
}
}
else
{
while (y < info.h || x < info.w)
{
- MIARCOCTANTSHIFT(dyoffset = bitsStride;);
+ DRVARCOCTANTSHIFT(dyoffset = bitsStride;);
if ((x == info.start.x) || (y == info.start.y))
{
mask = info.start.mask;
@@ -494,7 +494,7 @@ ARC (FbBits *dst,
mask = info.end.mask;
info.end = info.altend;
}
- MIARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;);
+ DRVARCSTEP(yoffset += dyoffset;, yoffset += bitsStride;);
}
}
if ((x == info.start.x) || (y == info.start.y))
@@ -669,7 +669,7 @@ POLYLINE (PixmapPtr pPixmap,
INT32 *pts = (INT32 *) ptsOrig;
int xoff = 0;
int yoff = 0;
- unsigned int bias = miGetZeroLineBias(pPixmap->pScreen);
+ unsigned int bias = drvGetZeroLineBias(pPixmap->pScreen);
BoxPtr pBox = RegionExtents(fbGetCompositeClip (pGC));
FbBits *dst;
@@ -806,7 +806,7 @@ POLYSEGMENT (PixmapPtr pPixmap,
INT32 *pts = (INT32 *) pseg;
int xoff = 0;
int yoff = 0;
- unsigned int bias = miGetZeroLineBias(pPixmap->pScreen);
+ unsigned int bias = drvGetZeroLineBias(pPixmap->pScreen);
BoxPtr pBox = RegionExtents(fbGetCompositeClip (pGC));
FbBits *dst;
diff --git a/fb/fbgc.c b/fb/fbgc.c
index c94d3f37a..8d1aa0aeb 100644
--- a/fb/fbgc.c
+++ b/fb/fbgc.c
@@ -39,15 +39,15 @@ const GCOps fbGCOps = {
fbPolyPoint,
fbPolyLine,
fbPolySegment,
- NULL,
+ drvPolyRectangle,
fbPolyArc,
- NULL,
+ drvFillPolygon,
fbPolyFillRect,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
+ drvPolyFillArc,
+ drvPolyText8,
+ drvPolyText16,
+ drvImageText8,
+ drvImageText16,
fbImageGlyphBlt,
fbPolyGlyphBlt,
fbPushPixels,
diff --git a/fb/fbseg.c b/fb/fbseg.c
index 23acf2437..b82607895 100644
--- a/fb/fbseg.c
+++ b/fb/fbseg.c
@@ -27,7 +27,7 @@
#include <stdlib.h>
#include "fb.h"
-#include "miline.h"
+#include "drvline.h"
#define fbBresShiftMask(mask,dir,bpp) ((bpp == FB_STIP_UNIT) ? 0 : \
((dir < 0) ? FbStipLeft(mask,bpp) : \
@@ -606,7 +606,7 @@ fbSegment (PixmapPtr pPixmap,
int octant;
int dashoff;
int doff;
- unsigned int bias = miGetZeroLineBias(pPixmap->pScreen);
+ unsigned int bias = drvGetZeroLineBias(pPixmap->pScreen);
unsigned int oc1; /* outcode of point 1 */
unsigned int oc2; /* outcode of point 2 */
@@ -676,7 +676,7 @@ fbSegment (PixmapPtr pPixmap,
int clipdx, clipdy;
int err;
- if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2-1,
+ if (drvZeroClipLine(pBox->x1, pBox->y1, pBox->x2-1,
pBox->y2-1,
&new_x1, &new_y1, &new_x2, &new_y2,
adx, ady, &clip1, &clip2,
diff --git a/mi/Makefile.am b/mi/Makefile.am
index 3821bbdc5..817d9d25b 100644
--- a/mi/Makefile.am
+++ b/mi/Makefile.am
@@ -40,6 +40,7 @@ libmi_la_SOURCES = \
mipolycon.c \
mipolygen.c \
mipolypnt.c \
+ mipolyrect.c \
mipolyseg.c \
mipolytext.c \
mipolyutil.c \
diff --git a/drv/mipolyrect.c b/mi/mipolyrect.c
index 9b0edc176..9b0edc176 100644
--- a/drv/mipolyrect.c
+++ b/mi/mipolyrect.c