Recent

Author Topic: Copyrect not working in Linux  (Read 1037 times)

rebzdu

  • New Member
  • *
  • Posts: 11
Copyrect not working in Linux
« on: November 30, 2020, 08:47:16 pm »
I have a program, which was working fine in Windows and Linux.
Shortly I recompiled the source in Linux with Lazarus Version #: 2.1.0, Date 2020-05-30, FPC-Version: 3.0.4, SVN-Revision 63251M, x86_64-linux-gtk2.
I draw an image in the background on
Code: Pascal  [Select][+][-]
  1. TempBild:TImage;
TempBild is created by
Code: Pascal  [Select][+][-]
  1. TempBild.Free;
  2. TempBild:=TImage.Create(Form1);
  3. TempBild.Left := 0;
  4. TempBild.Top := 0;
  5. TempBild.Width := Form1.ClientWidth;
  6. TempBild.Height := Form1.ClientHeight;
  7. With TempBild,Canvas do
  8.     begin
  9.     Brush.Color := clRed;{bz White;}
  10.     FillRect(Rect(0,0,ClientWidth,ClientHeight));
  11.     Font.Name := 'Arial';
  12.     Font.Size := 10;
  13.     end;
To check, if everything is well drawn I tested it by
Code: [Select]
TempBild.Picture.SaveToFile('TempBild.jpg');and everything is fine
I transfer it to the Canvas of Form1 with the following statements:
Code: Pascal  [Select][+][-]
  1. with TempBild.Canvas do
  2.     src := Rect(0,0,ClientWidth,ClientHeight);
  3. with Form1.Canvas do
  4.     dest := Rect(0,0,ClientWidth,ClientHeight);
  5. Form1.Canvas.CopyRect(dest,TempBild.Canvas,src);
  6.  
but nothing happens, in on my screen.
With older versions of Lazarus under Linux everything worked satisfactory.
Can anybody help me?

winni

  • Hero Member
  • *****
  • Posts: 2122
Re: Copyrect not working in Linux
« Reply #1 on: November 30, 2020, 09:14:27 pm »
Hi!

A canvas does not have a clientRect, clientWidth, ClientHeight.
So the source rect has to be:

Code: Pascal  [Select][+][-]
  1. src := Rect(0,0, TempBild.Width,TempBild.Height);

Second:

If you copy from canvas to canvas this has to be done in the OnPaint event of Form1.
This is not clear from your source.

Winni



Thaddy

  • Hero Member
  • *****
  • Posts: 10695
Re: Copyrect not working in Linux
« Reply #2 on: November 30, 2020, 09:42:59 pm »
f you copy from canvas to canvas this has to be done in the OnPaint event of Form1.
No, the canvas should be locked/unlocked with beginupdate/endupdate. OnPaint has nothing to do with it. On the contrary, you should prevent access - so prevent paint at all during the operation..
Although this can be achieved in OnPaint (provided the locking) that is not the correct spot.
BeginUpdate prevents any painting, so logically the wrong place for "OnPaint"....because there is no paint....
Basically you can do it anywhere, but make sure you use BeginUpdate/EndUpdate.
Only after that - this is a blocking operation - you should use OnPaint to show the results if necessary.
Or call paint.
« Last Edit: November 30, 2020, 09:54:06 pm by Thaddy »

winni

  • Hero Member
  • *****
  • Posts: 2122
Re: Copyrect not working in Linux
« Reply #3 on: November 30, 2020, 11:48:53 pm »

Basically you can do it anywhere, but make sure you use BeginUpdate/EndUpdate.


Very wise.

After the next hiding the app the drawaing on the Form.canvas is gone.
You come along and repaint it? Or who?

Winni


rebzdu

  • New Member
  • *
  • Posts: 11
Re: Copyrect not working in Linux
« Reply #4 on: December 01, 2020, 01:06:03 am »
Hallo winni,
I put it inside of FormPaint, and now it is also running with Lazarus on my Linux-PC  ;D

Hallo Thaddy
I tried to put it outside of FormPaint, but Lazarus complains, that there is no beginupdate resp. endupdate. TForm knows BeginFormUpdate/EndFormUpdate (did ypu mean this?), but  this didn't work as well, even if I call Paint resp. Invalidate/Paint after using CopyRect.  :(

What I don't understand, why my code was running one year ago on Windows and Linux, now only on Windows. On Linux I have the newest Version of Lazarus, on Windows I use an earlier version. Have there been any changes to CopyRect, so that FormPaint/Paint was called automatically in the previsous versions of Lazarus?
« Last Edit: December 01, 2020, 01:09:03 am by rebzdu »

rebzdu

  • New Member
  • *
  • Posts: 11
