wxPython, printing, previewing, font size, wxDC

Hi all,

In a previous post -- point size in printout --, there was
some discussion about printing and scaling. I want to add
some comments.

1) Printing or preparing the printing process under wxPython
is not an easy task. There are a lot of points to consider,
font size, dc size, preview, paper format... . Each point
works fine, but the interaction between them can lead to
"unexpected" results.

2) To come back to the Viking's problem, I agree with
Robin Dunn. The simplest way to set a correct font size is
to define a font size proportional to the size of the dc.
This is the way shown in the demo and it is globally working
fine.

3) I'm using the following apprach. I do not claim, this is
the best solution, but I get satisfying and practical results.
When preparing the printing job, I define my own font unit,
fsu, which is proportional to the size of the dc.

    fsu = dc.GetSizeTuple()[0] / 750.0
    
This is a float type. 750.0 is a trial and error number, it
corresponds more or less to the width of the dc for a
previewing of 100%. Later, I am using this fsu to define the
font size I want to use in my plot job.

    fs = int(fsu * 10 + 0.5)
    if fs < 1: fs = 1
    dc.SetFont(wxFont(fs, wxSWISS, wxNORMAL, wxNORMAL))

Using Python 2.3, do not forget to use integer font size, in
order to prevent the "Deprecation warning: get float, integer
expected..." or something like this. This simple approach is
working fine for printing and for previewing at all zoom
levels. Note that I am using this to generate scientific
plots, not pages of long text.

4) wxPython and printer dc size
Setting a font size proportional to the dc size is nice, but
this has a drawback. The dc size is the size of the printable
area of the printer. This size may vary for different printers.
So if you scale the font size according to the dc size, the
size of the printed font may vary too. I should agree, the
different dc sizes for a given paper format is small. No small
enough to avoid truncating issues, when defining the font size
to be used. A numerical example, printer1 has a printable
dc size heigth of n1, printer2 has a printable dc size n2.
Now I want to print m lines, so if I calculate the font size
for printer1 I get an theoretical font size of, let's sax,
11.9 and for printer2 I get 12.01.
The font size I defined in the dc is just the truncated
integers of the above values, 11 for printer1 and 12 for
printer2. I said truncated and not rounded, if you round the
theoretical value you may not print the last line.
Conclusion: two printers, two different point sizes.
In one sense, this is logical, the used point size depends on
the printable area capabilities. But see point 7)

5) Preview
Working with "print preview" is a good way to illustrate the
point 4) issue. Prepare a text of, let's say, 60 lines and
define a font size proportional to the dc size. Now play with
different zoom values, you will notice the print preview
page/canvas is not always desplaying the same amout of lines.

6) How to solve this?
One solution would be to be able to define non integer font
sizes. This is feasible in visual bacic (MFC) and java (if
I remember correctly), impossible using wxPython. (Please do
not flame about that point, the font size in MFC is really
an integer, but it is possible to contstruct a font with a
tenth of point precision.)

7) In point 4, we have seen the font size can fit the
printable area size. Unfortunatelly, this is not always
what the user wants. The user wants to define a fixed font
size and keep it for all the printers, eg a font size
of 10 or 12 for "usual" texts. In that case, the number of
lines on a page may vary according to the font size. Again
this is doable, but for a nice print (horizontally and/or
vertically centered), we miss an information, the sizes of
the non printable margins. How I can get this information
using wxPython? MFC has an api for this.

8) wxHTMLEasyPrinting is one another illustation, where
previewing and printing do no match.

9) Setting the font size proportional to the dc is nice.
Setting the font size proportional to the physical page size
is better. Especially for europeans, who are using the much
clever A* standard, instead of the legal or us paper format.
The dc unit beeing the pixel, how do I get the paper sheet
size in pixels? Or how do I get the paper size in the
same unit as the dc size? I found a solution, but this is
a hand calculation.

10) Steve Williams proposed a way to set the x- and y-scaling.
This is ok for drawings. You can not set a different x- and y-scale
for a font. This is a case where the A* format shows its
power.

Jean-Michel Fauth, Switzerland

Jean-Michel Fauth wrote:

Hi all,

In a previous post -- point size in printout --, there was
some discussion about printing and scaling. I want to add
some comments.

Could you prepare a wiki page for this? You've got some good info in this message and it would be nice to preserve it in the wiki.

6) How to solve this?
One solution would be to be able to define non integer font
sizes. This is feasible in visual bacic (MFC) and java (if I remember correctly), impossible using wxPython. (Please do
not flame about that point, the font size in MFC is really
an integer, but it is possible to contstruct a font with a
tenth of point precision.)

Yes, this would be nice, and probably doable. Please enter a feature request for this (or a patch! <wink> ) on the wxWindows SF project page, or bring it up on wx-dev.

7) In point 4, we have seen the font size can fit the printable area size. Unfortunatelly, this is not always what the user wants. The user wants to define a fixed font
size and keep it for all the printers, eg a font size
of 10 or 12 for "usual" texts. In that case, the number of
lines on a page may vary according to the font size. Again
this is doable, but for a nice print (horizontally and/or
vertically centered), we miss an information, the sizes of
the non printable margins. How I can get this information using wxPython? MFC has an api for this.

This was discussed several months ago on wx-dev and I think there is a task on the roadmap to give the printing framework an overhall to fix omissions like this.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Hi and thanks in advance
I am having trouble print previewing at the most basic level, I must be
missing something really obvious but would appreciate any help.
How do I draw text on the preview window. I don't seem to be able to
get a device context to anything.
Thanks Greg

Howdy Greg,

  The Print Preview uses the same canvas as the one you use for
printing.

  I used the demo to get me started a while back.

  The only thing the demo (and doc) lacks is a clear explanation for
multiple pages, but I got that working too.

  The main magic is your derived PrintOut class (subclassed from
wxPrintout). HasPage() and OnPrintPage() are the important methods.

  I created my PrintCanvas class which is derived from
wxScrolledWindow. OnPaint() and DoDrawing() are the important methods
here. I also implemented several convenience methods in this class like
PrintHeader(), PrintTitle(), PrintFooter(), etc.

  My code for the menu options of Print and PrintPreview are pretty much
the same as the demo code. Just instantiate your PrintCanvas and pass
that as a param to your PrintOut class and it'll print.

  PrintPreview use instantiate a wxPrintPreview object passing it an
instance of your PrintCanvas.

···

On Wed, 2003-10-22 at 20:22, Greg Binns wrote:

Hi and thanks in advance
I am having trouble print previewing at the most basic level, I must be
missing something really obvious but would appreciate any help.
How do I draw text on the preview window. I don't seem to be able to
get a device context to anything.
Thanks Greg

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

--
Jim West
CheckLogix -a Concord company
102 S. Tejon Ste 920, Colorado Springs, CO 80903
719.633.7005 x223 Fax: 719.633.7006 Cell: 719.660.5676