Exemple #1
0
/*
 *           REGION_FrameRgn
 * Create a region that is a frame around another region.
 * Expand all rectangles by +/- x and y, then subtract original region.
 */
BOOL
REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y )
{
    BOOL bRet;
    MWRGNOBJ *srcObj = (MWRGNOBJ*) GDI_GetObjPtr( hSrc, OBJ_REGION );

    if (srcObj->rgn->numRects != 0) 
    {
	MWRGNOBJ* destObj = (MWRGNOBJ*) GDI_GetObjPtr( hDest, OBJ_REGION );
	RECT *pRect, *pEndRect;
	RECT tempRect;

	EMPTY_REGION( destObj->rgn );
	
	pEndRect = srcObj->rgn->rects + srcObj->rgn->numRects;
	for(pRect = srcObj->rgn->rects; pRect < pEndRect; pRect++)
	{
	    tempRect.left = pRect->left - x;        
	    tempRect.top = pRect->top - y;
	    tempRect.right = pRect->right + x;
	    tempRect.bottom = pRect->bottom + y;
	    GdUnionRectWithRegion( &tempRect, destObj->rgn );
	}
	GdSubtractRegion( destObj->rgn, destObj->rgn, srcObj->rgn );
	bRet = TRUE;
    }
    else
	bRet = FALSE;
    return bRet;
}
Exemple #2
0
HRGN WINAPI
ExtCreateRegion(const XFORM* lpXform, DWORD dwCount, const RGNDATA* rgndata)
{
    HRGN hrgn = CreateRectRgn(0, 0, 0, 0);
    MWRGNOBJ *obj = (MWRGNOBJ *) GDI_GetObjPtr( hrgn, OBJ_REGION );
    RECT *pCurRect, *pEndRect;

    /*TRACE(region, " %p %ld %p. Returning %04x\n",
		lpXform, dwCount, rgndata, hrgn);*/
    if(!hrgn)
    {
        WARN(region, "Can't create a region!\n");
	return 0;
    }
    if(lpXform)
        WARN(region, "Xform not implemented - ignoring\n");
    
    if(rgndata->rdh.iType != RDH_RECTANGLES)
    {
        WARN(region, "Type not RDH_RECTANGLES\n");
	DeleteObject( hrgn );
	return 0;
    }

    pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount;
    for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
        GdUnionRectWithRegion( pCurRect, obj->rgn );

    return hrgn;
}
Exemple #3
0
/*
 *           REGION_UnionRectWithRgn
 *           Adds a rectangle to a HRGN
 *           A helper used by scroll.c
 */
BOOL
REGION_UnionRectWithRgn( HRGN hrgn, const RECT *lpRect )
{
    MWRGNOBJ *obj = (MWRGNOBJ *)hrgn;

    if(!obj) return FALSE;
    GdUnionRectWithRegion( lpRect, obj->rgn );
    return TRUE;
}
Exemple #4
0
/* update framebuffer*/
static void
fb_update(PSD psd, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height)
{
	MWRECT rc;

	if (!width)
		width = psd->xres;
	if (!height)
		height = psd->yres;

	/* add update rect to update region*/
	rc.left = x;
	rc.right = x + width;
	rc.top = y;
	rc.bottom = y + height;
	GdUnionRectWithRegion(&rc, fb_updateregion);
}
/*
 * Combine the passed rectangle with the update region for the given window.
 * Coordinates are passed relative to window.
 * If bUnion is TRUE, union the rectangle, otherwise subtract it.
 */