Re: Copyrect not working in Linux
« Reply #5 on: December 01, 2020, 07:44:59 pm »
Hello winni,
if I put it inside FormPaint, my Windows-Version is no longer working. There are white flashes between my own images in irregular intervals and my keystokes are no longer recognized  :(

Thaddy

  • Hero Member
  • *****
  • Posts: 10695
Re: Copyrect not working in Linux
« Reply #6 on: December 01, 2020, 09:11:26 pm »
You should follow my advice, not winni. He is mistaken.

winni

  • Hero Member
  • *****
  • Posts: 2122
Re: Copyrect not working in Linux
« Reply #7 on: December 01, 2020, 09:28:07 pm »
Hi!

In Thaddys mind I am allways wrong...

The error has another reason:

Never call Form1 in a procedure TForm1.......

The correct way is  :
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormPaint(Sender: TObject);
  2. ...
  3. begin                                      
  4. self.Canvas.CopyRect(dest,TempBild.Canvas,src);
  5. ...
  6. end;
  7.  

Winni

rebzdu

  • New Member
  • *
  • Posts: 11
Re: Copyrect not working in Linux
« Reply #8 on: December 01, 2020, 09:29:46 pm »
Hello Thaddy,
as I wrote this morning, Lazarus doesn't know BeginUpdate and EndUpdate, these aren't methods from TForm nor from TCanvas.
If I insert
Code: Pascal  [Select][+][-]
  1.     BeginUpdate;
  2.     Form1.Canvas.CopyRect(dest,TempBild.Canvas,src);
  3.     EndUpdate;
in my code I get the message
"Error illegal qualifier"

Sieben

  • Full Member
  • ***
  • Posts: 196
Re: Copyrect not working in Linux
« Reply #9 on: December 01, 2020, 09:37:51 pm »
TCanvas has Lock, TryLock and Unlock...
Lazarus 2.0.10, FPC 3.2.0, .deb install on Ubuntu Xenial 32 / Gtk2 / Unity7

rebzdu

  • New Member
  • *
  • Posts: 11
Re: Copyrect not working in Linux
« Reply #10 on: December 01, 2020, 09:55:44 pm »
Now I can compile without error messages.
But if I put the code outside of FormPaint, nothing happens, only if I insert it inside FormPaint.

winni

  • Hero Member
  • *****
  • Posts: 2122
Re: Copyrect not working in Linux
« Reply #11 on: December 01, 2020, 11:23:50 pm »
Hi!

That's the difference between theory (Thaddy)  and practice (Me).

Winni

lucamar

  • Hero Member
  • *****
  • Posts: 3455
Re: Copyrect not working in Linux
« Reply #12 on: December 02, 2020, 12:45:17 am »
But if I put the code outside of FormPaint, nothing happens, only if I insert it inside FormPaint.

I don't know how you're putting the code "outside of FormPaint" but, of course, you can put in any method/procedure/function. Only, it has to be called from the OnPaint handler (or similar); otherwise it'll never be executed! Code outside event handlers has to be called from somewhere ... ;D
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.10/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

rebzdu

  • New Member
  • *
  • Posts: 11
Re: Copyrect not working in Linux
« Reply #13 on: December 02, 2020, 01:43:25 am »
I don't call it by FormPaint, but at the end of my method I call Repaint:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.ZeigeTempBild;
  2. var src,dest:TRect;
  3. begin
  4. {$IFDEF DUMP}
  5. Append(log);
  6. writeln(log,'ZeigeTempBild');
  7. CloseFile(log);
  8. {$ENDIF}
  9. //TempBild.Picture.SaveToFile('TempBild '+IntToStr(BildNr)+'.jpg');
  10. with TempBild do
  11.     src := Rect(0,0,Width,Height);
  12. with Form1.Canvas do
  13.     dest := Rect(0,0,ClientWidth,ClientHeight);
  14. Canvas.Lock;
  15. Canvas.CopyRect(dest,TempBild.Canvas,src);
  16. Canvas.Unlock;
  17. Repaint;
  18. end;
The Method is call by a timer every second, which I controlled by the log-file. If I uncomment line 9 I get the propper images on my hard disk.
If I put lines 9-16 into FormPaint, it works in Linux, but I get the problems in Windows.
« Last Edit: December 03, 2020, 11:41:26 am by rebzdu »

circular

  • Hero Member
  • *****
  • Posts: 3648
    • Personal webpage
Re: Copyrect not working in Linux
« Reply #14 on: December 03, 2020, 12:33:21 pm »
I am confused. Is TempBild just to store an image that is not visible? If that's the case, then you would rather use TBitmap. And it is easy to draw a bitmap on a Canvas using the Draw function.

TImage is a visual component and its Canvas is not meant to store a bitmap. Though if you want to store a bitmap in it, you can use its Picture.Bitmap property.

Painting on the form, in order to be cross platform should be done only in the OnPaint events. Otherwise it won't work on Qt5 or MacOS.
Conscience is the debugger of the mind

 

TinyPortal © 2005-2018