[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