Version 1 of Printing a canvas under Windows

Updated 2001-08-22 10:59:24

Purpose: Demonstrate one way of printing a canvas under Win32.


KBK: I've seen a number of requests for ways to print the contents of a canvas under Windows. Alas, there is no graceful way. Nevertheless, there are approaches that work sometimes, and can be useful. For the most part, they work by using the 'postscript' command of the canvas widget to render the canvas as PostScript, and then either sending the result directly to a PostScript printer, or piping it through Ghostscript to interpret it and pushing the result at a Winprinter.

One tool that helps a lot is PrFile32.exe, available from: [L1 ]. Without this clever little program, Windows makes it insanely difficult to send a PostScript file to a PostScript printer. With it, it's a simple as saying

    exec prfile32.exe /q fileName.ps &

I also find it useful to be able to carve up a canvas that's bigger than a page and print it in overlapping tiles. I often use the following code to do it.

The code has obvious bugs that it doesn't allow a user-specified scale factor but rather assumes that the printout should show 150 screen pixels to the inch. It also hard-codes the assumption of US letter-sized paper, although the margins are wide enough that it should work with A4. I present it as a starting point for anyone who wants to try to do better.


    #------------------------------------------------------------------
    #
    # printcanvas.tcl --
    #
    #   Tcl procedure to spool a canvas via PrFile32.
    #
    #------------------------------------------------------------------

    package provide printcanvas 1.0

    namespace eval printcanvas {

        namespace export printcanvas

        # CONFIGURATION -- Path name of the PrintFile program.

        variable prfile {C:\Program Files\PrintFile\PrFile32.exe}

    }

    #------------------------------------------------------------------
    #
    # printcanvas::printcanvas --
    #
    #   Print the contents of a canvas
    #
    # Parameters:
    #   w -- Path name of the canvas
    #
    # Results:
    #   None.
    #
    # Side effects:
    #   Canvas content is converted to PostScript and spooled via
    #   PrintFile.  If the canvas is larger than a printer page,
    #   a file is created and spooled for each page.
    #
    #------------------------------------------------------------------

    proc printcanvas::printcanvas { w } {

        variable prfile

        set name [file join $::env(TEMP) [pid]page]
        set cmd [list exec $prfile /q /delete]
        set i 0
        foreach { xmin ymin xmax ymax } [$w cget -scrollregion] {}
        for { set x $xmin } { $x < $xmax } { incr x 1200 } {
            for { set y $ymin } { $y < $ymax } { incr y 825 } {
                set fname $name[incr i].ps
                $w create text [expr { $x+1210 }] [expr { $y+835 }] \
                    -text "Page $i" -anchor nw \
                    -tags printCanvasPageNo \
                    -font {Helvetica -18}
                eval [list $w create rectangle] \
                    [$w bbox printCanvasPageNo] \
                    [list -fill white -outline {} \
                         -tags printCanvasPageNoBg]
                $w raise printCanvasPageNo printCanvasPageNoBg
                $w postscript \
                    -file $fname \
                    -colormode gray \
                    -x $x -y $y -width 1350 -height 975 \
                    -pageheight 6.5i -pagewidth 9.0i \
                    -rotate true 
                lappend cmd $fname
                $w delete printCanvasPageNo
                $w delete printCanvasPageNoBg
            }
        }
        eval $cmd

        return
    }

GPS: How does this compare to Tkprint[L2 ]?


KBK (7 November 2000): I've never been able to get tkprint to generate output at other than microscopic size; maybe I'm missing something in how it's set up. Also, if you change the value of prfile to the appropriate 'lpr' command, the code works on Unix as well.


ClassyTk[L3 ] has support for native printing of the Canvas on Windows. (It is a hack, but works for me)