Recent

Author Topic: FillRoundRectAntialias problem  (Read 5785 times)

aradeonas

  • Hero Member
  • *****
  • Posts: 824
FillRoundRectAntialias problem
« on: January 28, 2016, 04:53:51 pm »
Hi,

As screenshot shows FillRoundRectAntialias side lines are not sharp but I want to know why? Antialias make round part looks better but why sides are not sharp? and how can I make them sharp as FillRoundRect?
Also I like to know why round parts are so much difrfrent even with same r? SHould not they have similar parts but with Antialiasing?
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormPaint(Sender: TObject);
  2. var
  3.   bmp:TBGRABitmap;
  4. begin
  5.   bmp:=TBGRABitmap.Create(Width,Height,BGRAWhite);
  6.   bmp.FillRoundRectAntialias(10,10,110,110,20,20,BGRABlack);
  7.   bmp.FillRoundRect(120,10,220,110,20,20,BGRABlack);
  8.   bmp.Draw(Canvas,0,0);
  9.   bmp.Free;
  10. end;  
« Last Edit: January 28, 2016, 05:01:50 pm by aradeonas »

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: FillRoundRectAntialias problem
« Reply #1 on: January 28, 2016, 08:29:46 pm »
Probably because the vertical and horizontal line are not pixel aligned.

Here is a detailed explanation of pixel alignment. It was written for AGG (Antigrain Geometry framework), but applies to any graphics framework.

http://www.antigrain.com/tips/line_alignment/line_alignment.agdoc.html#PAGE_LINE_ALIGNMENT
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

aradeonas

  • Hero Member
  • *****
  • Posts: 824
Re: FillRoundRectAntialias problem
« Reply #2 on: January 28, 2016, 09:05:51 pm »
Interesting, so I should wait for Circular comment on this,
But I always like to know how AGG works on this painting stuff. not these simple one, Photoshop like effects, blur,glow, filters and .... most I saw was drawing and I never liked its structure and left it 5-6 years ago and never saw it in use until your great works.

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: FillRoundRectAntialias problem
« Reply #3 on: January 29, 2016, 12:00:41 pm »
Interesting, so I should wait for Circular comment on this,
I couldn't see from your screenshot, but does BGRABitmap do sub-pixel drawing? A quick wais in normally to know if coordinates and dimensions are in floating point or integer values?

Quote
But I always like to know how AGG works on this painting stuff. not these simple one, Photoshop like effects, blur,glow, filters and ...
I love AGG (or rather AggPas) because of how flexible it is (eg: dynamic rendering pipeline - various rendering parts can be chained together in different orders to produce different end results). That is probably what makes most developers unsure about using it, because it is different to most graphics libraries. But that is also the secret that makes AGG/AggPas so great - plus the fact that in has very high quality rendering and massive amounts of features. The demos included with AGG/AggPas shows some possibilities for "effects" like blur, glow, drop shadows, zoom etc. The idea is that those can be easily put together in a class with an easy API for a specific application. AGG/AggPas doesn't hard-code it's features - the developer is in full control.

Anyway, back to your original question. Yes, I think Circular is probably the best person to answer and explain how you can pixel align vertical and horizontal lines.
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

aradeonas

  • Hero Member
  • *****
  • Posts: 824
Re: FillRoundRectAntialias problem
« Reply #4 on: January 29, 2016, 12:18:12 pm »
Quote
I couldn't see from your screenshot, but does BGRABitmap do sub-pixel drawing? A quick wais in normally to know if coordinates and dimensions are in floating point or integer values?
Yes Antialiased methods support this but maybe Im doing wrong.
Quote
AGG/AggPas doesn't hard-code it's features - the developer is in full control.
That is my problem. Long ago I made something custom for my self but I cant make graphic functions all by myself, that is very hard and time consuming and sure it will be buggy .

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: FillRoundRectAntialias problem
« Reply #5 on: January 29, 2016, 12:30:33 pm »
Quote
AGG/AggPas doesn't hard-code it's features - the developer is in full control.
That is my problem. Long ago I made something custom for my self but I cant make graphic functions all by myself, that is very hard and time consuming and sure it will be buggy .
In that case, simply use the TAgg2D class - it has all the usual Canvas "easy to use" functions already created (Line, Triangle, Rectangle, Ellipse, Arc, Curve, Polygon, Gradient, DrawText etc etc). You loose some of the power of AggPas, but then you can always extend TAgg2D (by creating a descendant class) to add new functionality too.

