A couple of questions
Carl Worth <[email protected]> Tue, 11 Jun 2002 10:47:21 +0000
| Newsgroups | gmane.comp.xfree86.render |
|---|---|
| Message-ID | <[email protected]> |
On Jun 11, Carl Worth wrote: > For that reason, I was just about to code up > XRenderCompositeDoublePolys. But I think I'll go to bed instead. I'll > probably get to it early tomorrow morning. OK, Here's a patch that implements XRenderCompositeDoublePolys. It implements the behavior I described earlier. That is, it actually renders a single shape described by multiple (possibly intersecting) polygons according to the even-odd or non-zero winding rule. This really isn't the same function that Jorge requested, since calling my XRenderCompositeDoublePolys will give different results than XRenderCompositeDoublePoly multiple times if the polygons intersect. Any votes for better naming here to clear things up? There might still be room for a function to render multiple separate polygons like Jorge wanted. Then again, that might get messy since the results would depend on the order in which order the polygons were rendered. -Carl PS. This patch has one infelicity: it discards a const qualifier. I didn't see a simple way to prevent this without changing the prototype for XRenderCompositeDoublePoly or introducing a needless copy. -- Carl Worth USC Information Sciences Institute [email protected]
Poly.c.diff
(text/plain, 4.5 KB)
Index: Poly.c
===================================================================
RCS file: /mirrors/xfree86/xc/lib/Xrender/Poly.c,v
retrieving revision 1.7
diff -u -r1.7 Poly.c
--- Poly.c 4 Jun 2002 23:22:36 -0000 1.7
+++ Poly.c 6 Jun 2002 14:24:22 -0000
@@ -93,6 +93,7 @@
Edge *active;
Edge *e, *en, *next;
XFixed y, next_y, intersect;
+ int in_out;
qsort (edges, nedges, sizeof (Edge), CompareEdge);
@@ -180,7 +181,7 @@
intersect = XRenderComputeIntersect (&e->edge, &e->next->edge);
/* make sure this point is below the actual intersection */
intersect = intersect + 1;
- if (intersect < next_y)
+ if (intersect < next_y && intersect > y)
next_y = intersect;
}
}
@@ -189,8 +190,24 @@
next_y = edges[inactive].edge.p1.y;
/* walk the list generating trapezoids */
- for (e = active; e && (en = e->next); e = en->next)
+ in_out = 0;
+ for (e = active; e && (en = e->next); e = e->next)
{
+ if (winding) {
+ if (e->clockWise) {
+ in_out++;
+ } else {
+ in_out--;
+ }
+ if (in_out == 0) {
+ continue;
+ }
+ } else {
+ in_out++;
+ if (in_out % 2 == 0) {
+ continue;
+ }
+ }
traps->top = y;
traps->bottom = next_y;
traps->left = e->edge;
@@ -233,65 +250,97 @@
int npoints,
int winding)
{
+ XPolygonDouble poly;
+
+ poly.points = fpoints;
+ poly.npoints = npoints;
+
+ XRenderCompositeDoublePolys(dpy, op, src, dst, maskFormat,
+ xSrc, ySrc, xDst, yDst,
+ &poly, 1, winding);
+}
+
+void
+XRenderCompositeDoublePolys (Display *dpy,
+ int op,
+ Picture src,
+ Picture dst,
+ _Xconst XRenderPictFormat *maskFormat,
+ int xSrc,
+ int ySrc,
+ int xDst,
+ int yDst,
+ _Xconst XPolygonDouble *polys,
+ int npolys,
+ int winding)
+{
Edge *edges;
XTrapezoid *traps;
- int i, nedges, ntraps;
+ int p, i, nedges, ntraps, npoints_total;
XFixed x, y, prevx = 0, prevy = 0, firstx = 0, firsty = 0;
XFixed top = 0, bottom = 0; /* GCCism */
- edges = (Edge *) Xmalloc (npoints * sizeof (Edge) +
- (npoints * npoints * sizeof (XTrapezoid)));
+ npoints_total = 0;
+ for (p = 0; p < npolys; p++) {
+ npoints_total += polys[p].npoints;
+ }
+
+ edges = (Edge *) Xmalloc (npoints_total * sizeof (Edge) +
+ (npoints_total * npoints_total * sizeof (XTrapezoid)));
if (!edges)
return;
- traps = (XTrapezoid *) (edges + npoints);
+ traps = (XTrapezoid *) (edges + npoints_total);
nedges = 0;
- for (i = 0; i <= npoints; i++)
+ for (p = 0; p < npolys; p++)
{
- if (i == npoints)
+ for (i = 0; i <= polys[p].npoints; i++)
{
- x = firstx;
- y = firsty;
- }
- else
- {
- x = XDoubleToFixed (fpoints[i].x);
- y = XDoubleToFixed (fpoints[i].y);
- }
- if (i)
- {
- if (y < top)
+ if (i == polys[p].npoints)
+ {
+ x = firstx;
+ y = firsty;
+ }
+ else
+ {
+ x = XDoubleToFixed (polys[p].points[i].x);
+ y = XDoubleToFixed (polys[p].points[i].y);
+ }
+ if (i)
+ {
+ if (y < top)
+ top = y;
+ else if (y > bottom)
+ bottom = y;
+ if (prevy < y)
+ {
+ edges[nedges].edge.p1.x = prevx;
+ edges[nedges].edge.p1.y = prevy;
+ edges[nedges].edge.p2.x = x;
+ edges[nedges].edge.p2.y = y;
+ edges[nedges].clockWise = True;
+ nedges++;
+ }
+ else if (prevy > y)
+ {
+ edges[nedges].edge.p1.x = x;
+ edges[nedges].edge.p1.y = y;
+ edges[nedges].edge.p2.x = prevx;
+ edges[nedges].edge.p2.y = prevy;
+ edges[nedges].clockWise = False;
+ nedges++;
+ }
+ /* drop horizontal edges */
+ }
+ else
+ {
top = y;
- else if (y > bottom)
bottom = y;
- if (prevy < y)
- {
- edges[nedges].edge.p1.x = prevx;
- edges[nedges].edge.p1.y = prevy;
- edges[nedges].edge.p2.x = x;
- edges[nedges].edge.p2.y = y;
- edges[nedges].clockWise = True;
- nedges++;
- }
- else if (prevy > y)
- {
- edges[nedges].edge.p1.x = x;
- edges[nedges].edge.p1.y = y;
- edges[nedges].edge.p2.x = prevx;
- edges[nedges].edge.p2.y = prevy;
- edges[nedges].clockWise = False;
- nedges++;
- }
- /* drop horizontal edges */
- }
- else
- {
- top = y;
- bottom = y;
- firstx = x;
- firsty = y;
+ firstx = x;
+ firsty = y;
+ }
+ prevx = x;
+ prevy = y;
}
- prevx = x;
- prevy = y;
}
ntraps = XRenderComputeTrapezoids (edges, nedges, winding, traps);
/* XXX adjust xSrc/xDst */