Beispiel #1
0
void
fb_graphicsflush(PSD psd)
{
	MWRECT *prc = fb_updateregion->rects;
	int count = fb_updateregion->numRects;
	int x, y, w, h;
	int n = 1;

	/* use single bounding box extent*/
	x = fb_updateregion->extents.left;
	y = fb_updateregion->extents.top;
	w = fb_updateregion->extents.right - x;
	h = fb_updateregion->extents.bottom - y;
	DPRINTF("Extents: %d (%d,%d %d,%d)\n", count, x, y, w, h);

	/* or loop through individual list*/
	while (--count >= 0) {
		int rx1, ry1, rx2, ry2;

		rx1 = prc->left;
		ry1 = prc->top;
		rx2 = prc->right;
		ry2 = prc->bottom;
		DPRINTF(" %d: %d,%d %d,%d\n", n++, rx1, ry1, rx2-rx1, ry2-ry1);
		++prc;
	}

	/* empty update region*/
	GdSetRectRegion(fb_updateregion, 0, 0, 0, 0);
}
/* clear update region for layered windows repainting.
 * Since layered windows is recursive, you cannot clear this
 * region after the window is painted, since other windows
 * may depend on repainting this region too.  Instead, enqueue
 * a message to clear region until all painting is complete
 */
void chkUpdateRegion(HWND hWnd)
{
	if (hWnd->gotClearRegionMsg == REGION_NEEDSCLEAR)
	{
		hWnd->gotClearRegionMsg = REGION_CLEARED;
		GdSetRectRegion(hWnd->update, 0, 0, 0, 0);
	}	
}
Beispiel #3
0
BOOL WINAPI 
EndPaint(HWND hwnd, CONST PAINTSTRUCT *lpPaint)
{
	ReleaseDC(hwnd, lpPaint->hdc);
#if UPDATEREGIONS
	/* don't clear update region until done dragging*/
	if(mwERASEMOVE && !dragwp)
		GdSetRectRegion(hwnd->update, 0, 0, 0, 0);
#endif
	ShowCaret(hwnd);
	return TRUE;
}
Beispiel #4
0
/*
 * Allows either or both left and top to be greater than right or bottom.
 */
VOID WINAPI
SetRectRgn( HRGN hrgn, INT left, INT top, INT right, INT bottom )
{
    MWRGNOBJ * obj;
    MWCLIPREGION *rgn;

    /*TRACE(region, " %04x %d,%d-%d,%d\n", hrgn, left, top, right, bottom );*/
    
    if (!(obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION ))) return;

    if (left > right) { INT tmp = left; left = right; right = tmp; }
    if (top > bottom) { INT tmp = top; top = bottom; bottom = tmp; }

    rgn = obj->rgn;
    GdSetRectRegion(rgn, left, top, right, bottom);
}
Beispiel #5
0
BOOL WINAPI 
EndPaint(HWND hwnd, CONST PAINTSTRUCT *lpPaint)
{
	if( hwnd->paintBrush != NULL )
		{
		SelectObject ( lpPaint->hdc, GetStockObject(NULL_BRUSH) );
		DeleteObject ( hwnd->paintBrush );
		hwnd->paintBrush = NULL;
		}
	if( hwnd->paintPen != NULL )
		{
		SelectObject ( lpPaint->hdc, GetStockObject(BLACK_PEN) );
		DeleteObject ( hwnd->paintPen );
		hwnd->paintPen = NULL;
		}
	ReleaseDC(hwnd, lpPaint->hdc);
#if UPDATEREGIONS
	/* don't clear update region until done dragging*/
	if(mwERASEMOVE && !dragwp)
		GdSetRectRegion(hwnd->update, 0, 0, 0, 0);
#endif
	ShowCaret(hwnd);
	return TRUE;
}
Beispiel #6
0
/*
 * Set the clip rectangles for a window taking into account other
 * windows that may be obscuring it.  The windows that may be obscuring
 * this one are the siblings of each direct ancestor which are higher
 * in priority than those ancestors.  Also, each parent limits the visible
 * area of the window.  The clipping is not done if it is already up to
 * date of if the window is not outputtable.
 */
