home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 December / PCWorld_2000-12_cd.bin / Komunikace / Comanche / comanche.exe / lib / iwidgets2.2.0 / scripts / canvasprintbox.itk < prev    next >
Text File  |  1999-02-24  |  36KB  |  1,291 lines

  1. #
  2. # CanvasPrintBox v1.5
  3. # ----------------------------------------------------------------------
  4. # Implements a print box for printing the contents of a canvas widget
  5. # to a printer or a file. It is possible to specify page orientation, the
  6. # number of pages to print the image on and if the output should be
  7. # stretched to fit the page.
  8. # CanvasPrintBox is a "super-widget" that can be used as an
  9. # element in ones own GUIs. It is used to print the contents
  10. # of a canvas (called the source hereafter) to a printer or a
  11. # file. Possible settings include: portrait and landscape orientation
  12. # of the output, stretching the output to fit the page while maintaining
  13. # a proper aspect-ratio and posterizing to enlarge the output to fit on
  14. # multiple pages. A stamp-sized copy of the source will be shown (called
  15. # the stamp hereafter) at all times to reflect the effect of changing
  16. # the settings will have on the output.
  17. #
  18. # ----------------------------------------------------------------------
  19. # AUTHOR: Tako Schotanus               EMAIL: Tako.Schotanus@bouw.tno.nl
  20. # ----------------------------------------------------------------------
  21. #                Copyright (c) 1995  Tako Schotanus
  22. # ======================================================================
  23. # Permission is hereby granted, without written agreement and without
  24. # license or royalty fees, to use, copy, modify, and distribute this
  25. # software and its documentation for any purpose, provided that the
  26. # above copyright notice and the following two paragraphs appear in
  27. # all copies of this software.
  28. # IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
  29. # DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 
  30. # ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 
  31. # IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
  32. # DAMAGE.
  33. #
  34. # THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 
  35. # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
  36. # FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  37. # ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  38. # PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  39. # ======================================================================
  40.  
  41. #
  42. # Default resources.
  43. #
  44. option add *Canvasprintbox.filename "canvas.ps" widgetDefault
  45. option add *Canvasprintbox.hPageCnt 1 widgetDefault
  46. option add *Canvasprintbox.orient landscape widgetDefault
  47. option add *Canvasprintbox.output printer widgetDefault
  48. option add *Canvasprintbox.pageSize A4 widgetDefault
  49. option add *Canvasprintbox.posterize 0 widgetDefault
  50. option add *Canvasprintbox.printCmd lpr widgetDefault
  51. option add *Canvasprintbox.printRegion "" widgetDefault
  52. option add *Canvasprintbox.vPageCnt 1 widgetDefault
  53.  
  54. #
  55. # Usual options.
  56. #
  57. itk::usual Canvasprintbox {
  58.     keep -background -cursor -textbackground 
  59. }
  60.  
  61. #<
  62. #
  63. # CanvasPrintBox is a "super-widget" that can be used as an
  64. # element in ones own GUIs. It is used to print the contents
  65. # of a canvas (called the source hereafter) to a printer or a
  66. # file. Possible settings include: portrait and landscape orientation
  67. # of the output, stretching the output to fit the page while maintaining
  68. # a proper aspect-ratio and posterizing to enlarge the output to fit on
  69. # multiple pages. A stamp-sized copy of the source will be shown (called
  70. # the stamp hereafter) at all times to reflect the effect of changing
  71. # the settings will have on the output.
  72. #
  73. #>
  74. class iwidgets::Canvasprintbox {
  75.     inherit itk::Widget
  76.     
  77.     #
  78.     # Just holds the names of some widgets/objects. "win" is used to
  79.     # determine if the object is fully constructed and initialized.
  80.     #
  81.     protected variable win ""
  82.     protected variable canvw ""
  83.     
  84.     #
  85.     # The canvas we want to print.
  86.     #
  87.     protected variable canvas ""
  88.     
  89.     #
  90.     # Boolean indicating if the attribute "orient" is set
  91.     # to landscape or not.
  92.     #
  93.     protected variable rotate 1
  94.     
  95.     #
  96.     # Holds the configure options that were used to create this object.
  97.     #
  98.     protected variable init_opts ""
  99.     
  100.     #
  101.     # The following attributes hold a list of lines that are
  102.     # currently drawn on the "stamp" to show how the page(s) is/are
  103.     # oriented. The first holds the vertical dividing lines and the
  104.     # second the horizontal ones.
  105.     #
  106.     protected variable hlines ""
  107.     protected variable vlines ""
  108.     
  109.     #
  110.     # Updating is set when the thumbnail is being drawn. Settings
  111.     # this to 0 while drawing is still busy will terminate the
  112.     # proces.
  113.     # Restart_update can be set to 1 when the thumbnail is being
  114.     # drawn to force a redraw.
  115.     #
  116.     protected variable updating 0
  117.     protected variable restart_update 0
  118.     
  119.     #
  120.     # Holds the current state for all check- and radiobuttons.
  121.     #
  122.     private common prtcanvglob
  123.     
  124.     itk_option define -filename filename FileName ""
  125.     itk_option define -hpagecnt hPageCnt PageCnt 1
  126.     itk_option define -orient orient Orient "landscape"
  127.     itk_option define -output output Output "printer"
  128.     itk_option define -pagesize pageSize PageSize "A4"
  129.     itk_option define -posterize posterize Posterize 0
  130.     itk_option define -printcmd printCmd PrintCmd ""
  131.     itk_option define -printregion printRegion PrintRegion ""
  132.     itk_option define -stretch stretch Stretch 0
  133.     itk_option define -vpagecnt vPageCnt PageCnt 1
  134.     
  135.     constructor {args} {}
  136.     destructor {}
  137.  
  138.     # ---------------------------------------------------------------
  139.     # PUBLIC METHODS
  140.     #----------------------------------------------------------------
  141.     
  142.     method getoutput {}
  143.     method print {}
  144.     method refresh {}
  145.     method setcanvas {canv}
  146.     method stop {}
  147.     
  148.     # ---------------------------------------------------------------
  149.     # PROTECTED METHODS
  150.     #----------------------------------------------------------------
  151.     
  152.     protected method _calc_poster_size {}
  153.     protected method _calc_print_region {}
  154.     protected method _calc_print_scale {}
  155.     protected method _calc_stamp_scale {}
  156.     protected method _config_optimum {}
  157.     protected method _mapEventHandler {}
  158.     protected method _update_UI {}
  159.     protected method _update_attr {}
  160.     protected method _update_canvas {}
  161.     protected method _update_canvas_thread {}
  162.     protected method _update_prtfile {}
  163.     protected method _update_widgets {}
  164.  
  165.     # ---------------------------------------------------------------
  166.     # PUBLIC CLASS METHODS
  167.     #----------------------------------------------------------------
  168.     
  169.     public proc ezPaperInfo {size {attr ""} \
  170.         {orient "portrait"} {window ""}} {}
  171. }
  172.  
  173. #
  174. # Provide a lowercased access method for the Canvasprintbox class.
  175. proc ::iwidgets::canvasprintbox {args} {
  176.     uplevel ::iwidgets::Canvasprintbox $args
  177. }
  178.  
  179. # ------------------------------------------------------------------
  180. #                             OPTIONS
  181. # ------------------------------------------------------------------
  182.  
  183. #<
  184. # A list of four coordinates specifying which part of the canvas to print.
  185. # An empty list means that the canvas' entire scrollregion should be
  186. # printed. Any change to this attribute will automatically update the "stamp".
  187. # Defaults to an empty list.
  188. #>
  189. configbody iwidgets::Canvasprintbox::printregion {
  190.     if {$itk_option(-printregion) != ""
  191.     && [llength $itk_option(-printregion)] != 4} {
  192.         error {bad option "printregion": should contain 4 coordinates}
  193.     }
  194.     _update_canvas
  195. }
  196.  
  197. #<
  198. # Specifies where the postscript output should go: to the printer
  199. # or to a file. Can take on the values "printer" or "file".
  200. # The corresponding entry-widget will reflect the contents of
  201. # either the printcmd attribute or the filename attribute.
  202. #>
  203. configbody iwidgets::Canvasprintbox::output {
  204.     case $itk_option(-output) {
  205.         file {
  206.         }
  207.         printer {
  208.         }
  209.         default {
  210.         error {bad output option \"$itk_option(-output)\":\
  211.             should be file or printer}
  212.         }
  213.     }
  214.     _update_UI
  215. }
  216.  
  217. #<
  218. # The command to execute when printing the postscript output.
  219. # The command will get the postscript directed to its standard
  220. # input. (Only when output is set to "printer")
  221. #>
  222. configbody iwidgets::Canvasprintbox::printcmd {
  223.     if {$win != ""} {
  224.         set itk_option(-output) "printer"
  225.     }
  226.     _update_UI
  227. }
  228.  
  229. #<
  230. # The file to write the postscript output to (Only when output
  231. # is set to "file"). If posterizing is turned on and hpagecnt
  232. # and/or vpagecnt is more than 1, x.y is appended to the filename
  233. # where x is the horizontal page number and y the vertical page number.
  234. #>
  235. configbody iwidgets::Canvasprintbox::filename {
  236.     if {$win != ""} {
  237.         set itk_option(-output) "file"
  238.     }
  239.     _update_UI
  240. }
  241.  
  242. #<
  243. # The pagesize the printer supports. Changes to this attribute
  244. # will be reflected immediately in the "stamp".
  245. #>
  246. configbody iwidgets::Canvasprintbox::pagesize {
  247.     set opt [string tolower $itk_option(-pagesize)]
  248.     set lst [string tolower [ezPaperInfo types]]
  249.     if {[lsearch $lst $opt] == -1} {
  250.         error "bad option \"pagesize\": should be one of: [ezPaperInfo types]"
  251.     }
  252.     _update_UI
  253.     _update_canvas
  254. }
  255.  
  256. #<
  257. # Determines the orientation of the output to the printer (or file).
  258. # It can take the value "portrait" or "landscape" (default). Changes
  259. # to this attribute will be reflected immediately in the "stamp".
  260. #>
  261. configbody iwidgets::Canvasprintbox::orient {
  262.     case $itk_option(-orient) {
  263.         portrait {
  264.         }
  265.         landscape {
  266.         }
  267.         default {
  268.         error {bad orient option \"$itk_option(-orient)\":\
  269.             should be portrait or landscape}
  270.         }
  271.     }
  272.     _update_UI
  273.     _update_canvas
  274. }
  275.  
  276. #<
  277. # Determines if the output should be stretched to fill the
  278. # page (as defined by the attribute pagesize) as large as
  279. # possible. The aspect-ratio of the output will be retained
  280. # and the output will never fall outside of the boundaries
  281. # of the page.
  282. #>
  283. configbody iwidgets::Canvasprintbox::stretch {
  284.     if {$itk_option(-stretch) != 0 && $itk_option(-stretch) != 1} {
  285.         error {bad option "stretch": should be a boolean}
  286.     }
  287.     _update_UI
  288. }
  289.  
  290. #<
  291. # Indicates if posterizing is turned on or not. Posterizing
  292. # the output means that it is possible to distribute the
  293. # output over more than one page. This way it is possible to
  294. # print a canvas/region which is larger than the specified
  295. # pagesize without stretching. If used in combination with
  296. # stretching it can be used to "blow up" the contents of a
  297. # canvas to as large as size as you want (See attributes:
  298. # hpagecnt end vpagecnt). Any change to this attribute will
  299. # automatically update the "stamp".
  300. #>
  301. configbody iwidgets::Canvasprintbox::posterize {
  302.     if {$itk_option(-posterize) != 0 && $itk_option(-posterize) != 1} {
  303.         error {bad option "posterize": should be a boolean}
  304.     }
  305.     _update_UI
  306.     _update_canvas
  307. }
  308.  
  309. #<
  310. # Is used in combination with "posterize" to determine over
  311. # how many pages the output should be distributed. This
  312. # attribute specifies how many pages should be used horizontaly.
  313. # Any change to this attribute will automatically update the "stamp".
  314. #>
  315. configbody iwidgets::Canvasprintbox::hpagecnt {
  316.     _update_UI
  317.     _update_canvas
  318. }
  319.  
  320. #<
  321. # Is used in combination with "posterize" to determine over
  322. # how many pages the output should be distributed. This
  323. # attribute specifies how many pages should be used verticaly.
  324. # Any change to this attribute will automatically update the "stamp".
  325. #>
  326. configbody iwidgets::Canvasprintbox::vpagecnt {
  327.     _update_UI
  328.     _update_canvas
  329. }
  330.  
  331. # ------------------------------------------------------------------
  332. # CONSTRUCTOR
  333. # ------------------------------------------------------------------
  334. body iwidgets::Canvasprintbox::constructor {args} {
  335.     itk_component add outputom {
  336.         iwidgets::optionmenu $itk_interior.outputom \
  337.             -labelmargin 5 -labelpos w -cyclicon 1\
  338.             -labeltext "Output to :" \
  339.             -items {Printer File} \
  340.             -command [code $this _update_attr]
  341.     } {
  342.         keep -cursor -background
  343.     }
  344.     $itk_component(outputom) select Printer
  345.     pack $itk_component(outputom) \
  346.         -anchor center -expand 0 -fill x -ipadx 0 -ipady 0 \
  347.         -padx 0 -pady 0 -side top
  348.  
  349.     itk_component add prtflentry {
  350.         iwidgets::entryfield $itk_interior.prtflentry \
  351.             -labeltext {Printer command :} \
  352.             -command [code $this _update_prtfile]
  353.     } {
  354.         keep -background -cursor -textbackground
  355.     }
  356.     pack $itk_component(prtflentry) \
  357.         -anchor center -expand 0 -fill x -ipadx 0 -ipady 0 \
  358.         -padx 0 -pady 0 -side top
  359.  
  360.     itk_component add paperom {
  361.         iwidgets::optionmenu $itk_interior.paperom \
  362.             -labelmargin 5 -labelpos w -cyclicon 1\
  363.             -labeltext "Paper size :" \
  364.             -command [code $this refresh]
  365.     } {
  366.         keep -cursor -background
  367.     }
  368.     $itk_component(paperom) configure -items [ezPaperInfo types]
  369.     $itk_component(paperom) select A4
  370.     pack $itk_component(paperom) \
  371.         -anchor center -expand 0 -fill x -ipadx 0 -ipady 0 \
  372.         -padx 0 -pady 0 -side top
  373.  
  374.     itk_component add canvasframe {
  375.         frame $itk_interior.f18 -borderwidth 2 -relief ridge
  376.     } {
  377.         keep -background -cursor
  378.     }
  379.     pack $itk_component(canvasframe) \
  380.         -anchor center -expand 1 -fill both -ipadx 0 -ipady 0 \
  381.         -padx 2 -pady 2 -side top
  382.  
  383.     itk_component add canvas {
  384.         canvas $itk_component(canvasframe).c1 \
  385.             -borderwidth 2 -relief sunken \
  386.             -scrollregion {0c 0c 10c 10c} \
  387.             -width 100 -height 100
  388.     } {
  389.         keep -background -cursor
  390.     }
  391.     pack $itk_component(canvas) \
  392.         -anchor center -expand 1 -fill both -ipadx 0 -ipady 0 \
  393.         -padx 0 -pady 9 -side top
  394.  
  395.     itk_component add optionsframe {
  396.         frame $itk_interior.f26 -borderwidth 2
  397.     } {
  398.         keep -background -cursor
  399.     }
  400.     pack $itk_component(optionsframe) \
  401.         -anchor center -expand 0 -fill x -ipadx 0 -ipady 0 \
  402.         -padx 2 -pady 4 -side top
  403.  
  404.     itk_component add orientom {
  405.         iwidgets::optionmenu $itk_component(optionsframe).orientom \
  406.             -labelmargin 5 -labelpos w -cyclicon 1\
  407.             -labeltext "Orientation :" \
  408.             -items {Portrait Landscape} \
  409.             -command [code $this refresh]
  410.     } {
  411.         keep -cursor -background
  412.     }
  413.     $itk_component(orientom) select Landscape
  414.     pack $itk_component(orientom) \
  415.         -anchor center -expand 0 -fill x -ipadx 0 -ipady 0 \
  416.         -padx 0 -pady 0 -side top
  417.  
  418.     itk_component add stretchframe {
  419.         frame $itk_component(optionsframe).f14 -borderwidth 2
  420.     } {
  421.         keep -background -cursor
  422.     }
  423.     pack $itk_component(stretchframe) \
  424.         -anchor center -expand 0 -fill x -ipadx 0 -ipady 0 \
  425.         -padx 0 -pady 0 -side top
  426.  
  427.     set prtcanvglob($this,stretchcb) 0
  428.     itk_component add stretchcb {
  429.         checkbutton $itk_component(stretchframe).cb1 \
  430.             -relief flat -text {Stretch to fit} \
  431.             -variable [scope prtcanvglob($this,stretchcb)] \
  432.             -command [code $this refresh]
  433.     } {
  434.         keep -background -cursor
  435.     }
  436.     pack $itk_component(stretchcb) \
  437.         -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 \
  438.         -padx 0 -pady 0 -side left
  439.  
  440.     itk_component add posterframe {
  441.         frame $itk_component(optionsframe).f15 -borderwidth 2
  442.     } {
  443.         keep -background -cursor
  444.     }
  445.     pack $itk_component(posterframe) \
  446.         -anchor center -expand 0 -fill x -ipadx 0 -ipady 0 \
  447.         -padx 0 -pady 0 -side top
  448.  
  449.     set prtcanvglob($this,postercb) 0
  450.     itk_component add postercb {
  451.         checkbutton $itk_component(posterframe).cb1 \
  452.             -relief flat -text {Posterize on} \
  453.             -variable [scope prtcanvglob($this,postercb)] \
  454.             -command [code $this refresh]
  455.     } {
  456.         keep -background -cursor
  457.     }
  458.     pack $itk_component(postercb) \
  459.         -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 \
  460.         -padx 0 -pady 0 -side left
  461.  
  462.     itk_component add hpcnt {
  463.         iwidgets::entryfield $itk_component(posterframe).e1 \
  464.             -validate integer -width 3 \
  465.             -command [code $this refresh]
  466.     } {
  467.         keep -cursor -background -textbackground
  468.     }
  469.     pack $itk_component(hpcnt) \
  470.         -anchor center -expand 0 -fill x -ipadx 0 -ipady 0 \
  471.         -padx 0 -pady 0 -side left
  472.  
  473.     itk_component add posterlbl1 {
  474.         label $itk_component(posterframe).l1 -text by
  475.     } {
  476.         keep -background -cursor
  477.     }
  478.     pack $itk_component(posterlbl1) \
  479.         -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 \
  480.         -padx 0 -pady 0 -side left
  481.  
  482.     itk_component add vpcnt {
  483.         iwidgets::entryfield $itk_component(posterframe).e2 \
  484.             -validate integer -width 3 \
  485.             -command [code $this refresh]
  486.     } {
  487.         keep -cursor -background -textbackground
  488.     }
  489.     pack $itk_component(vpcnt) \
  490.         -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 \
  491.         -padx 0 -pady 0 -side left
  492.  
  493.     itk_component add posterlbl2 {
  494.         label $itk_component(posterframe).l2 -text pages.
  495.     } {
  496.         keep -background -cursor
  497.     }
  498.     pack $itk_component(posterlbl2) \
  499.         -anchor center -expand 0 -fill none -ipadx 0 -ipady 0 \
  500.         -padx 0 -pady 0 -side left
  501.     
  502.     bind $itk_component(canvas) <Map> [code $this _mapEventHandler]
  503.     bind $itk_component(canvas) <Configure> [code $this refresh]
  504.     
  505.     set init_opts $args
  506.     
  507.     eval itk_initialize $args
  508. }
  509.  
  510. # ---------------------------------------------------------------
  511. # PUBLIC METHODS
  512. #----------------------------------------------------------------
  513.  
  514. #<
  515. # This is used to set the canvas that has to be printed.
  516. # A stamp-sized copy will automatically be drawn to show how the
  517. # output would look with the current settings.
  518. #
  519. # In:    canv - The canvas to be printed
  520. # Out:    canvas (attrib) - Holds the canvas to be printed
  521. #>    
  522. body iwidgets::Canvasprintbox::setcanvas {canv} {
  523.     set canvas $canv
  524.     if {$win != ""} {
  525.         _config_optimum
  526.         _update_canvas
  527.     }
  528. }
  529.  
  530. #<
  531. # Returns the value of the -printercmd or -filename option
  532. # depending on the current setting of -output.
  533. #
  534. # In:    itk_option (attrib)
  535. # Out:    The value of -printercmd or -filename
  536. #>
  537. body iwidgets::Canvasprintbox::getoutput {} {
  538.     case $itk_option(-output) in {
  539.         file {
  540.             return $itk_option(-filename)
  541.         }
  542.         printer {
  543.             return $itk_option(-printcmd)
  544.         }
  545.     }
  546. }
  547.  
  548. #<
  549. # Perfrom the actual printing of the canvas using the current settings of
  550. # all the attributes.
  551. #
  552. # In:    itk_option, rotate (attrib)
  553. # Out:    A boolean indicating wether printing was successful
  554. #>
  555. body iwidgets::Canvasprintbox::print {} {
  556.     global env
  557.  
  558.     if {$updating} {
  559.         set updating 0
  560.     }
  561.     
  562.     _update_prtfile
  563.     _update_attr
  564.  
  565.     if {$itk_option(-output) == "file"} {
  566.         set nm $itk_option(-filename)
  567.         if {[string range $nm 0 1] == "~/"} {
  568.             set nm [file join $env(HOME) [string range $nm 2 end]]
  569.         }
  570.     } else {
  571.         if {$tcl_platform(platform) == "macintosh"} {
  572.             error "can't print to LPR on a Mac.\nTry printing to a file, and passing that to LaserWriter 8"
  573.         }
  574.         set nm "/tmp/xge[winfo id $canvas]"
  575.     }
  576.  
  577.     if {$itk_option(-posterize)} {
  578.         set vpc $itk_option(-vpagecnt)
  579.         set hpc $itk_option(-hpagecnt)
  580.     } else {
  581.         set vpc 1
  582.         set hpc 1
  583.     }
  584.  
  585.     set pr [_calc_print_region]
  586.     set x1 [lindex $pr 0]
  587.     set y1 [lindex $pr 1]
  588.     set x2 [lindex $pr 2]
  589.     set y2 [lindex $pr 3]
  590.     set cx [expr int(($x2 + $x1) / 2)]
  591.     set cy [expr int(($y2 + $y1) / 2)]
  592.     if {!$itk_option(-stretch)} {
  593.         set ps [_calc_poster_size]
  594.         set pshw [expr int([lindex $ps 0] / 2)]
  595.         set pshh [expr int([lindex $ps 1] / 2)]
  596.         set x [expr $cx - $pshw]
  597.         set y [expr $cy - $pshh]
  598.         set w [ezPaperInfo $itk_option(-pagesize) pwidth $itk_option(-orient) $win]
  599.         set h [ezPaperInfo $itk_option(-pagesize) pheight $itk_option(-orient) $win]
  600.     } else {
  601.         set x $x1
  602.         set y $y1
  603.         set w [expr ($x2 - $x1) / $hpc]
  604.         set h [expr ($y2 - $y1) / $vpc]
  605.     }
  606.  
  607.     set i 0
  608.     set px $x
  609.     while {$i < $hpc} {
  610.         set j 0
  611.         set py $y
  612.         while {$j < $vpc} {
  613.             if {$hpc > 1 || $vpc > 1} {
  614.                 set nm2 "$nm$i.$j"
  615.             } else {
  616.                 set nm2 $nm
  617.             }
  618.             if {$itk_option(-stretch)} {
  619.                 $canvas postscript \
  620.                   -file $nm2 \
  621.                   -rotate $rotate \
  622.                   -x $px -y $py \
  623.                   -width $w \
  624.                   -height $h \
  625.                   -pagex [ezPaperInfo $itk_option(-pagesize) centerx] \
  626.                   -pagey [ezPaperInfo $itk_option(-pagesize) centery] \
  627.                   -pagewidth [ezPaperInfo $itk_option(-pagesize) pwidth $itk_option(-orient)] \
  628.                   -pageheight [ezPaperInfo $itk_option(-pagesize) pheight $itk_option(-orient)]
  629.             } else {
  630.                 $canvas postscript \
  631.                   -file $nm2 \
  632.                   -rotate $rotate \
  633.                   -x $px -y $py \
  634.                   -width $w \
  635.                   -height $h \
  636.                   -pagex [ezPaperInfo $itk_option(-pagesize) centerx] \
  637.                   -pagey [ezPaperInfo $itk_option(-pagesize) centery]
  638.             }
  639.  
  640.             if {$itk_option(-output) != "file"} {
  641.                 set cmd "cat $nm2 | $itk_option(-printcmd)"
  642.                 if {[catch {eval "exec $cmd"}]} {
  643.                     return 0
  644.                 }
  645.                 catch {exec rm $nm2}
  646.             }
  647.  
  648.             set py [expr $py + $h]
  649.             incr j
  650.         }
  651.         set px [expr $px + $w]
  652.         incr i
  653.     }
  654.  
  655.     return 1
  656. }
  657.  
  658. #<
  659. # Retrieves the current value for all edit fields and updates
  660. # the stamp accordingly. Is useful for Apply-buttons.
  661. #>
  662. body iwidgets::Canvasprintbox::refresh {} {
  663.     _update_attr
  664.     _update_canvas
  665. }
  666.  
  667. #<
  668. # Stops the drawing of the "stamp". I'm currently unable to detect
  669. # when a Canvasprintbox gets withdrawn. It's therefore advised
  670. # that you perform a stop before you do something like that.
  671. #>
  672. body iwidgets::Canvasprintbox::stop {} {
  673.     if {$updating} {
  674.         set updating 0
  675.     }
  676. }
  677.  
  678. # ---------------------------------------------------------------
  679. # PROTECTED METHODS
  680. #----------------------------------------------------------------
  681.  
  682. #
  683. # Calculate the total size the output would be with the current
  684. # settings for "pagesize" and "posterize" (and "hpagecnt" and
  685. # "vpagecnt"). This size will be the size of the printable area,
  686. # some space has been substracted to take into account that a
  687. # page should have borders because most printers can't print on
  688. # the very edge of the paper.
  689. #
  690. # In:    posterize, hpagecnt, vpagecnt, pagesize, orient (attrib)
  691. # Out:    A list of two numbers indicating the width and the height
  692. #    of the total paper area which will be used for printing
  693. #    in pixels.
  694. #
  695. body iwidgets::Canvasprintbox::_calc_poster_size {} {
  696.     if {$itk_option(-posterize)} {
  697.         set vpc $itk_option(-vpagecnt)
  698.         set hpc $itk_option(-hpagecnt)
  699.     } else {
  700.         set vpc 1
  701.         set hpc 1
  702.     }
  703.  
  704.     set tpw [expr [ezPaperInfo $itk_option(-pagesize) pwidth $itk_option(-orient) $win] * $hpc]
  705.     set tph [expr [ezPaperInfo $itk_option(-pagesize) pheight $itk_option(-orient) $win] * $vpc]
  706.  
  707.     return "$tpw $tph"
  708. }
  709.  
  710. #
  711. # Calculate the scaling factor that would be needed to fit the
  712. # whole "source" into the "stamp". This takes into account the
  713. # total amount of "paper" that would be needed to print the
  714. # contents of the "source".
  715. #
  716. # In:    -
  717. # Out:    A float specifying the scaling factor
  718. #
  719. body iwidgets::Canvasprintbox::_calc_stamp_scale {} {
  720.     set width [winfo width $canvw]
  721.     set height [winfo height $canvw]
  722.     set ps [_calc_poster_size]
  723.     set xsf [expr $width / [lindex $ps 0]]
  724.     set ysf [expr $height / [lindex $ps 1]]
  725.     if {$xsf < $ysf} {
  726.         set sf $xsf
  727.     } else {
  728.         set sf $ysf
  729.     }
  730.  
  731.     return $sf
  732. }
  733.  
  734. #
  735. # Determine which area of the "source" canvas will be printed.
  736. # If "printregion" was set by the "user" this will be used and
  737. # converted to pixel-coordinates. If the user didn't set it
  738. # the bounding box that contains all canvas-items will be used
  739. # instead.
  740. #
  741. # In:    printregion, canvas (attrib)
  742. # Out:    Four floats specifying the region to be printed in
  743. #    pixel-coordinates (topleft & bottomright).
  744. #
  745. body iwidgets::Canvasprintbox::_calc_print_region {} {
  746.     if {$itk_option(-printregion) != ""} {
  747.         set printreg $itk_option(-printregion)
  748.     } else {
  749.         set printreg [$canvas bbox all]
  750.     }
  751.  
  752.     if {$printreg != ""} {
  753.         set prx1 [winfo fpixels $canvas [lindex $printreg 0]]
  754.         set pry1 [winfo fpixels $canvas [lindex $printreg 1]]
  755.         set prx2 [winfo fpixels $canvas [lindex $printreg 2]]
  756.         set pry2 [winfo fpixels $canvas [lindex $printreg 3]]
  757.  
  758.         set res "$prx1 $pry1 $prx2 $pry2"
  759.     } else {
  760.         set res "0 0 0 0"
  761.     }
  762.     
  763.     return $res
  764. }
  765.  
  766. #
  767. # Calculate the scaling factor needed if the output was
  768. # to be stretched to fit exactly on the page (or pages).
  769. # If stretching is turned off this will always return 1.0.
  770. #
  771. # In:    stretch (attrib)
  772. # Out:    A float specifying the scaling factor.
  773. #
  774. body iwidgets::Canvasprintbox::_calc_print_scale {} {
  775.     if {$itk_option(-stretch)} {
  776.         set pr [_calc_print_region]
  777.         set prw [expr [lindex $pr 2] - [lindex $pr 0]]
  778.         set prh [expr [lindex $pr 3] - [lindex $pr 1]]
  779.         set ps [_calc_poster_size]
  780.         set psw [lindex $ps 0]
  781.         set psh [lindex $ps 1]
  782.         set sfx [expr $psw / $prw]
  783.         set sfy [expr $psh / $prh]
  784.         if {$sfx < $sfy} {
  785.             set sf $sfx
  786.         } else {
  787.             set sf $sfy
  788.         }
  789.         return $sf
  790.     } else {
  791.         return 1.0
  792.     }
  793. }
  794.  
  795. #
  796. # Change the configuration options in such a way that the
  797. # "source" canvas will fit the page in the best possible
  798. # way. This might mean changing the orientation of the
  799. # output and/or stretching the output to fit the page.
  800. # If either of these options was set by the "user" the
  801. # option won't be changed, this might result on a less than
  802. # perfect fit.
  803. #
  804. # In:    canvas, orientset, orient, stretchset, stretch (attrib)
  805. # Out:    -
  806. #
  807. body iwidgets::Canvasprintbox::_config_optimum {} {
  808.     if {$canvas != ""} {
  809.         set pr [_calc_print_region]
  810.         set w [expr [lindex $pr 2] - [lindex $pr 0]]
  811.         set h [expr [lindex $pr 3] - [lindex $pr 1]]
  812.  
  813.         if {[lsearch $init_opts -orient] == -1} {
  814.             if {$w > $h} {
  815.                 set itk_option(-orient) "landscape"
  816.             } else {
  817.                 set itk_option(-orient) "portrait"
  818.             }
  819.         }
  820.  
  821.         if {[lsearch $init_opts -stretch] == -1} {
  822.             set ps [_calc_poster_size]
  823.             if {[lindex $ps 0] < $w || [lindex $ps 1] < $h} {
  824.                 set itk_option(-stretch) 1
  825.             }
  826.         }
  827.     }
  828. }
  829.  
  830. #
  831. # Schedule the thread that makes a copy of the "source"
  832. # canvas to the "stamp".
  833. #
  834. # In:    win, canvas (attrib)
  835. # Out:    -
  836. #
  837. body iwidgets::Canvasprintbox::_update_canvas {} {
  838.     if {$win == "" || $canvas == "" || [$canvas find all] == ""} {
  839.         return
  840.     }
  841.     
  842.     if {$updating} {
  843.         set restart_update 1
  844.     } else {
  845.         set restart_update 0
  846.         set updating 1
  847.         after idle [code $this _update_canvas_thread]
  848.     }
  849. }
  850.  
  851. #
  852. # Make a copy of the "source" canvas to the "stamp".
  853. #
  854. # In:    win, canvas, posterize, hpagecnt, vpagecnt,
  855. #    vlines, hlines (attrib)
  856. # Out:    -
  857. #
  858. body iwidgets::Canvasprintbox::_update_canvas_thread {} {
  859.     if {$itk_option(-posterize)} {
  860.         set vpc $itk_option(-vpagecnt)
  861.         set hpc $itk_option(-hpagecnt)
  862.     } else {
  863.         set vpc 1
  864.         set hpc 1
  865.     }
  866.  
  867.     if {$hpc == [llength $vlines] && $vpc == [llength $hlines]} {
  868.         set updating 0
  869.         return
  870.     }    
  871.  
  872.     $canvw delete all
  873.     set ps [_calc_poster_size]
  874.     set sf [_calc_stamp_scale]
  875.     set w [expr [lindex $ps 0] * $sf]
  876.     set h [expr [lindex $ps 1] * $sf]
  877.     set width [winfo width $canvw]
  878.     set height [winfo height $canvw]
  879.     set x1 [expr ($width - $w) / 2]
  880.     set y1 [expr ($height - $h) / 2]
  881.     set x2 [expr $x1 + $w]
  882.     set y2 [expr $y1 + $h]
  883.     set cx [expr ($x2 + $x1) / 2]
  884.     set cy [expr ($y2 + $y1) / 2]
  885.  
  886.     set printreg [_calc_print_region]
  887.     set prx1 [lindex $printreg 0]
  888.     set pry1 [lindex $printreg 1]
  889.     set prx2 [lindex $printreg 2]
  890.     set pry2 [lindex $printreg 3]
  891.     set prcx [expr ($prx2 + $prx1) / 2]
  892.     set prcy [expr ($pry2 + $pry1) / 2]
  893.  
  894.     set psf [_calc_print_scale]
  895.  
  896.     #
  897.     # Copy all items from the "real" canvas to the canvas
  898.     # showing what we'll send to the printer. Bitmaps and
  899.     # texts are not copied because they can't be scaled,
  900.     # a rectangle will be created instead.
  901.     #
  902.     update
  903.     set cnt 0
  904.     set tsf [expr $sf * $psf]
  905.     set dx [expr $cx - ($prcx * $tsf)]
  906.     set dy [expr $cy - ($prcy * $tsf)]
  907.     $canvw create rectangle $x1 $y1 $x2 $y2 -fill white
  908.     set items [eval "$canvas find overlapping $printreg"]
  909.     foreach i $items {
  910.         #
  911.         # Determine the item's type and coordinates
  912.         #
  913.         set t [$canvas type $i]
  914.         set crds [$canvas coords $i]
  915.  
  916.         #
  917.         # Ask for the item's configuration settings and strip
  918.         # it to leave only a list of option names and values.
  919.         #
  920.         set cfg [$canvas itemconfigure $i]
  921.         set cfg2 ""
  922.         foreach c $cfg {
  923.             if {[llength $c] == 5} {
  924.                 lappend cfg2 [lindex $c 0] [lindex $c 4]
  925.             }
  926.         }
  927.  
  928.         #
  929.         # Handle texts and bitmaps differently: they will
  930.         # be represented as rectangles.
  931.         #
  932.         if {$t == "text" || $t == "bitmap" || $t == "window"} {
  933.             set t "rectangle"
  934.             set crds [$canvas bbox $i]
  935.             set cfg2 "-outline {} -fill gray"
  936.         }
  937.  
  938.         #
  939.         # Remove the arrows from a line item when the scale
  940.         # factor drops below 1/3rd of the original size.
  941.         # This to prevent the arrowheads from dominating the
  942.         # display.
  943.         #
  944.         if {$t == "line" && $tsf < 0.33} {
  945.             lappend cfg2 -arrow none
  946.         }
  947.         
  948.         #
  949.         # Create a copy of the item on the "printing" canvas.
  950.         #
  951.         set i2 [eval "$canvw create $t $crds $cfg2"]
  952.         $canvw scale $i2 0 0 $tsf $tsf
  953.         $canvw move $i2 $dx $dy
  954.  
  955.         incr cnt
  956.         if {[expr $cnt % 25] == 0} {
  957.             update
  958.             if {!$updating} {
  959.                 return
  960.             }
  961.             if {$restart_update} {
  962.                 set updating 0
  963.                 after idle [code $this _update_canvas]
  964.             }
  965.         }
  966.     }
  967.  
  968.     set p $x1
  969.     set i 1
  970.     set vlines ""
  971.     while {$i < $hpc} {
  972.         set p [expr $p + ($w / $hpc)]
  973.         set l [$canvw create line $p $y1 $p $y2]
  974.         lappend vlines $l
  975.         incr i
  976.     }
  977.     set p $y1
  978.     set i 1
  979.     set vlines ""
  980.     while {$i < $vpc} {
  981.         set p [expr $p + ($h / $vpc)]
  982.         set l [$canvw create line $x1 $p $x2 $p]
  983.         lappend vlines $l
  984.         incr i
  985.     }
  986.     
  987.     set updating 0
  988. }
  989.  
  990. #
  991. # Update dependencies among widgets. (For example: disabling
  992. # an entry-widget when its associated checkbox-button is used
  993. # to turn of the option (the entry's value is not needed
  994. # anymore and this should be reflected in the fact that it
  995. # isn't possible to change it anymore).
  996. #
  997. # In:    itk_option, rotate (attrib) - the widget settings
  998. #    itk_component (attrib) - the widgets
  999. # Out:    -
  1000. #
  1001. body iwidgets::Canvasprintbox::_update_widgets {} {
  1002.     if {$itk_option(-posterize)} {
  1003.         $itk_component(vpcnt) configure -state normal
  1004.         $itk_component(hpcnt) configure -state normal
  1005.     } else {
  1006.         $itk_component(vpcnt) configure -state disabled
  1007.         $itk_component(hpcnt) configure -state disabled
  1008.     }
  1009.  
  1010.     case $itk_option(-output) in {
  1011.         printer {
  1012.             $itk_component(prtflentry) configure -labeltext "Printer command :"
  1013.             $itk_component(prtflentry) clear
  1014.             $itk_component(prtflentry) insert 0 $itk_option(-printcmd)
  1015.         }
  1016.         file {
  1017.             $itk_component(prtflentry) configure -labeltext "Filename :"
  1018.             $itk_component(prtflentry) clear
  1019.             $itk_component(prtflentry) insert 0 $itk_option(-filename)
  1020.         }
  1021.     }
  1022.  
  1023.     case $itk_option(-orient) in {
  1024.         landscape {
  1025.             set rotate 1
  1026.         }
  1027.         portrait {
  1028.             set rotate 0
  1029.         }
  1030.     }
  1031. }
  1032.  
  1033. #
  1034. # Updates the user-interface whenever one of the attributes
  1035. # is changes by the "user".
  1036. #
  1037. # In:    itk_component (attrib) - the widgets to update
  1038. #    prtcanvglob (common) - global variables for the radio-
  1039. #        buttons and checkboxes.
  1040. # Out:    -
  1041. #
  1042. body iwidgets::Canvasprintbox::_update_UI {} {
  1043.     if {$win != ""} {
  1044.         $itk_component(outputom) select \
  1045.             "*[string range $itk_option(-output) 1 end]"
  1046.  
  1047.         $itk_component(paperom) select \
  1048.             "*[string range $itk_option(-pagesize) 1 end]"
  1049.  
  1050.         $itk_component(orientom) select \
  1051.             "*[string range $itk_option(-orient) 1 end]"
  1052.         
  1053.         set prtcanvglob($this,stretchcb) $itk_option(-stretch)
  1054.         set prtcanvglob($this,postercb) $itk_option(-posterize)
  1055.         $itk_component(vpcnt) delete 0 end
  1056.         $itk_component(vpcnt) insert 0 $itk_option(-vpagecnt)
  1057.         $itk_component(hpcnt) delete 0 end
  1058.         $itk_component(hpcnt) insert 0 $itk_option(-hpagecnt)
  1059.         _update_widgets
  1060.     }
  1061. }
  1062.  
  1063. #
  1064. # Update the attributes to reflect changes made in the user-
  1065. # interface.
  1066. #
  1067. # In:    itk_option (attrib) - the attributes to update
  1068. #    itk_component (attrib) - the widgets
  1069. #    prtcanvglob (common) - the global var holding the state
  1070. #        of all radiobuttons and checkboxes.
  1071. # Out:    -
  1072. #
  1073. body iwidgets::Canvasprintbox::_update_attr {} {
  1074.     if {$win != ""} {
  1075.                 set outp [$itk_component(outputom) get]
  1076.                 if {$outp != $itk_option(-output)} {
  1077.                         case $itk_option(-output) in {
  1078.                                 printer {
  1079.                                         set itk_option(-printcmd) [$itk_component(prtflentry) get]
  1080.                                 }
  1081.                                 file {
  1082.                                         set itk_option(-filename) [$itk_component(prtflentry) get]
  1083.                                 }
  1084.                         }
  1085.                 }
  1086.                 set itk_option(-output) [string tolower $outp]
  1087.  
  1088.  
  1089.         set itk_option(-pagesize) \
  1090.             [string tolower [$itk_component(paperom) get]]
  1091.         set itk_option(-orient) \
  1092.             [string tolower [$itk_component(orientom) get]]
  1093.         set itk_option(-stretch) $prtcanvglob($this,stretchcb)
  1094.         set itk_option(-posterize) $prtcanvglob($this,postercb)
  1095.         set vpc [$itk_component(vpcnt) get]
  1096.         if {$vpc >= 1} {
  1097.             set itk_option(-vpagecnt) $vpc
  1098.         } else {
  1099.             $itk_component(vpcnt) delete 0 end
  1100.             $itk_component(vpcnt) insert 0 $itk_option(-vpagecnt)
  1101.         }
  1102.         set hpc [$itk_component(hpcnt) get]
  1103.         if {$hpc >= 1} {
  1104.             set itk_option(-hpagecnt) [$itk_component(hpcnt) get]
  1105.         } else {
  1106.             $itk_component(hpcnt) delete 0 end
  1107.             $itk_component(hpcnt) insert 0 $itk_option(-hpagecnt)
  1108.         }
  1109.         _update_widgets
  1110.     }
  1111. }
  1112.  
  1113.  
  1114. #
  1115. # Updates the values for the attributes "printcmd" and "filename"
  1116. # every time the corresponding setting of the "To printer" and
  1117. # "To file" radiobuttons is changed.
  1118. #
  1119. # In:    itk_option, itk_component (atrib)
  1120. # Out:
  1121. #
  1122. body iwidgets::Canvasprintbox::_update_prtfile {} {
  1123.     case $itk_option(-output) in {
  1124.         printer {
  1125.             set itk_option(-printcmd) [$itk_component(prtflentry) get]
  1126.         }
  1127.         file {
  1128.             set itk_option(-filename) [$itk_component(prtflentry) get]
  1129.         }
  1130.     }
  1131. }
  1132.  
  1133. #
  1134. # Gets called when the CanvasPrintBox-widget gets mapped.
  1135. #
  1136. body iwidgets::Canvasprintbox::_mapEventHandler {} {
  1137.     set win $itk_interior
  1138.     set canvw $itk_component(canvas)
  1139.     if {$canvas != ""} {
  1140.         setcanvas $canvas
  1141.     }
  1142.     _update_UI
  1143. }
  1144.  
  1145. #
  1146. # Destroy this object and its associated widgets.
  1147. #
  1148. body iwidgets::Canvasprintbox::destructor {} {
  1149.     if {$updating} {
  1150.         set updating 0
  1151.     }
  1152. }
  1153.  
  1154. #
  1155. # Hold the information about common paper sizes. A bit of a hack, but it
  1156. # should be possible to add your own if you take a look at it.
  1157. #
  1158. body iwidgets::Canvasprintbox::ezPaperInfo {size {attr ""} \
  1159.     {orient "portrait"} {window ""}} {
  1160.     
  1161.     set size [string tolower $size]
  1162.     set attr [string tolower $attr]
  1163.     set orient [string tolower $orient]
  1164.     
  1165.     case $size in {
  1166.         types {
  1167.             return "A5 A4 A3 A2 A1 Legal Letter"
  1168.         }
  1169.         a5 {
  1170.             set paper(x1) "1.0c"
  1171.             set paper(y1) "1.0c"
  1172.             set paper(x2) "13.85c"
  1173.             set paper(y2) "20.0c"
  1174.             set paper(pheight) "19.0c"
  1175.             set paper(pwidth) "12.85c"
  1176.             set paper(height) "21.0c"
  1177.             set paper(width) "14.85c"
  1178.             set paper(centerx) "7.425c"
  1179.             set paper(centery) "10.5c"
  1180.         }
  1181.         a4 {
  1182.             set paper(x1) "1.0c"
  1183.             set paper(y1) "1.0c"
  1184.             set paper(x2) "20.0c"
  1185.             set paper(y2) "28.7c"
  1186.             set paper(pheight) "27.7c"
  1187.             set paper(pwidth) "19.0c"
  1188.             set paper(height) "29.7c"
  1189.             set paper(width) "21.0c"
  1190.             set paper(centerx) "10.5c"
  1191.             set paper(centery) "14.85c"
  1192.         }
  1193.         a3 {
  1194.             set paper(x1) "1.0c"
  1195.             set paper(y1) "1.0c"
  1196.             set paper(x2) "28.7c"
  1197.             set paper(y2) "41.0c"
  1198.             set paper(pheight) "40.0c"
  1199.             set paper(pwidth) "27.7c"
  1200.             set paper(height) "42.0c"
  1201.             set paper(width) "29.7c"
  1202.             set paper(centerx) "14.85c"
  1203.             set paper(centery)  "21.0c"
  1204.         }
  1205.         a2 {
  1206.             set paper(x1) "1.0c"
  1207.             set paper(y1) "1.0c"
  1208.             set paper(x2) "41.0c"
  1209.             set paper(y2) "58.4c"
  1210.             set paper(pheight) "57.4c"
  1211.             set paper(pwidth) "40.0c"
  1212.             set paper(height) "59.4c"
  1213.             set paper(width) "42.0c"
  1214.             set paper(centerx) "21.0c"
  1215.             set paper(centery)  "29.7c"
  1216.         }
  1217.         a1 {
  1218.             set paper(x1) "1.0c"
  1219.             set paper(y1) "1.0c"
  1220.             set paper(x2) "58.4c"
  1221.             set paper(y2) "83.0c"
  1222.             set paper(pheight) "82.0c"
  1223.             set paper(pwidth) "57.4c"
  1224.             set paper(height) "84.0c"
  1225.             set paper(width) "59.4c"
  1226.             set paper(centerx) "29.7c"
  1227.             set paper(centery)  "42.0c"
  1228.         }
  1229.         legal {
  1230.             set paper(x1) "0.2i"
  1231.             set paper(y1) "0.2i"
  1232.             set paper(x2) "8.3i"
  1233.             set paper(y2) "13.8i"
  1234.             set paper(pheight) "13.6i"
  1235.             set paper(pwidth) "8.1i"
  1236.             set paper(height) "14.0i"
  1237.             set paper(width) "8.5i"
  1238.             set paper(centerx) "4.25i"
  1239.             set paper(centery) "7.0i"
  1240.         }
  1241.         letter {
  1242.             set paper(x1) "0.2i"
  1243.             set paper(y1) "0.2i"
  1244.             set paper(x2) "8.3i"
  1245.             set paper(y2) "10.8i"
  1246.             set paper(pheight) "10.6i"
  1247.             set paper(pwidth) "8.1i"
  1248.             set paper(height) "11.0i"
  1249.             set paper(width) "8.5i"
  1250.             set paper(centerx) "4.25i"
  1251.             set paper(centery) "5.5i"
  1252.         }
  1253.         default {
  1254.             error "ezPaperInfo: Unknown paper type ($type)"
  1255.         }
  1256.     }
  1257.     
  1258.     set inv(x1) "y1"
  1259.     set inv(x2) "y2"
  1260.     set inv(y1) "x1"
  1261.     set inv(y2) "x2"
  1262.     set inv(pwidth) "pheight"
  1263.     set inv(pheight) "pwidth"
  1264.     set inv(width) "height"
  1265.     set inv(height) "width"
  1266.     set inv(centerx) "centery"
  1267.     set inv(centery) "centerx"
  1268.     
  1269.     case $orient in {
  1270.         landscape {
  1271.             set res $paper($inv($attr))
  1272.         }
  1273.         portrait {
  1274.             set res $paper($attr)
  1275.         }
  1276.         default {
  1277.             error "ezPaperInfo: orientation should be\
  1278.                 portrait or landscape (not $orient)"
  1279.         }
  1280.     }
  1281.     
  1282.     if {$window != ""} {
  1283.         set res [winfo fpixels $window $res]
  1284.     }
  1285.     
  1286.     return $res
  1287.