Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2008-05

Printer margins

15 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Felipe Monteiro de Carvalho

Hello,

Printing to the 0,0 position in the canvas from the Printer seams to print nothing, until the margin is reached (Mac OS X), so I did a small research to find out which top/left margin to use, but it seams that it's not implemented in LCL.

Searching for Delphi, people seam to use this:

GetDeviceCaps( printer.handle, LOGPIXELSX );

Top Margin: PHYSICALOFFSETY
Left Margin: PHYSICALOFFSETX
Right Margin: ((PHYSICALWIDTH) - (PHYSICALOFFSETX + HORZRES)) div LOGPIXELSX Bottom Margin: ((PHYSICALHEIGHT) - (PHYSICALOFFSETY + VERTRES)) div LOGPIXELSY

Alternatively we can also use PageWidth and PageHeight to get how much we can draw in the paper, but this doesn't help with the left/top offset.

PHYSICALOFFSETX doesn't exist in LCL, so I think it isn't implemented for GetDeviceCaps.

What do people currently use to print?

Also, this winapi method is rather clumsy, maybe we should add some margin properties to TPrinter, what do you think?

thanks,

Felipe Monteiro de Carvalho

Reply by email

Jesus Reyes
to Felipe Monteiro de Carvalho

--- Felipe Monteiro de Carvalho
escribi?:

Show quoted text 37 lines
Hello, Printing to the 0,0 position in the canvas from the Printer seams to print nothing, until the margin is reached (Mac OS X), so I did a small research to find out which top/left margin to use, but it seams that it's not implemented in LCL. Searching for Delphi, people seam to use this: GetDeviceCaps( printer.handle, LOGPIXELSX ); Top Margin: PHYSICALOFFSETY Left Margin: PHYSICALOFFSETX Right Margin: ((PHYSICALWIDTH) - (PHYSICALOFFSETX + HORZRES)) div LOGPIXELSX Bottom Margin: ((PHYSICALHEIGHT) - (PHYSICALOFFSETY + VERTRES)) div LOGPIXELSY Alternatively we can also use PageWidth and PageHeight to get how much we can draw in the paper, but this doesn't help with the left/top offset. PHYSICALOFFSETX doesn't exist in LCL, so I think it isn't implemented for GetDeviceCaps. What do people currently use to print? Also, this winapi method is rather clumsy, maybe we should add some margin properties to TPrinter, what do you think? thanks, -- Felipe Monteiro de Carvalho

This is already done, see components/printers/win32/winprinter.inc for windows.

Basically you set the wished (existing) paper name using: printer.papersize.papername := 'papername'; then you have printer.papersize.physicalrect and printer.papersize.workrect to work with, see also lazreport/source/lr_prntr.pas code

Jesus Reyes A.

____________________________________________________________________________________ Yahoo! Deportes Beta
?No te pierdas lo ?ltimo sobre el torneo clausura 2008! Ent?rate aqu? http://deportes.yahoo.com

Reply by email

Felipe Monteiro de Carvalho
to Jesus Reyes

Ok, thanks, that works nicely, but you have to guess the paper being used.

If we are using a TPrintDialog then the user should be able to select the target paper and margins in the TPrintDialog.

So maybe some way to get the paper name is missing from TPrintDialog, or even better, get all margins form there.

Here is my current code:

procedure TfrmPrint.btnPrintClick(Sender: TObject);
var
  PaperWorkRect: TRect;
  PrintDlg: TPrintDialog;
begin
  PrintDlg := TPrintDialog.Create(Self);
  try
    if PrintDlg.Execute then
    begin
      Printer.BeginDoc;
      Printer.papersize.papername := 'A4';
      PaperWorkRect := Printer.PaperSize.PaperRect.WorkRect;
      Printer.Canvas.TextOut(PaperWorkRect.Left, PaperWorkRect.Top, 'TextOut');
      Printer.EndDoc;
    end;
  finally
    PrintDlg.Free;
  end;
end;

thanks,

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Felipe Monteiro de Carvalho

Hello,

Reminder.

Who is responsible for the printer subsystem?

thanks,

Felipe

