This is the expected behavior. Your code is logical, but there is some detail with antialias rectangle to take into account. The convention for integer coordinate rectangles (non antialiased) is like windows TRect convention, i.e. the first coordinate is the upperleft pixel and the second coordinate is the loweright "plus one". But for antialiased rectangles, this is different, because coordinates are not pixels, but can be between pixels. An integer value here means "in the center of" a pixel.
See here for more information :
http://wiki.freepascal.org/BGRABitmap_tutorial_13So when you write :
b.RoundRectAntialias(r.Left, r.Top, r.Right, r.Bottom,
1, 1, BGRABlack, 20, []);
It means that the topleft corner is in the middle of the topleft pixel, and that the topleft corner is in the middle of the bottomright pixel "plus one", which is in fact outside of the rectangle. So if you want the rectangle to fit in the rectangle, you need to write something like :
b.RoundRectAntialias(r.Left, r.Top, r.Right-1, r.Bottom-1,
1, 1, BGRABlack, 1, []);
If you want to have a bigger border and that fits into the rectangle, then you can write for example :
procedure TForm1.FormPaint(Sender: TObject);
var
b: TBGRABitmap;
r: TRect;
w: single;
begin
b := TBGRABitmap.Create(100,100,BGRAWhite);
r := b.ClipRect;
w := 20;
b.RoundRectAntialias(r.Left-0.5+w/2, r.Top-0.5+w/2, r.Right-0.5-w/2, r.Bottom-0.5-w/2,
1, 1, BGRABlack, w, []);
b.Draw(Self.Canvas,rect(5,5,5+2*b.Width,5+2*b.Height),False);
b.Free;
end;
Regards.