Recent

Author Topic: Bug in Canvas functions that use 4 parameters as a Rect.  (Read 2124 times)

jamie

  • Hero Member
  • *****
  • Posts: 7306
Bug in Canvas functions that use 4 parameters as a Rect.
« on: August 07, 2025, 02:44:23 am »
I've noticed a bug using for example Canvas.FillRect using four parms instead of a TRect.

The TRect overload works correctly, however, the 4 parameters overload does not, the Last two parameters are defining a TRect without adding +1 to the corners, as it should be in a TRect.

Jamie
The only true wisdom is knowing you know nothing

wp

  • Hero Member
  • *****
  • Posts: 13210
Re: Bug in Canvas functions that use 4 parameters as a Rect.
« Reply #1 on: August 07, 2025, 10:00:09 am »
How do you detect this?

I used this code:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormPaint(Sender: TObject);
  2. begin
  3.   Canvas.Brush.Color := clBlack;
  4.   Canvas.FillRect(10, 10, 20, 20);
  5.   Canvas.Brush.Color := clWhite;
  6.   Canvas.FillRect(Rect(10, 10, 20, 20));
  7.  
  8.   Canvas.Brush.Color := clBlack;
  9.   Canvas.FillRect(Rect(30, 10, 40, 20));
  10.   Canvas.Brush.Color := clWhite;
  11.   Canvas.FillRect(30, 10, 40, 20);
  12. end;
If the two FillRect calls would result in differently sized rectangles I would expect to see a black line at the right and bottom edges of one of the drawn squares. But I don't (Windows-11).

jamie

  • Hero Member
  • *****
  • Posts: 7306
Re: Bug in Canvas functions that use 4 parameters as a Rect.
« Reply #2 on: August 07, 2025, 11:53:19 am »
When using a rectangle function the surface area is always inside the lower right corner.
This means you always need to adjust the lower right corner values to account for this.
When using a non rectangle function the left upper corner and lower right corner should be the exact plot locations.

A 100x100 area is 0 0,100,100 for a rect and 0,0,99,99 for a plot function.

Its obvious the plot version is using the rectangle version in the background without making adjustments.

It is no different from drawing a line from the first point to the second point,  the second Point needs to be exact not plus one like you would find in a rectangle function

The plotted overliad should be corrected or at least documented better.

I found this using the plotted overload to specify the exact surface plot.
The only true wisdom is knowing you know nothing

wp

  • Hero Member
  • *****
  • Posts: 13210
Re: Bug in Canvas functions that use 4 parameters as a Rect.
« Reply #3 on: August 07, 2025, 12:01:07 pm »
I don't understand what you mean with "plot function". Assuming that you mean drawing a line, the following code works as expected for me:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormPaint(Sender: TObject);
  2. begin
  3.   Canvas.Brush.Color := clWhite;
  4.   Canvas.FillRect(10, 10, 20, 20);
  5.   Canvas.Pen.Color := clBlack;
  6.   Canvas.Line(10, 10, 20, 20);
  7.  
  8.   Canvas.Brush.Color := clWhite;
  9.   Canvas.FillRect(Rect(30, 10, 40, 20));
  10.   Canvas.Pen.Color := clBlack;
  11.   Canvas.Line(30, 10, 40, 20);
  12. end;


jamie

  • Hero Member
  • *****
  • Posts: 7306
Re: Bug in Canvas functions that use 4 parameters as a Rect.
« Reply #4 on: August 07, 2025, 11:58:39 pm »
You are correct, you don't understand it.

FillRect(10,10,19,19) and  FillRect(Rect(10,10,20,20)); should produce the same results, but they don't


The first, is a plotted rectangle on the surface using two locations as separate sets of parameters, the second set should point directly to the last pixels of the surface that is to be painted, not outside the painted surface.

 As for the TRECT overload, the Right, Bottom always needs to be one more than the actual painted surface, this is just how it's been since windows 3.x

 But if you are going to have a two location plots without using a TRECT then the second set X2,Y2 should be pointing exactly on the last pixel row, not outside it like the TRECT does.

 Currently the X1,Y1, X2,Y2 simply constructs a TRECT using these values without making the compensation to force the X2,Y2 outside the interior so that the TRECT overload can correctly function.

 Do you understand this now? if not, I'll remove this post because it's getting too much for me to handle trying to explain the defect of the four parameter overload.