Felipe Monteiro de Carvalho wrote 34 lines
Ok, thanks, that works nicely, but you have to guess the paper being used. If we are using a TPrintDialog then the user should be able to select the target paper and margins in the TPrintDialog. So maybe some way to get the paper name is missing from TPrintDialog, or even better, get all margins form there. Here is my current code: procedure TfrmPrint.btnPrintClick(Sender: TObject); var PaperWorkRect: TRect; PrintDlg: TPrintDialog; begin PrintDlg := TPrintDialog.Create(Self); try if PrintDlg.Execute then begin Printer.BeginDoc; Printer.papersize.papername := 'A4'; PaperWorkRect := Printer.PaperSize.PaperRect.WorkRect; Printer.Canvas.TextOut(PaperWorkRect.Left, PaperWorkRect.Top, 'TextOut'); Printer.EndDoc; end; finally PrintDlg.Free; end; end; thanks, -- Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho

Reply by email

Jesus Reyes
to Felipe Monteiro de Carvalho

--- Felipe Monteiro de Carvalho
escribi?:

Hello, Reminder.

I was also expecting feedback from other users and then forgot about it, sorry.

Who is responsible for the printer subsystem?

Normally that would be me, at least for the OS's I normally use.

Show quoted text 17 lines
thanks, Felipe On Tue, Jun 3, 2008 at 9:54 PM, Felipe Monteiro de Carvalho wrote: > Ok, thanks, that works nicely, but you have to guess the paper being used. > > If we are using a TPrintDialog then the user should be able to select > the target paper and margins in the TPrintDialog. > > So maybe some way to get the paper name is missing from TPrintDialog, > or even better, get all margins form there.

If we are talking about standard dialogs here, then we are out of luck, standard TPrinterDialog has no direct paper select capabilities, however if when using TPrinterDialog you click printer properties and select a paper in printer properties dialog, that choice should be honoured, if not you have found a bug.

I don't know if this apply to all applications but usually printing takes two optional steps, in step one you select printer properties using TPrinterSetupDialog (which normally have printer and direct paper selecting capabilities, BTW, you can use this instead of TPrinterDialog if you don't need page range selection), and step 2, where you select page range printing using TPrinterDialog.

At least this is my understanding, it would be nice to hear from other users what are their expectatives.

Jesus Reyes A.

____________________________________________________________________________________ Yahoo! Deportes Beta
?No te pierdas lo ?ltimo sobre el torneo clausura 2008! Ent?rate aqu? http://deportes.yahoo.com

Reply by email

Felipe Monteiro de Carvalho
to Jesus Reyes
Jesus Reyes wrote 5 lines
If we are talking about standard dialogs here, then we are out of luck, standard TPrinterDialog has no direct paper select capabilities, however if when using TPrinterDialog you click printer properties and select a paper in printer properties dialog, that choice should be honoured, if not you have found a bug.

Indeed. The cause of the bug is that people under Delphi use Windows API to get the margins, and here we need a cross-platform solution which currently doesn't exist.

Show quoted text 9 lines
I don't know if this apply to all applications but usually printing takes two optional steps, in step one you select printer properties using TPrinterSetupDialog (which normally have printer and direct paper selecting capabilities, BTW, you can use this instead of TPrinterDialog if you don't need page range selection), and step 2, where you select page range printing using TPrinterDialog. At least this is my understanding, it would be nice to hear from other users what are their expectatives.

Under Mac OS X only 1 dialog makes everything.

Ummm .... 2 dialogs that can set the paper .... where should the margin properties go?

Also, I just thougth now that we also need to get the default paper even if we don't use any dialog.

So maybe a function in Printers or something like that could return the margins?

thanks,

Felipe Monteiro de Carvalho

Reply by email

Jesus Reyes
to Felipe Monteiro de Carvalho
Indeed. The cause of the bug is that people under Delphi use Windows API to get the margins, and here we need a cross-platform solution which currently doesn't exist.

At this point we are not trying to implement windows api in other platforms, we currently have a high level mechanism to abstract the api and it's crossplatform, that's why I think we don't need a lowlevel one.

Show quoted text 6 lines
Under Mac OS X only 1 dialog makes everything. Ummm .... 2 dialogs that can set the paper .... where should the margin properties go?

I'm a little confused, it seems there are two kinds of margins: printer's physical limits (we call it here workable area) and user artificial margis. I thought you were talking about first kind, but now I think you are talking about second one.

What do you expect a hypotethical margins feature to do?, specifically in canvas, currently margins are just information which you can use (when available, remember that printable area is printer driver specific setup, some don't even specify one) it doesn't have any effect in canvas drawing

Also, I just thougth now that we also need to get the default paper even if we don't use any dialog.

Printer.PaperSize.DefaultPaper

So maybe a function in Printers or something like that could return the margins?
Printer.paperSize.PaperRect.WorkRect; // that's printable area (if
set)
thanks, -- Felipe Monteiro de Carvalho

