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]

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 */

Reply via email to