void
GsSetClipWindow(GR_WINDOW *wp, MWCLIPREGION *userregion, int flags)
{
	GR_WINDOW	*orgwp;		/* original window pointer */
	GR_WINDOW	*pwp;		/* parent window */
	GR_WINDOW	*sibwp;		/* sibling windows */
	GR_COORD	minx;		/* minimum clip x coordinate */
	GR_COORD	miny;		/* minimum clip y coordinate */
	GR_COORD	maxx;		/* maximum clip x coordinate */
	GR_COORD	maxy;		/* maximum clip y coordinate */
	GR_COORD	diff;		/* difference in coordinates */
	GR_SIZE		bs;		/* border size */
	GR_COORD	x, y, width, height;
	MWCLIPREGION	*vis, *r;

	if (wp->unmapcount || !wp->output)
		return;

	clipwp = wp;

	/*
	 * Start with the rectangle for the complete window.
	 * We will then cut pieces out of it as needed.
	 */
	x = wp->x;
	y = wp->y;
	width = wp->width;
	height = wp->height;

	/*
	 * First walk upwards through all parent windows,
	 * and restrict the visible part of this window to the part
	 * that shows through all of those parent windows.
	 */
	pwp = wp;
	while (pwp != rootwp) {
		pwp = pwp->parent;

		diff = pwp->x - x;
		if (diff > 0) {
			width -= diff;
			x = pwp->x;
		}

		diff = (pwp->x + pwp->width) - (x + width);
		if (diff < 0)
			width += diff;

		diff = pwp->y - y;
		if (diff > 0) {
			height -= diff;
			y = pwp->y;
		}

		diff = (pwp->y + pwp->height) - (y + height);
		if (diff < 0)
			height += diff;
	}

	/*
	 * If the window is completely clipped out of view, then
	 * set the clipping region to indicate that.
	 */
	if (width <= 0 || height <= 0) {
		GdSetClipRegion(clipwp->psd, NULL);
		return;
	}

	/*
	 * Allocate region to clipped size of window
	 */
	vis = GdAllocRectRegion(x, y, x+width, y+height);

	/* 
	 * Allocate temp region
	 */
	r = GdAllocRegion();

	/*
	 * Now examine all windows that obscure this window, and
	 * for each obscuration, break up the clip rectangles into
	 * the smaller pieces that are still visible.  The windows
	 * that can obscure us are the earlier siblings of all of
	 * our parents.
 	 */
	orgwp = wp;
	pwp = wp;
	while (pwp != NULL) {
		wp = pwp;
		pwp = wp->parent;

		if(!pwp) {
			/* We're clipping the root window*/
			if (!(flags & GR_MODE_EXCLUDECHILDREN))
				/* start with root's children*/
				sibwp = rootwp->children;
			else sibwp = NULL;	 /* no search*/
			wp = NULL;		 /* search all root's children*/
		} else {
			sibwp = pwp->children;	 /* clip siblings*/
		}

		for (; sibwp != wp; sibwp = sibwp->siblings) {
			if (sibwp->unmapcount || !sibwp->output)
				continue;

			bs = sibwp->bordersize;
			minx = sibwp->x - bs;
			miny = sibwp->y - bs;
			maxx = sibwp->x + sibwp->width + bs;
			maxy = sibwp->y + sibwp->height + bs;

			GdSetRectRegion(r, minx, miny, maxx, maxy);
			GdSubtractRegion(vis, vis, r);
		}

		/* if not clipping the root window, stop when you reach it*/
		if (pwp == rootwp)
			break;
	}

	wp = orgwp;
	/*
	 * If not the root window, clip all children.
	 * (Root window's children are are clipped above)
	 */
	if(wp != rootwp && !(flags & GR_MODE_EXCLUDECHILDREN)) {
		for (sibwp=wp->children; sibwp; sibwp = sibwp->siblings) {
			if (sibwp->unmapcount || !sibwp->output)
				continue;

			bs = sibwp->bordersize;
			minx = sibwp->x - bs;
			miny = sibwp->y - bs;
			maxx = sibwp->x + sibwp->width + bs;
			maxy = sibwp->y + sibwp->height + bs;

			GdSetRectRegion(r, minx, miny, maxx, maxy);
			GdSubtractRegion(vis, vis, r);
		}
	}

	/*
	 * Intersect with user region, if set.
	 */
	if (userregion) {
		/* temporarily offset region by window coordinates*/
		GdOffsetRegion(userregion, wp->x, wp->y);
		GdIntersectRegion(vis, vis, userregion);
		GdOffsetRegion(userregion, -wp->x, -wp->y);
	}

	/*
	 * Set the clip region (later destroy handled by GdSetClipRegion)
	 */
	GdSetClipRegion(clipwp->psd, vis);

	/*
	 * Destroy temp region
	 */
	GdDestroyRegion(r);
}
Beispiel #7
0
/*
 *           GdAllocPolyPolygonRegion
 */
