OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [tags/] [start/] [insight/] [itcl/] [iwidgets3.0.0/] [generic/] [canvasprintbox.itk] - Blame information for rev 1782

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.