Jamie



The only true wisdom is knowing you know nothing

wp

  • Hero Member
  • *****
  • Posts: 13210
Re: Bug in Canvas functions that use 4 parameters as a Rect.
« Reply #5 on: August 08, 2025, 12:47:06 am »
No, I don't understand it (but please don't delete the post...)

If you were right Delphi would have the same issue. Unfortunately, it does not have two FillRect overloads, but there are a TRect and a 4-parameter overload for the Rectangle method. According to your argument Rectangle(10, 10, 19, 19) and Rectangle(Rect(10, 10, 20, 20)) should produce the same results. But in the screenshot the left square drawn by Rectangle(10, 10, 19, 19) definitely is smaller than the right square drawn by Rectangle(Rect(30, 10, 40, 20)) (offset horizontally by 20 px for better clarity).

A rectangle is defined by the top/left and bottom/right corner points. But the bottom and right sides are drawn one pixel before the value specified. This is a general convention in graphics, and it does not matter whether the four coordinates are specified separately or bound together in a TRect structure.

jamie

  • Hero Member
  • *****
  • Posts: 7306
Re: Bug in Canvas functions that use 4 parameters as a Rect.
« Reply #6 on: August 08, 2025, 01:44:07 am »
I just looked at the Delphi Help for the Canvan.Rectangle version of the  4 parameters and it does state what I have been saying, the X,Y values are exactly where you want the drawing to take place.

 TRect.Right and Bottom has always been 1+ beyond the area you are interested in.
 
 All this means is the four-parameter version if calling the TRECT version in the background, which I believe would make sense, needs to increase the X2,Y2 by 1 when creating the TRECT fields.

 Normally I use the TRECT versions mostly because I come from the old Windows, where this has been the practice because using simple code to subtract left from Right to get the size of the area without adding 1 which would take more CPU processing otherwise.

Jamie
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 7306
Re: Bug in Canvas functions that use 4 parameters as a Rect.
« Reply #7 on: August 15, 2025, 12:30:54 am »
Is there going to be anything done about this, or should I just erase this post?

Jamie
The only true wisdom is knowing you know nothing

440bx

  • Hero Member
  • *****
  • Posts: 5809
Re: Bug in Canvas functions that use 4 parameters as a Rect.
« Reply #8 on: August 15, 2025, 12:44:06 am »
FillRect(10,10,19,19) and  FillRect(Rect(10,10,20,20)); should produce the same results, but they don't
No, they should definitely not produce the same result.

It doesn't matter how the rect is specified.  FillRect and other rectangle APIs exclude the bottom and right coordinates from what is done on/in the rectangle.

Given two different rectangles, you'll get two different results regardless of the method used to specify the rectangles.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

jamie

  • Hero Member
  • *****
  • Posts: 7306
Re: Bug in Canvas functions that use 4 parameters as a Rect.
« Reply #9 on: August 15, 2025, 12:59:32 am »
I understand that however, the 4 parameters are calling the RECT version without compensating for the lower X,Y

 As for the RECT version, its correct but the non Rectangle version are not. They are supposed to be exactly the size.

 Looking at my D, I see they have it correct, the 4 parm versions are specified exactly on target.

 I stand by my statement about the two should be the same results with different X,Y finals sizes.

 I'll see if there is a way to delete this post since I know it will never get fixed anytime soon, if not at all.

 Jamie
The only true wisdom is knowing you know nothing

wp

  • Hero Member
  • *****
  • Posts: 13210
Re: Bug in Canvas functions that use 4 parameters as a Rect.
« Reply #10 on: August 15, 2025, 01:04:35 am »
Why do you want to delete this post? This is a valid discussion.

jamie

  • Hero Member
  • *****
  • Posts: 7306
Re: Bug in Canvas functions that use 4 parameters as a Rect.
« Reply #11 on: August 15, 2025, 01:20:20 am »
Because for one thing, After looking at the LCL sources, it looks like it would be an abomination to fix. 

Also, I am sure there are lots of Laz (LCL) code out there, would most likely require fixing if they used any of those existing functions. Just think about the various Paint, CAD, Map, grids, etc. code that has adapted to this.

  Its like building a sky scraper on a broken foundation.

 Jamie
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018