Arbitrary Rectangle Selection

Keith Vetter 2007-10-12 : I'd thought I'd share some new techniques I've created while adding a new feature to my KLIMB bike mapping program which lets you plan bike routes interactively on topo maps [L1 ].

The new feature is another way of printing out bike routes by collecting multiple, smaller map segments and laying them out on a page. The key problem, however, is that the smaller map segments, in order to better cover the bike route, can be at any angle.

I'm still working on this new feature, and would like feedback on it, especially on the user interaction in specifying the map segment--it's tricky because the user can move, rotate and resize the selection.

A selection box is drawn on the map. The user can grab and move it anywhere. Grabbing the SE corner or by using the 3rd button, the user can rotate the box. Grabbing either of two resize controls lets you change the size.

The second aspect of this problem is laying out the results, and I haven't really done much with that yet. The third aspect is printing the result--that's going to be real fun to solve.

I included demo code, including a sample map image (compressed to death jpeg so it doesn't look great).


Some technical details.

The hardest/funnest part was extracting an angled rectangle area off a canvas. Initially I used TclMagick to do it, but because of poor documentation (I ended up using the php doc) and a few programming snags, I realized that that was overkill. Instead I used xphoto from Enhanced photo image copy command.

I use Img to grab the whole window, then crop that image to the bounding box of the selection. Next, I use xphoto to rotate the image. Then, after some simple trig, I use Img again to crop down to the selected area.


 ##+##########################################################################
 #
 # Clipbox -- grabs rectangular region of an image at any angle or size
 # by Keith Vetter, Sep, 2007
 #
 
 package require Tk
 package require Img
 
 set hasXPhoto 1
 if {[catch {load xphoto.dll}]} {
     wm withdraw .
     set msg "ERROR: missing xphoto.dll\n\n"
     append msg "This program requires the xphoto extension, which\n"
     append msg "can be downloaded from https://wiki.tcl-lang.org/11924\n\n"
     append msg "You can still run the program and interact with\n"
     append msg "the map but you cannot take snapshots."
     tk_messageBox -icon error -message $msg
     set hasXPhoto 0
     wm deiconify .
 }
 
 namespace eval ::ClipBox {
     variable P                                  ;# Box position
     variable M                                  ;# Mousing info
 
     unset -nocomplain P
     set P(clr,1) cyan
     set P(clr,0) red
     array set M {
         xy {} minWidth 200 minHeight 200 mousing 0 resizeSize 8 cornerSize 15
         cursor,corner exchange cursor,strip hand2 cursor,width fleur
         cursor,height fleur
     }
 }
 
 ##+##########################################################################
 #
 # Go -- creates the initial instance of our clipping box
 #
 proc ::ClipBox::Go {W p0 angle width height} {
     variable P
     set P(0) $p0
     set P(a,deg) $angle
     set P(w) $width
     set P(h) $height
 
     $W delete BOX
     $W create poly -tag {BOX clip} -fill cyan -stipple gray50 -width 2 \
         -outline black -dash -
     $W create poly -tag {BOX corner} -outline black -fill {} -width 2
     $W create poly -tag {BOX width} -fill black
     $W create poly -tag {BOX height} -fill black
     $W create text -100 -100 -text "N" -font {Helvetica 20 bold} -fill red \
         -anchor s -tag {BOX north northText}
     $W create line -100 -100 -200 -200 -width 5 -tag {BOX north northLine} \
         -fill red -arrow first -arrowshape {25 25 6}
 
     foreach tag {clip corner width height} {
         $W bind $tag <1> [list ::ClipBox::MouseDown %W $tag %x %y]
         $W bind $tag <B1-Motion> [list ::ClipBox::MouseMove %W $tag %x %y]
         $W bind $tag <ButtonRelease-1>  [list ::ClipBox::MouseUp %W]
         $W bind $tag <Enter> [list ::ClipBox::MouseEnter %W $tag]
         $W bind $tag <Leave> [list ::ClipBox::MouseLeave %W $tag]
 
         $W bind $tag <3> [list ::ClipBox::MouseDown %W corner %x %y]
         $W bind $tag <B3-Motion> [list ::ClipBox::MouseMove %W corner %x %y]
         $W bind $tag <ButtonRelease-3>  [list ::ClipBox::MouseUp %W]
     }
     ::ClipBox::DrawClipBox $W
 }
 ##+##########################################################################
 #
 # DrawClipBox -- repositions all elements of our clipbox
 #
 proc ::ClipBox::DrawClipBox {W} {
     set xy [::ClipBox::GetBoxCoords]
     lassign [::ClipBox::GetSmallBoxCoords] bxy wxy hxy
     lassign [::ClipBox::NorthArrow] top bot
     $W coords clip $xy
     $W coords corner $bxy
     $W coords width $wxy
     $W coords height $hxy
     $W coords northText $top
     $W coords northLine [concat $top $bot]
 }
 ##+##########################################################################
 #
 # GetBoxCoords -- given topleft corner, width, height and angle
 # returns coordinates of the box
 #
 proc ::ClipBox::GetBoxCoords {} {
     variable P
 
     set w $P(w)
     set h $P(h)
     set a $P(a,deg)
 
     set a [expr {$a * acos(-1) / 180}]          ;# Radians
 
     lassign $P(0) x0 y0
     set x1 [expr {$x0 + $w*cos($a)}]
     set y1 [expr {$y0 + $w*sin($a)}]
     set P(1) [list $x1 $y1]
 
     set top [::Data::VSub $P(1) $P(0)]
     set left [::Data::VNormalTo $top $h]
     set P(3) [::Data::VAdd $P(0) $left]
     set P(2) [::Data::VAdd $P(3) $top]
 
     set xy [concat $P(0) $P(1) $P(2) $P(3)]
 
     return $xy
 }
 ##+##########################################################################
 #
 # GetSmallBoxCoords -- returns coords for rotate box and two sizing boxes
 #
 proc ::ClipBox::GetSmallBoxCoords {} {
     variable P
     variable M
 
     # Assumes P(0-3) are correct
     set top  [::Data::VSub $P(1) $P(0)]
     set left [::Data::VSub $P(3) $P(0)]
     set nTop  [::Data::VReScale $top 1]
     set nLeft [::Data::VReScale $left 1]
 
     set c2 $P(2)
     set c1 [::Data::VAdd $c2 $nLeft -$M(cornerSize)]
     set c0 [::Data::VAdd $c1 $nTop -$M(cornerSize)]
     set c3 [::Data::VAdd $c0 $nLeft $M(cornerSize)]
     set cxy [concat $c0 $c1 $c2 $c3]
 
     # Width adjust box
     set w [::Data::VAdd $P(1) $left .5]
     set rSize2 [expr {$M(resizeSize)/2.0}]
     set w1 [::Data::VAdd $w $nLeft -$rSize2]
     set w0 [::Data::VAdd $w1 $nTop -$M(resizeSize)]
     set w3 [::Data::VAdd $w0 $nLeft $M(resizeSize)]
     set w2 [::Data::VAdd $w3 $nTop $M(resizeSize)]
     set wxy [concat $w0 $w1 $w2 $w3]
 
     # Height adjust box
     set h [::Data::VAdd $P(3) $top .5]
     set h2 [::Data::VAdd $h $nTop $rSize2]
     set h1 [::Data::VAdd $h2 $nLeft -$M(resizeSize)]
     set h0 [::Data::VAdd $h1 $nTop -$M(resizeSize)]
     set h3 [::Data::VAdd $h0 $nLeft $M(resizeSize)]
     set hxy [concat $h0 $h1 $h2 $h3]
 
     return [list $cxy $wxy $hxy]
 }
 ##+##########################################################################
 #
 # NorthArrow -- computes where north compass arrow should be positioned
 #
 proc ::ClipBox::NorthArrow {} {
     variable P
 
     set cornerOffset 35
     set fudgeFactor {0 15}
     set arrowLength {0 150}
 
     set dir [expr {$P(a,deg) >= 0 ? 1 : -1}]
     if {($P(a,deg) >= 0 && $P(a,deg) <= 90) || $P(a,deg) < -90} {
         set bisect [::Data::VBisect $P(1) $P(0) $P(3)]
         set pt $P(0)
     } else {
         set bisect [::Data::VBisect $P(2) $P(3) $P(0)]
         set pt $P(3)
     }
     set pt1 [::Data::VAdd $pt $bisect $cornerOffset]
     set top [::Data::VAdd $pt1 $fudgeFactor]
     set bot [::Data::VAdd $top $arrowLength $dir]
     if {$dir == -1} {lassign [list $bot $top] top bot}
     return [list $top $bot]
 }
 
 proc ::ClipBox::MouseEnter {W who} {
     variable M
     if {[info exists M(cursor,$who)]} {
         $W config -cursor $M(cursor,$who)
     }
 }
 proc ::ClipBox::MouseLeave {W who} {
     variable M
     if {$M(mousing)} return                     ;# Mouse down, don't change
     $W config -cursor {}
 }
 proc ::ClipBox::MouseDown {W who x y} {
     variable M
     variable P
 
     set M(xy) [list [$W canvasx $x] [$W canvasy $y]]
     set M(mousing) 1
     if {$who eq "corner"} {
         $W config -cursor $M(cursor,corner)
         ::ClipBox::FourCorners $W
 
         # Create pivot
         lassign $P(0) X Y
         set xy [list [expr {$X-10}] [expr {$Y-10}] [expr {$X+10}] [expr {$Y+10}]]
         $W create oval $xy -tag {BOX pivot} -fill black
         ::ClipBox::MouseMove $W $who $x $y
     }
 }
 proc ::ClipBox::MouseUp {W} {
     variable M
     set M(mousing) 0
     $W delete pivot
     $W config -cursor {}
 }
 proc ::ClipBox::MouseMove {W who x y} {
     variable M
 
     set x [$W canvasx $x]
     set y [$W canvasy $y]
     if {$who eq "corner"} {
         ::ClipBox::MouseSpin $W $who $x $y
     } elseif {$who eq "width" || $who eq "height"} {
         ::ClipBox::MouseResize $W $who $x $y
     } else {
         lassign $M(xy) bx by
         set M(xy) [list $x $y]
         set dx [expr {$x - $bx}]
         set dy [expr {$y - $by}]
         $W move BOX $dx $dy
         ::ClipBox::Onscreen $W
     }
 }
 ##+##########################################################################
 #
 # MouseSpin -- rotates clipbox to keep mouse point on the main diagonal
 #
 proc ::ClipBox::MouseSpin {W who x y} {
     variable P
 
     set v [::Data::VReScale [::Data::VSub [list $x $y] $P(0)] 1]
     set n [::Data::VDot [list 1 0] $v]
     set a1 [expr {acos($n)}]
     if {[lindex $v 1] < 0} { set a1 [expr {-$a1}] } ;# Quadrant check
     set a2 [expr {atan2($P(h), $P(w))}]
     set a3 [expr {$a1 - $a2}]
     set P(a,deg) [expr {$a3 * 180 / acos(-1)}]
     ::ClipBox::DrawClipBox $W
     ::ClipBox::Onscreen $W
 }
 ##+##########################################################################
 #
 # MouseResize -- resizes clipbox vertically or horizontally
 #
 proc ::ClipBox::MouseResize {W who x y} {
     variable P
     variable M
 
     ::ClipBox::FourCorners $W
     set top  [::Data::VSub $P(1) $P(0)]
     set left [::Data::VSub $P(3) $P(0)]
     set nTop  [::Data::VReScale $top 1]
     set nLeft [::Data::VReScale $left 1]
 
     if {$who eq "width"} {
         set p0 [::Data::VAdd $P(0) $left .5]
         set v [::Data::VSub [list $x $y] $p0]
         set w [::Data::VDot $nTop $v]
 
         if {$w < $M(minWidth)} return
         set P(w) $w
     } else {
         set p0 [::Data::VAdd $P(0) $top .5]
         set v [::Data::VSub [list $x $y] $p0]
         set h [::Data::VDot $nLeft $v]
 
         if {$h < $M(minHeight)} return
         set P(h) $h
     }
     ::ClipBox::DrawClipBox $W
     ::ClipBox::Onscreen $W
 }
 ##+##########################################################################
 #
 # Onscreen -- figures out if clipbox is off the screen at all
 #
 proc ::ClipBox::Onscreen {W} {
     variable P
 
     lassign [$W coords clip] x0 y0 x1 y1 x2 y2 x3 y3
     set l [expr {round([::Data::Min $x0 $x1 $x2 $x3])}]
     set r [expr {round([::Data::Max $x0 $x1 $x2 $x3])}]
     set t [expr {round([::Data::Min $y0 $y1 $y2 $y3])}]
     set b [expr {round([::Data::Max $y0 $y1 $y2 $y3])}]
 
     set cx0 [$W canvasx 0]
     set cy0 [$W canvasy 0]
     set cx1 [expr {$cx0 + [winfo width $W]}]
     set cy1 [expr {$cy0 + [winfo height $W]}]
 
     set onscreen 1
     if {$l < $cx0 || $t < $cy0 || $r > $cx1 || $b > $cy1} {
         set onscreen 0
     }
     $W itemconfig clip -fill $P(clr,$onscreen)
     return $onscreen
 }
 proc ::ClipBox::PointOnscreen {W pt} {
     lassign $pt x y
     set cx0 [$W canvasx 0]
     set cy0 [$W canvasy 0]
     set cx1 [expr {$cx0 + [winfo width $W]}]
     set cy1 [expr {$cy0 + [winfo height $W]}]
 
     return [expr {$x >= $cx0 && $x <= $cx1 && $y >= $cy0 && $y <= $cy1}]
 }
 ##+##########################################################################
 #
 # FourCorners -- fills in our data structures with clipbox's corners
 #
 proc ::ClipBox::FourCorners {W} {
     variable P
     foreach idx {0 1 2 3} {x y} [$W coords clip] {
         set P($idx) [list $x $y]
     }
 }
 ##+##########################################################################
 #
 # GetClipBoxSizes -- computes parameters needed to crop, rotate
 # and crop again the image
 #
 proc ::ClipBox::GetClipBoxSizes {W} {
     variable P
 
     ::ClipBox::FourCorners $W
     lassign $P(0) x0 y0; lassign $P(1) x1 y1; lassign $P(2) x2 y2; lassign $P(3) x3 y3
     set l [expr {round([::Data::Min $x0 $x1 $x2 $x3])}]
     set r [expr {round([::Data::Max $x0 $x1 $x2 $x3])}]
     set t [expr {round([::Data::Min $y0 $y1 $y2 $y3])}]
     set b [expr {round([::Data::Max $y0 $y1 $y2 $y3])}]
     #set P(bbox) [list $l $t $r $b]
     set P(bbox) [::ClipBox::World2Canvas $W $l $t $r $b]
 
     set dy [expr {$y1 - $y0}]
     set dx [expr {$x1 - $x0}]
     set dx2 [expr {$x3 - $x0}]
     set dy2 [expr {$y3 - $y0}]
 
     # Question: use values from p or recompute from coordinates???
 
     set P(a,rad) [expr {atan2($dy,$dx)}]
     set P(a,deg) [expr {$P(a,rad)*180/acos(-1)}]
     set P(w) [expr {round(hypot($dx,$dy))}]
     set P(h) [expr {round(hypot($dx2,$dy2))}]
 
     # R0 is topleft corner in the rotated image
     # R1 is bottomright corner in the rotated image
     set P(rx0) [expr {abs(round($dy2 * sin($P(a,rad))))}]
     set P(ry0) [expr {abs(round($dx * sin($P(a,rad))))}]
     set P(rx1) [expr {$P(rx0) + $P(w)}]
     set P(ry1) [expr {$P(ry0) + $P(h)}]
 }
 ##+##########################################################################
 #
 # World2Canvas -- translates world coordinates into canvas ones
 #
 proc ::ClipBox::World2Canvas {W args} {
     set x0 [$W canvasx 0]
     set y0 [$W canvasy 0]
     set result {}
     foreach {x y} $args {
         set x [expr {round($x - $x0)}]
         set y [expr {round($y - $y0)}]
         lappend result $x $y
     }
     return $result
 }
 ##+##########################################################################
 #
 # Snapshot -- extracts content of the clipbox, with the proper
 # cropping and rotating.
 #
 proc ::ClipBox::Snapshot {W} {
     variable P
 
     # Hide everything except compass north
     raise [winfo toplevel $W]
     $W lower BOX ; $W raise north
     update idletasks
 
     ::ClipBox::GetClipBoxSizes $W
     set snap [image create photo -data $W]
     set rot [image create photo]
     set chop [image create photo]
     $W raise BOX ; $W raise north
 
     set crop [eval ::ClipBox::SafeCrop $snap $P(bbox)]
     $rot copy $crop -rotate $P(a,deg)
     $chop copy $rot -from $P(rx0) $P(ry0) $P(rx1) $P(ry1)
 
     image delete $snap
     image delete $crop
     image delete $rot
 
     if {[::ClipBox::PointOnscreen $W $P(1)]} {  ;# Move clipbox forward
         set P(0) $P(1)
         ::ClipBox::DrawClipBox $W
     }
     return $chop
 }
 ##+##########################################################################
 #
 # SafeCrop -- crops image handling off image coordinates
 #
 proc ::ClipBox::SafeCrop {cimg left top right bottom} {
     set w [image width $cimg]
     set h [image height $cimg]
 
     set pad(l) [expr {$left < 0 ? -$left : 0}]
     set left [::Data::Max $left 0]
     set pad(t) [expr {$top < 0 ? -$top : 0}]
     set top [::Data::Max $top 0]
     set pad(r) [expr {$right > $w ? $right-$w : 0}]
     set right [::Data::Min $right $w]
     set pad(b) [expr {$bottom > $h ? $bottom-$h : 0}]
     set bottom [::Data::Min $bottom $h]
 
     set crop [image create photo]
     $crop copy $cimg -from $left $top $right $bottom
     set pimg [::ClipBox::PadImage $crop $pad(l) $pad(t) $pad(r) $pad(b)]
 
     return $pimg
 }
 ##+##########################################################################
 #
 # PadImage -- adds requested borders to the image
 #
 proc ::ClipBox::PadImage {img left top right bottom} {
     if {$left == 0 && $top == 0 && $right == 0 && $bottom == 0} {return $img}
 
     set w [expr {[image width $img] + $left + $right}]
     set h [expr {[image height $img] + $top + $bottom}]
 
     set tmp [image create photo -width $w -height $h]
     $tmp put yellow -to 0 0 $w $h
     $tmp copy $img -to $left $top
     image delete $img
     return $tmp
 }
 
 namespace eval ::ShowPics {
     variable S
     unset -nocomplain S
     image create bitmap ::bmp::up -data {
         #define up_width 11
         #define up_height 11
         static char up_bits = {
             0x00, 0x00, 0x20, 0x00, 0x70, 0x00, 0xf8, 0x00, 0xfc, 0x01, 0xfe,
             0x03, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00
         }
     }
     image create bitmap ::bmp::down -data {
         #define down_width 11
         #define down_height 11
         static char down_bits = {
             0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0xfe,
             0x03, 0xfc, 0x01, 0xf8, 0x00, 0x70, 0x00, 0x20, 0x00, 0x00, 0x00
         }
     }
     image create bitmap ::bmp::x -foreground white -data {
         #define X_width 11
         #define X_height 11
         static char X_bits = {
             0x04, 0x01, 0x8e, 0x03, 0xdf, 0x07, 0xfe, 0x03, 0xfc, 0x01, 0xf8,
             0x00, 0xfc, 0x01, 0xfe, 0x03, 0xdf, 0x07, 0x8e, 0x03, 0x04, 0x01
         }
     }
 }
 
 proc ::ShowPics::ShowImg {W} {
     variable S
     global I
 
     set img [::ClipBox::Snapshot $W]
     if {! [winfo exists .show]} {
         toplevel .show
         wm protocol .show WM_DELETE_WINDOW ::ShowPics::Cleanup
         wm title .show "Snap Shot Gallery"
         RightWindow .show $W
         #wm transient .show [winfo toplevel $W]
         unset -nocomplain S
     }
     set id [expr {1 + [llength [grid slaves .show]]}]
     set w .show.$id
     frame $w
     grid $w -sticky w
     if {$id > 1} { grid config $w -pady {10 0}}
 
     button $w.up -image ::bmp::up -takefocus 0 \
         -command [list ::ShowPics::Swap up $id]
     button $w.x -image ::bmp::x -bg red -takefocus 0 \
         -command [list ::ShowPics::DeleteRow $id]
     button $w.down -image ::bmp::down -takefocus 0 \
         -command [list ::ShowPics::Swap down $id]
     frame $w.right -bd 2 -relief solid
     ::ShowPics::OneImage $w.right $img $id
 
     set S($id,img) $img
     set S($id,txt) "<description for this map>"
     ::ShowPics::DoButtons
 
     grid $w.up $w.right -sticky s
     grid $w.x ^ -pady 5
     grid $w.down ^ -sticky n -pady [list 0 [winfo reqheight $w.right.txt]]
 
     grid rowconfigure $w {0 2} -weight 1
     grid columnconfigure $w 0 -pad 10
     raise .show
 }
 proc ::ShowPics::Cleanup {} {
     variable S
 
     destroy .show
     foreach arr [array names S *,img] {
         image delete $S($arr)
     }
     unset -nocomplain S
 }
 proc ::ShowPics::OneImage {w img id} {
     variable S
 
     set S($id,w) $w.img
     label $w.img -image $img -bd 0
     label $w.id -text "MAP $id" -font {Helvetica 12 bold} -anchor e
     entry $w.txt -font {Helvetica 12 bold} -justify c -bd 0 \
         -textvariable ::ShowPics::S($id,txt)
     pack $w.img -side top -fill both -expand 1
     pack $w.id -side right
     pack $w.txt -side left -fill both -expand 1
 }
 proc ::ShowPics::SwapRows {row1 row2} {
     variable S
 
     set txt $S($row1,txt)
     set S($row1,txt) $S($row2,txt)
     set S($row2,txt) $txt
 
     set img $S($row1,img)
     set S($row1,img) $S($row2,img)
     set S($row2,img) $img
     $S($row1,w) config -image $S($row1,img)
     $S($row2,w) config -image $S($row2,img)
 }
 proc ::ShowPics::Swap {dir which} {
     set other [expr {$dir eq "up" ? $which-1 : $which+1}]
     ::ShowPics::SwapRows $which $other
 }
 proc ::ShowPics::DeleteRow {which} {
     variable S
 
     set len [llength [array names S *,img]]
     for {set row $which} {$row < $len} {incr row} {
         ::ShowPics::SwapRows $row [expr {$row+1}]
     }
     destroy .show.$len
     image delete $S($len,img)
     array unset S $len,*
     ::ShowPics::DoButtons
     if {$len == 1} ::ShowPics::Cleanup
 }
 proc ::ShowPics::DoButtons {} {
     variable S
 
     set len [llength [array names S *,img]]
     if {$len == 0} return
     for {set i 1} {$i <= $len} {incr i} {
         .show.$i.up config -state normal
         .show.$i.down config -state normal
     }
     .show.1.up config -state disabled
     .show.$len.down config -state disabled
 }
 
 ################################################################
 #
 # Utility routines
 #
 namespace eval ::Data {}
 proc ::Data::Max {a args} {
     foreach arg $args {if {$arg > $a} { set a $arg}}
     return $a
 }
 proc ::Data::Min {a args} {
     foreach arg $args {if {$arg < $a} { set a $arg}}
     return $a
 }
 proc ::Data::VAdd {v1 v2 {scaling 1}} {
     lassign $v1 x1 y1; lassign $v2 x2 y2
     return [list [expr {$x1 + $scaling*$x2}] [expr {$y1 + $scaling*$y2}]]
 }
 proc ::Data::VSub {v1 v2} { return [::Data::VAdd $v1 $v2 -1] }
 proc ::Data::VReScale {v scaling} {
     lassign $v x y
     set len [expr {hypot($x,$y)}]
     return [list [expr {$x * $scaling / $len}] [expr {$y * $scaling / $len}]]
 }
 proc ::Data::VNormalTo {vv length} {
     lassign  $vv x y
     set len [expr {hypot($x,$y)}]
     set xx [expr {-$y * $length / $len}]
     set yy [expr {$x * $length / $len}]
     return [list $xx $yy]
 }
 proc ::Data::VBisect {p1 p2 p3} {
     set v1 [::Data::VReScale [::Data::VSub $p1 $p2] 1]
     set v2 [::Data::VReScale [::Data::VSub $p3 $p2] 1]
     set v [::Data::VReScale [::Data::VAdd $v1 $v2] 1]
     return $v
 }
 proc ::Data::VDot {v1 v2} {
     lassign $v1 x1 y1; lassign $v2 x2 y2
     return [expr {$x1*$x2 + $y1*$y2}]
 }
 
 proc RightWindow {w {W .}} {
     update idletasks
 
     set W [winfo toplevel $W]
     set y [expr {3 + [winfo y $W]}]              ;# Top of main window
     set x [expr {15 + [winfo x $W] + [winfo width $W]}] ;# Right side
     wm geom $w +$x+$y
 }
 
 ################################################################
 #
 # DEMO CODE BELOW
 #
 
 image create photo ::img::img -data {
     /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAP//////////////////////////////////////////
     ////////////////////////////////////////////2wBDAf//////////////////////////
     ////////////////////////////////////////////////////////////wAARCALrBEADASIA
     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
     dgaAAAlZyjUoAka1KAAAAH//2Q==
 }
proc About {} {
    set msg "Route Map Selection\nby Keith Vetter\n\n"
    append msg "This demonstrates a package that lets\n"
    append msg "select arbitrary rectangular areas of\n"
    append msg "canvas and to extract exactly that area.\n\n"

    append msg "You can move the selection by dragging it,\n"
    append msg "you can resize the selection by dragging\n"
    append msg "a resize button, and you can rotate the\n"
    append msg "selection by dragging the resize control\n"
    append msg "or by dragging with the 3rd mouse button.\n"

    tk_messageBox -icon info -message $msg
}

 ################################################################
 #
 # Demo code
 
 proc DoDisplay {} {
     bind all <F2> {console show}
     wm title . "Clip Box Demo"
     canvas .c -highlightthickness 0 -bd 0 \
         -width [image width ::img::img] -height [image height ::img::img]
     .c create image 0 0 -image ::img::img -anchor nw
     .c config -scrollregion [.c bbox all]
     button .chop -text "Take Snap Shot" -command [list ::ShowPics::ShowImg .c]
     if {! $::hasXPhoto} { .chop config -state disabled }
     button .about -text About -command About
     pack .c -side top
     #pack .chop .about -side left -pady 10 -expand 1 -padx 10
     pack .about -side right -padx 10 -pady 10
     pack .chop -side bottom -pady 10
 
     bind .c <2>          [bind Text <2>]         ;# Enable dragging w/ <2>
     bind .c <B2-Motion>  [bind Text <B2-Motion>]
 }
 
 DoDisplay
 wm geom . +1+1
 ::ClipBox::Go .c {35 135} -7 700 200
 set W .c
 
 return