Alexandre Julliard : gdi32: Add helper functions to manage blocks of points in CreatePolyPolygonRgn.
Alexandre Julliard
julliard at winehq.org
Tue Apr 23 13:52:23 CDT 2013
Module: wine
Branch: master
Commit: 6a9b775f36e80d1e8a776ccf904dbab11e255fc6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6a9b775f36e80d1e8a776ccf904dbab11e255fc6
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Apr 22 21:57:32 2013 +0200
gdi32: Add helper functions to manage blocks of points in CreatePolyPolygonRgn.
---
dlls/gdi32/region.c | 106 +++++++++++++++++++++++----------------------------
1 files changed, 48 insertions(+), 58 deletions(-)
diff --git a/dlls/gdi32/region.c b/dlls/gdi32/region.c
index 12f106b..bc784dc 100644
--- a/dlls/gdi32/region.c
+++ b/dlls/gdi32/region.c
@@ -165,11 +165,39 @@ static inline BOOL is_in_rect( const RECT *rect, int x, int y )
* the buffers together
*/
-typedef struct _POINTBLOCK {
+struct point_block
+{
POINT pts[NUMPTSTOBUFFER];
- struct _POINTBLOCK *next;
-} POINTBLOCK;
+ int count;
+ struct point_block *next;
+};
+
+static struct point_block *add_point( struct point_block *block, int x, int y )
+{
+ if (block->count == NUMPTSTOBUFFER)
+ {
+ struct point_block *new = HeapAlloc( GetProcessHeap(), 0, sizeof(*new) );
+ if (!new) return NULL;
+ block->next = new;
+ new->count = 0;
+ new->next = NULL;
+ block = new;
+ }
+ block->pts[block->count].x = x;
+ block->pts[block->count].y = y;
+ block->count++;
+ return block;
+}
+static void free_point_blocks( struct point_block *block )
+{
+ while (block)
+ {
+ struct point_block *tmp = block->next;
+ HeapFree( GetProcessHeap(), 0, block );
+ block = tmp;
+ }
+}
/*
@@ -2665,33 +2693,30 @@ static void REGION_FreeStorage(ScanLineListBlock *pSLLBlock)
*
* Create an array of rectangles from a list of points.
*/
-static BOOL REGION_PtsToRegion(int numFullPtBlocks, int iCurPtBlock,
- POINTBLOCK *FirstPtBlock, WINEREGION *reg)
+static BOOL REGION_PtsToRegion( struct point_block *FirstPtBlock, WINEREGION *reg )
{
RECT *rects;
POINT *pts;
- POINTBLOCK *CurPtBlock;
+ struct point_block *pb;
int i;
RECT *extents;
INT numRects;
extents = ®->extents;
- numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1;
+ for (pb = FirstPtBlock, numRects = 0; pb; pb = pb->next) numRects += pb->count;
if (!init_region( reg, numRects )) return FALSE;
reg->size = numRects;
- CurPtBlock = FirstPtBlock;
rects = reg->rects - 1;
numRects = 0;
extents->left = LARGE_COORDINATE, extents->right = SMALL_COORDINATE;
- for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) {
+ for (pb = FirstPtBlock; pb; pb = pb->next)
+ {
/* the loop uses 2 points per iteration */
- i = NUMPTSTOBUFFER >> 1;
- if (!numFullPtBlocks)
- i = iCurPtBlock >> 1;
- for (pts = CurPtBlock->pts; i--; pts += 2) {
+ i = pb->count / 2;
+ for (pts = pb->pts; i--; pts += 2) {
if (pts->x == pts[1].x)
continue;
if (numRects && pts->x == rects->left && pts->y == rects->bottom &&
@@ -2710,7 +2735,6 @@ static BOOL REGION_PtsToRegion(int numFullPtBlocks, int iCurPtBlock,
if (rects->right > extents->right)
extents->right = rects->right;
}
- CurPtBlock = CurPtBlock->next;
}
if (numRects) {
@@ -2737,19 +2761,15 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
WINEREGION *obj;
EdgeTableEntry *pAET; /* Active Edge Table */
INT y; /* current scanline */
- int iPts = 0; /* number of pts in buffer */
EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/
ScanLineList *pSLL; /* current scanLineList */
- POINT *pts; /* output buffer */
EdgeTableEntry *pPrevAET; /* ptr to previous AET */
EdgeTable ET; /* header node for ET */
EdgeTableEntry AET; /* header node for AET */
EdgeTableEntry *pETEs; /* EdgeTableEntries pool */
ScanLineListBlock SLLBlock; /* header for scanlinelist */
int fixWAET = FALSE;
- POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */
- POINTBLOCK *tmpPtBlock;
- int numFullPtBlocks = 0;
+ struct point_block FirstPtBlock, *block; /* PtBlock buffers */
INT poly, total;
TRACE("%p, count %d, polygons %d, mode %d\n", Pts, *Count, nbpolygons, mode);
@@ -2774,10 +2794,11 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
if (! (pETEs = HeapAlloc( GetProcessHeap(), 0, sizeof(EdgeTableEntry) * total )))
return 0;
- pts = FirstPtBlock.pts;
REGION_CreateETandAET(Count, nbpolygons, Pts, &ET, &AET, pETEs, &SLLBlock);
pSLL = ET.scanlines.next;
- curPtBlock = &FirstPtBlock;
+ block = &FirstPtBlock;
+ FirstPtBlock.count = 0;
+ FirstPtBlock.next = NULL;
if (mode != WINDING) {
/*
@@ -2799,21 +2820,8 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
* for each active edge
*/
while (pAET) {
- pts->x = pAET->bres.minor_axis, pts->y = y;
- pts++, iPts++;
-
- /*
- * send out the buffer
- */
- if (iPts == NUMPTSTOBUFFER) {
- tmpPtBlock = HeapAlloc( GetProcessHeap(), 0, sizeof(POINTBLOCK));
- if(!tmpPtBlock) goto done;
- curPtBlock->next = tmpPtBlock;
- curPtBlock = tmpPtBlock;
- pts = curPtBlock->pts;
- numFullPtBlocks++;
- iPts = 0;
- }
+ block = add_point( block, pAET->bres.minor_axis, y );
+ if (!block) goto done;
EVALUATEEDGEEVENODD(pAET, pPrevAET, y);
}
REGION_InsertionSort(&AET);
@@ -2846,22 +2854,8 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
* are in the Winding active edge table.
*/
if (pWETE == pAET) {
- pts->x = pAET->bres.minor_axis, pts->y = y;
- pts++, iPts++;
-
- /*
- * send out the buffer
- */
- if (iPts == NUMPTSTOBUFFER) {
- tmpPtBlock = HeapAlloc( GetProcessHeap(), 0,
- sizeof(POINTBLOCK) );
- if(!tmpPtBlock) goto done;
- curPtBlock->next = tmpPtBlock;
- curPtBlock = tmpPtBlock;
- pts = curPtBlock->pts;
- numFullPtBlocks++;
- iPts = 0;
- }
+ block = add_point( block, pAET->bres.minor_axis, y );
+ if (!block) goto done;
pWETE = pWETE->nextWETE;
}
EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
@@ -2880,7 +2874,7 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
if (!(obj = HeapAlloc( GetProcessHeap(), 0, sizeof(*obj) ))) goto done;
- if (!REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, obj))
+ if (!REGION_PtsToRegion(&FirstPtBlock, obj))
{
HeapFree( GetProcessHeap(), 0, obj );
goto done;
@@ -2893,11 +2887,7 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
done:
REGION_FreeStorage(SLLBlock.next);
- for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
- tmpPtBlock = curPtBlock->next;
- HeapFree( GetProcessHeap(), 0, curPtBlock );
- curPtBlock = tmpPtBlock;
- }
+ free_point_blocks( FirstPtBlock.next );
HeapFree( GetProcessHeap(), 0, pETEs );
return hrgn;
}
More information about the wine-cvs
mailing list