X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~yarrgweb/git?p=ypp-sc-tools.db-live.git;a=blobdiff_plain;f=pctb%2Fyppsc-ocr-resolver;h=7aa707759efbcb80f5deaeaddeb0557e9789e937;hp=016a95e58bfc90557e370ca7c36728dca32a0531;hb=f364c130b3b7d2e46e6cb57e4ff39a59fb54b226;hpb=89dfaeec1540f73ba85dbd25dd5332416f98778e diff --git a/pctb/yppsc-ocr-resolver b/pctb/yppsc-ocr-resolver index 016a95e..7aa7077 100755 --- a/pctb/yppsc-ocr-resolver +++ b/pctb/yppsc-ocr-resolver @@ -1,14 +1,42 @@ #!/usr/bin/wish -# usage: -# run show-thing without args +# helper program for OCR in PCTB upload client + +# This is part of ypp-sc-tools, a set of third-party tools for assisting +# players of Yohoho Puzzle Pirates. +# +# Copyright (C) 2009 Ian Jackson +# +# 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 3 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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Yohoho and Puzzle Pirates are probably trademarks of Three Rings and +# are used without permission. This program is not endorsed or +# sponsored by Three Rings. + + +# invocation: +# OUT OF DATE +# run this without args # then on stdin write -# one line which is a Tcl list for unk_{l,r} unk_contexts glyphsdone +# one line which is a Tcl list for unk_{l,r} unk_contexts glyphsdone etc. # the xpm in the format expected -# then expect child to raise SIGSTOP or exit 0 or exit nonzero -# if child raised SIGSTOP, check database was updated +# then expect child to exit 0, or write a single 0 byte to fd 4 +# if it wrote a byte to fd 4, it can take another question +#---------- library routines ---------- + proc manyset {list args} { foreach val $list var $args { upvar 1 $var my @@ -16,6 +44,10 @@ proc manyset {list args} { } } +proc must_gets {f lvar} { + upvar 1 $lvar l + if {[gets $f l] < 0} { error "huh?" } +} #---------- display core ---------- @@ -56,58 +88,277 @@ static unsigned char csr_bits[] = { frame .d.mi.csr_0 -bg white -width 1 frame .d.mi.csr_1 -bg white -width 1 + frame .d.pe + frame .d.pe.grid + button .d.pe.ok -text OK + pack .d.pe.grid .d.pe.ok -side left - pack .d.csr .d.mi .d.got .d.ctx -side top + pack .d.mi .d.ctx -side top pack .d frame .help pack .help } -proc show_context {maxhv x ctxs} { - global mul - upvar 1 $maxhv maxh - set w .d.ctx.at$x - if {[llength $ctxs]==1} { set fg blue } { set fg yellow } - label $w -bg black -fg $fg -text [join $ctxs "/\n"] -justify left - place $w -x [expr {($x-1)*$mul}] -y 0 - set wh [winfo reqheight $w] - if {$wh > $maxh} { set maxh $wh } -} - -proc resize_widgets {} { +proc resize_widgets_core {} { global mulcols mulrows csrh gotsh ctxh glyphsdone global unk_l unk_contexts foreach w {.d.csr .d.got .d.ctx} { $w configure -width $mulcols } - #.d configure -height [expr {$csrh+$mulrows+$gotsh+$ctxh}] - foreach w {0 1} { - .d.mi.csr_$w configure -height $mulrows - } eval destroy [winfo children .d.ctx] +} + +set last_ht {} + +proc helptext {t} { + global last_ht + if {![string compare $t $last_ht]} return + eval destroy [grid slaves .help] + set y 0; foreach l $t { + set x 0; foreach c $l { + set w .help.at${x}x${y} + label $w -text $c + grid $w -row $y -column $x -padx 5 + incr x + } + incr y + } + set last_ht $t +} + +proc bind_key {k proc} { + global keybindings + bind . $proc + set keybindings($k) [expr {!![string length $proc]}] +} +proc unbind_all_keys {} { + global keybindings + foreach k [array names keybindings] { bind_key $k {} } +} + +#---------- database read and write common wrapper ---------- + +proc db_getsl {f} { + if {[gets $f l] < 0} { error "unexpected db eof" } + return $l +} + +proc read_database {fn} { + global reqkind database database_fn + upvar #0 database_magic/$reqkind magic + catch { unset database } + + set database_fn $fn + if {![file exists $database_fn]} return + set f [open $database_fn r] + if {[string compare [db_getsl $f] $magic]} { error "$l $reqkind ?" } + + read_database_header/$reqkind $f + while 1 { + set l1 [db_getsl $f] + + if {![string length $l1]} continue + if {[regexp {^\#} $l1]} continue + if {![string compare . $l1]} break + + read_database_entry/$reqkind $f $l1 + } + close $f +} + +proc write_database {} { + global reqkind database_fn database + upvar #0 database_magic/$reqkind magic + + set f [open $database_fn.new w] + puts $f $magic + + write_database_header/$reqkind $f + + set ol {} + foreach bm [array names database] { + lappend ol [format_database_entry/$reqkind $bm $database($bm)] + } + foreach o [lsort $ol] { + puts $f $o + } + puts $f "." + close $f + file rename -force $database_fn.new $database_fn +} + +proc required/char {} { + global mulrows glyphsdone unk_l unk_r unk_contexts rows + + must_gets stdin l + + manyset [lrange $l 0 3] unk_l unk_r unk_contexts + set glyphsdone [lrange $l 3 end] + debug "GOT $l" + + char_read_xpm stdin + resize_widgets_core + foreach w {0 1} { + .d.mi.csr_$w configure -height $mulrows + } set maxh 0 foreach {min max contexts got} $glyphsdone { show_context maxh $min $contexts } show_context maxh $unk_l $unk_contexts .d.ctx configure -height $maxh + pack forget .d.pe + pack .d.csr -side top -before .d.mi + pack .d.got .d.ctx -side top -after .d.mi + + read_database ./charset-$rows.txt + draw_glyphsdone + startup_cursor +} + +#========== PIXMAPS ========== + +#---------- pixmap database read and write ---------- + +set database_magic/pixmap {# ypp-sc-tools pctb pixmaps v1} + +proc read_database_header/pixmap {f} { } +proc read_database_entry/pixmap {f def} { + global database + + set im "" + + set p3 [db_getsl $f]; append im $p3 "\n" + if {[string compare $p3 P3]} { error "$p3 ?" } + + set wh [db_getsl $f]; append im $wh "\n"; manyset $wh w h + set depth [db_getsl $f]; append im $depth "\n" + + for {set y 0} {$y < $h} {incr y} { + set line [db_getsl $f]; append im $line "\n" + } + set database($im) $def +} +proc write_database_header/pixmap {f} { puts $f "" } +proc format_database_entry/pixmap {im def} { + return "$def\n$im" +} + +#---------- pixmap display and input handling ---------- + +proc foreach_pixmap_col {var body} { + global alloptions + upvar 1 $var col + for {set col 0} {$col < [llength $alloptions]/3} {incr col} { + uplevel 1 $body + } +} + +proc pixmap_select {ncol} { + global alloptions + debug "PIX SELECT $ncol [llength $alloptions]" + foreach_pixmap_col col { + if {$col==$ncol} continue + .d.pe.grid.l$col selection clear 0 end + } + pixmap_maybe_ok +} +proc pixmap_maybe_ok {} { + global alloptions pixmap_selcol pixmap_selrow + set nsel 0 + foreach_pixmap_col col { + set cs [.d.pe.grid.l$col curselection] + incr nsel [llength $cs] + set pixmap_selcol $col + set pixmap_selrow [lindex $cs 0] + } + if {$nsel==1} { + .d.pe.ok configure -state normal -command pixmap_ok + } else { + .d.pe.ok configure -state disabled -command {} + } +} +proc pixmap_ok {} { + global database ppm pixmap_selcol pixmap_selrow mainkind alloptions + foreach_pixmap_col col { + .d.pe.grid.l$col configure -state disabled + } + .d.pe.ok configure -state disabled + helptext {{{ Processing }}} + manyset [lrange $alloptions [expr {$pixmap_selcol*3}] end] \ + colname coldesc rows + manyset [lrange $rows [expr {$pixmap_selrow*2}] end] \ + rowname rowdesc + set result "$colname - $rowname" + debug "UPDATE PIXMAP AS >$result<" + set database($ppm) $result + write_database + done/$mainkind } +proc required/pixmap {} { + global unk_what ppm mulcols alloptions + must_gets stdin unk_what + debug "GOT pixmap $unk_what" + set ppm {} + while 1 { + must_gets stdin ppml + if {![string length $ppml]} break + append ppm $ppml "\n" + } + set data [exec pnmscale 2 << $ppm] + image create photo image/main -data $data + + set alloptions [exec ./yppsc-resolver-pixoptions $unk_what] + + read_database ./pixmaps.txt + + set mulcols [image width image/main] + set mulrows [image height image/main] + resize_widgets_core + place forget .d.mi.csr_0 + place forget .d.mi.csr_1 + + pack forget .d.csr .d.got + pack .d.pe -side top -before .d.mi -pady 10 + + eval destroy [winfo children .d.pe.grid] + set col 0; foreach {colname coldesc rows} $alloptions { + debug "INIT $col $colname \"$coldesc\"" + label .d.pe.grid.t$col -text $colname + listbox .d.pe.grid.l$col + foreach {rowname rowdesc} $rows { + debug "INIT $col $colname \"$coldesc\" $rowname \"$rowdesc\"" + .d.pe.grid.l$col insert end $rowdesc + } + bind .d.pe.grid.l$col <> [list pixmap_select $col] + grid .d.pe.grid.t$col -column $col -row 0 + grid .d.pe.grid.l$col -column $col -row 1 + incr col + } + pixmap_maybe_ok + + helptext { + {{Indicate the correct parse of this image, and click OK.}} + } +} + +#========== CHARACTER SET ========== #---------- xpm input processor ---------- -proc read_xpm {f} { +proc char_read_xpm {f} { global glyphsdone mul inter rhsmost_max unk_l unk_r mulcols mulrows global cols rows wordmap set o {} set y -3 while 1 { - if {[gets $f l] < 0} { error "huh? "} + must_gets $f l if {![regexp {^"(.*)",$} $l dummy l]} { append o "$l\n" if {[regexp {^\}\;$} $l]} break @@ -206,8 +457,18 @@ proc read_xpm {f} { image create photo image/main -data $data } +#---------- character set editor display ---------- -#---------- per-invocation display ---------- +proc show_context {maxhv x ctxs} { + global mul + upvar 1 $maxhv maxh + set w .d.ctx.at$x + if {[llength $ctxs]==1} { set fg blue } { set fg yellow } + label $w -bg black -fg $fg -text [join $ctxs "/\n"] -justify left + place $w -x [expr {($x-1)*$mul}] -y 0 + set wh [winfo reqheight $w] + if {$wh > $maxh} { set maxh $wh } +} proc draw_glyphsdone {} { global glyphsdone mul inter @@ -229,29 +490,11 @@ proc startup_cursor {} { set cur_0 $unk_l set cur_1 [expr {$unk_r+1}] - set last_ht {} recursor } - -#---------- runtime display and keystroke handling ---------- - -proc helptext {t} { - global last_ht - if {![string compare $t $last_ht]} return - eval destroy [grid slaves .help] - set y 0; foreach l $t { - set x 0; foreach c $l { - set w .help.at${x}x${y} - label $w -text $c - grid $w -row $y -column $x -padx 5 - incr x - } - incr y - } - set last_ht $t -} +#---------- character set runtime display and keystroke handling ---------- proc recursor/0 {} { recursor//01 0 } proc recursor/1 {} { recursor//01 1 } @@ -336,16 +579,6 @@ proc recursor/already {} { } } -proc bind_key {k proc} { - global keybindings - bind . $proc - set keybindings($k) [expr {!![string length $proc]}] -} -proc unbind_all_keys {} { - global keybindings - foreach k [array names keybindings] { bind_key $k {} } -} - proc bind_leftright_q {var min max} { bind_key Left [list leftright $var $min $max -1] bind_key Right [list leftright $var $min $max +1] @@ -371,9 +604,9 @@ proc recursor {} { recursor/$cur_mode } +#---------- character database read and write ---------- -#---------- database read and write ---------- - +# OUT OF DATE # database format: # series of glyphs: # ... @@ -382,57 +615,32 @@ proc recursor {} { # $database($context 0x 0x...) = $hex -set database_header {# ypp-sc-tools pctb font v1} - -proc db_getsl {f} { - if {[gets $f l] < 0} { error "unexpected db eof" } - return $l -} +set database_magic/char {# ypp-sc-tools pctb font v1} -proc read_database {} { - global database database_header rows database_fn - catch { unset database } - set database_fn ./charset-$rows.txt - if {![file exists $database_fn]} return - set f [open $database_fn r] - if {[string compare [db_getsl $f] $database_header]} { error "$l ?" } +proc read_database_header/char {f} { + global rows if {([db_getsl $f])+0 != $rows} { error "wrong h ?" } +} +proc read_database_entry/char {f context} { + global database + set bm $context + set strq [db_getsl $f] while 1 { - set context [db_getsl $f] - if {![string length $context]} continue - if {[regexp {^\#} $context]} continue - if {![string compare . $context]} break - - set bm $context - set strq [db_getsl $f] - while 1 { - set l [db_getsl $f] - if {![string length $l]} break - lappend bm [format %x 0x$l] - } - set database($bm) $strq + set l [db_getsl $f] + if {![string length $l]} break + lappend bm [format %x 0x$l] } - close $f + set database($bm) $strq } -proc write_database {} { - global database rows database_fn database_header - set ol {} - foreach bm [array names database] { - set strq $database($bm) - set o "[lindex $bm 0]\n$strq\n" - foreach x [lrange $bm 1 end] { append o "$x\n" } - - lappend ol $o - } - set f [open $database_fn.new w] - puts $f "$database_header\n$rows\n" - foreach o [lsort $ol] { - puts $f $o - } - puts $f "." - close $f - file rename -force $database_fn.new $database_fn +proc write_database_header/char {f} { + puts $f "$rows\n" +} +proc format_database_entry/char {bm strq} { + global database rows + set o "[lindex $bm 0]\n$strq\n" + foreach x [lrange $bm 1 end] { append o "$x\n" } + return $o } proc dbkey {ctx l r} { @@ -475,7 +683,6 @@ proc update_database/DELETE {l r ctxs} { write_database } - proc RETURN_RESULT {how what} { global mainkind place forget .d.csr.csr @@ -488,52 +695,28 @@ proc RETURN_RESULT {how what} { done/$mainkind } -#---------- main progrm ---------- - -proc main/test {} { - global glyphsdone unk_l unk_r unk_contexts - - set glyphsdone { - 7 11 1 M - 13 17 0 a - 19 23 0 n - } - set unk_l 25 - set unk_r 29 - set unk_contexts Test - - set f [open text.xpm] - read_xpm $f - close $f +#========== main program ========== - read_database - resize_widgets - draw_glyphsdone - startup_cursor +proc main/default {} { + puts stderr "Do not run this program directly." + exit 12 } -proc done/test {} { +proc done/default {} { } proc required {} { - global glyphsdone unk_l unk_r unk_contexts + global reqkind + + fileevent stdin readable {} + fconfigure stdin -blocking yes - if {[gets stdin l]<0} { + if {[gets stdin reqkind]<0} { if {[eof stdin]} { fconfigure stdin -blocking yes; exit 0 } return } init_widgets - manyset [lrange $l 0 3] unk_l unk_r unk_contexts - set glyphsdone [lrange $l 3 end] - debug "GOT $l" - - fileevent stdin readable {} - fconfigure stdin -blocking yes - read_xpm stdin - resize_widgets - read_database - draw_glyphsdone - startup_cursor + required/$reqkind } proc main/automatic {} { @@ -547,7 +730,7 @@ proc done/automatic {} { proc debug {m} { } -set mainkind test +set mainkind default foreach arg $argv { switch -exact -- $arg { {--debug} { proc debug {m} { puts stderr "SHOW-THING $m" } }