draw with clipping inside a gadget when GM_RENDER

Online Status

Hello, This is my first post on this forum. So happy this exists, I often ask myself tons of question on OS3 development.

I'm currently trying to code my first boopsi gadget,I'm currently playing around with GM_RENDER to render the gadget itself, following an old reaction example found on aminet, and reading docs. and I see the target rastport you are meant to draw is not "clipped" to the gadget itself, but clipped to the entire window (see screenshot)... This would be OK because the gadget dimensions are known, but:

... What I want to do is to use DrawEllipse(rp,...) within the boundaries of the gadget, with a clipping rectangle that fits the gadgets.

I was telling myself it looks like what some functions of layers.library would do. And I never understood anything to that library.

I guess drawing a clipped ellipse in the gadget implies that a new rastport is created which take account of both the windows layers and some new layer rectangle for the gadget to "make a logic and" with the rectangle... Or maybe there is something more simple ?

It would be great if didn't have to manage an offscreen bitmap/rastport/copy for this, actually.

http://victorien.ferry.free.fr/boopsigadgetrenderclip.jpg

Render functions goes like:

` ULONG F_SAVED KeyboardView_Render(Class *C, struct Gadget *Gad, struct gpRender *Render, ULONG update) { KeyboardView *gdata; struct RastPort *rp; LONG l,left,top,width,height,right,bottom; ULONG retval=1;

gdata=INST_DATA(C, Gad);

if(Render->MethodID==GM_RENDER) else

if(rp) { WORD left =Gad->LeftEdge; WORD top =Gad->TopEdge; WORD width =Gad->Width; WORD height =Gad->Height;

  SetDrMd(rp,JAM1);
  SetAPen(rp,1);
  RectFill(rp,left,
              top,
              left + width  -1,
              top  + height -1) ;
{
    UWORD xc = left + ((width*gdata->_circleCenterX)>>16);
    UWORD yc = top + ((height*gdata->_circleCenterY)>>16);
    SetAPen(rp,2);
    DrawEllipse(rp,xc,yc,width>>1,height>>1);
    SetAPen(rp,3);
    DrawEllipse(rp,xc,yc,width>>2,height>>2);
}

if (Render->MethodID != GM_RENDER)
  ReleaseGIRPort(rp);

} return(retval); } `

Online Status

the markdown completely ripped off the code

ULONG F_SAVED KeyboardView_Render(Class *C, struct Gadget *Gad, struct gpRender *Render, ULONG update)
{
KeyboardView *gdata;
struct RastPort *rp;
LONG l,left,top,width,height,right,bottom;
ULONG retval=1;

gdata=INST_DATA(C, Gad);

if(Render->MethodID==GM_RENDER)
{
rp=Render->gpr_RPort;
update=Render->gpr_Redraw;
}
else
{
rp = ObtainGIRPort(Render->gpr_GInfo);
}

if(rp)
{
WORD left =Gad->LeftEdge;
WORD top =Gad->TopEdge;
WORD width =Gad->Width;
WORD height =Gad->Height;

SetDrMd(rp,JAM1);
SetAPen(rp,1);
RectFill(rp,left,
top,
left + width -1,
top + height -1) ;
{
UWORD xc = left + ((width*gdata->_circleCenterX)>>16);
UWORD yc = top + ((height*gdata->_circleCenterY)>>16);
SetAPen(rp,2);
DrawEllipse(rp,xc,yc,width>>1,height>>1);
SetAPen(rp,3);
DrawEllipse(rp,xc,yc,width>>2,height>>2);
}

if (Render->MethodID != GM_RENDER)
ReleaseGIRPort(rp);
}
return(retval);
}

Online Status

Hey look at that ! Will try.
*layers.library InstallClipRegion -- Install clip region in layer*

Online Status

... InstallClipRegion completely resolved the problem ! The ellipses are clipped to the gadget boundaries.
I could find an example on the DevCD.
I didn't new all that NewRegion() / OrRegion(rectangle) in graphics.
I hope this does not do too much sub-allocations...
The new render code looks like that:

if(rp)
{
struct Rectangle gadgetrec;
struct Region *oldClipRegion;
WORD left =Gad->LeftEdge;
WORD top =Gad->TopEdge;
WORD width =Gad->Width;
WORD height =Gad->Height;

//
gadgetrec.MinX = left;
gadgetrec.MinY = top;
gadgetrec.MaxX = left + width -1;
gadgetrec.MaxY = top + height -1;
// In OM_NEW : gdata->_clipRegion = NewRegion(); , OM_DISPOSE DisposeRegion(gdata->_clipRegion);
#ifdef USE_REGION_CLIPPING
ClearRegion(gdata->_clipRegion);
OrRectRegion(gdata->_clipRegion, &gadgetrec);

oldClipRegion = InstallClipRegion( rp->Layer, gdata->_clipRegion);
#endif
SetDrMd(rp,JAM1);
SetAPen(rp,1);
RectFill(rp,left,
top,
left + width -1,
top + height -1) ;
{
UWORD xc = left + ((width*gdata->_circleCenterX)>>16);
UWORD yc = top + ((height*gdata->_circleCenterY)>>16);
SetAPen(rp,2);
DrawEllipse(rp,xc,yc,width>>1,height>>1);
SetAPen(rp,3);
DrawEllipse(rp,xc,yc,width>>2,height>>2);
}
#ifdef USE_REGION_CLIPPING
InstallClipRegion( rp->Layer,oldClipRegion); // important to pass NULL if oldClipRegion is NULL.
#endif
if (Render->MethodID != GM_RENDER)
ReleaseGIRPort(rp);
}