It's not possible to draw this with exact antialiasing, but you can do an approximation with two steps :
- first draw the button with border using TBGRAMultishapeFiller
- then draw the light as a RoundRectangle using light color and using the right size and radius.
Computing the radius of the RoundRectangle can be complicated.
I've just added properties to FillInfo objects, so you can compute it with BGRABitmap. To do your example, you can now do it like this :
procedure TForm1.FormPaint(Sender: TObject);
var
image: TBGRABitmap;
fiBorder,fiLight: TFillBorderRoundRectInfo; //in BGRAFillInfo
multi: TBGRAMultishapeFiller; //in BGRAPolygon
multiGrad: TBGRAMultiGradient; //in BGRAGradientScanner
gradScan: TBGRAGradientScanner;
begin
image := TBGRABitmap.Create(clientwidth,clientheight,ColorToBGRA(ColorToRGB(clBtnFace)));
//to avoid undefined when freeing
multiGrad := nil;
gradScan := nil;
//compute information for the bounding round rectangle
fiBorder := TFillBorderRoundRectInfo.Create(10,10,300,200,40,40,5,[]);
multi := TBGRAMultishapeFiller.Create;
multi.AddShape(fiBorder,BGRA(128,128,128)); //fill the border with gray
//check if there is an inner border (there can be none if the round rectangle is too small)
if fiBorder.InnerBorder <> nil then
begin
//create multigradient (blue-white-red)
multiGrad := TBGRAMultiGradient.Create([BGRA(128,128,255),BGRAWhite,BGRA(128,0,0)],[0,0.5,1],True);
//create linear gradient from top to bottom of inner border
gradScan := TBGRAGradientScanner.Create(multiGrad,gtLinear,PointF(50,fiBorder.InnerBorder.TopLeft.Y),PointF(50,fiBorder.InnerBorder.BottomRight.Y));
multi.AddShape(fiBorder.InnerBorder,gradScan); //fill round rectangle with gradient
end;
//render the round rectangle with border
multi.Draw(image);
multi.Free;
gradScan.Free;
multiGrad.Free;
fiBorder.Free;
//then compute light position : it is 5 pixel wider
fiLight := TFillBorderRoundRectInfo.Create(10,10,300,200,40,40,5+5,[]);
//check if there is an inner position
if fiLight.InnerBorder <> nil then
with fiLight.InnerBorder do //fill with light
image.RoundRectAntialias(topleft.x,topleft.y,bottomright.x,bottomright.y,radiusx,radiusY,BGRA(255,255,255,64),5);
fiLight.free;
image.Draw(Canvas,0,0,True);
image.free;
end;