[PATCH v3 1/2] gdi32: Move the scan conversion to a helper function.

Huw Davies huw at codeweavers.com
Tue Jun 9 04:54:48 CDT 2020


Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/gdi32/region.c | 154 +++++++++++++++++++++-----------------------
 1 file changed, 73 insertions(+), 81 deletions(-)

diff --git a/dlls/gdi32/region.c b/dlls/gdi32/region.c
index 93238b5a843..893b6d6f4d3 100644
--- a/dlls/gdi32/region.c
+++ b/dlls/gdi32/region.c
@@ -2583,67 +2583,25 @@ static void REGION_FreeStorage(ScanLineListBlock *pSLLBlock)
     }
 }
 
-/***********************************************************************
- *           create_polypolygon_region
- *
- * Helper for CreatePolyPolygonRgn.
- */
-HRGN create_polypolygon_region( const POINT *Pts, const INT *Count, INT nbpolygons, INT mode,
-                                const RECT *clip_rect )
+static void scan_convert( WINEREGION *obj, EdgeTable *ET, INT mode, const RECT *clip_rect )
 {
-    HRGN hrgn = 0;
-    WINEREGION *obj = NULL;
-    INT y;                           /* current scanline        */
-    struct list WETE, *pWETE;        /* Winding Edge Table */
-    ScanLineList *pSLL;              /* current scanLineList    */
-    EdgeTable ET;                    /* header node for ET      */
-    struct list AET;                 /* header for AET     */
-    EdgeTableEntry *pETEs;           /* EdgeTableEntries pool   */
-    ScanLineListBlock SLLBlock;      /* header for scanlinelist */
+    struct list AET;
+    ScanLineList *pSLL;
     struct edge_table_entry *active;
-    unsigned int nb_points;
-    int cur_band = 0, prev_band = 0;
-    INT i, poly, total, first = 1;
+    INT i, y, first = 1, cur_band = 0, prev_band = 0;
 
-    TRACE("%p, count %d, polygons %d, mode %d\n", Pts, *Count, nbpolygons, mode);
-
-    /* special case a rectangle */
+    if (clip_rect) ET->ymax = min( ET->ymax, clip_rect->bottom );
 
-    if (((nbpolygons == 1) && ((*Count == 4) ||
-       ((*Count == 5) && (Pts[4].x == Pts[0].x) && (Pts[4].y == Pts[0].y)))) &&
-	(((Pts[0].y == Pts[1].y) &&
-	  (Pts[1].x == Pts[2].x) &&
-	  (Pts[2].y == Pts[3].y) &&
-	  (Pts[3].x == Pts[0].x)) ||
-	 ((Pts[0].x == Pts[1].x) &&
-	  (Pts[1].y == Pts[2].y) &&
-	  (Pts[2].x == Pts[3].x) &&
-	  (Pts[3].y == Pts[0].y))))
-        return CreateRectRgn( min(Pts[0].x, Pts[2].x), min(Pts[0].y, Pts[2].y),
-                              max(Pts[0].x, Pts[2].x), max(Pts[0].y, Pts[2].y) );
-
-    for(poly = total = 0; poly < nbpolygons; poly++)
-        total += Count[poly];
-    if (! (pETEs = HeapAlloc( GetProcessHeap(), 0, sizeof(EdgeTableEntry) * total )))
-	return 0;
-
-    nb_points = REGION_CreateEdgeTable( Count, nbpolygons, Pts, &ET, pETEs, &SLLBlock, clip_rect );
-    if (!(obj = alloc_region( nb_points / 2 )))
-        goto done;
-
-    if (clip_rect) ET.ymax = min( ET.ymax, clip_rect->bottom );
     list_init( &AET );
-    pSLL = ET.scanlines.next;
-    if (mode != WINDING) {
-        /*
-         *  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 != NULL && y == pSLL->scanline) {
+    pSLL = ET->scanlines.next;
+
+    if (mode != WINDING)
+    {
+        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 != NULL && y == pSLL->scanline)
+            {
                 REGION_loadAET(&AET, &pSLL->edgelist);
                 pSLL = pSLL->next;
             }
@@ -2676,33 +2634,26 @@ HRGN create_polypolygon_region( const POINT *Pts, const INT *Count, INT nbpolygo
             }
         }
     }
-    else {
-        /*
-         *  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 != NULL && y == pSLL->scanline) {
+    else /* mode == WINDING */
+    {
+        struct list WETE, *pWETE;
+
+        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 != NULL && y == pSLL->scanline)
+            {
                 REGION_loadAET(&AET, &pSLL->edgelist);
                 REGION_computeWAET( &AET, &WETE );
                 pSLL = pSLL->next;
             }
             pWETE = list_head( &WETE );
 
-            /*
-             *  for each active edge
-             */
             if (!clip_rect || y >= clip_rect->top)
             {
                 LIST_FOR_EACH_ENTRY( active, &AET, struct edge_table_entry, entry )
                 {
-                    /*
-                     *  add to the buffer only those edges that
-                     *  are in the Winding active edge table.
-                     */
+                    /* Add to the buffer only those edges that are in the Winding active edge table. */
                     if (pWETE == &active->winding_entry)
                     {
                         if (first)
@@ -2722,10 +2673,7 @@ HRGN create_polypolygon_region( const POINT *Pts, const INT *Count, INT nbpolygo
                 }
             }
 
-            /*
-             *  recompute the winding active edge table if
-             *  we just resorted or have exited an edge.
-             */
+            /* Recompute the winding active edge table if we just resorted or have exited an edge. */
             if (next_scanline( &AET, y )) REGION_computeWAET( &AET, &WETE );
 
             if (obj->numRects)
@@ -2736,7 +2684,7 @@ HRGN create_polypolygon_region( const POINT *Pts, const INT *Count, INT nbpolygo
         }
     }
 
-    assert( obj->numRects <= nb_points / 2 );
+    assert( obj->numRects <= obj->size );
 
     if (obj->numRects)
     {
@@ -2751,11 +2699,55 @@ HRGN create_polypolygon_region( const POINT *Pts, const INT *Count, INT nbpolygo
         }
     }
     REGION_compact( obj );
+}
 
-    if (!(hrgn = alloc_gdi_handle( obj, OBJ_REGION, &region_funcs )))
-        free_region( obj );
+/***********************************************************************
+ *           create_polypolygon_region
+ *
+ * Helper for CreatePolyPolygonRgn.
+ */
+HRGN create_polypolygon_region( const POINT *Pts, const INT *Count, INT nbpolygons, INT mode,
+                                const RECT *clip_rect )
+{
+    HRGN hrgn = 0;
+    WINEREGION *obj = NULL;
+    EdgeTable ET;                    /* header node for ET      */
+    EdgeTableEntry *pETEs;           /* EdgeTableEntries pool   */
+    ScanLineListBlock SLLBlock;      /* header for scanlinelist */
+    unsigned int nb_points;
+    INT poly, total;
+
+    TRACE("%p, count %d, polygons %d, mode %d\n", Pts, *Count, nbpolygons, mode);
+
+    /* special case a rectangle */
+
+    if (((nbpolygons == 1) && ((*Count == 4) ||
+       ((*Count == 5) && (Pts[4].x == Pts[0].x) && (Pts[4].y == Pts[0].y)))) &&
+	(((Pts[0].y == Pts[1].y) &&
+	  (Pts[1].x == Pts[2].x) &&
+	  (Pts[2].y == Pts[3].y) &&
+	  (Pts[3].x == Pts[0].x)) ||
+	 ((Pts[0].x == Pts[1].x) &&
+	  (Pts[1].y == Pts[2].y) &&
+	  (Pts[2].x == Pts[3].x) &&
+	  (Pts[3].y == Pts[0].y))))
+        return CreateRectRgn( min(Pts[0].x, Pts[2].x), min(Pts[0].y, Pts[2].y),
+                              max(Pts[0].x, Pts[2].x), max(Pts[0].y, Pts[2].y) );
+
+    for(poly = total = 0; poly < nbpolygons; poly++)
+        total += Count[poly];
+    if (! (pETEs = HeapAlloc( GetProcessHeap(), 0, sizeof(EdgeTableEntry) * total )))
+	return 0;
+
+    nb_points = REGION_CreateEdgeTable( Count, nbpolygons, Pts, &ET, pETEs, &SLLBlock, clip_rect );
+    if ((obj = alloc_region( nb_points / 2 )))
+    {
+        scan_convert( obj, &ET, mode, clip_rect );
+
+        if (!(hrgn = alloc_gdi_handle( obj, OBJ_REGION, &region_funcs )))
+            free_region( obj );
+    }
 
-done:
     REGION_FreeStorage(SLLBlock.next);
     HeapFree( GetProcessHeap(), 0, pETEs );
     return hrgn;
-- 
2.23.0




More information about the wine-devel mailing list