/
tkscan
2229 lines (2004 loc) · 77.8 KB
/
tkscan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" "$@"
# TkScan Version and Date
set c(version) "0.8"
set c(date) "May 1997"
#----------------------------------------------------------------
# About TkScan
#----------------------------------------------------------------
set about_tkscan "
TkScan
Version $c(version), $c(date)\n
A tcl/tk GUI for command-line scanner driver
Written by Hang-Bae Kim (hbkim@delta.ft.uam.es)
Copying policy : GNU Public License
"
#----------------------------------------------------------------
# README
#----------------------------------------------------------------
set readme_tkscan "
TkScan version $c(version)
A tcl/tk GUI for command-line scanner driver
Copyright (C) 1997 Hang Bae Kim (hbkim@delta.ft.uam.es)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
TkScan is a tcl/tk GUI for command-line scanner driver.
I have written it for my own use with my Mustek 800IISP scanner.
But I put it in the public with the hope that it may be helpful to someone.
Remember that scanning itself is done by the scanner driver not by this
GUI. Therefore you NEED the appropriate command-line scanner driver for
your scanner. TkScan just does the scanning area selection on a previewed
image, the choice of options, e.g. scanning mode, resolution and some
enhancements like gamma correction, running scanner driver and sending the
output where you want. You can fit it to your scanner and driver without
much difficulty, by modifying `scanner_driver'.tcl referring your driver
manual.
Currently it supports
* Epson SCSI scanner via `ep_scan'
* HP SCSI scanner via `hpscanpbm'
* Microtek SCSI scanner via `mtekscan'
* Mustek Flatbed scanner via `scanimage'(SANE) or `mscan'
- I wrote `epson-ep_scan.tcl' `hp-hpscanpbm.tcl' `microtek-mtekscan.tcl'
just referring manuals, without testing. They can be considered as
scratch. So they may not work, or even may include simple typos.
I hope you can cope with this situation. If you write a correctly
working script, please send a copy to me.
- I give thanks to Boris Tobotras(tobotras@jet.msk.su) for sending
the patch for hpscanpbm.
With TkScan you can
* preview an image to be scanned on a small canvas whose size and
mode you can select
* adjust scanning mode and resolutions and other options
supported by the scanner and driver with mouse clicks
* select the one or more scanning areas on a previewed image canvas
If you select several scanning areas, TkScan will scan them successively.
TkScan shows the expected screen pixel sizes and raw data sizes of the
images as well as its real size in several length units (mm,cm,pt,inch).
* make the output raw data directly go where you want:
- to image editor (XV, ImageMagic or GIMP),
- to file in the format you want,
- to printer or to ghostscript(ghostview or gv) in postscript format
with the size and position adjustment,
- to fax modem to be directly sent as a fax,
- to the ocr software to be processed by ocr
(_not_ implemented yet in this version).
* see the progress of scanning both in graphic and numeric percentage
and file size fraction.
* interrupt scanning with the Stop button.
* configure TkScan to fit it to your tastes.
TkScan requires
* Scanner and command-line driver listed above, or you can add your own.
* Tcl/Tk, probably most versions will work.
* ImageMagic, to convert the scanned image to various formats
* XV, ImageMagic, or GIMP or all of them, for ImageEditor
* Ghostscript and ghostview(or gv), to view the postscript output
* Efax, to send the scanned image to a fax modem
- I left the output to OCR blank, Because I could not find a good
OCR software for Linux. Does anyone know about it?
- All the above binaries should lie in your PATH.
How to use
See Guide in the Help menu.
Bug or Comment to
Hang-Bae Kim, hbkim@delta.ft.uam.es
"
#----------------------------------------------------------------
# Usage of TkScan
#----------------------------------------------------------------
set usage_tkscan "
How to use TkScan version $c(version)
Contents
0. Command line option
1. Previewing
2. Selection of regions to be scanned
3. Selection of mode and resolution
4. Selection of output destination
5. Scanning
6. Configuration
Section 0. Command line option
tkscan \[-geometry +x+y\] \[ImageEditor|File|Printer|Fax|OCR\]
Section 1. Preview
* Click \[Preview\] button to initiate preview scanning.
* Preview scanning can be interrupted by clicking \[Stop\] button.
* The preview mode and resolution can be chosen in Preference of File menu.
Section 2. Selection of regions to be scanned
* The selection of scanning regions on the preview image is done with
left mouse button. Press left button at one corner of the rectangle you
want to scan, move mouse while pressing it and release at the other corner.
* You can finetune the region using finetuning buttons around blue rectangle.
* The blue rectagle continuously shows a region to be scanned, while the
scanning region window diplays coordinates of upper-left and lower-right
coners, the width times height in the length unit chosen (Real Size) and
in screen pixel (Screen Size), and the file size of the image in raw
format (Data Size). Screen Size and Data Size also vary as you change
scanning mode and resolution.
* The size of A4, Letter paper or others are preset in \[preset\] button. You
can add your own regions in configuration file (See Configuration section).
* You can select several regions on the preview image canvas.
Set one blue rectangle and click the middle mouse button inside it (or
\[Regist\] button). Blue rectangle becomes red and the number 1 appears
at the center. Then make another blue rectangle and press the middle
button inside it. Now the second red rectangle is registered. Repeat
this as many times as you want. Click of the right mouse button inside
the red rectangle will remove it. Double click of the right button (or
click of the \[Clear\] button) deletes all rectangles. TkScan will scan
red rectangles successively in order of their registration numbers.
Section 3. Selection of mode, resolution and options
This is transparent: Use mode \[Mode\] menubutton and \[Resolution\] scale.
Screen Size and Data Size change accordingly as mode and resolution change.
* If you want to adjust other options, press \[Open Manager\] button. Then
Option manager window appears and you can do it there. Available options
depend on the scanning mode.
* Several frequently used mode are preset in Mode munu. You can define your
own quick_mode in configuration file (See Configuration section.)
Section 4. Selection of output desination
This is done by \[Output to\] menubutton.
* Image Editor
- You can select image editor among XV, ImageMagic and GIMP in Preference.
- There is also \[SW\] checkbutton, which select that each scanned image
appears in separate image editor or all images in one image editor
when several red rectangles are scanned successively.
* File
If you select this, File Manager Window appears.
- Select the output file format.
- You can specify a filename for scanned image in \[Filename\] entry.
If you use # in the filename, the last # is replaced with the retangle
number(0 for blue rectangle, the number at the center for red rectangles).
The default filename is scanout-#.surfix where appropriate surfix is
attached for the file format. You can change it in the configuration file.
* Printer
If you select this, Print Manager Window appears.
- Select a printer. `gv' is for sending output to ghostview(or gv).
- Use \[Zoom\] scale and \[Position\] menubutton to select the size and
position of printed image. Zoom scale is percentage of Real Size.
- \[Reprint\] button is for printing again the scanned image with changed
zoom and position.
* Fax
If you select this, Fax Manager Window appears.
- With this, each scanned page is converted tiffg3 format using efix and
listed in Page List Box.
- In Page List Box, you can
+ view each page converted to tiffg3 format by double click of
left mouse button,
+ view whole pages by pressing \[View\] button,
+ rearrange the order of pages using \[Up\] and \[Down\] button,
+ remove a page from the list using \[Remove\] button,
+ \[Attach\] button does not work yet.
- You should specify the fax number. \[List\] calls Fax Number List Window,
in which you can maintain frequently used fax numbers.
* OCR
- This is not implemented yet. I could not find a good OCR software running
under Linux. Please let me know if anyone knows or heard of it.
Section 5. Scanning
This is done by pressing \[SCAN\] button. TkScan will scan the blue rectangle
region. If you registered red rectangles, then red rectangle regions are
scanned successively and the blue rectangle is ignored even when it exists.
As scanning is in progress, the progress report appears in the status bar.
If you want to interrupt in the middle of scanning, press \[Stop\] button.
It kill driver command and recover the state before scanning.
If it does not work for some reason, double click \[Stop\] button. This
surely stops scanning and recover TkScan for another scanning.
Note that while \[Stop\] button kills scanning command immediately,
it takes some time for scanner to respond. Scanner is a slowly responding
peripharal. I do not recommend frequent use of \[Stop\] button.
Section 6. Configuration
If you select Preference in File menu, Preference Window appears.
* Specify your scanner device if your scanner driver does not find the
scanner device correctly without device option. Otherwise, to leave it
blank is OK.
* You can change the preview image mode and resolution to those you prefer.
Press \[Apply\] button after selection.
* Gamma correction can be done either by the driver itself or by the
external programs like xv or ImageMagic's display or convert if it is
not available in the driver. Choose what you prefer.
* TkScan makes ~/.tkscan directory to keep its configuration files and
scanned image files temporarily. You can delete those temporary files in
this directory when exit or right now to free your hard disk.
* If you select Save current config in File menu, the various configuration
settings are stored in the ~/.tkscan/init file. You can modify this file
to fit your taste. If you feel like doing more changes, observe the
`tkscan' script and copy necessary parts to ~/.tkscan/init file,
then modify them.
"
#------------------------------------------------------------------------
# MicroTek SCSI scanner -- mtekscan
#------------------------------------------------------------------------
# Full scanning size. This should be in inches.
set s(scanwidth) 8.5
set s(scanheight) 11.6
# Minimum, maximum and step of scanning resolution in dpi
set s(resolutionRange) {1 600 1}
# Time(in miliseconds) for coming back from the opposite end
# after finishing full height scanning
set s(scantime) 20000
# Command-line driver
set s(command) "mtekscan"
# Scanner device (leave empty for autodetection)
set s(device) ""
# Options other than for mode and resolution
# Label Type Variable Values or Range Default value
set s(optionList) {
{ {Backtrack} m backtrack {yes no} yes }
{ {Speed} r speed {1 7 1} 1 }
{ {Brightness} r brightness {-100 100 1} 0 }
{ {Exposure Time} r exposuretime {-18 21 3} 0 }
{ {Contrast} r contrast {-42 49 1} 0 }
{ {Halftoning} r halftoning {0 11 1} 0 }
{ {Shadow} r shadow {0 255 1} 0 }
{ {Midtone} r midtone {0 255 1} 128 }
{ {Highlight} r highlight {0 255 1} 255 }
{ {Gamma} r gamma {0.2 5.0 0.1} 1.0 }
}
set s(modedepoptionList) { shadow midtone highlight halftoning gamma }
# Supported scanning modes
# Mode Format bpp Mode-dependent options
set s(modeList) {
{ Lineart pbm 1 {} }
{ Halftone pbm 1 {halftoning} }
{ Gray pgm 8 {shadow midtone highlight gamma} }
{ Color ppm 24 {shadow midtone highlight gamma} }
}
# Gamma correction support
# 0 : support by scanner driver
# 1 : support by external (image editor, image converter) commands
set s(gamma_support) 0
#------------------------------------------------------------------------
# Procedure launching scanner driver
#------------------------------------------------------------------------
proc run_scanner_driver { i file } { global s c
set command $s(command)
set file "-o $c(tkscandir)/$file.pnm"
foreach j {tx ty bx by} { set $j [pixelto inch [expr $s($j$i)-$s(o)]] }
set geometry "-f $tx $ty $bx $by"
switch $s(mode) {
Lineart { set mode "-b" }
Halftone { set mode "-a" }
Gray { set mode "-g" }
Color { set mode "-c" }
}
set resolution "-r $s(resolution)"
set option "-v $s(speed) -k $s(contrast) -d $s(brightness) \
-e $s(exposuretime)"
if {$s(backtrack) == "no"} {append option " -B"}
foreach i $s($s(mode)option) { switch $i {
halftoning {append option " -H $s(halftoning)"}
shadow {append option " -s $s(shadow)"}
midtone {append option " -m $s(midtone)"}
highlight {append option " -l $s(highlight)"}
gamma { if {$s(gamma_support)==0} {append option " -G $s(gamma)"}}
}}
set cmdline "$command $s(device) $mode $resolution $option $geometry $file"
exec sh -c "echo $cmdline" &
}
#----------------------------------------------------------------
# Miscellanous Configuration
#----------------------------------------------------------------
# Period in miliseconds for checking scanning progress
set s(loopperiod) 1000
# Preview and Scan mode
set c(prefile) preview
set s(preresolutionRange) {15 40 1}
set s(premode) Gray
set s(preresolution) 27
set s(Defaultmode) Color
set s(Defaultresolution) 150
# Quick mode description: unspecified options are set to Default.
set c(mode_quick_set) {
{ Copy { mode=Gray resolution=150 } }
{ Fax { mode=Lineart resolution=200 } }
{ OCR { mode=Lineart resolution=300 } }
{ Default {} }
}
# Paper quick settings, length in inch.
set c(size_quick_set) {
{ Max { 0.0 0.0 $s(scanwidth) $s(scanheight) } }
{ A4 { 0.0 0.0 8.268 11.6 } }
{ Letter { 0.0 0.0 8.5 11.0 } }
{ Photo { 0.0 0.0 5.906 3.937 } }
}
# Length units, their display formats and conversion factors
set s(unitList) {
{ mm 25.5 %0.0f }
{ cm 2.54 %0.1f }
{ inch 1.0 %0.2f }
{ pt 72.0 %0.0f }
}
# Define variables for later use
foreach i $s(optionList) {
set variable [lindex $i 2]
set default [lindex $i 4]
set s(Default$variable) $default
set s(pre$variable) $default
}
foreach i $s(modeList) { set modename [lindex $i 0]
set s([set modename]format) [lindex $i 1]
set s([set modename]dsizefactor) [lindex $i 2]
set s([set modename]option) [lindex $i 3]
}
foreach i $s(unitList) { set unitname [lindex $i 0]
set s(c$unitname) [lindex $i 1]
set s(f$unitname) [lindex $i 2]
}
foreach i $c(mode_quick_set) { set c(qmode[lindex $i 0]) [lindex $i 1] }
foreach i $c(size_quick_set) { set c(qpaper[lindex $i 0]) [lindex $i 1] }
# Adopted scanning mode options in this program
set s(settingList) "mode resolution"
foreach i $s(optionList) {lappend s(settingList) [lindex $i 2]}
foreach i $s(settingList) {set s($i) $s(Default$i)}
# Fonts
# entry font
set l(f1) -adobe-helvetica-bold-r-*--12-120-*-*-*-*-*-*
# fixed font
set l(f2) -bitstream-courier-bold-r-*--14-140-*-*-*-*-*-*
# Color
# entry color
set l(c1) blue
# primary rectangle
set l(c2) blue
# registed rectangle
set l(c3) red
# currently processed rectangle
set l(c5) blue
# scanning progress bar
set l(c6) blue
#----------------------------------------------------------------
# User Configuration
#----------------------------------------------------------------
# The directory where the configuration file and temporary files are kept
set c(tkscandir) $env(HOME)/.tkscan
if [file exists $c(tkscandir)] {
if [file isdirectory $c(tkscandir)] {
} else {
puts "tkscan: ~/.tkscan exists but not a directory"
exit
}
} else {
puts "tkscan: No $c(tkscandir) directory, create it."
exec mkdir $c(tkscandir)
}
set c(scanout) ""
set c(userconf) "$c(tkscandir)/init"
set c(tmpdirclear) 1
# The following entries are saved in the user configuration file.
set s(saveList) "device preresolutionRange premode preresolution pregamma unit"
foreach i $s(settingList) {append s(saveList) " Default$i"}
set c(saveList) "mode_quick_set size_quick_set tmpdirclear"
#----------------------------------------------------------------
# Main Window
#----------------------------------------------------------------
proc mainWindow {} { global s c w l
# Menubar
#
frame .menu -bd 1 -relief flat
pack .menu -side top -fill x
mb .menu.f File .menu.f.m
mb .menu.m Mode .menu.m.m
mb .menu.h Help .menu.h.m
label .menu.l -text "TkScan v$c(version)" -width 15 -pady 0 \
-fg red -font -*-times-bold-r-*--14-140-*
pack .menu.f .menu.m .menu.l -side left
pack .menu.h -side right
menu .menu.f.m -tearoff false
.menu.f.m add command -label Preference -command preferenceWindow
.menu.f.m add command -label "Set current as Default" \
-command "savecur Default"
.menu.f.m add command -label "Save current config" \
-command "savesettings"
.menu.f.m add separator
.menu.f.m add command -label Quit -command do_exit
menu .menu.m.m -tearoff false
foreach i $c(mode_quick_set) {
set qmodename [lindex $i 0]
.menu.m.m add command -command "setquickmode $qmodename" \
-label $qmodename
}
menu .menu.h.m -tearoff false
.menu.h.m add command -label About -command aboutWindow
.menu.h.m add command -label Readme -command readmeWindow
.menu.h.m add command -label Guide -command usageWindow
# Separator - not indispensible, just for good looking.
canvas .sep1 -relief sunken -height 0 -borderwidth 1
pack .sep1 -side top -fill x
# Left frame
#
frame .left -bd 5 -relief flat
pack .left -side left -anchor nw -fill y
# Preview image canvas
set w(prev) .left.preview
canvas $w(prev) -relief sunken
pack $w(prev) -side top
bind $w(prev) <ButtonPress-1> "settop %x %y"
bind $w(prev) <B1-Motion> "setbottom %x %y"
bind $w(prev) <ButtonPress-2> "registrect %x %y"
bind $w(prev) <ButtonPress-3> "deleterect %x %y"
bind $w(prev) <Double-Button-3> "deleteallrect"
# Right frame
#
frame .right -bd 5 -relief flat
pack .right -side left -expand yes -fill both
# OUTPUT
set w(ou) .right.output
set w(outputto) $w(ou).u.m
frame $w(ou) -bd 1 -relief groove
frame $w(ou).u
pack $w(ou).u -side top -fill x
rl $w(ou).u.l "Output to"
menubutton $w(outputto) -menu $w(ou).u.m.m \
-anchor w -width 18 -padx 6 -pady 2 -relief ridge -fg $l(c1)
pack $w(ou).u.l $w(ou).u.m -side left -fill x
menu $w(ou).u.m.m -tearoff false
foreach i $c(outputtoList) { set label [lindex $i 0]
$w(ou).u.m.m add command -label $label -command "setoutputto $label"
}
# Scanning mode selection
set w(mo) .right.mode
frame $w(mo) -bd 1 -relief groove
# MODE
frame $w(mo).m
pack $w(mo).m -side top -anchor nw -fill x
rl $w(mo).m.label "Mode"
menubutton $w(mo).m.mode -menu $w(mo).m.mode.m \
-anchor w -width 18 -padx 6 -pady 2 -relief ridge -fg $l(c1)
pack $w(mo).m.label $w(mo).m.mode -side left
menu $w(mo).m.mode.m -tearoff false
foreach i $s(modeList) { set modename [lindex $i 0]
$w(mo).m.mode.m add command -label $modename \
-command "setmode $modename"
}
# RESOLUTION
frame $w(mo).r
pack $w(mo).r -side top -anchor nw
rl $w(mo).r.label "Resolution"
entry $w(mo).r.entry -textvariable s(resolution) \
-justify right -relief sunken -width 4 -font $l(f1) -fg $l(c1)
scale $w(mo).r.scale -variable s(resolution) -command setresolution \
-from [lindex $s(resolutionRange) 0] \
-to [lindex $s(resolutionRange) 1] \
-resolution [lindex $s(resolutionRange) 2] \
-length 100 -orient horizontal -showvalue false
pack $w(mo).r.label $w(mo).r.entry $w(mo).r.scale -side left
# OPTIONS
frame $w(mo).e
pack $w(mo).e -side top -anchor nw
rl $w(mo).e.label "Options"
button $w(mo).e.button -text "Open Manager >>" \
-command optionWindow \
-anchor e -width 19 -relief ridge -padx 0 -pady 0
set w(optionbutton) $w(mo).e.button
pack $w(mo).e.label $w(mo).e.button -side left
# SCANNING GEOMETRY DISPLAY
set w(ge) .right.geometry
frame $w(ge) -bd 1 -relief groove
canvas $w(ge).xy -width 210 -height 80 -bd 1 -relief flat
pack $w(ge).xy -fill x
set w(ft) $w(ge).xy
set finetune_buttons {
{ tx- { 8 17 } { 8 33 } { 0 25 } }
{ tx+ { 13 17 } { 13 33 } { 21 25 } }
{ bx- { 38 17 } { 38 33 } { 30 25 } }
{ bx+ { 43 17 } { 43 33 } { 51 25 } }
{ ty- { 17 8 } { 33 8 } { 25 0 } }
{ ty+ { 17 13 } { 33 13 } { 25 21 } }
{ by- { 17 38 } { 33 38 } { 25 30 } }
{ by+ { 17 43 } { 33 43 } { 25 51 } }
}
set xs 86
set ys 21
$w(ft) create rectangle [expr 10+$xs] [expr 10+$ys] \
[expr 40+$xs] [expr 40+$ys] -outline blue
foreach i $finetune_buttons {
set btag [lindex $i 0]
for {set j 1} {$j<=3} {incr j} {
set x$j [expr [lindex [lindex $i $j] 0] +$xs]
set y$j [expr [lindex [lindex $i $j] 1] +$ys]
}
$w(ft) create polygon $x1 $y1 $x2 $y2 $x3 $y3 -fill black -tag $btag
$w(ft) bind $btag <Any-Enter> "$w(ft) itemconfig current -fill red"
$w(ft) bind $btag <Any-Leave> "$w(ft) itemconfig current -fill black"
$w(ft) bind $btag <ButtonPress> "set s(xx) 0; finetune $btag"
$w(ft) bind $btag <ButtonRelease> "set s(xx) 1"
}
# Coordinates
$w(ft) create text [expr 5+$xs] [expr 15+$ys] -tag ul -anchor se \
-fill $l(c1) -font $l(f1)
$w(ft) create text [expr 45+$xs] [expr 35+$ys] -tag lr -anchor nw \
-fill $l(c1) -font $l(f1)
# Label and Buttons
rl $w(ft).l "Geometry"
label $w(ft).u -text "Length Unit"
menubutton $w(ft).m -text $s(unit) -menu $w(ft).m.m \
-width 4 -pady 0 -relief ridge -fg $l(c1)
menu $w(ft).m.m -tearoff false
foreach i $s(unitList) { set label [lindex $i 0]
$w(ft).m.m add command -label $label -command \
"setunit $label ; $w(ft).m configure -text $label"
}
menubutton $w(ft).p -text "Preset" -menu $w(ft).p.m \
-width 6 -pady 0 -relief ridge
menu $w(ft).p.m -tearoff false
foreach i $c(size_quick_set) {
set qpapername [lindex $i 0]
$w(ft).p.m add command -command "setquickpaper $qpapername" \
-label $qpapername
}
button $w(ft).r -text Regist -command {registrect $s(tx0) $s(ty0)} \
-padx 0 -pady 0 -relief ridge
button $w(ft).d -text Delete -command {deleterect $s(tx0) $s(ty0)} \
-padx 0 -pady 0 -relief ridge
button $w(ft).c -text Clear -command deleteallrect \
-padx 0 -pady 0 -relief ridge
$w(ft) create window 0 0 -window $w(ft).l -anchor nw
$w(ft) create window 102 0 -window $w(ft).u -anchor nw
$w(ft) create window 177 0 -window $w(ft).m -anchor nw
$w(ft) create window 163 22 -window $w(ft).p -anchor nw
$w(ft) create window 0 39 -window $w(ft).r -anchor nw
$w(ft) create window 0 61 -window $w(ft).d -anchor nw
$w(ft) create window 46 61 -window $w(ft).c -anchor nw
# SIZE : Real, Screen, Data
sizeline $w(ge).rs "Real Size" "mm^2"
sizeline $w(ge).ss "Screen Size" "pixel^2"
sizeline $w(ge).ds "Data Size" "KB"
# BUTTONS
set w(bt) .right.buttons
frame $w(bt) -bd 1 -relief flat
button $w(bt).p -text Preview -command "Preview" -width 5 -pady 4
button $w(bt).s -text SCAN -command {Scan [timetagscanout]} \
-width 10 -pady 4
button $w(bt).q -text Stop -command "set s(stop) 1" \
-width 3 -pady 4 -state disabled
bind $w(bt).q <Double-Button-1> {
set s(pid) [getpid $s(command)]
if {"$s(pid)" != ""} { foreach i $s(pid) { exec kill -9 $i } }
set s(stop) 0
set s(runscan) 0
$w(bt).p configure -state normal
$w(bt).s configure -state normal
$w(bt).q configure -state disabled
}
pack $w(bt).p $w(bt).s $w(bt).q -side left -expand yes -fill x
# MESSAGE LINE
# Scanning progress: percentage in bar and number
set w(st) .right.status
set w(stat_text) $w(st).text
set w(stat_prog) $w(st).prog
set w(prog_bar) $w(stat_prog).bar
set w(prog_perc) $w(stat_prog).percent
set s(prog_bar_wd) 173
frame $w(st) -bd 1 -relief groove
pack $w(st) -side bottom -fill x
label $w(stat_text) -anchor w -relief flat -font $l(f1)
frame $w(stat_prog)
pack $w(stat_text) $w(stat_prog) -side top -fill x
canvas $w(prog_bar) -width $s(prog_bar_wd) -height 15 -bd 1 -relief ridge
label $w(prog_perc) -width 5 -padx 1 -pady 0 -anchor e -bd 1 -relief ridge
pack $w(prog_bar) $w(prog_perc) -side left
set s(sg) [$w(prog_bar) create rectangle 0 0 0 18 -fill $l(c6)]
pack $w(ou) $w(mo) $w(ge) $w(bt) -side top -expand yes -fill x
pack $w(st) -side bottom -expand yes -fill x
}
#-----------------------------------------------------------------
# Preference Window
#-----------------------------------------------------------------
proc preferenceWindow {} { global s c w l
if [winfo exists .preference] { return }
toplevel .preference
wm title .preference "TkScan: Preference"
# Driver and Device
set pd .preference.device
frame $pd -bd 1 -relief groove
frame $pd.u
frame $pd.d
pack $pd.u $pd.d -side top -fill x
label $pd.u.l -text Command -width 15 -anchor e
entry $pd.u.d -textvariable s(command) \
-width 20 -font $l(f1) -fg $l(c1) -relief sunken
pack $pd.u.l $pd.u.d -side left
label $pd.d.l -text Device -width 15 -anchor e
entry $pd.d.d -textvariable s(device) \
-width 20 -font $l(f1) -fg $l(c1) -relief sunken
pack $pd.d.l $pd.d.d -side left
# Preview
set pp .preference.preview
frame $pp -bd 1 -relief groove
frame $pp.m
pack $pp.m -side top -fill x
label $pp.m.p -text "Preview Mode" -width 15 -anchor e
menubutton $pp.m.m -menu $pp.m.m.m -width 10 -relief ridge -fg $l(c1)
set w(premodebutton) $pp.m.m
pack $pp.m.p $pp.m.m -side left
menu $pp.m.m.m -tearoff false
foreach i $s(modeList) { set modename [lindex $i 0]
$pp.m.m.m add command -label $modename \
-command "setpremode $modename"
}
$pp.m.m.m add command -label Current \
-command "setpremode Current"
frame $pp.r
pack $pp.r -side top -fill x
label $pp.r.l -text "Resolution" -width 15 -padx 0 -anchor e
set s(prepreresolution) $s(preresolution)
entryscale $pp.r s(prepreresolution) {} $s(preresolutionRange) 60
button $pp.r.b -text Apply -width 5 -padx 0 \
-command {setpreresolution $s(prepreresolution)}
pack $pp.r.l $pp.r.e $pp.r.s $pp.r.b -side left
setpremode $s(premode)
# Gamma support
set pg .preference.gamma
frame $pg -bd 1 -relief groove
label $pg.l -text "Gamma Support" -width 15 -anchor e
radiobutton $pg.1 -text Driver -variable s(gamma_support) -value 0
radiobutton $pg.2 -text External -variable s(gamma_support) -value 1
pack $pg.l $pg.1 $pg.2 -side left
# Image Editor
set ie .preference.ie
frame $ie -bd 1 -relief groove
label $ie.l -text "Image Editor" -width 15 -anchor e
menubutton $ie.mb -menu $ie.mb.m -text $c(ImageEditor) \
-width 12 -relief ridge -fg $l(c1)
checkbutton $ie.cb -text SW -variable c(ImageEditorWinmode)
pack $ie.l $ie.mb $ie.cb -side left
menu $ie.mb.m -tearoff false
foreach i $c(ImageEditorList) { set iename [lindex $i 0]
$ie.mb.m add command -label $iename -command "
$ie.mb configure -text $iename
set c(ImageEditor) $iename
"
}
# Image and Fax viewer
set pv .preference.viewer
frame $pv -bd 1 -relief groove
frame $pv.1
frame $pv.2
pack $pv.1 $pv.2 -side top
label $pv.1.l -text "Image Viewer" -width 15 -anchor e
entry $pv.1.e -textvariable file(viewer) -width 20 -fg $l(c1) -font $l(f1)
pack $pv.1.l $pv.1.e -side left
label $pv.2.l -text "Fax Viewer" -width 15 -anchor e
entry $pv.2.e -textvariable fax(viewer) -width 20 -fg $l(c1) -font $l(f1)
pack $pv.2.l $pv.2.e -side left
# Printer paper
set pa .preference.paper
frame $pa -bd 1 -relief groove
label $pa.l -text "Printer Paper" -width 15 -anchor e
radiobutton $pa.1 -text A4 -variable pr(paper) -value A4
radiobutton $pa.2 -text Letter -variable pr(paper) -value Letter
pack $pa.l $pa.1 $pa.2 -side left
# Temporary directory
set pt .preference.tmpdir
frame $pt -bd 1 -relief groove
frame $pt.u
frame $pt.d
pack $pt.u $pt.d -side top -fill x
label $pt.u.1 -text "TMP Directory" -width 15 -anchor e
checkbutton $pt.u.2 -text "Clear when Exit" -variable c(tmpdirclear)
pack $pt.u.1 $pt.u.2 -side left -fill x
label $pt.d.1 -text "" -width 15 -anchor e
button $pt.d.2 -text "Clear Now" -width 12 \
-command clear_tkscandir
pack $pt.d.1 $pt.d.2 -side left -fill x
# Packing
pack $pd $pp $pg $ie $pv $pa $pt -side top -fill x
# Buttons
set pb .preference.button
frame $pb
pack $pb -side bottom -expand yes -fill x
button $pb.h -text Done -pady 0 -command { destroy .preference }
pack $pb.h -side left -expand yes -fill x
}
#--------------------------------------------------------------------
# optionWindow
#--------------------------------------------------------------------
proc optionWindow {} { global s w l
if [winfo exists .option] {
$w(optionbutton) configure -text "Open Manager >>"
destroy .option
return
}
$w(optionbutton) configure -text "Close Manager <<"
frame .option -bd 5 -relief flat
pack .option -side left -fill both
label .option.ti -text "TkScan Option Manager" \
-width 24 -pady 4 -relief ridge
canvas .option.sep -width 0 -height 5 -relief flat
pack .option.ti .option.sep -side top
foreach i $s(optionList) {
set Label [lindex $i 0]
set Type [lindex $i 1]
set Variable [lindex $i 2]
set Values [lindex $i 3]
set wn .option.$Variable
frame $wn
pack $wn -side top -fill x
label $wn.l -text $Label -width 12 -anchor e
switch $Type {
s {}
m {
menubutton $wn.mb -menu $wn.mb.m -text $s($Variable) \
-anchor w -width 13 -padx 10 -pady 2 -relief ridge -fg $l(c1)
menu $wn.mb.m -tearoff false
pack $wn.l $wn.mb -side left
foreach i $Values {
$wn.mb.m add command -label $i -command \
"set s($Variable) $i ; $wn.mb configure -text $i"
}
}
r {
entryscale $wn s($Variable) {} $Values 72
pack $wn.l $wn.e $wn.s -side left
}
}
}
option_select
}
#-------------------------------------------------------------------------
# Windows for Help menu
#-------------------------------------------------------------------------
proc aboutWindow {} { global about_tkscan
if [winfo exists .about] return
toplevel .about
wm title .about "TkScan: About"
label .about.l -text $about_tkscan
button .about.b -width 8 -text OK -command "destroy .about"
pack .about.l .about.b -side top
}
proc readmeWindow {} {global readme_tkscan l
if [winfo exists .readme] return
toplevel .readme
wm title .readme "TkScan: README"
frame .readme.b
pack .readme.b -side top -fill x
label .readme.b.1 -text "TkScan README" -width 15
button .readme.b.2 -text Close -command {destroy .readme}
pack .readme.b.1 .readme.b.2 -side left
frame .readme.u
pack .readme.u -side top -fill x
text .readme.u.t -width 68 -height 20 -font $l(f1) \
-yscrollcommand ".readme.u.s set"
pack .readme.u.t -side left
scrollbar .readme.u.s -command ".readme.u.t yview" -orient vertical
pack .readme.u.s -side right -fill y
.readme.u.t insert end $readme_tkscan
}
proc usageWindow {} {global usage_tkscan l
if [winfo exists .usage] return
toplevel .usage
wm title .usage "TkScan: Guide"
frame .usage.b
pack .usage.b -side top -fill x
label .usage.b.1 -text "TkScan Guide" -width 15
button .usage.b.2 -text Close -command {destroy .usage}
pack .usage.b.1 .usage.b.2 -side left
frame .usage.u
pack .usage.u -side top -fill x
text .usage.u.t -width 68 -height 20 -font $l(f1) \
-yscrollcommand ".usage.u.s set"
pack .usage.u.t -side left
scrollbar .usage.u.s -command ".usage.u.t yview" -orient vertical
pack .usage.u.s -side right -fill y
.usage.u.t insert end $usage_tkscan
}
#----------------------------------------------------------------
# Procedures for configurations
#----------------------------------------------------------------
proc savesettings {} { global s c
set file [open "$c(userconf)" w]
puts $file "# tkscan user configuration
# If you feel like doing more changes, observe the `tkscan' script and
# copy necessary parts here, then change them.\n"
foreach i $s(saveList) { puts $file "set s($i)\t\"$s($i)\"" }
foreach i $c(saveList) { puts $file "set c($i)\t\"$c($i)\"" }
puts $file "\n# end of tkscan user configuration"
close $file
}
proc setcur { type } { global s w
foreach i $s(settingList) {set s($i) $s($type$i)}
setmode $s(mode)
}
proc savecur { type } { global s
foreach i $s(settingList) {set s($type$i) $s($i)}
}
proc setmode { mode } { global s c w
set s(mode) $mode
if $s(premodecurrent) { set s(premode) $mode }
$w(mo).m.mode configure -text $mode
if [winfo exists .option] { option_select }
showsize 0
}
proc option_select {} { global s
foreach i $s(modedepoptionList) { .option.$i.l configure -fg gray }
foreach i $s($s(mode)option) { .option.$i.l configure -fg black }
}
proc setquickmode { mode } { global s c
setcur Default
foreach k $c(qmode$mode) {
set l [string first = $k]
set arg [string range $k 0 [expr [string first = $k]-1]]
set val [string range $k [expr [string first = $k]+1] end]
set s($arg) $val
}
# if { [set i $c(qmode$mode\outputto)] != "" } { setoutputto $i }
setmode $s(mode)
}
proc setquickpaper { paper } { global s c
for {set j 0} {$j<4} {incr j} { set z$j [format "%0.0f" \
[expr [lindex $c(qpaper$paper) $j]*$s(preresolution)+$s(o)]] }
settop $z0 $z1 ; setbottom $z2 $z3
}
proc setpremode { mode } { global s w
$w(premodebutton) configure -text $mode
if { $mode == "Current" } {
set s(premodecurrent) 1
set s(premode) $s(mode)
} else {
set s(premodecurrent) 0
set s(premode) $mode
}
}
proc setpreresolution { resolution } { global s w
set s(preresolution) $resolution
previewcanvas
deleteallrect
image create photo preview -data {}
}
proc previewcanvas {} { global s w
set s(o) 6
set s(prebd) 2
set s(scanpwidth) [format "%0.0f" [expr $s(scanwidth) *$s(preresolution)]]
set s(scanpheight) [format "%0.0f" [expr $s(scanheight)*$s(preresolution)]]
set s(maxpwidth) [expr $s(scanpwidth) +$s(o)]
set s(maxpheight) [expr $s(scanpheight)+$s(o)]
set s(prewidth) [expr $s(scanpwidth) +2*($s(o)-$s(prebd)-1)]
set s(preheight) [expr $s(scanpheight)+2*($s(o)-$s(prebd)-1)]
$w(prev) configure -width $s(prewidth) -height $s(preheight) -bd $s(prebd)
}
proc setresolution { resolution } { global s
set s(resolution) $resolution
showsize 0
}
proc setunit { unit } { global s w
set s(unit) $unit
$w(ge).rs.unit configure -text "$unit^2"
showsize 0
}
proc showsize { i } { global s w
set txd [format "$s(f$s(unit))" [pixelto $s(unit) [expr $s(tx$i)-$s(o)]]]
set tyd [format "$s(f$s(unit))" [pixelto $s(unit) [expr $s(ty$i)-$s(o)]]]
set bxd [format "$s(f$s(unit))" [pixelto $s(unit) [expr $s(bx$i)-$s(o)]]]
set byd [format "$s(f$s(unit))" [pixelto $s(unit) [expr $s(by$i)-$s(o)]]]
set wd [pixelto $s(unit) [expr $s(bx$i)-$s(tx$i)]]
set ht [pixelto $s(unit) [expr $s(by$i)-$s(ty$i)]]
set s(sizeReal) [format "$s(f$s(unit)) x $s(f$s(unit))" $wd $ht]
set pwd [expr [pixelto inch [expr $s(bx$i)-$s(tx$i)]] * $s(resolution).0]
set pht [expr [pixelto inch [expr $s(by$i)-$s(ty$i)]] * $s(resolution).0]
set dsizefactor $s($s(mode)dsizefactor)
set dsize [expr $pwd * $pht * $dsizefactor / 8192.0]
set s(sizeScreen) [format "%0.0f x %0.0f" $pwd $pht]
set s(sizeData) [format "%0.1f" $dsize]
$w(ft) itemconfigure ul -text "($txd, $tyd)"
$w(ft) itemconfigure lr -text "($bxd, $byd)"
$w(ge).rs.size configure -text "$s(sizeReal)"
$w(ge).ss.size configure -text "$s(sizeScreen)"