Rotated Text Font

Keith Vetter 2007-09-17 : A while ago I needed text angled 90 degrees down for labels on a graph. Initially I used the code from Quick Photo Rotation, but then I decided to cache the results, thereby essentially creating my own rotated font.

WikiDbImage rotafont.jpg

It works by combining gif images of individual letters creating an image with the requested text at a 90 degree rotation. Not very flexible, but fits my needs.


 ##+##########################################################################
 #
 # rotatedFont.tcl -- simple vertical font 
 # by Keith Vetter
 #
 
 package require Tk
 
 namespace eval ::RotatedFont {
    variable ALPHA                              ;# Rotated text
    array set ALPHA {
        32 R0lGODlhDwADAJEAANnZ2f///////////yH5BAEAAAAALAAAAAAPAAMAAAIGhI+py00FADs=
        33 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIPhI95EUdxCH4EUHyCj3kFADs=
        34 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIWhI+pF0EhfLSIyMyUDIkJHy0iMvOQAgA7
        35 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIfhBNhYWZmAIlN8DEsICiEHxEWd2dIbIKPYQFBIXzMKwA7
        36 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIdhI+JEUYx4UNchFEIm+JjEOywiAuCDxFhQSF8TCwAOw==
        37 R0lGODlhDwAPAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAA8AAAI5hI+pEEEJ4SPFJ/gXGGgUgOITfAiLCArhXwQiHoXwMSMSKQ5AEHyg+ABB8OMg7o7iE3yMiEBEhAwpADs=
        38 R0lGODlhDwALAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAsAAAIxhI+JEUHwESg2wceIi6AQPoRRfIIfEBFHIXyIsDAK4UcEBFBC+BAWgWgkAATBR4jMAgA7
        39 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAINhI+pF0EhfLSIyMxDCgA7
        40 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIShBmf4BvFN4IfcRdBMOLuIAguADs=
        41 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIRDOFjYAQaJYRP8Y3gG8Un+AUAOw==
        42 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIWhI+pF5sUhODjRUQQfAwIRDQSwsfMAgA7
        43 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIWhA+BiEYhfMTIBIofBB8hMpFC+IiRVgA7
        44 R0lGODlhDwADAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAMAAAIMhI8JAUEhfLSIyKQCADs=
        45 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIMhB13d0YhfMTIzERSADs=
        46 R0lGODlhDwADAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAMAAAIKhI95EapAEsLHAgA7
        47 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAINhBMEHzMiMpPEhI8ZVwA7
        48 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIchEHxg+ADxT+CH3cQdxTCh0Cj+EfwgeIHwcfEAgA7
        49 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIVhI95oUAhfIp/BJ/iH8EPgo+py0kFADs=
        50 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIihGMGYWZGEsKOO4igAAARBD8C4oJC+BFGsQl+xEUEwcfEAgA7
        51 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIhhBNmYWZGEsKOO4ijABEEPyzCgkL4QPGN4ENEWFAIHxMLADs=
        52 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIbhB1xdwcUhOCjhUUQfKP4RvCB4h/Bt0BERCQFADs=
        53 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIjhBMWZmZGEoAZwYe4CKCE8OMiICiEDwERQUgIvkXEBcHHvAIAOw==
        54 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIghEGxCf5R/CD4FhgRBB8CA4JC+BQfIAg+REQchfAxrwAAOw==
        55 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIchH8RiGiUEH7EWQTBt4iwoBA+QkQEwceLyMwjBQA7
        56 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIghBEREEEhfKD4R/DjIiwIfljEBcGn+EfwISIsKISPiQUAOw==
        57 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIfhGMQEUHwIYziE/wIiAMK4UNEYBB8o/hB8I9iE3xMLAA7
        58 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIOhI95EUYJ4V+ERRB8TC0AOw==
        59 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIRhI8JAUEBIgi+RYQFhfAxtQAAOw==
        60 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIbhA+BiEBBCD5aQGQCCQBB8DEuEIFC2HF3dwekADs=
        61 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIZhB8Qd3cUhOCjBUSmkSAEHy0gMo0EIfiYWgA7
        62 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIZhBFncXcUAILgY1wgHgUh+GgBkXkkhI+pUAA7
        63 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIbhI+pF0HwIQIjKIQfARFHIXyk2AQfISIyE5ECADs=
        64 R0lGODlhDwAMAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAwAAAJEhI95FJ/gW6AFGgWICACgAAABQLEBIAAIAQQABAUIAAggIAAQABQAAoBiA0AAEAIIAAgKEAAAQUDMIMyMAlBsgm+BeAUAOw==
        65 R0lGODlhDwAJAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAkAAAImhEPwESMi00iAiCD4aGERBB8DIoJC+AEUm+AbxSb4GIGIQCF8hAIAOw==
        66 R0lGODlhDwAJAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAkAAAInhGNmEGZG4h/Bp/hH8OPi4o4CQABAEPy4CAuCT/GP4ENEWFAIHxMLADs=
        67 R0lGODlhDwAJAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAkAAAIjhI+ZFJvgH8UPgg8RCEEh/LiDuKMQPgRaoFEI3wIjguBjXgEAOw==
        68 R0lGODlhDwAJAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAkAAAIkhGNmEGZG4h/Bp/hH8OMO4o5C+BBoEQQ74g4ofhD8o9gEHzMLADs=
        69 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIghGNmEGZG4h/Bp/hH8OPi4o4CRARAEPy4g7ijhLAjrgAAOw==
        70 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIchGNmEGZG4h/Bp/hH8OPi4u5IDAiCjxiZRwkACgA7
        71 R0lGODlhDwAJAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAkAAAInhI+ZFJvgH8UPgg8RCEEh/LiDuKMAAQAQBD8i4oLgW0RYUEL4F4gFADs=
        72 R0lGODlhDwAJAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAkAAAIlhGNmEGZG4h/Bp/hH8OPi4u4ACeFjXFwQfIp/BJ/iH8GPO4ijAgA7
        73 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIRhGNmEGZG4h/Bp/hH8OMO4qgAOw==
        74 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIahBFxd0cx4aNFJlIIHwKN4h/BB4pvBB8xrgAAOw==
        75 R0lGODlhDwAJAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAkAAAIohGNmEGZG4h/Bp/hH8OPi4u5ITPgXEGEUhOBHxEFQCD/iLu4ohA9xBQA7
        76 R0lGODlhDwAIAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAgAAAIdhGNmEGZG4h/Bp/hH8OMO4o5C+IgRmUdxCD6mWgEAOw==
        77 R0lGODlhDwALAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAsAAAIthGNmEGZG4h/Bj7OIIPhH8Qk+xSf4FxGIeCQm/AuECArhU/wj+BT/CH7cQRwVADs=
        78 R0lGODlhDwAJAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAkAAAIihGNmEGZG4h/Bj7uIuzskJnyMCMSjmPAxIjAIPsU/go8YVwA7
        79 R0lGODlhDwAKAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAoAAAInhI+ZFJvgH8UPgg8RCEEh/LiDuKMQPgRaBMGOuAOKHwT/KDbBx8wCADs=
        80 R0lGODlhDwAIAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAgAAAIghGNmEGZG4h/Bp/hH8OPi4u4ACQBB8JFiE3yEiMhMRAoAOw==
        81 R0lGODlhDwAKAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAoAAAIqhI+ZFJvgH8UPgg8RCEEBACKC4ENcRFAIH+LCgkLYERdH8YPgH8Um+JhZADs=
        82 R0lGODlhDwAJAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAkAAAIphGNmEGZG4h/Bp/hH8OPi4u5IAoAg+BARcRTCjwig2AQ/DiKC4EMgXgEAOw==
        83 R0lGODlhDwAIAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAgAAAIlhI95EUFAIszMKABERBD8uAgLgh8WcUHwKTZAEHyLCAtKCB/zCgA7
        84 R0lGODlhDwAIAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAgAAAIehI8RiGgUwo87iDuKfwSf4h/BjzuIuzuGhPDxIq4AADs=
        85 R0lGODlhDwAIAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAgAAAIdhI8QaRTfCD7FP4IfdxB3FMJHjLQg+EDxjeAjxhUAOw==
        86 R0lGODlhDwAJAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAkAAAIlhI8QmUcJ4SNERBD8i4gACuFTbIKPEYGIRxIABMFHiIgg+HgRVwA7
        87 R0lGODlhDwANAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAA0AAAI0hI8QmUYx4R/FJ/gUn+BfRCBQCP8iLhCPxCH4R/EJPsUGgCD4EXF3dyQBQBB8hIgIgo8YVwA7
        88 R0lGODlhDwAJAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAkAAAIthGNmEGZGEsKOuIugABARBD8sIIIQwr+IQAQKEhAE/yLighDCjziLIPhxB3FUADs=
        89 R0lGODlhDwAIAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAgAAAIhhI8QmUcJ4cdBRFAIn+IHBMGn2AQfAyOAQvh4EZlIAaAAADs=
        90 R0lGODlhDwAIAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAgAAAIohEPwESMwKCH8iIgLCuEHRMRRCD8uIoBC+HEQERTCjziLIPgRcRYEFwA7
        91 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIPhI9J8dEAINMIHDMzC4ILADs=
        92 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIPhI8RiEYx4V9EIB6F8BEKADs=
        93 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIODOFjHMVHA4BMI/AxrwAAOw==
        94 R0lGODlhDwAIAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAgAAAIYhA+BiEcJ4WNGZlIIHy8yjRLCR4vMTCMFADs=
        95 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIUDOEjRiZSCB8xMpFC+IiRiRTCRywAOw==
        96 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIKhI+pGasUwsfEAgA7
        97 R0lGODlhDwAGAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAYAAAIYhBEWdwcUwwj+BYQFwT+KT/CPYhN8DMQrADs=
        98 R0lGODlhDwAGAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAYAAAIXhBn/CD5QfCP4cRB3R/EJPkZEICJChhQAOw==
        99 R0lGODlhDwAGAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAYAAAIYhBERcXdA4hP8CwxEoAAQQfAxLAIREQKkADs=
        100 R0lGODlhDwAGAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAYAAAIYhBERcXdA4hP8CwwLgk/xj+BT/CP4cXdWADs=
        101 R0lGODlhDwAGAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAYAAAIZhBERcXdA4hP8CwsIgn9hEUHwMSACEREypAA7
        102 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIThGMWZmZA4hvBB4p/BD8OwoLgAgA7
        103 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIlRBIBEQQfAiKA4hD8gAgIAmJmAUFBIoLgB0RYUEL4EIEQBB9TCwA7
        104 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIahGNmEGZG4h/Bp/hH8DEQjeIT/KP4BP8C8QoAOw==
        105 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIShGMWZmZA4oMRfIoPRvDj7qwAADs=
        106 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIRDOFDoFH8AwMAAuMbGMHHvAIAOw==
        107 R0lGODlhDwAIAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAgAAAIihGNmEGZG4h/Bp/hH8MPi7g5IHIJ/EWFB8C/iAhFICB+hAAA7
        108 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIRhGNmEGZG4h/Bp/hH8OPurAAAOw==
        109 R0lGODlhDwAKAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAoAAAIjhGMWZmZA4hP8o/gEHy8yKT7BP4pP8PEik+IT/KP4BP8C8QoAOw==
        110 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIahGMWZmZA4hP8o/gEHy8yKT7BP4pP8C8QrwAAOw==
        111 R0lGODlhDwAGAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAYAAAIXhBERcXdA4hP8CwxEoPgEHyMiEBEhQwoAOw==
        112 R0lGODlhDwAGAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAYAAAIXjH8En+IfwQ+LgyD4R/EJPkZEICJChhQAOw==
        113 R0lGODlhDwAGAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAYAAAIahBERcXdA4hP8sDgIgk/xjeADxT+CH3d3RgUAOw==
        114 R0lGODlhDwAGAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAYAAAIXhGMWZmZA4hP8o/gE/+ICEY+E8PEiEqgAOw==
        115 R0lGODlhDwAGAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAYAAAIchBMQYWZmSICIIPgXEAEUwr+IsCD4GAERBB9TCwA7
        116 R0lGODlhDwAEAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAQAAAIQhG+BCBSf4B/FN4IPgYFGBQA7
        117 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIYhG+BaBSb4B/FJ/gXiGgUn+AfxSf4F4hXADs=
        118 R0lGODlhDwAFAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAUAAAIShB0RcXcUn+BfBCIexSH4iJFQADs=
        119 R0lGODlhDwAIAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAgAAAIdhB8Rd0fxCf5FBCIeiQn/KD7Bv4hAxCMx4SNGQgEAOw==
        120 R0lGODlhDwAGAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAYAAAIbhGMWZmZAEoARfISICIJ/FJvgY0RYEPwLDDQqADs=
        121 R0lGODlhDwAGAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAYAAAIYTAg/7uKMYsKHCKDYBP8iAhGPxISPGAkFADs=
        122 R0lGODlhDwAGAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAYAAAIahGMQYWYGSAwIgn8Un+BfWEQQ/Iu4QESEACkAOw==
        123 R0lGODlhDwAFAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAUAAAIUhI+poUex4QIACIwNABdAQAg+xhUAOw==
        124 R0lGODlhDwADAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAMAAAIJhI9J8dEIPuYVADs=
        125 R0lGODlhDwAFAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAUAAAIUDOFjHMUGgAsgABQbLgg+BiIiHikAOw==
        126 R0lGODlhDwAHAJEAANnZ2QAAAP///////yH5BAEAAAAALAAAAAAPAAcAAAIVhB1xd2cUwkeMzKMQPmJkIiWEj6lWADs=
    }
 }
 proc ::RotatedFont::CreateRotateTextImage {txt} {
    variable ALPHA                              ;# Alphabet images
 
    set ltxt {}
    set h 0
    foreach ch [split $txt ""] {                ;# Pass1: create chars, get size
        scan $ch %c ch
        if {! [info exists ALPHA($ch)]} { set ch 63 }
        lappend ltxt $ch
 
        set iname "::img::rot::$ch"
        if {[lsearch [image names] $iname] == -1} {
            image create photo $iname -data $ALPHA($ch)
        }
        incr h [image height $iname]
    }
    set img [image create photo -width 21 -height $h]
 
    set y 0
    foreach ch $ltxt {
        $img copy ::img::rot::$ch -to 0 $y
        incr y [image height ::img::rot::$ch]
    }
 
    return $img
 }
 
 # Demo code
 pack [canvas .c]
 set x 100
 foreach word {"Now is the" "time for all" "good men" "to come to the aid" "of their country"} {
    set img [::RotatedFont::CreateRotateTextImage $word]
    .c create image [incr x -13] 10 -image $img -anchor nw
 }
 return

Also see "Rotate text and images using img extension", "Rotate text on a canvas", "Vector Font"...


KBK 2008-11-03 I was sufficiently intrigued with this idea to do it directly in the canvas, creating 'line' items for the rotated text. There's a demonstrator in the Half Bakery at https://wiki.tcl-lang.org/_repo/hershey/