Recent

Author Topic: CopyRect Paintbox canvas to Bitmap canvas  (Read 9920 times)

pleoman

  • New Member
  • *
  • Posts: 15
CopyRect Paintbox canvas to Bitmap canvas
« on: February 22, 2015, 11:05:42 pm »
I'm trying to move a program from Delphi to Lazarus to compile on a macbook pro. I'm not using the Delphi to Lazarus converters. I'm rewriting everything from scratch. The Delphi version of the program I want to convert is WMa2.exe at www.casconorwich.org/pages/math.html. The program includes about 15 procedures for drawing different figures on a paintbox,over 7,000 lines of code. The drawings are simple, lines and polygons, graphs of math functions. I have 2 questions:

1) In Delphi, I can draw figures on the paintbox within each procedure. For example, a simple procedure might look like:

Procedure DrawFig;
begin
With Screen1.Paintbox1.Canvas do
begin
//Draw something on paintbox1.canvas...
end;
end;

  But this doesn't work in Lazarus unless I call the procedure from the OnPaint
procedure? This is what I've been reading from all the forum messages and examples. Is there a way, maybe using the Sender or some handle, to draw on the paintbox directly from a procedure without calling it from the Paintbox1Paint procedure? I've run out of ideas.

2) I also want to copy the paintbox.canvas to a bitmap after each change to the paintbox canvas. In Delphi, I use
 Bitmap.Canvas.CopyRect(DRect,Screen1.Paintbox1.Canvas,DRect);
But I can't get CopyRect to work in carbon. If I also draw on the bitmap.canvas every time I draw on the Paintbox1.canvas, then that works fine, but that adds an awful lot more code. Is there an easier way that I'm missing? Is it possible to move a paintbox canvas to a bitmap canvas?


Lazarus v1.2.6 carbon widgetset
FPC-2.6.4.intel-macosx
Macbook pro version 10.7.5 Intel Core i7

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3538
Re: CopyRect Paintbox canvas to Bitmap canvas
« Reply #1 on: February 23, 2015, 11:35:01 pm »
Quote
  But this doesn't work in Lazarus unless I call the procedure from the OnPaint
procedure? This is what I've been reading from all the forum messages and examples. Is there a way, maybe using the Sender or some handle, to draw on the paintbox directly from a procedure without calling it from the Paintbox1Paint procedure? I've run out of ideas.

Create a TBitmap with the same size of the paintbox
Draw to the TBitmap any time you want (outside OnPaint for example)
In the OnPaint event draw the TBitmap to the paintbox

Quote
2) I also want to copy the paintbox.canvas to a bitmap after each change to the paintbox canvas. In Delphi, I use
 Bitmap.Canvas.CopyRect(DRect,Screen1.Paintbox1.Canvas,DRect);
But I can't get CopyRect to work in carbon. If I also draw on the bitmap.canvas every time I draw on the Paintbox1.canvas, then that works fine, but that adds an awful lot more code. Is there an easier way that I'm missing? Is it possible to move a paintbox canvas to a bitmap canvas?

Mac APIs are really restrictive about what you can get from a onscreen canvas, really this is a platform restriction. You need to draw to a bitmap like I said above.

Or just use TImage instead of TPaintbox: http://wiki.freepascal.org/Developing_with_Graphics#Painting_on_the_bitmap_of_a_TImage

pleoman

  • New Member
  • *
  • Posts: 15
Re: CopyRect Paintbox canvas to Bitmap canvas
« Reply #2 on: February 26, 2015, 02:33:07 pm »
Thanks for the suggestions.
With the software I wrote for my students using Delphi, They draw math functions on a paintbox with a time delay, so they can watch the graph evolve. If the graph is drawn to a bitmap, the entire graph just gets dumped to the screen. But I will experiment with the TImage component to see if there is a way I can draw with time delay.
Thanks again.

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: CopyRect Paintbox canvas to Bitmap canvas
« Reply #3 on: February 27, 2015, 02:14:01 am »
If the graph is drawn to a bitmap, the entire graph just gets dumped to the screen.
That is a good thing, basically it is doublebuffering. Prevents graphics from flashing, and might improve the visual performance.

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3538
Re: CopyRect Paintbox canvas to Bitmap canvas
« Reply #4 on: February 27, 2015, 02:29:54 am »
They draw math functions on a paintbox with a time delay, so they can watch the graph evolve.

Call TPaintbox.Invalidate before the time delays, and make the time delays loops with Application.ProcessMessages + small sleep

This way you will be able to see the graph evolve.

pleoman

  • New Member
  • *
  • Posts: 15
Re: CopyRect Paintbox canvas to Bitmap canvas
« Reply #5 on: February 28, 2015, 10:31:01 pm »
The delay works great using the computer clock. The graph evolves on the paintbox1.canvas fine. I use Application.ProcessMessages and all works well. My problem is copying the graphs from paintbox1.canvas to something else like a bitmap for saving, printing, copying to clipboard, etc. It looks like, with carbon, that I'll have to repeat each drawing process that I perform on a paintbox.canvas to a bitmap as well, because CopyRect isn't working. Of course, my students using a mac could pull up the Grab.app and select that part of the graph they want to submit, but that will be a last resort.
Thanks to all for the interest.

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: CopyRect Paintbox canvas to Bitmap canvas
« Reply #6 on: February 28, 2015, 11:47:46 pm »
Animated (changing) graphics should be done with TTimer.

Draw() is faster for this than CopyRect(), especially if you draw the whole thing to TBitmap. Then you can also use TBitmap's SaveToFile and whatever you want with its canvas. You can consider TPaintBox as a temporary display. TImage has a permanent Bitmap.Canvas (note that it is different to TImage.canvas), but it is still recommended to have 1 of your own.

 

TinyPortal © 2005-2018