fpGUI includes a Lazarus IDE add-on package which registers new project types, that way you can select "Project -> New.. -> fpGUI+Agg2D Application" to get started. That makes it very easy to create a new project with a TAgg2D instance already created for you, and the code comments tells you exactly where you need to write your code. See the <fpgui>/docs/INSTALL.txt instructions for details. You should then be able to use that exact same Agg2D drawing code you wrote in Lazarus's AggPas+LCL too, as they have 99.9% the same TAgg2D API.
« Last Edit: January 29, 2016, 12:32:29 pm by Graeme »
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

aradeonas

  • Hero Member
  • *****
  • Posts: 824
Re: FillRoundRectAntialias problem
« Reply #6 on: January 29, 2016, 12:42:04 pm »
Thanks Graeme, I will try it. I tried demos again recently but didnt tried "TAgg2D" and "fpGUI+Agg2D Application".

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: FillRoundRectAntialias problem
« Reply #7 on: January 29, 2016, 09:14:31 pm »
Hello Aradeonas and Graeme

That's indeed a question of subpixel alignment.

If one draw a rectangle using integer coordinates (aliased), the top-left specifies the top-left pixel, and the bottom-right specifies the pixel outside of the rectangle. The idea is that the width and height are simply the difference between the bottom-right values and top-left values.

When using floating point coordinates, it depends how coordinates are defined, if they are centered on pixels or the top-left of a pixel. In BGRABitmap, the functions use pixel-centered coordinate. So using integers means in that case "in the middle of the pixel". To fill completely the pixel, one need to subtract 0.5 to the top-left values and also subtract 0.5 to the bottom-right values.

For example to fill exactly one pixel at the top-left of the bitmap, you would write FillRectAntialias(-0.5,-0.5,0.5,0.5,...)

When using coordinates that are not centered, you could use the same values as with the integer-parametered functions, so that would seem simpler at first glance. But when you would draw a line that is one-pixel wide, it would be blurred because the coordinate would be between pixels.

There is no perfect solution. Using pixel-centered coordinates is simpler when drawing lines, using non-centered coordinates is simpler when filling shapes.
Conscience is the debugger of the mind

aradeonas

  • Hero Member
  • *****
  • Posts: 824
Re: FillRoundRectAntialias problem
« Reply #8 on: January 29, 2016, 09:24:38 pm »
Quote
There is no perfect solution. Using pixel-centered coordinates is simpler when drawing lines, using non-centered coordinates is simpler when filling shapes.
Hi Circular,
I can understand what you say but as user points when I say to it draw from x=10 to x=110 it should just do it and for this maybe has a parameter for filling x=10 to 109 for this problem because correcting value everytime is not a good and easy way.
Can you prepare a better way so when I say fill a rect with FillRoundRectAntialias it just do it without these problems and no need to add 0.5 to each value like (-0.5,-0.5,0.5,0.5,...)?

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: FillRoundRectAntialias problem
« Reply #9 on: January 29, 2016, 09:28:03 pm »
I thought about it a lot when I wrote those functions, and I do not find any simple solution.

Of course you could instead call RoundRectAntialias (not the Fill one) and specify a border of 1 pixel that is the same color as the inside.
Conscience is the debugger of the mind

aradeonas

  • Hero Member
  • *****
  • Posts: 824
Re: FillRoundRectAntialias problem
« Reply #10 on: January 29, 2016, 09:35:11 pm »
Yes I use that for now but a helper parameter may that correct values helps for future usage.

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: FillRoundRectAntialias problem
« Reply #11 on: January 30, 2016, 05:33:48 am »
Hmmm... maybe like a pixelCenteredCoordinate parameter, that would be True by default?
Conscience is the debugger of the mind

aradeonas

  • Hero Member
  • *****
  • Posts: 824
Re: FillRoundRectAntialias problem
« Reply #12 on: January 30, 2016, 10:04:30 am »
Yes. Becuase I think most of the time we just want a RoundRect in perfect shape.

circular

  • Hero Member
  • *****
  • Posts: 4196
    • Personal webpage
Re: FillRoundRectAntialias problem
« Reply #13 on: February 06, 2016, 05:22:45 pm »
Applied on SVN.

Now there is a parameter pixelCenteredCoordinates that by default equals to True. If you want crisp borders with integer coordinates, set this parameter to False.

This applies to FillRectAntialias and FillRoundRectAntialias.
Conscience is the debugger of the mind

aradeonas

  • Hero Member
  • *****
  • Posts: 824
Re: FillRoundRectAntialias problem
« Reply #14 on: February 06, 2016, 05:29:40 pm »
Thank you very much  :D

 

TinyPortal © 2005-2018