Jesus Reyes A.

____________________________________________________________________________________ Yahoo! Deportes Beta
?No te pierdas lo ?ltimo sobre el torneo clausura 2008! Ent?rate aqu? http://deportes.yahoo.com

Reply by email

Felipe Monteiro de Carvalho
to Jesus Reyes
I'm a little confused, it seems there are two kinds of margins: printer's physical limits (we call it here workable area) and user artificial margis. I thought you were talking about first kind, but now I think you are talking about second one.

I think we need both.

If WorkAre is the Physical limits, then what is
Printer.PaperSize.PaperRect.PhysicalRect ?

What do you expect a hypotethical margins feature to do?,

You can use it when drawing to the printer canvas. say:

Printer.Canvas.Draw(someImg, MarginX, MarginY);
Jesus Reyes wrote
Printer.PaperSize.DefaultPaper

Nice! But does it really honor the paper choosen by the user in the print dialog? I looked at the code but I can't find an answer.

thanks,

Felipe Monteiro de Carvalho

Reply by email

Jesus Reyes
to Felipe Monteiro de Carvalho

--- Felipe Monteiro de Carvalho
escribi?:

Show quoted text 11 lines
> I'm a little confused, it seems there are two kinds of margins: > printer's physical limits (we call it here workable area) and user > artificial margis. I thought you were talking about first kind, but > now I think you are talking about second one. I think we need both. If WorkAre is the Physical limits, then what is Printer.PaperSize.PaperRect.PhysicalRect ?

That would be page width and height encoded in a TRect

Show quoted text 7 lines
> What do you expect a hypotethical margins feature to do?, You can use it when drawing to the printer canvas. say: Printer.Canvas.Draw(someImg, MarginX, MarginY);

perhaps some code:

with Printer.PaperSize.PaperRect do begin
  MarginX := WorkRect.Left;
  MarginY := WorRect.Top;
  Printer.Canvas.Draw(someImg, MarginX, MarginY);
  // nothing stops us to define a user/application specific margin
  MarginX := 100;
  MarginY := 110;
  Printer.Canvas.Draw(someImg, MarginX, MarginY);
end;

Now, guess what? I completly forgot about the windows specific dialog: TPageSetupDialog there one can select Paper, Orientation and ta-da, Margins and also has a printer button. Margins here seems to refer to adjust printable area, so say you set marginsX=100 MarginY=100 in dialog and when you do canvas.Draw(0,0,SomeImg) it will print SomeImg at (100,100) mm, I'm not sure about this interpretation maybe somebody else can help here. I never used this dialog so I forgot it, sorry.

I don't know if there is a specific api for setting and retrieving this margins, but I guess if we have to have this feature we should use Printer.PaperSize class as an interface to such api.

TPageSetupDialog was a contribution, unfortunately it's not crossplatform, I expect new contributions to be crossplaforms other wise we end with problems.

Show quoted text 5 lines
> Printer.PaperSize.DefaultPaper Nice! But does it really honor the paper choosen by the user in the print dialog? I looked at the code but I can't find an answer.

Printer.PaperSize.DefaultPaperName it's supposed to be the paper you set in specific control panel OS dialogs so it's readonly, PaperSize.PaperName it's the currently selected paper using dialogs or code, available papers are in PaperSize.SupportedPapers list.

If you select a paper in dialog or code and PaperName doesn't reflect that selection, you have found a bug :D

thanks, -- Felipe Monteiro de Carvalho

____________________________________________________________________________________ Yahoo! Deportes Beta
?No te pierdas lo ?ltimo sobre el torneo clausura 2008! Ent?rate aqu? http://deportes.yahoo.com

Reply by email

Felipe Monteiro de Carvalho
to Jesus Reyes

Some more interresting information. Consider the following code:

procedure TfrmPrint.btnPrintClick(Sender: TObject);
var
  PrintDlg: TPrintDialog;
begin
  PrintDlg := TPrintDialog.Create(Self);
  try
    if PrintDlg.Execute then
    begin
      Caption := Printer.PaperSize.PaperName;
    end;
  finally
    PrintDlg.Free;
  end;
end;

It works under Windows. If you change the paper in the dialog, the correct paper is used.

