

proc anno_init {w m cmap} {
   global anno_data

   if [info exist anno_data(gm,$m,$w)] {return ""}

   if {$cmap != ""} {
      set anno_data(gm,$m,$w) [anno_im -cmap $cmap -transform $m]
      $anno_data(gm,$m,$w) configure -lastviewer $w
   } else {
      set anno_data(gm,$m,$w) [anno_im -transform $m]
   }
   if {[info command $anno_data(gm,$m,$w)] != ""} {

  #   $anno_data(gm,$m,$w) configure -gone_with_viewer 1
  #     we will to see how to make this option work correct, for
  #     the time being, this obj will be deleted in vframe_cmd $w remove

      $w add_image $anno_data(gm,$m,$w)
      set anno_data(list,$m,$w) ""
      return $anno_data(gm,$m,$w)
   } else {
      mess "anno_init $w $m $camp: falied to create anno_im\n" red
      unset anno_data(gm,$m,$w)
      return ""
   }
}

proc anno_win_coord_axes {w} {
   global anno_data

   if ![info exist anno_data(gm,0,$w)] {return}

   set anno_gm $anno_data(gm,0,$w)
   if ![info exist anno_data(axes,$w)] {
      set ww [winfo width $w]
      set hh [winfo height $w]
      set xp 80
      if {3*$xp > $ww} {set xp [expr $ww / 4]}
      set yp [expr 3 * $hh / 4]
      set L [expr $hh / (4 + $hh / 100)]
      set anno_data(axes,$w) [$anno_gm create axis 1 #ff88ff $L $xp $yp]  
      set anno_data(axes_on,$w) 1
   } else {
      if {[$anno_gm isvalid $anno_data(axes,$w)] != ""} {
         $anno_gm remove $anno_data(axes,$w)
      }
      unset anno_data(axes,$w)
      set anno_data(axes_on,$w) 0
   }
}


proc anno_win_gvsize {w} {
   global anno_data v3p_vmax
 
   if ![info exist anno_data(gm,0,$w)] {return}
   if ![info exist v3p_vmax] {return}
 
   set anno_gm $anno_data(gm,0,$w)
   if ![info exist anno_data(gvsize,$w)] {
      set anno_data(gvsize,$w) [$anno_gm create gvsize 1 #7788ff v3p_vmax]
      set anno_data(gvsize_on,$w) 1
   } else {
      if {[$anno_gm isvalid $anno_data(gvsize,$w)] != ""} {
         $anno_gm remove $anno_data(gvsize,$w)
      }
      unset anno_data(gvsize,$w)
      set anno_data(gvsize_on,$w) 0
   }
}


proc anno_init_win {w wintitle bs_vN bb_vN be_vN} {
   global anno_data

   if {![winfo exist $w] || ([winfo class $w] != "Tdv_Viewer")} {
      error "Tdv_Viewer $w does not exist" 
      return ""
   }

   set anno_data(button_states,$w) $bs_vN
   set anno_data(button_bindings,$w) $bb_vN
   set anno_data(button_events,$w) $be_vN

   lappend anno_data(win_list) $wintitle $w
}

proc anno_reset_mouse_binding {w} {
    global anno_data

   if ![info exist anno_data(button_events,$w)] {return}

   if [info exist $anno_data(button_events,$w)] {
      unset $anno_data(button_events,$w)
   }

   upvar #0 $anno_data(button_states,$w) but_states
   upvar #0 $anno_data(button_bindings,$w) but_bindings

   if {[info exist but_states] && [info exist but_bindings]} {
      foreach bp $but_states bb $but_bindings { bind $w $bp $bb }
   }
   set but_states ""
   set but_bindings ""

   global tdv_win_type
   if {![info exist tdv_win_type($w)] || ($tdv_win_type($w) != "1d")} {
      if {[lsearch [bind $w <ButtonPress-2>] tdv_begin_op] != 0} {
         tdv_dynamics_bindings $w
      }
   }

   catch {banner "" $w; $w configure -cursor {left_ptr red white}}
}

proc anno_setup_mouse_binding {w} {
    global anno_data

    if ![info exist anno_data(button_events,$w)] {
       if {[anno_init_win $w Current button_states($w) \
                  button_bindings($w) button_events($w)] == ""} {
          return 0
       }
    }
    upvar #0 $anno_data(button_events,$w) but_var

    if [info exists but_var] {
       puts "mouse binding for window $w changed: Reset Mouse"

       anno_reset_mouse_binding $w
       catch {unset but_var}
    }

    upvar #0 $anno_data(button_states,$w) but_states
    upvar #0 $anno_data(button_bindings,$w) but_bindings

    foreach n {1 2 3} {
       foreach bp {ButtonPress ButtonRelease} {
          if {[bind $w <$bp-$n>] != ""} {
             lappend but_states <$bp-$n>
             lappend but_bindings [bind $w <$bp-$n>]
             bind $w <$bp-$n> ""
          }
       }
    }
    foreach bp {ButtonPress ButtonRelease Button1-Motion Button2-Motion} {
       lappend but_states <$bp>
       lappend but_bindings [bind $w <$bp>]
    }

    bind $w <ButtonPress> "set $anno_data(button_events,$w) \"%b %x %y\""
    bind $w <ButtonRelease> "set $anno_data(button_events,$w) \"-%b %x %y\""
    bind $w <Button1-Motion> "set $anno_data(button_events,$w) \"0 %x %y\""
    bind $w <Button2-Motion> "set $anno_data(button_events,$w) \"0 %x %y\""

    return 1
}


proc anno_create {what w m args} {
    global anno_data

    if ![info exist anno_data(gm,$m,$w)] {return ""}

    return [eval $anno_data(gm,$m,$w) create $what $args]
}

proc anno_action {what {rec 1} {stick_ptr 0} {an_tomove ""}} {
    global anno_data 

    if $anno_data(model) { error "not yet implemented" }

    set w $anno_data(win)
    set m $anno_data(model)    
    if ![info exist anno_data(gm,$m,$w)] {
	anno_init $w $m ""
	#error "$w $m need to be initialized for annotations"
	#return ""
    }
    set anno_gm $anno_data(gm,$m,$w)
    upvar #0 $anno_data(button_events,$w) but_var

    if {[anno_setup_mouse_binding $w] == 0} {return}

    set arr $anno_data(arrow)
    set params "$anno_data(linew) $anno_data(lcolor)"
    set last_anno ""
    set last_pos ""

    switch $what {
       line {
          banner "Click the left button to define the line, middle to\
                end it, and right to finish creating lines." $w
          catch {$w configure -cursor {crosshair red white}}
          set $anno_data(button_events,$w) ""
          set ok 1; set an ""; set line ""
          set params "$params $arr"
          set last_bt 0 

          while {$ok} {
            tkwait variable $anno_data(button_events,$w)
            if ![info exist $anno_data(button_events,$w)] {break}
            set val [set but_var]
            set x0 [lindex $val 1]; set y0 [lindex $val 2]

            switch -- [lindex $val 0] {
               1 {
                   if {$an == ""} {
                      append line " $x0 $y0"
                      set an [eval $anno_gm create line $params $line]
                      lappend last_anno $an
                   } elseif {$line != ""} {
                      set n2 [expr [llength $line] -2]
                      if {($last_bt == 0) || ($x0 != [lindex $line $n2]) \
                                          || ($y0 != [lindex $line end]) } {
                         eval $anno_gm modify $an $params $line $x0 $y0
                      }
                   }
                   catch {$w configure -cursor {pencil red white}}
                   set last_bt 1
                 }
              -1 { 
                   if {$an != ""} {
                      set n2 [expr [llength $line] -2]
                      if {($n2 < 1) || ($x0 != [lindex $line $n2]) \
                                    || ($y0 != [lindex $line end]) } {
                         append line " $x0 $y0"
                         eval $anno_gm modify $an $params $line
                      }
                   }
                   catch {$w configure -cursor {crosshair red white}}
                   set last_bt -1 
                 }
               0 {
                   if {($last_bt >= 0) || $stick_ptr} {
                      eval $anno_gm modify $an $params $line $x0 $y0
                   }
                   set last_bt 0
                 }
               2 {
                   if {$line != ""} {lappend last_pos $line}
                   set line ""; set an ""
                 }
               3 { 
                   set ok 0
                   if {$line != ""} {lappend last_pos $line}
                 }
             }
          }
       }
       utftext - text {
          set text [question_box .text "Text annotation" "Enter the text."]
          if {$what == "utftext"} { set text [ucode_scan_entry $text] }
          if {$text != ""} {
              banner "Select the location on the screen with the mouse." $w
              catch {$w configure -cursor {xterm red white}}
              set $anno_data(button_events,$w) ""
              while 1 {
                   tkwait variable $anno_data(button_events,$w) 
                   set pos "[lrange [set but_var] 1 2]"
                   if {[lindex [set but_var] 0] == 1} break
              }
              set a [eval $anno_gm create $what $pos $anno_data(lcolor) \
                        $anno_data(font) \{$text\} $anno_data(angle)]
              lappend last_anno $a
              lappend last_pos  $pos
          }
       }
       pixmap {
          set file [futil_get_file "Select a PPM file." . "" *.ppm]
          if {$file != ""} {
	     banner "Select the location on the screen with the mouse." $w
             catch { $w configure -cursor {crosshair red white}}
             set $anno_data(button_events,$w) ""
             while 1 {
                  tkwait variable $anno_data(button_events,$w)
                  set pos "[lrange [set but_var] 1 2]"
                  if {[lindex [set but_var] 0] == 1} break
             }
             set a [eval $anno_gm create pixmap $pos \"$file\"]
             lappend last_anno $a
             lappend last_pos  $pos
          }
       }
       cmap {
          set cmp ""
          if {([info command v3p_colormap_cmd] == "") || \
                   ([set cmp [v3p_colormap_cmd choose]] == "")} {
             anno_reset_mouse_binding $w
             return ""
          } else {
             banner "Select the location on the screen with the mouse." $w
             catch { $w configure -cursor {crosshair red white}}
             set $anno_data(button_events,$w) ""
             while 1 {
                  tkwait variable $anno_data(button_events,$w)
                  set pos "[lrange [set but_var] 1 2]"
                  if {[lindex [set but_var] 0] == 1} break
             }
             set xp [lindex $pos 0]
             set yp [lindex $pos 1]

             set ww [expr 10 + 3 * [winfo width $w] / 80]
             if {$ww > 40} {set ww 40}
             set h1 [winfo height $w] 
             if {$h1 < 160} {
                set hh [expr $h1 - 16]
             } elseif {$h1 > 720} {
                set hh 280
             } else {
                set hh [expr 100 + $h1 / 4]
             }

             set a [$anno_gm create cmap $cmp $xp [expr $yp + $hh] \
                                   -type 0 0 0 0 -size $ww $hh]
             lappend last_anno $a
             lappend last_pos  $pos
          }
       }
       circle {
          banner "Select the center on the screen with the mouse." $w
          catch {$w configure -cursor {crosshair red white}}

          set $anno_data(button_events,$w) ""
          while 1 {
              tkwait variable $anno_data(button_events,$w)
              set pos "[lrange [set but_var] 1 2]"
              if {[lindex [set but_var] 0] == 1} break
          }
          set pos2 $pos
          set a [eval $anno_gm create circle $params $pos $pos2 0]
          catch {$w configure -cursor {bottom_side red white}}
          lappend last_anno $a
          while 1 {
              tkwait variable $anno_data(button_events,$w)
              set pos2 "[lrange [set but_var] 1 2]"
              eval $anno_gm modify $a $params $pos $pos2 0
              if {[lindex [set but_var] 0] < 0} break
          }
          lappend last_pos $pos $pos2 
       }
       box {
          banner "Drag the box with the left button." $w

          catch {$w configure -cursor {crosshair red white}}
          set $anno_data(button_events,$w) ""
          while 1 {
              tkwait variable $anno_data(button_events,$w)
              set pos "[lrange [set but_var] 1 2]"
              if {[lindex [set but_var] 0] == 1} break
          }
          set pos2 $pos
          set a [eval $anno_gm create box $params $pos $pos2]
          catch {$w configure -cursor {bottom_right_corner red white}}
          lappend last_anno $a
          while 1 {
             tkwait variable $anno_data(button_events,$w)
             set pos2 "[lrange [set but_var] 1 2]"
             eval $anno_gm modify $a $params $pos $pos2
             if {[lindex [set but_var] 0] < 0} break
          }
          lappend last_pos $pos $pos2
       }
       oneline {
          banner "Drag the line with the left button." $w
          set params "$params $arr"

          catch {$w configure -cursor {crosshair red white}}
          set $anno_data(button_events,$w) ""
          while 1 {
              tkwait variable $anno_data(button_events,$w)
              set pos "[lrange [set but_var] 1 2]"
              if {[lindex [set but_var] 0] == 1} break
          }
          set a [eval $anno_gm create line $params $pos]
          catch {$w configure -cursor {pencil red white}}
          lappend last_anno $a
          set pos2 $pos
          while 1 {
             tkwait variable $anno_data(button_events,$w)
             set pos2 "[lrange [set but_var] 1 2]"
             eval $anno_gm modify $a $params $pos $pos2
             if {[lindex [set but_var] 0] < 0} break
          }
          lappend last_pos $pos $pos2
       }
       polygon {
          banner "Click the left button to define nodes, middle to\
                end it, and right to finish creating polygons." $w
          catch {$w configure -cursor {crosshair red white}}

          set $anno_data(button_events,$w) ""
          set pos ""; set line ""
          set ok 1; set an ""
          set params "$params 0"
          set last_bt 0

          while {$ok} {
             tkwait variable $anno_data(button_events,$w)
             if ![info exist $anno_data(button_events,$w)] {break}
             set val [set but_var]
             set x0 [lindex $val 1]; set y0 [lindex $val 2]
             set pos "$x0 $y0"

             switch -- [lindex $val 0] {
               1 {
                   if {$an == ""} {
                      append line " $pos"
                      set an [eval $anno_gm create line $params $pos $line]
                      lappend last_anno $an
                   } else {
                      set n2 [expr [llength $line] -2]
                      if {($last_bt == 0) || ($x0 != [lindex $line $n2]) \
                                          || ($y0 != [lindex $line end]) } {
                         eval $anno_gm modify $an $params $pos $line $pos
                      }
                   }
                   set last_bt 1
                 }
              -1 {
                   if {$an != ""} {
                      set n2 [expr [llength $line] -2]
                      if {($n2 < 1) || ($x0 != [lindex $line $n2]) \
                                    || ($y0 != [lindex $line end]) } {
                         append line " $pos"
                         eval $anno_gm modify $an $params $pos $line
                      }
                   }
                   set last_bt -1
                 }
               0 {
                   if {($last_bt >= 0) || $stick_ptr} {
                      eval $anno_gm modify $an $params $pos $line $pos
                   }
                   set last_bt 0
                 }
               2 {
                    if {$line != ""} { lappend last_pos [append pos $line] }
                    set pos ""; set line ""; set an ""
                 }
               3 {
                    if {$line != ""} { lappend last_pos [append pos $line] }
                    set ok 0
                 }
             }
          }
       }
       mark {
          banner "Select the location on the screen with the left button;\
                      right = finish." $w
          catch {$w configure -cursor {crosshair red white}}
          set ok 1
          set $anno_data(button_events,$w) ""
          while {$ok} {
             tkwait variable $anno_data(button_events,$w)
             if ![info exist $anno_data(button_events,$w)] {break}
             switch -- [lindex [set but_var] 0] {
                1 {
                    set pos "[lrange [set but_var] 1 2]"
                    set a [eval $anno_gm create mark $params $pos \
                                 $anno_data(marksize) $anno_data(stype) \
                                 $anno_data(symbol_fill)]
                    lappend last_anno $a
                    lappend last_pos $pos
                  }
                2 - 3 {set ok 0}
             }
          }
       }
       pick {
          banner "Select the annotations with left button,\
                     confirm = middle/right." $w
          catch {$w configure -cursor {hand2 red white}}
          set $anno_data(button_events,$w) ""
          set a_picked ""
          while 1 {
             tkwait variable $anno_data(button_events,$w)
             if ![info exist $anno_data(button_events,$w)] {
                if {$a_picked != ""} {
                   if [info exists a_color] {
                      $anno_gm lowlight $a_picked $a_color
                      unset a_color
                   }
                   lappend last_anno $a_picked
                }
                break
             }
             set val [set but_var]
             set x0 [lindex $val 1]; set y0 [lindex $val 2]
             set ptr_status [lindex $val 0]
             if {$ptr_status >= 1} {
                if {$a_picked != ""} {
                   if [info exists a_color] {
                      $anno_gm lowlight $a_picked $a_color
                      unset a_color
		   }
                }
                if {$ptr_status > 1} {
                   lappend last_anno $a_picked
                   break
                }
             }      
             if {$ptr_status == 1} {
                set a_picked [$anno_gm select $x0 $y0]
                if {$a_picked != ""} {
                   set a_color [lindex [$anno_gm highlight $a_picked] 0]
                }
             }
          }
       } 
       move {
          banner "Select and move the annotations with the left button,\
                    middle/right = done" $w
          catch {$w configure -cursor {hand2 red white}}
          set $anno_data(button_events,$w) ""
          tkwait variable $anno_data(button_events,$w)
          while 1 {
             if ![info exist $anno_data(button_events,$w)] {break}
             set ok 0
             set val [set but_var]
             set x0 [lindex $val 1]; set y0 [lindex $val 2]
             set ptr_status [lindex $val 0]
             set a ""
             if {$ptr_status == 1} {
                if {$an_tomove != ""} {
                   set a $an_tomove
                } else {
                   set a [$anno_gm select $x0 $y0]
                } 
                if {$a != ""} {
                   set a_color [lindex [$anno_gm highlight $a] 0]
                   lappend last_anno $a
                   set ok 1
                   catch {$w configure -cursor {fleur red white}}
                }
             } elseif {$ptr_status > 1} {
                break
             }
             while {$ok} {
                tkwait variable $anno_data(button_events,$w)
                set val [set but_var]
                set xp [lindex $val 1]; set yp [lindex $val 2]
                set dx [expr $xp -$x0]; set dy [expr $yp - $y0]
                set b [$anno_gm move $a $dx $dy]
                if {$b != $a} {break}
                set x0 $xp; set y0 $yp
                if {[lindex $val 0] != 0} {
                   if [info exists a_color] {
                      $anno_gm lowlight $a $a_color
                   }
                   catch {unset a_color}
                   break
                }
             }
             if {[info exist anno_data(picked_anno)] && \
                    ($anno_data(picked_anno) == $a)} {
                update_anno_pick $a
             }
             catch {$w configure -cursor {hand2 red white}}
             tkwait variable $anno_data(button_events,$w)
          }
       }
       delete {
          banner "Select the annotations to delete with left button,\
                middle button = confirm, right = cancel." $w

          catch {$w configure -cursor {draped_box red white}}
          set $anno_data(button_events,$w) ""
          set to_del ""
          set ok 1
          while {$ok} {
             tkwait variable $anno_data(button_events,$w)
             if ![info exist $anno_data(button_events,$w)] {break}
             set val [set but_var]
             switch -- [lindex $val 0] {
                1 {
                    set a [$anno_gm select [lindex $val 1] [lindex $val 2]]
                    set p [lsearch $anno_data(list,$m,$w) $a]
                    if {$p < 0} {set a ""}
                    if {$a != ""} {
                       if {[lsearch $to_del $a] < 0} {
                           set a_color [$anno_gm highlight $a]
                           lappend to_del $a
                       }
                    }
                  }
                2 {
                    foreach a $to_del {
                       $anno_gm remove $a
                       set p [lsearch $anno_data(list,$m,$w) $a]
                       if {$p >= 0} {
                          set anno_data(list,$m,$w) \
                                  [lreplace $anno_data(list,$m,$w) $p $p]
                       }
                    }
                    set ok 0
                  }
                3 { set ok 0 }
             }
          }
       }
       undo {
          set na [llength $anno_data(list,$m,$w)]
          incr na -1
          set a [lindex $anno_data(list,$m,$w) $na]
          if {[$anno_gm isvalid $a] != ""} { 
             $anno_gm remove $a
             incr na -1
             set anno_data(list,$m,$w) [lrange $anno_data(list,$m,$w) 0 $na]
          }
       }
    }
    anno_reset_mouse_binding $w

    if { $rec  && ($what != "move") && ($what != "pick")} {
       foreach a $last_anno {
          lappend anno_data(list,$m,$w) $a
       }
    }
    return [list $last_anno $last_pos]
}


proc get_2d_pts_on_anno {w how npts {keep_anno 0} {pargs ""}} {
   global anno_data

   if ![info exist anno_data(gm,0,$w)] {
       error "$w need to be initialized for annotations"
       return ""
   }

   set anno_data(win) $w
   set anno_data(model) 0

   set used_symm [$w get -use_symmtry]
   if {$used_symm} { $w configure -use_symmtry 0; $w redraw }

   set pos ""
   set annos ""
   switch -- $how {
      pts {
         if {$pargs == ""} {
            set rr [anno_action mark 0]
            append annos [lindex $rr 0]
            set pos [lindex $rr 1]
         } else {
            set pos $pargs
         }
      }
      circle {

         puts "pargs = $pargs"

         if {$pargs == ""} {
            set rr [anno_action circle 0]
            append annos [lindex $rr 0]
            set pargs [lindex $rr 1]
         }

         puts "pargs = $pargs"

         set x1 [lindex [lindex $pargs 0] 0]
         set y1 [lindex [lindex $pargs 0] 1]
         set x2 [lindex [lindex $pargs 1] 0]
         set y2 [lindex [lindex $pargs 1] 1]
         if {($x1 == "") || ($x2 == "") || ($y1 == "") || ($y2 == "")} {
            return ""
         }
         set dist [expr sqrt(($x2 - $x1) * ($x2 - $x1) + \
                        ($y2 - $y1) * ($y2 - $y1))]
         for {set i 0} {$i <= $npts} {incr i} {
             set angle [expr 6.28318530718 * double($i) / $npts]
             set x [expr $x1 + $dist * cos($angle)]
             set y [expr $y1 + $dist * sin($angle)]
             lappend pos "$x $y"
         }
      }
      fcircle {
         if {$pargs == ""} {
            set rr [anno_action circle 0]
            append annos [lindex $rr 0]
            set pargs [lindex $rr 1]
         }
         set x1 [lindex [lindex $pargs 0] 0]
         set y1 [lindex [lindex $pargs 0] 1]
         set x2 [lindex [lindex $pargs 1] 0]
         set y2 [lindex [lindex $pargs 1] 1]
         if {($x1 == "") || ($x2 == "") || ($y1 == "") || ($y2 == "")} {
            return ""
         }
         set dist [expr sqrt(($x2 - $x1) * ($x2 - $x1) + \
                        ($y2 - $y1) * ($y2 - $y1))]
         set nsp $npts
         set n [expr 0.5 + sqrt(($nsp * 4 + 23.0)/3.0) * 0.5 ]
         set n [expr int($n)]
         set a [expr $dist / ($n - 1.0)]
         set a1 [expr $a * 0.8660254037844386]
         set a2 [expr $a /2.0]
         set theta 0
         for {set k 0} {$k < 6} {incr k} {
            set cos_t [expr cos($theta)]
            set sin_t [expr sin($theta)]
            set eta0 $a; set xsi 0
            for {set j 0} {$j < ($n-1)} {incr j} {
               set eta $eta0
               for {set i 0} {$i < ($n-$j-1)} {incr i} {
                  set x [expr $x1 + $cos_t * $xsi + $sin_t * $eta]
                  set y [expr $y1 - $sin_t * $xsi + $cos_t * $eta]
                  lappend pos "$x $y"

                # draw pt ($x $y)

                  set eta [expr $eta + $a]
               }
               set xsi [expr $xsi + $a1]
               set eta0 [expr $eta0 + $a2]
            }
            set theta [expr $theta + 1.0471975511965976]
         }
         lappend pos "$x1 $y1"
      }
      fbox {
         if {$pargs == ""} {
            set rr [anno_action box 0]
            append annos [lindex $rr 0]
            set pargs [lindex $rr 1]
         }
         set x1 [lindex [lindex $pargs 0] 0]
         set y1 [lindex [lindex $pargs 0] 1]
         set x2 [lindex [lindex $pargs 1] 0]
         set y2 [lindex [lindex $pargs 1] 1]
         if {($x1 == "") || ($x2 == "") || ($y1 == "") || ($y2 == "")} {
            return ""
         }
         set nsp $npts
         set lx [expr $x2 - $x1]
         set ly [expr $y2 - $y1]
         set a [expr sqrt(abs($lx * $ly) / ($nsp - 2 * sqrt($nsp) +1.0))]
         set nx [expr $lx / $a]; set ny [expr $ly / $a]

         if {$nx >= 0} {set nx [expr int($nx) +1]; set ax $a} \
         else {set nx [expr int(-$nx) +1]; set ax -$a}

         if {$ny  >= 0} { set ny [expr int($ny) +1]; set ay $a } \
         else { set ny [expr int(-$ny) +1]; set ay -$a }

         set x1s [expr ($x1 + $x2 - $ax * ($nx -1))/2]
         set y1s [expr ($y1 + $y2 - $ay * ($ny -1))/2]

         for {set j 0} {$j < $ny} {incr j} {
            for {set i 0} {$i < $nx} {incr i} {
                set x [expr $x1s + $i * $ax]
                set y [expr $y1s + $j * $ay]
                lappend pos "$x $y"

               # draw the pt "$x $y"
            }
         }
      }
      oneline {
         if {$pargs == ""} {
            set rr [anno_action oneline 0]
            append annos [lindex $rr 0]
            set pargs [lindex $rr 1]
         }
         set x1 [lindex [lindex $pargs 0] 0]
         set y1 [lindex [lindex $pargs 0] 1]
         set x2 [lindex [lindex $pargs 1] 0]
         set y2 [lindex [lindex $pargs 1] 1]
         if {($x1 == "") || ($x2 == "") || ($y1 == "") || ($y2 == "")} {
            return ""
         }
         set nsp $npts
         set dx [expr ($x2 - $x1) / ($nsp - 1.0)]
         set dy [expr ($y2 - $y1) / ($nsp - 1.0)]
         for {set i 0} {$i < $nsp} {incr i} {
            set x [expr $x1 + $dx * $i]
            set y [expr $y1 + $dy * $i]
            lappend pos "$x $y"
         }
      }
      box {
         if {$pargs == ""} {
            set rr [anno_action box 0]
            append annos [lindex $rr 0]
            set p0 [lindex [lindex $rr 1] 0]
            set p1 [lindex [lindex $rr 1] 1]
            set x0 [lindex $p0 0]
            set y0 [lindex $p0 1]
            set x1 [lindex $p1 0]
            set y1 [lindex $p1 1]
            if {($x0 != "") && ($x1 != "") && ($y0 != "") && ($y1 != "")} {
               if {$x0 > $x1} { set r $x0; set x0 $x1; set x1 $r }
               if {$y0 < $y1} { set r $y0; set y0 $y1; set y1 $r }
               set ps ""
               lappend ps $x0 $y0
               lappend ps $x1 $y0
               lappend ps $x1 $y1
               lappend ps $x0 $y1
               lappend ps $x0 $y0
               lappend pargs $ps
            }
         }
      }
      polygon {
         if {$pargs == ""} {
            set rr [anno_action polygon 0]
            append annos [lindex $rr 0]
            set pargs [lindex $rr 1]

            set p0 [lindex $pargs 0]
            set x0 [lindex $p0 2]
            set y0 [lindex $p0 3]
            set x1 [lindex $p0 4]
            set y1 [lindex $p0 5]
            set x2 [lindex $p0 6]
            set y2 [lindex $p0 7]

            if {($x0 != "") && ($x1 != "") && ($x2 != "") && \
                ($y0 != "") && ($y1 != "") && ($y2 != "")} {
               set D [expr ($x1 - $x0) * $y0 - ($y1 - $y0) * $x0]
               set A [expr ($x1 - $x0) * $y2 - ($y1 - $y0) * $x2]

               if {$A > $D} {
                  set pp ""
                  foreach ss $pargs {
                     set rr ""
                     foreach {x y} $ss {
                        set rr [linsert $rr 0 $x $y]
                     }
                     set pp [linsert $pp 0 $rr]
                  }
                  set pargs $pp
               }
            }
         }
      }
      lines {
         if {$pargs == ""} {
            set rr [anno_action line 0]
            append annos [lindex $rr 0]
            set pargs [lindex $rr 1]
         }
      }
   }

   if {($pos == "") && ($pargs != "")} {
      if {$npts < 3} {
         foreach ss $pargs {
            foreach {x y} $ss {
               lappend pos "$x $y"
            }
         }
      } else {
         set larc ""; set larc_sum 0
         foreach ss $pargs {
            set as 0
            set x0 [lindex $ss 0]; set y0 [lindex $ss 1]
            foreach {x1 y1} [lrange $ss 2 end] {
               set as [expr $as + sqrt(($x1 - $x0) * ($x1 - $x0) + \
                        ($y1 - $y0) * ($y1 - $y0))]
               set x0 $x1;  set y0 $y1
            }
            lappend larc $as
            set larc_sum [expr $larc_sum + $as]
         }

         set nn [llength $pargs]
         set darc [expr $larc_sum / ($npts -1.0)]

         for {set i 0} {$i < $nn} {incr i} {
            set ds [lindex $larc $i]
            set dd [expr $ds / $darc]
            set nd [expr int( $dd )]
            if {$nd < 3} {set nd 3}
            set dd [expr $ds / ($nd - 1.0)]

            set ss [lindex $pargs $i]
            set x0 [lindex $ss 0]; set y0 [lindex $ss 1]
            lappend pos "$x0 $y0"

            set as $dd
            foreach {x1 y1} [lrange $ss 2 end] {
               set bs [expr sqrt(($x1 - $x0) * ($x1 - $x0) + \
                        ($y1 - $y0) * ($y1 - $y0))]
               while {$as <= $bs} {
                  set x [expr $x0 + ($x1 - $x0) * $as / double($bs)]
                  set y [expr $y0 + ($y1 - $y0) * $as / double($bs)]
                  lappend pos "$x $y"

                  set as [expr $as + $dd]
               }
               set as [expr $as - $bs]

               set x0 $x1;  set y0 $y1
            }
            if {$as < [expr 0.1 * $dd]} {
               lappend pos "$x0 $y0"
            }
         }
      }
   }

   if {!$keep_anno} {
      foreach a $annos {
         $anno_data(gm,0,$w) remove $a
      }
   } else {
      if ![info exist anno_data($w,2d_annos)] {
         set anno_data($w,2d_annos) ""
      }
      eval lappend anno_data($w,2d_annos) $annos
   }
   if {$used_symm} { $w configure -use_symmtry $used_symm }

   return $pos
}