MWCLIPREGION *
GdAllocPolyPolygonRegion(MWPOINT *points, int *count, int nbpolygons, int mode)
{
    MWCLIPREGION *rgn;
    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    */
    MWPOINT *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;
    int poly, total;

    if(!(rgn = GdAllocRegion()))
        return NULL;

    /* special case a rectangle */

    if (((nbpolygons == 1) && ((*count == 4) ||
       ((*count == 5) && (points[4].x == points[0].x)
        && (points[4].y == points[0].y)))) &&
        (((points[0].y == points[1].y) &&
          (points[1].x == points[2].x) &&
          (points[2].y == points[3].y) &&
          (points[3].x == points[0].x)) ||
         ((points[0].x == points[1].x) &&
          (points[1].y == points[2].y) &&
          (points[2].x == points[3].x) &&
          (points[3].y == points[0].y))))
    {
        GdSetRectRegion( rgn,
	    MWMIN(points[0].x, points[2].x), MWMIN(points[0].y, points[2].y),
	    MWMAX(points[0].x, points[2].x), MWMAX(points[0].y, points[2].y) );
        return rgn;
    }

    for(poly = total = 0; poly < nbpolygons; poly++)
        total += count[poly];
    if (! (pETEs = malloc( sizeof(EdgeTableEntry) * total )))
    {
        GdDestroyRegion( rgn );
        return 0;
    }
    pts = FirstPtBlock.pts;
    REGION_CreateETandAET(count, nbpolygons, points, &ET, &AET,
        pETEs, &SLLBlock);
    pSLL = ET.scanlines.next;
    curPtBlock = &FirstPtBlock;

    if (mode != MWPOLY_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) {
                REGION_loadAET(&AET, pSLL->edgelist);
                pSLL = pSLL->next;
            }
            pPrevAET = &AET;
            pAET = AET.next;

            /*
             *  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 = malloc( sizeof(POINTBLOCK));
                    if(!tmpPtBlock) {
                        return 0;
                    }
                    curPtBlock->next = tmpPtBlock;
                    curPtBlock = tmpPtBlock;
                    pts = curPtBlock->pts;
                    numFullPtBlocks++;
                    iPts = 0;
                }
                EVALUATEEDGEEVENODD(pAET, pPrevAET, y);

            }
            REGION_InsertionSort(&AET);
        }
    }
    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) {
                REGION_loadAET(&AET, pSLL->edgelist);
                REGION_computeWAET(&AET);
                pSLL = pSLL->next;
            }
            pPrevAET = &AET;
            pAET = AET.next;
            pWETE = pAET;

            /*
             *  for each active edge
             */
            while (pAET) {
                /*
                 *  add to the buffer only those edges that
                 *  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 = malloc( sizeof(POINTBLOCK) );
                        if(!tmpPtBlock) {
                            return 0;
                        }
                        curPtBlock->next = tmpPtBlock;
                        curPtBlock = tmpPtBlock;
                        pts = curPtBlock->pts;
                        numFullPtBlocks++;    iPts = 0;
                    }
                    pWETE = pWETE->nextWETE;
                }
                EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
            }

            /*
             *  recompute the winding active edge table if
             *  we just resorted or have exited an edge.
             */
            if (REGION_InsertionSort(&AET) || fixWAET) {
                REGION_computeWAET(&AET);
                fixWAET = FALSE;
            }
        }
    }
    REGION_FreeStorage(SLLBlock.next);
    REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, rgn);
    for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
        tmpPtBlock = curPtBlock->next;
        free( curPtBlock );
        curPtBlock = tmpPtBlock;
    }
    free( pETEs );
    return rgn;
}