Rotated canvas text


WikiDbImage rotatext.jpg

Tom Krehbiel shared the following interesting code in the Tcl chatroom, which may display a large E in various rotation angles (X only, not on all Linuxes...):

tomk: Are you aware that it is possible to rotate single character in a Tk canvas?

kennykb: Rotate single char in Tk canvas? How?

tomk: I have some code that someone (smarter than me) posted. I don't remember when or who. You want me to sent you a copy?

kennykb: Sure, glad to look at it. This supposed to be Tcl code? Or is someone changing the canvas implementation?


 proc rotmatrix {size angle} {
    set size [expr {double($size)}]
    set angle [expr {double($angle)*acos(0.0)/90.0}]; # In radians
    set c [expr {$size*cos($angle)}]
    set s [expr {$size*sin($angle)}]
    # Due to Tk's XLFD (X Logical Font Description)
    # parser, we need to round values
    set s [format "\[%.f %.f %.f %.f\]" $c [expr {-$s}] $s $c]
    regsub -all -- "-" $s ~ s
    return $s
 }
 pack [scrollbar .vs -orient vertical -command {.c yview}] -side right -fill y
 pack [scrollbar .hs -orient horizontal -command {.c xview}] -side bottom -fill x
 pack [canvas .c -bg white -xscrollcommand {.hs set} -yscrollcommand {.vs set}]\
        -side left -expand 1 -fill both
 set nb 16
 set size 24
 set size 64
 set text "The Quick Brown Fox jumps over the Lazy Black Dog"
 set text "E"
 .c configure -scrollregion [list -1000 0 1000 [expr {$size*$nb*2}]]
 set x 100
 for {set i 0} {$i < 16} {incr i} {
    set y [expr {10+$i*$size*2}]
    set angle [expr {360.0*$i/$nb}]
    .c create text $x $y -text [format "%.1f°    " $angle] -anchor ne -font \
       -adobe-times-medium-r-*-*-$size-*-*-*-*-*-*-*
    .c create text $x $y -text $text -anchor nw -font \
       -adobe-times-medium-r-*-*-[rotmatrix $size $angle]-*-*-*-*-*-*-*
    .c create rectangle [expr {$x-2}] [expr {$y-2}] [expr {$x+2}] [expr {$y+2}]\
       -outline black -fill red
 }

suchenwi: WOW! YES!

tomk: I added the 64 font size and the text "E". If you remove them you get a string version.

kennykb Guys: Before you get too excited, this is Unix-only and not supported by every X server.

suchenwi: Works here on Solaris via Reflection, but not native on PC - there the E is only scaled smaller. But it's definitely only recommendable for a single letter...

bschwarz: doesn't work on linux

kennykb: The functionality is X, mostly. The comment about Tk's XLFD parser has to do with whether Tk will recognize the string as an XLFD or a Tk font name.

trb: works on my linux: 2.2.18. XFree86 v 3360 tk 8.3


DKF: Note that the above does not work with an IRIX Xserver.


The BLT extension can also rotate text on a canvas


GJS Wouldn't all this be easier if TK supported a rotate command. The syntax would be simple I think. Use a -rotate option on some of the widgets or pathname rotate

  pathName create type cordList -rotate degrees
  pathName rotate tagOrId ?degrees?

In the second form if degrees was omitted the command would return the current rotation. Acceptable values for degrees should be integers ranging from -360 to 360, positive values rotating clockwise, negative values rotating counter-clockwise, 0 being defalualt. 360 and -360 should be understood as 0.


KBK 2008-11-03 I tried an entirely different approach to rotated text on a canvas as a "weekend fun project." Results are here: https://wiki.tcl-lang.org/_repo/hershey/ It's ugly, but might get somone out of occasional trouble.


DKF 2008-11-03: I've been looking through the Tk font code (as part of trying to implement TIP#119) and that contains comments about what I now know are matrices, saying that the author (JO?) didn't know what they meant and so hacked their way past them.

DKF 2008-11-22: And Tk now knows how to draw rotated text directly, so long as you're using a canvas text item and set the -angle on it.

lm 2008/11/25: ABSOLUTLY GREAT ! I really need that for my app. I'm currently using images with rotated text inside (pixane package) but it takes an enormous amount of time. Donal, is it possible to have that into Tcl/Tk 8.5.6 ??

DKF: It should be possible to backport, as it's pretty isolated from everything else (i.e. it doesn't touch other things heavily). But I've definitely not got time to do it.