void
MwUnionUpdateRegion(HWND wp, MWCOORD x, MWCOORD y, MWCOORD width,
	MWCOORD height, BOOL bUnion)
{
#if UPDATEREGIONS
	MWRECT rc;

	if (wp->unmapcount)
		return;

	/* convert window relative coords to screen coords*/
	rc.left = x + wp->winrect.left;
	rc.top = y + wp->winrect.top;
	rc.right = rc.left + width;
	rc.bottom = rc.top + height;

	if(bUnion)
		GdUnionRectWithRegion(&rc, wp->update);
	else
		GdSubtractRectFromRegion(&rc, wp->update);
#endif
}
Exemple #6
0
HRGN WINAPI
CreateRoundRectRgn( INT left, INT top, INT right, INT bottom,
	INT ellipse_width, INT ellipse_height )
{
    MWRGNOBJ * obj;
    HRGN hrgn;
    int asq, bsq, d, xd, yd;
    RECT rect;
    
    /* Check if we can do a normal rectangle instead */
    if (ellipse_width == 0 || ellipse_height == 0)
	return CreateRectRgn( left, top, right, bottom );

    /* Make the dimensions sensible */
    if (left > right) { INT tmp = left; left = right; right = tmp; }
    if (top > bottom) { INT tmp = top; top = bottom; bottom = tmp; }

    ellipse_width = MWABS(ellipse_width);
    ellipse_height = MWABS(ellipse_height);

    /* Create region */

    if (!(hrgn = REGION_CreateRegion()))
	    return 0;
    obj = (MWRGNOBJ *)hrgn;
    /*TRACE(region,"(%d,%d-%d,%d %dx%d): ret=%04x\n",
	       left, top, right, bottom, ellipse_width, ellipse_height, hrgn);*/

    /* Check parameters */

    if (ellipse_width > right-left) ellipse_width = right-left;
    if (ellipse_height > bottom-top) ellipse_height = bottom-top;

    /* Ellipse algorithm, based on an article by K. Porter */
    /* in DDJ Graphics Programming Column, 8/89 */

    asq = ellipse_width * ellipse_width / 4;        /* a^2 */
    bsq = ellipse_height * ellipse_height / 4;      /* b^2 */
    if (asq == 0) asq = 1;
    if (bsq == 0) bsq = 1;
    d = bsq - asq * ellipse_height / 2 + asq / 4;   /* b^2 - a^2b + a^2/4 */
    xd = 0;
    yd = asq * ellipse_height;                      /* 2a^2b */

    rect.left   = left + ellipse_width / 2;
    rect.right  = right - ellipse_width / 2;

    /* Loop to draw first half of quadrant */

    while (xd < yd)
    {
	if (d > 0)  /* if nearest pixel is toward the center */
	{
	      /* move toward center */
	    rect.top = top++;
	    rect.bottom = rect.top + 1;
	    GdUnionRectWithRegion( &rect, obj->rgn );
	    rect.top = --bottom;
	    rect.bottom = rect.top + 1;
	    GdUnionRectWithRegion( &rect, obj->rgn );
	    yd -= 2*asq;
	    d  -= yd;
	}
	rect.left--;        /* next horiz point */
	rect.right++;
	xd += 2*bsq;
	d  += bsq + xd;
    }

    /* Loop to draw second half of quadrant */

    d += (3 * (asq-bsq) / 2 - (xd+yd)) / 2;
    while (yd >= 0)
    {
	  /* next vertical point */
	rect.top = top++;
	rect.bottom = rect.top + 1;
	GdUnionRectWithRegion( &rect, obj->rgn );
	rect.top = --bottom;
	rect.bottom = rect.top + 1;
	GdUnionRectWithRegion( &rect, obj->rgn );
	if (d < 0)   /* if nearest pixel is outside ellipse */
	{
	    rect.left--;     /* move away from center */
	    rect.right++;
	    xd += 2*bsq;
	    d  += xd;
	}
	yd -= 2*asq;
	d  += asq - yd;
    }

    /* Add the inside rectangle */

    if (top <= bottom)
    {
	rect.top = top;
	rect.bottom = bottom;
	GdUnionRectWithRegion( &rect, obj->rgn );
    }
    obj->rgn->type = SIMPLEREGION; /* FIXME? */
    return hrgn;
}
Exemple #7
0
/**
 * Set a clip region for future drawing actions.
 * Each pixel will be drawn only if lies in one or more of the contained
 * clip rectangles.  All clip rectangles are modified
 * if necessary to lie within the device area.  Call only after device
 * has been initialized.
 *
 * @param psd Drawing surface.
 * @param reg New clipping region.
 */
void
GdSetClipRegion(PSD psd, MWCLIPREGION *reg)
{
  if(clipregion)
  	GdDestroyRegion(clipregion);

  if(!reg)
	  reg = GdAllocRegion();

  clipregion = reg;


#if 0
  MWRECT	rc;
  /* Copy the clip table to our own static array, modifying each
   * rectangle as necesary to fit within the device area.  If the clip
   * rectangle lies entirely outside of the device area, then skip it.
   */
  while (count-- > 0) {
	MWCLIPRECT cr;
	MWCLIPRECT *rp = &cr;

	*rp = *table++;
	if (rp->x < 0) {
		rp->width += rp->x;
		rp->x = 0;
	}
	if (rp->y < 0) {
		rp->height += rp->y;
		rp->y = 0;
	}
	if ((rp->x >= psd->xvirtres) || (rp->width <= 0) ||
	    (rp->y >= psd->yvirtres) || (rp->height <= 0))
		continue;
	if (rp->x + rp->width > psd->xvirtres)
		rp->width = psd->xvirtres - rp->x;
	if (rp->y + rp->height > psd->yvirtres)
		rp->height = psd->yvirtres - rp->y;
	rc.left = rp->x;
	rc.top = rp->y;
	rc.right = rp->x+rp->width;
	rc.bottom = rp->y+rp->height;
	GdUnionRectWithRegion(&rc, clipregion);
  }
#endif

  /* If there were no surviving clip rectangles, then set the clip
   * cache to prevent all drawing.
   */
  if (clipregion->numRects == 0) {
	clipminx = MIN_MWCOORD;
	clipminy = MIN_MWCOORD;
	clipmaxx = MAX_MWCOORD;
	clipmaxy = MAX_MWCOORD;
	clipresult = FALSE;
	return;
  }

  /* There was at least one valid clip rectangle. Default the clip
   * cache to be the first clip rectangle.
   */
  clipminx = clipregion->rects[0].left;
  clipminy = clipregion->rects[0].top;
  clipmaxx = clipregion->rects[0].right - 1;
  clipmaxy = clipregion->rects[0].bottom - 1;
  clipresult = TRUE;
}