Commit 9fe77b4d authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

gdi32: Exponentially grow successive point buffers.

parent 77568fd0
...@@ -173,31 +173,28 @@ static inline BOOL is_in_rect( const RECT *rect, int x, int y ) ...@@ -173,31 +173,28 @@ static inline BOOL is_in_rect( const RECT *rect, int x, int y )
} }
/* /*
* number of points to buffer before sending them off
* to scanlines() : Must be an even number
*/
#define NUMPTSTOBUFFER 200
/*
* used to allocate buffers for points and link * used to allocate buffers for points and link
* the buffers together * the buffers together
*/ */
struct point_block struct point_block
{ {
POINT pts[NUMPTSTOBUFFER]; int count, size;
int count;
struct point_block *next; struct point_block *next;
POINT pts[1]; /* Variable sized array - must be last. */
}; };
static struct point_block *add_point( struct point_block *block, int x, int y ) static struct point_block *add_point( struct point_block *block, int x, int y )
{ {
if (block->count == NUMPTSTOBUFFER) if (block->count == block->size)
{ {
struct point_block *new = HeapAlloc( GetProcessHeap(), 0, sizeof(*new) ); struct point_block *new;
int size = block->size * 2;
new = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( struct point_block, pts[size] ) );
if (!new) return NULL; if (!new) return NULL;
block->next = new; block->next = new;
new->count = 0; new->count = 0;
new->size = size;
new->next = NULL; new->next = NULL;
block = new; block = new;
} }
...@@ -2676,6 +2673,9 @@ static WINEREGION *REGION_PtsToRegion( struct point_block *FirstPtBlock ) ...@@ -2676,6 +2673,9 @@ static WINEREGION *REGION_PtsToRegion( struct point_block *FirstPtBlock )
return reg; return reg;
} }
/* Number of points in the first point buffer. Must be an even number. */
#define NUMPTSTOBUFFER 200
/*********************************************************************** /***********************************************************************
* CreatePolyPolygonRgn (GDI32.@) * CreatePolyPolygonRgn (GDI32.@)
*/ */
...@@ -2692,7 +2692,8 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count, ...@@ -2692,7 +2692,8 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
EdgeTableEntry *pETEs; /* EdgeTableEntries pool */ EdgeTableEntry *pETEs; /* EdgeTableEntries pool */
ScanLineListBlock SLLBlock; /* header for scanlinelist */ ScanLineListBlock SLLBlock; /* header for scanlinelist */
BOOL fixWAET = FALSE; BOOL fixWAET = FALSE;
struct point_block FirstPtBlock, *block; /* PtBlock buffers */ char first_blk_buf[FIELD_OFFSET( struct point_block, pts[NUMPTSTOBUFFER] )];
struct point_block *first_block = (struct point_block *)first_blk_buf, *block;
struct edge_table_entry *active, *next; struct edge_table_entry *active, *next;
INT poly, total; INT poly, total;
...@@ -2721,9 +2722,10 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count, ...@@ -2721,9 +2722,10 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
REGION_CreateEdgeTable(Count, nbpolygons, Pts, &ET, pETEs, &SLLBlock); REGION_CreateEdgeTable(Count, nbpolygons, Pts, &ET, pETEs, &SLLBlock);
list_init( &AET ); list_init( &AET );
pSLL = ET.scanlines.next; pSLL = ET.scanlines.next;
block = &FirstPtBlock; block = first_block;
FirstPtBlock.count = 0; first_block->count = 0;
FirstPtBlock.next = NULL; first_block->size = NUMPTSTOBUFFER;
first_block->next = NULL;
if (mode != WINDING) { if (mode != WINDING) {
/* /*
...@@ -2802,13 +2804,13 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count, ...@@ -2802,13 +2804,13 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
} }
} }
if (!(obj = REGION_PtsToRegion( &FirstPtBlock ))) goto done; if (!(obj = REGION_PtsToRegion( first_block ))) goto done;
if (!(hrgn = alloc_gdi_handle( obj, OBJ_REGION, &region_funcs ))) if (!(hrgn = alloc_gdi_handle( obj, OBJ_REGION, &region_funcs )))
free_region( obj ); free_region( obj );
done: done:
REGION_FreeStorage(SLLBlock.next); REGION_FreeStorage(SLLBlock.next);
free_point_blocks( FirstPtBlock.next ); free_point_blocks( first_block->next );
HeapFree( GetProcessHeap(), 0, pETEs ); HeapFree( GetProcessHeap(), 0, pETEs );
return hrgn; return hrgn;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment