[fpc-devel] Slight calculation error in Bounds() procedure in Classes unit.
Mattias Gärtner
nc-gaertnma at netcologne.de
Wed Jun 9 13:49:45 CEST 2010
Zitat von Aleksa Todorovic <alexione at gmail.com>:
> On Wed, Jun 9, 2010 at 11:30, Graeme Geldenhuys
> <graemeg.lists at gmail.com> wrote:
>> Op 2010-06-09 11:02, Florian Klaempfl het geskryf:
>>> interpretation of bounds, the current behaviour is perfectly valid for
>>> any other uses.
>>
>> Not as I see it, and described in the bug report. Think of the pixel
>> screen/grid like the grid of a spreadsheet (as as a magnified look of the
>> top corner of your screen)
>>
>> 0 1
>> +---+---+---
>> 0 | x | |
>> +-+-+---+---
>> 1 | | |
>> +-+-+---+---
>> 2 | | |
>> +-+-+---+---
>>
>>
>> x is at (0,0). A pixel is always 1x1, you don't get smaller (we are not
>> using sub-pixels like on LCD screens, because they don't apply to all
>> screens).
It's correct that a pixel is an area, usually of size 1x1. So when you
say it is at 0,0, then you are really saying: the left,top corner of
the pixel is at 0,0 and the right, bottom corner is at 1,1. With the
Bounds function:
Bounds(0,0,1,1)
Math: Right-Left=Width
Graeme: Right-Left=Width-1
For example: Let's say you have a position 3.
The math says it is the left edge of pixel 3 (usually the fourth pixel).
Graeme says: If it is a Left, then it is the left edge of pixel 3, if
it is a Right then it is the right edge of pixel 3.
Graeme's definition is useful for drawing a pixel based rectangle
(with line width of 1).
When computing with coordinates the math definition is easier as you
don't have to know if it is a left or right.
> [...]
>> 0 1
>> +---+---+---
>> 0 | x | x |
>> +-+-+---+---
>> 1 | x | x |
>> +-+-+---+---
>> 2 | | |
>> +-+-+---+---
>>
>> In this example we have a rectangle. Top/Left = (0,0) and Bottom/Right =
>> (1,1). This means Width = 2 pixels and Height = 2 pixels. Clearly visible
>> in the image above.
That's only correct for a line width of 1.
The rectangle has a line width of 1 pixel, 0.5 pixel around the four
x. This means the rectangle has Width=1 and Height=1, but including
the thickness of the line the total rectangle has Width=2 and Height=2.
The difference can be seen when using libraries that supports sub
pixel rendering like aggpas.
>> But if we call Classes.Bounds(0,0,2,2) it reports Bottom/Right as (2,2)
>> which is wrong (again looking at the image above as reference). This is my
>> point. Bounds() cannot be used in this case in a graphical environment.
Yes, it can. If you want the rectangle including the line width of 1,
you must add 1. If you use a line width of 5 you must add 5.
Maybe you want a Bounds function like this:
function RectangleHull(Left, Top, Width, Height: integer; LineWidth:
integer = 1): TRect;
> Actually, everything works fine here :-) You just have to change your
> point of view regarding coordinates. You assume that integer
> coordinates represent center of pixel, but they actually represent
> top-left corner of pixel. In other words, think of coordinate 0 as
> 0.0, not 0.5 and the math will work perfectly fine :-)
The math works with 0.0, 0.5 and 0.9. But if you don't use sub pixel
rendering you won't see the difference.
> [...]
Mattias
More information about the fpc-devel
mailing list