Recent

Author Topic: BGRABitmap - border width and offset  (Read 5195 times)

Dibo

  • Hero Member
  • *****
  • Posts: 1045
BGRABitmap - border width and offset
« on: April 05, 2012, 09:19:51 pm »
Hi,

I noticed a problem with drawing border. For example I have this code:
Code: Pascal  [Select]
  1. procedure TForm1.FormPaint(Sender: TObject);
  2. var
  3.   b: TBGRABitmap;
  4.   r: TRect;
  5. begin
  6.   b := TBGRABitmap.Create(100,100);
  7.   r := b.ClipRect;
  8.   b.RoundRectAntialias(r.Left, r.Top, r.Right, r.Bottom,
  9.     1, 1, BGRABlack, 20, []);
  10.   b.Draw(Self.Canvas,0,0,False);
  11.   b.Free;
  12. end;
When the border thickens, then it offset to the right. It seems that right border is cut. Even if I set border width to 1, I don't see right edge. I always use own function which calculate correct rect to width, but maybe there is any explanation for such behavior?

Regards.

circular

  • Hero Member
  • *****
  • Posts: 3047
    • Personal webpage
Re: BGRABitmap - border width and offset
« Reply #1 on: April 12, 2012, 04:40:23 pm »
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_13

So when you write :
Code: [Select]
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 :
Code: [Select]
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 :
Code: [Select]
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.
« Last Edit: April 14, 2012, 12:50:29 am by circular »
Conscience is the debugger of the mind

Dibo

  • Hero Member
  • *****
  • Posts: 1045
Re: BGRABitmap - border width and offset
« Reply #2 on: April 12, 2012, 09:00:31 pm »
Thanks for explanation. I try your solution.

circular

  • Hero Member
  • *****
  • Posts: 3047
    • Personal webpage
Re: BGRABitmap - border width and offset
« Reply #3 on: April 12, 2012, 10:26:54 pm »
You're welcome
Conscience is the debugger of the mind

lainz

  • Guest
Re: BGRABitmap - border width and offset
« Reply #4 on: April 13, 2012, 04:44:32 am »
Thanks for explanation. I try your solution.

Which kind of super control you're doing!

Dibo

  • Hero Member
  • *****
  • Posts: 1045
Re: BGRABitmap - border width and offset
« Reply #5 on: April 13, 2012, 09:33:23 am »
BGRAButton. I'm just trying to make code simpler ;)

lainz

  • Guest
Re: BGRABitmap - border width and offset
« Reply #6 on: April 13, 2012, 01:53:07 pm »
Yes, that is a super control  :D

circular

  • Hero Member
  • *****
  • Posts: 3047
    • Personal webpage
Re: BGRABitmap - border width and offset
« Reply #7 on: April 14, 2012, 12:51:09 am »
Sorry, there was a problem with the layout of my post. I think it's better now.  :)
Conscience is the debugger of the mind