Recent

Author Topic: [SOLVED] Is this a bug in Canvas.line procedure?  (Read 1473 times)

Hartmut

  • Hero Member
  • *****
  • Posts: 749
[SOLVED] Is this a bug in Canvas.line procedure?
« on: December 10, 2022, 01:11:44 pm »
I have an issue with Canvas.line procedure, because all lines seem to be too short. If I draw a line of 5 pixels, I get only a line of 4 pixels. The pixels which are missing are *different* on Windows and Linux.

I see this issue on Lazarus 2.0.10 and Lazarus 2.0.6 and Lazarus 1.8.4 on Windows 7 (32-bit) and Linux Ubuntu 18.04 (64-bit). I did not find this as a bug in GitLab Bugtracker.

Here is my code:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;
  9.  
  10. type
  11.  
  12.  { TForm1 }
  13.  
  14.  TForm1 = class(TForm)
  15.   Button_Close: TButton;
  16.   Image1: TImage;
  17.   procedure Button_CloseClick(Sender: TObject);
  18.   procedure FormActivate(Sender: TObject);
  19.  private
  20.  public
  21.  end;
  22.  
  23. var
  24.  Form1: TForm1;
  25.  
  26. implementation
  27.  
  28. {$R *.lfm}
  29.  
  30. procedure draw_lines;
  31.    {draws 8 lines like a compass rose of length=5 each}
  32.    var CV: TCanvas;
  33.        i: integer;
  34.    begin
  35.    CV:=Form1.Image1.Canvas;
  36.    CV.Brush.Color:=clWhite; {set background to white}
  37.    CV.Clear;
  38.    CV.Clear;
  39.  
  40.    CV.Pen.Color:=clBlack;   {set pen color to black}
  41.    CV.Pen.Width:=1;
  42.  
  43.    CV.line(12,10,16,10); {line (A) to the East}
  44.    CV.line(10,12,10,16); {line (B) to the South}
  45.    CV.line(8,10,4,10);   {line (C) to the West}
  46.    CV.line(10,8,10,4);   {line (D) to the North}
  47.  
  48.    CV.line(12,8,16,4);   {line (E) to the North-East}
  49.    CV.line(12,12,16,16); {line (F) to the South-East}
  50.    CV.line(8,12,4,16);   {line (G) to the South-West}
  51.    CV.line(8,8,4,4);     {line (H) to the North-West}
  52.  
  53.    for i:=0 to 16 do  if not odd(i) then
  54.        begin
  55.        CV.Pixels[i,0]:=clBlue; {draw ruler at x-axis}
  56.        CV.Pixels[0,i]:=clBlue; {draw ruler at y-axis}
  57.        end;
  58.    end;
  59.  
  60. { TForm1 }
  61.  
  62. procedure TForm1.FormActivate(Sender: TObject);
  63.    begin
  64.    draw_lines;
  65.    Button_Close.Cancel:=true; {enable ESC-key}
  66.    end;
  67.  
  68. procedure TForm1.Button_CloseClick(Sender: TObject);
  69.    begin
  70.    Close;
  71.    end;
  72.  
  73. end.

I attached a compilable project with original screenshots and zoomed screenshots for both OS.
In "Windows_zoom.png" you see, that all lines have only 4 pixels instead of 5 and that always the last pixel (seen from the drawing direction) is missing.
In "Linux_zoom.png" also all lines have only 4 pixels instead of 5, but the missing pixels are other ones.

What do you think? Is this a bug or do/expect I something wrong?
If someone does a test on his/her system, please write your Lazarus- and OS-Version. Thanks in advance.
« Last Edit: December 11, 2022, 01:07:36 pm by Hartmut »

circular

  • Hero Member
  • *****
  • Posts: 4217
    • Personal webpage
Re: Is this a bug in Canvas.line procedure?
« Reply #1 on: December 10, 2022, 01:50:10 pm »
Hi Hartmut,

It is expected that the last pixel will not be drawn. It is related to the system of coordinates and the way drawing works with one-pixel lines.

If you think about drawing a polygon, you can do it by doing successive lines, and the corners, where the line connects, is not drawn twice.

It is also related to filling shapes. Coordinates are meant to be the top-left corner of the pixel. So for example, FillRect(0,0,4,4) will draw a 4 pixel wide square, including the pixel at (0,0) and excluding the pixel at (4,4).

Following the logic of last pixel not drawn, the Windows screenshot is correct while the Linux one is not. So I would call it a bug on Linux.

Maybe the bug appears only with the Line function. You can try instead to call MoveTo and LineTo to specify the direction of the line, though in principle the first coordinate is the starting one.

If that doesn't fix the problem, and until the drawing functions are fixed, I suggest to do a fixed version of Line function, that draw the first and the last pixel, by accessing the Colors property. You could call that LineWithEnd(ACanvas: TCanvas; X1,Y1,X2,Y2: integer)

Another alternative is to use a graphics library. I won't mention BGRABitmap because it is the one I did  :D
« Last Edit: December 10, 2022, 01:54:17 pm by circular »
Conscience is the debugger of the mind

Handoko

  • Hero Member
  • *****
  • Posts: 5150
  • My goal: build my own game engine using Lazarus
