gdi32: Move the scan conversion to a helper function.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1b33e0f72e
commit
31605eb417
|
@ -2583,67 +2583,25 @@ static void REGION_FreeStorage(ScanLineListBlock *pSLLBlock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
static void scan_convert( WINEREGION *obj, EdgeTable *ET, INT mode, const RECT *clip_rect )
|
||||||
* 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;
|
struct list AET;
|
||||||
WINEREGION *obj = NULL;
|
ScanLineList *pSLL;
|
||||||
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 edge_table_entry *active;
|
struct edge_table_entry *active;
|
||||||
unsigned int nb_points;
|
INT i, y, first = 1, cur_band = 0, prev_band = 0;
|
||||||
int cur_band = 0, prev_band = 0;
|
|
||||||
INT i, poly, total, first = 1;
|
|
||||||
|
|
||||||
TRACE("%p, count %d, polygons %d, mode %d\n", Pts, *Count, nbpolygons, mode);
|
if (clip_rect) ET->ymax = min( ET->ymax, clip_rect->bottom );
|
||||||
|
|
||||||
/* 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 )))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (clip_rect) ET.ymax = min( ET.ymax, clip_rect->bottom );
|
|
||||||
list_init( &AET );
|
list_init( &AET );
|
||||||
pSLL = ET.scanlines.next;
|
pSLL = ET->scanlines.next;
|
||||||
if (mode != WINDING) {
|
|
||||||
/*
|
if (mode != WINDING)
|
||||||
* for each scanline
|
{
|
||||||
*/
|
for (y = ET->ymin; y < ET->ymax; y++)
|
||||||
for (y = ET.ymin; y < ET.ymax; y++) {
|
{
|
||||||
/*
|
/* Add a new edge to the active edge table when we get to the next edge. */
|
||||||
* Add a new edge to the active edge table when we
|
if (pSLL != NULL && y == pSLL->scanline)
|
||||||
* get to the next edge.
|
{
|
||||||
*/
|
|
||||||
if (pSLL != NULL && y == pSLL->scanline) {
|
|
||||||
REGION_loadAET(&AET, &pSLL->edgelist);
|
REGION_loadAET(&AET, &pSLL->edgelist);
|
||||||
pSLL = pSLL->next;
|
pSLL = pSLL->next;
|
||||||
}
|
}
|
||||||
|
@ -2676,33 +2634,26 @@ HRGN create_polypolygon_region( const POINT *Pts, const INT *Count, INT nbpolygo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else /* mode == WINDING */
|
||||||
/*
|
{
|
||||||
* for each scanline
|
struct list WETE, *pWETE;
|
||||||
*/
|
|
||||||
for (y = ET.ymin; y < ET.ymax; y++) {
|
for (y = ET->ymin; y < ET->ymax; y++)
|
||||||
/*
|
{
|
||||||
* Add a new edge to the active edge table when we
|
/* Add a new edge to the active edge table when we get to the next edge. */
|
||||||
* get to the next edge.
|
if (pSLL != NULL && y == pSLL->scanline)
|
||||||
*/
|
{
|
||||||
if (pSLL != NULL && y == pSLL->scanline) {
|
|
||||||
REGION_loadAET(&AET, &pSLL->edgelist);
|
REGION_loadAET(&AET, &pSLL->edgelist);
|
||||||
REGION_computeWAET( &AET, &WETE );
|
REGION_computeWAET( &AET, &WETE );
|
||||||
pSLL = pSLL->next;
|
pSLL = pSLL->next;
|
||||||
}
|
}
|
||||||
pWETE = list_head( &WETE );
|
pWETE = list_head( &WETE );
|
||||||
|
|
||||||
/*
|
|
||||||
* for each active edge
|
|
||||||
*/
|
|
||||||
if (!clip_rect || y >= clip_rect->top)
|
if (!clip_rect || y >= clip_rect->top)
|
||||||
{
|
{
|
||||||
LIST_FOR_EACH_ENTRY( active, &AET, struct edge_table_entry, entry )
|
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 (pWETE == &active->winding_entry)
|
||||||
{
|
{
|
||||||
if (first)
|
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 (next_scanline( &AET, y )) REGION_computeWAET( &AET, &WETE );
|
||||||
|
|
||||||
if (obj->numRects)
|
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)
|
if (obj->numRects)
|
||||||
{
|
{
|
||||||
|
@ -2751,11 +2699,55 @@ HRGN create_polypolygon_region( const POINT *Pts, const INT *Count, INT nbpolygo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
REGION_compact( obj );
|
REGION_compact( 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, ®ion_funcs )))
|
if (!(hrgn = alloc_gdi_handle( obj, OBJ_REGION, ®ion_funcs )))
|
||||||
free_region( obj );
|
free_region( obj );
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
REGION_FreeStorage(SLLBlock.next);
|
REGION_FreeStorage(SLLBlock.next);
|
||||||
HeapFree( GetProcessHeap(), 0, pETEs );
|
HeapFree( GetProcessHeap(), 0, pETEs );
|
||||||
return hrgn;
|
return hrgn;
|
||||||
|
|
Loading…
Reference in New Issue