But it doesn't work under Mac OS X with Carbon. The returned paper seams to be the default one, doesn't matter what is choosen in the dialog.

I still need to check if it works under Linux.

thanks,

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Jesus Reyes: --- Felipe Monteiro de Carvalho escribi?: That would be page width and height encoded in…
Jesus Reyes wrote
> If WorkAre is the Physical limits, then what is > Printer.PaperSize.PaperRect.PhysicalRect ? That would be page width and height encoded in a TRect

I don't understand. What is the difference between WorkRect and PhysicalRect?

If you use WorkRect to know what Canvas area is drawable, what do you use PhysicalRect for?

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Felipe Monteiro de Carvalho

Also, am I correct to assume that layout configurations such as having several pages per sheet (with the apropriate size change to fit) is done automatically by the operating system? Under Mac OS X it is processed automatically, but not sure about other operating systems.

Also, the Page range isn't automatic...

thanks,

Felipe Monteiro de Carvalho

Reply by email

Felipe Monteiro de Carvalho
to Felipe Monteiro de Carvalho: I don't understand. What is the difference between WorkRect and PhysicalRect? If you use…

ping about this e-mail:

thanks

Felipe Monteiro de Carvalho wrote 14 lines
On Tue, Jun 10, 2008 at 9:09 PM, Jesus Reyes wrote: >> If WorkAre is the Physical limits, then what is >> Printer.PaperSize.PaperRect.PhysicalRect ? > > That would be page width and height encoded in a TRect I don't understand. What is the difference between WorkRect and PhysicalRect? If you use WorkRect to know what Canvas area is drawable, what do you use PhysicalRect for? -- Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho

Reply by email

Jesus Reyes
to Felipe Monteiro de Carvalho

--- El s?b 21-jun-08, Felipe Monteiro de Carvalho escribi?:

Show quoted text 27 lines
De:: Felipe Monteiro de Carvalho Asunto: Re: [Lazarus] Printer margins A: "General mailing list" Fecha: s?bado, 21 junio, 2008, 4:14 pm ping about this e-mail: thanks On Sat, Jun 14, 2008 at 12:32 PM, Felipe Monteiro de Carvalho wrote: > On Tue, Jun 10, 2008 at 9:09 PM, Jesus Reyes wrote: >>> If WorkAre is the Physical limits, then what is >>> Printer.PaperSize.PaperRect.PhysicalRect ? >> >> That would be page width and height encoded in a TRect > > I don't understand. What is the difference between WorkRect and PhysicalRect? > > If you use WorkRect to know what Canvas area is drawable, what do you > use PhysicalRect for? >

my appologize I though I already replied.

Maybe I created some confusion about physical limits, sorry. I didn't now how to express (apart from printable area) how to describe the area is physically printable by the printer (supposedly), now windows GetDeviceCaps give two terms PHYSICALWIDTH and PHYSICALHEIGHT, they are plainly the physical dimmensions of page.

that is, Printer.PaperSize.PaperRect.PhysicalRect is Page Widht and Height encoded in a rect or if you like code (winprinters.inc:605)

      with aPaperRC.PhysicalRect do begin
        Left  :=0;
        Top   :=0;
        Right :=Windows.GetDeviceCaps(fDC, PHYSICALWIDTH);
        Bottom:=Windows.GetDeviceCaps(fDC, PHYSICALHEIGHT);
      end;

Then we have also Printer.PaperSize.PaperRect.WorkRect that is the printable area which is always smaller or equal to PhysicalRect, I call this physical limits because supossedly out of this limits the printer can't print. In code, see winprinters.inc also:

      with aPaperRC.WorkRect do begin
        Left  :=Windows.GetDeviceCaps(fDC, PHYSICALOFFSETX);
        Top   :=Windows.GetDeviceCaps(fDC, PHYSICALOFFSETY);
        Right :=Left   + Windows.GetDeviceCaps(fDC, HORZRES);
        Bottom:=Top    + Windows.GetDeviceCaps(fDC, VERTRES);
      end;

I initially treated Printer.PaperSize.PaperRect.WorkRect as "the margins" which is not completly true as I wrote in my previous msg.

Jesus Reyes A.

____________________________________________________________________________________ Yahoo! Deportes Beta
?No te pierdas lo ?ltimo sobre el torneo clausura 2008! Ent?rate aqu? http://deportes.yahoo.com

Reply by email