Re: Is this a bug in Canvas.line procedure?
« Reply #2 on: December 10, 2022, 02:23:17 pm »
Don't use TCanvas. The more one tries it the more he/she will know TCanvas is not suitable for building serious applications.

That 'bug' has been existed for a very long time, no one care to fix it, even no one reports it. Because no one really uses it for any serious project. Other than that mentioned bug, I also knew some weird behaviors about TCanvas.

TCanvas is good for learning only. Once you've understand how to do basic graphics, you should learn other graphics libraries. At least TBGRABitmap.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Is this a bug in Canvas.line procedure?
« Reply #3 on: December 10, 2022, 02:33:38 pm »
Hi!

This is not a bug.

If you dont exclude the last pixel then the number of pixel will be false.

line (0,y,100,y)

would draw 101 pixel instead of 100.

Winni

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Is this a bug in Canvas.line procedure?
« Reply #4 on: December 10, 2022, 03:09:32 pm »
But surely it is a bug that identical code produces different displays on Linux and Windows?

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Is this a bug in Canvas.line procedure?
« Reply #5 on: December 10, 2022, 05:05:50 pm »
But surely it is a bug that identical code produces different displays on Linux and Windows?

Who wrote that???

Linux/gtk2 produces correct results.

Don't know about Windows because I dont support biilionairs

Winni

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Is this a bug in Canvas.line procedure?
« Reply #6 on: December 10, 2022, 05:12:31 pm »
Don't know about Windows because I dont support biilionairs
You don't need Windows yourself.
Hartmut already provided two (zoomed) illustrations of identical code rendered under Windows and Linux (presumably gtk2), and the rendered results clearly differ.

See his first post.
« Last Edit: December 10, 2022, 05:14:14 pm by howardpc »

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: Is this a bug in Canvas.line procedure?
« Reply #7 on: December 10, 2022, 06:10:09 pm »
It works as shown for Windows on Mac.

I also get the Windows result on Linux (gtk2).
« Last Edit: December 10, 2022, 06:18:06 pm by VTwin »
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

Hartmut

  • Hero Member
  • *****
  • Posts: 749
Re: Is this a bug in Canvas.line procedure?
« Reply #8 on: December 10, 2022, 06:24:35 pm »
Thanks to all for your replies. I'm still collecting your opinions.

...
I also get the Windows result on Linux (gtk2).

Please: which Lazarus version did you use and which Linux version?

EDIT: sorry, I found it in your footer.

VTwin

  • Hero Member
  • *****
  • Posts: 1215
  • Former Turbo Pascal 3 user
Re: Is this a bug in Canvas.line procedure?
« Reply #9 on: December 10, 2022, 06:41:07 pm »
BTW, I also recommend TBGRABitmap.
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.6 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.6 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.6 (64 bit on VBox)

paweld

  • Hero Member
  • *****
  • Posts: 991
Re: Is this a bug in Canvas.line procedure?
« Reply #10 on: December 10, 2022, 08:16:41 pm »
on windows and linux (gtk2) the results are the same- Winsows 10, Lazarus 2.3.0, FPC 3.2.3- Debian 11, Lazarus 2.3.0, FPC 3.2.3
Best regards / Pozdrawiam
paweld

Hartmut

  • Hero Member
  • *****
  • Posts: 749
Re: Is this a bug in Canvas.line procedure?
« Reply #11 on: December 11, 2022, 01:07:00 pm »
Thanks again to all for your answers. I learned that:
 - it is correct, that the last pixel is "missing"
 - so on Windows there is no bug
 - my bug on Linux is fixed in Lazarus 2.2.4 and 2.3.0
 - for more serious applications BGRABitmap if preferable over TCanvas.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4467
  • I like bugs.
Re: Is this a bug in Canvas.line procedure?
« Reply #12 on: December 11, 2022, 04:00:25 pm »
Please: which Lazarus version did you use and which Linux version?
A reminder: Linux is a kernel and does not do any graphics.
The GUI and graphics libraries that run on Linux also run on other Unix related systems.
LCL has bindings for many GUI widgetset libraries like GTK2, GTK3, QT4 and QT5.
Instead of telling their Linux version people should tell their widgetset used by LCL.
Such a graph bug can be in generic LCL code, in LCL widgetset binding code, or in the underlying graph library (less likely).
[Edit] From the comments I understood this bug is in TCanvas which is part of generic LCL (not dependent on widgetsets). I have not realized it is so buggy. I don't do much graphics programming myself.

I wonder why nobody tested this with QT5. It is considered the most stable LCL widgetset running on Linux.
« Last Edit: December 11, 2022, 07:54:13 pm by JuhaManninen »
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

Hartmut

  • Hero Member
  • *****
  • Posts: 749
Re: [SOLVED] Is this a bug in Canvas.line procedure?
« Reply #13 on: December 11, 2022, 07:20:13 pm »
Thank you JuhaManninen for clarification. I did not know this so clearly. I tested with GTK2.

zeljko

  • Hero Member
  • *****
  • Posts: 1596
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: [SOLVED] Is this a bug in Canvas.line procedure?
« Reply #14 on: December 18, 2022, 10:54:01 am »
Just tested on LinuxMint 20.3 gtk2,qt,qt5 and qt6 all works fine. gtk3 have glitches.

 

TinyPortal © 2005-2018