fleshed out rect enumeration method.

This commit is contained in:
michaelp%netscape.com 1999-02-10 00:35:04 +00:00
Родитель 3282820c93
Коммит db932c1eb9
3 изменённых файлов: 142 добавлений и 2 удалений

Просмотреть файл

@ -206,6 +206,8 @@ PRBool nsRegionGTK::ForEachRect(nsRectInRegionFunc *func, void *closure)
BOX *pbox;
nsRect rect;
//code lifted from old xfe. MMP
NS_ASSERTION(!(nsnull == func), "no callback");
pbox = pRegion->rects;
@ -214,9 +216,9 @@ PRBool nsRegionGTK::ForEachRect(nsRectInRegionFunc *func, void *closure)
while (nbox--)
{
rect.x = pbox->x1;
rect.width = (pbox->x2 - pbox->x1) + 1;
rect.width = (pbox->x2 - pbox->x1);
rect.y = pbox->y1;
rect.height = (pbox->y2 - pbox->y1) + 1;
rect.height = (pbox->y2 - pbox->y1);
(*func)(closure, rect);
pbox++;
}

Просмотреть файл

@ -17,6 +17,7 @@
*/
#include "nsRegionMac.h"
#include "prmem.h"
static NS_DEFINE_IID(kRegionIID, NS_IREGION_IID);
@ -178,6 +179,95 @@ PRBool nsRegionMac :: ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt
PRBool nsRegionMac :: ForEachRect(nsRectInRegionFunc *func, void *closure)
{
/* This is a minor adaptation of code written by Hugh Fisher
and published in the RegionToRectangles example in the InfoMac archives.
ported to raptor from old macfe. MMP
*/
#define EndMark 32767
#define MaxY 32767
#define StackMax 1024
typedef struct {
short size;
Rect bbox;
short data[];
} ** Internal;
Internal region;
short width, xAdjust, y, index, x1, x2, x;
nsRect box;
short stackStorage[1024];
short * buffer;
region = (Internal)mRegion;
/* Check for plain rectangle */
if ((**region).size == 10) {
box.x = (**region).bbox.left;
box.y = (**region).bbox.top;
box.width = (**region).bbox.right - box.x;
box.height = (**region).bbox.bottom - box.y;
(*func)(closure, box);
return PR_FALSE;
}
/* Got to scale x coordinates into range 0..something */
xAdjust = (**region).bbox.left;
width = (**region).bbox.right - xAdjust;
/* Most regions will be less than 1024 pixels wide */
if (width < StackMax)
buffer = stackStorage;
else {
buffer = (short *)PR_Malloc(width * 2);
if (buffer == NULL)
/* Truly humungous region or very low on memory.
Quietly doing nothing seems to be the
traditional Quickdraw response. */
return PR_FALSE;
}
/* Initialise scan line list to bottom edges */
for (x = (**region).bbox.left; x < (**region).bbox.right; x++)
buffer[x - xAdjust] = MaxY;
index = 0;
/* Loop until we hit an empty scan line */
while ((**region).data[index] != EndMark) {
y = (**region).data[index];
index ++;
/* Loop through horizontal runs on this line */
while ((**region).data[index] != EndMark) {
x1 = (**region).data[index];
index ++;
x2 = (**region).data[index];
index ++;
x = x1;
while (x < x2) {
if (buffer[x - xAdjust] < y) {
/* We have a bottom edge - how long for? */
box.x = x;
box.y = buffer[x - xAdjust];
while (x < x2 && buffer[x - xAdjust] == box.y) {
buffer[x - xAdjust] = MaxY;
x ++;
}
/* Pass to client proc */
box.width = x - box.x;
box.height = y - box.y;
(*func)(closure, box);
} else {
/* This becomes a top edge */
buffer[x - xAdjust] = y;
x ++;
}
}
}
index ++;
}
/* Clean up after ourselves */
if (width >= StackMax)
PR_Free((void *)buffer);
#undef EndMark
#undef MaxY
#undef StackMax
return PR_FALSE;
}

Просмотреть файл

@ -17,6 +17,7 @@
*/
#include "nsRegionWin.h"
#include "prmem.h"
static NS_DEFINE_IID(kRegionIID, NS_IREGION_IID);
@ -168,6 +169,53 @@ PRBool nsRegionWin :: ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt
PRBool nsRegionWin :: ForEachRect(nsRectInRegionFunc *func, void *closure)
{
LPRGNDATA pRgnData;
LPRECT pRects;
DWORD dwCount, dwResult;
unsigned int num_rects;
nsRect rect;
// code lifted from old winfe. MMP
NS_ASSERTION(!(nsnull == func), "no callback");
/* Get the size of the region data */
dwCount = GetRegionData(mRegion, 0, NULL);
NS_ASSERTION(!(dwCount == 0), "bad region");
if (dwCount == 0)
return PR_FALSE;
pRgnData = (LPRGNDATA)PR_Malloc(dwCount);
NS_ASSERTION(!(nsnull == pRgnData), "failed allocation");
if (pRgnData == NULL)
return PR_FALSE;
dwResult = GetRegionData(mRegion, dwCount, pRgnData);
NS_ASSERTION(!(dwResult == 0), "get data failed");
if (dwResult == 0) {
PR_Free(pRgnData);
return PR_FALSE;
}
for (pRects = (LPRECT)pRgnData->Buffer, num_rects = 0;
num_rects < pRgnData->rdh.nCount;
num_rects++, pRects++)
{
rect.x = pRects->left;
rect.y = pRects->top;
rect.width = pRects->right - rect.x;
rect.height = pRects->bottom - rect.y;
(*func)(closure, rect);
}
PR_Free(pRgnData);
return PR_FALSE;
}