PageRenderTime 76ms CodeModel.GetById 30ms app.highlight 18ms RepoModel.GetById 23ms app.codeStats 1ms

/Lib/lib-tk/tkFont.py

http://unladen-swallow.googlecode.com/
Python | 216 lines | 188 code | 6 blank | 22 comment | 0 complexity | b3d1e8a4bce58c1e06fbab91eaf3bc94 MD5 | raw file
  1# Tkinter font wrapper
  2#
  3# written by Fredrik Lundh, February 1998
  4#
  5# FIXME: should add 'displayof' option where relevant (actual, families,
  6#        measure, and metrics)
  7#
  8
  9__version__ = "0.9"
 10
 11import Tkinter
 12
 13# weight/slant
 14NORMAL = "normal"
 15ROMAN = "roman"
 16BOLD   = "bold"
 17ITALIC = "italic"
 18
 19def nametofont(name):
 20    """Given the name of a tk named font, returns a Font representation.
 21    """
 22    return Font(name=name, exists=True)
 23
 24class Font:
 25
 26    """Represents a named font.
 27
 28    Constructor options are:
 29
 30    font -- font specifier (name, system font, or (family, size, style)-tuple)
 31    name -- name to use for this font configuration (defaults to a unique name)
 32    exists -- does a named font by this name already exist?
 33       Creates a new named font if False, points to the existing font if True.
 34       Raises _Tkinter.TclError if the assertion is false.
 35
 36       the following are ignored if font is specified:
 37
 38    family -- font 'family', e.g. Courier, Times, Helvetica
 39    size -- font size in points
 40    weight -- font thickness: NORMAL, BOLD
 41    slant -- font slant: ROMAN, ITALIC
 42    underline -- font underlining: false (0), true (1)
 43    overstrike -- font strikeout: false (0), true (1)
 44
 45    """
 46
 47    def _set(self, kw):
 48        options = []
 49        for k, v in kw.items():
 50            options.append("-"+k)
 51            options.append(str(v))
 52        return tuple(options)
 53
 54    def _get(self, args):
 55        options = []
 56        for k in args:
 57            options.append("-"+k)
 58        return tuple(options)
 59
 60    def _mkdict(self, args):
 61        options = {}
 62        for i in range(0, len(args), 2):
 63            options[args[i][1:]] = args[i+1]
 64        return options
 65
 66    def __init__(self, root=None, font=None, name=None, exists=False, **options):
 67        if not root:
 68            root = Tkinter._default_root
 69        if font:
 70            # get actual settings corresponding to the given font
 71            font = root.tk.splitlist(root.tk.call("font", "actual", font))
 72        else:
 73            font = self._set(options)
 74        if not name:
 75            name = "font" + str(id(self))
 76        self.name = name
 77
 78        if exists:
 79            self.delete_font = False
 80            # confirm font exists
 81            if self.name not in root.tk.call("font", "names"):
 82                raise Tkinter._tkinter.TclError, "named font %s does not already exist" % (self.name,)
 83            # if font config info supplied, apply it
 84            if font:
 85                root.tk.call("font", "configure", self.name, *font)
 86        else:
 87            # create new font (raises TclError if the font exists)
 88            root.tk.call("font", "create", self.name, *font)
 89            self.delete_font = True
 90        # backlinks!
 91        self._root  = root
 92        self._split = root.tk.splitlist
 93        self._call  = root.tk.call
 94
 95    def __str__(self):
 96        return self.name
 97
 98    def __eq__(self, other):
 99        return self.name == other.name and isinstance(other, Font)
100
101    def __getitem__(self, key):
102        return self.cget(key)
103
104    def __setitem__(self, key, value):
105        self.configure(**{key: value})
106
107    def __del__(self):
108        try:
109            if self.delete_font:
110                self._call("font", "delete", self.name)
111        except (KeyboardInterrupt, SystemExit):
112            raise
113        except Exception:
114            pass
115
116    def copy(self):
117        "Return a distinct copy of the current font"
118        return Font(self._root, **self.actual())
119
120    def actual(self, option=None):
121        "Return actual font attributes"
122        if option:
123            return self._call("font", "actual", self.name, "-"+option)
124        else:
125            return self._mkdict(
126                self._split(self._call("font", "actual", self.name))
127                )
128
129    def cget(self, option):
130        "Get font attribute"
131        return self._call("font", "config", self.name, "-"+option)
132
133    def config(self, **options):
134        "Modify font attributes"
135        if options:
136            self._call("font", "config", self.name,
137                  *self._set(options))
138        else:
139            return self._mkdict(
140                self._split(self._call("font", "config", self.name))
141                )
142
143    configure = config
144
145    def measure(self, text):
146        "Return text width"
147        return int(self._call("font", "measure", self.name, text))
148
149    def metrics(self, *options):
150        """Return font metrics.
151
152        For best performance, create a dummy widget
153        using this font before calling this method."""
154
155        if options:
156            return int(
157                self._call("font", "metrics", self.name, self._get(options))
158                )
159        else:
160            res = self._split(self._call("font", "metrics", self.name))
161            options = {}
162            for i in range(0, len(res), 2):
163                options[res[i][1:]] = int(res[i+1])
164            return options
165
166def families(root=None):
167    "Get font families (as a tuple)"
168    if not root:
169        root = Tkinter._default_root
170    return root.tk.splitlist(root.tk.call("font", "families"))
171
172def names(root=None):
173    "Get names of defined fonts (as a tuple)"
174    if not root:
175        root = Tkinter._default_root
176    return root.tk.splitlist(root.tk.call("font", "names"))
177
178# --------------------------------------------------------------------
179# test stuff
180
181if __name__ == "__main__":
182
183    root = Tkinter.Tk()
184
185    # create a font
186    f = Font(family="times", size=30, weight=NORMAL)
187
188    print f.actual()
189    print f.actual("family")
190    print f.actual("weight")
191
192    print f.config()
193    print f.cget("family")
194    print f.cget("weight")
195
196    print names()
197
198    print f.measure("hello"), f.metrics("linespace")
199
200    print f.metrics()
201
202    f = Font(font=("Courier", 20, "bold"))
203    print f.measure("hello"), f.metrics("linespace")
204
205    w = Tkinter.Label(root, text="Hello, world", font=f)
206    w.pack()
207
208    w = Tkinter.Button(root, text="Quit!", command=root.destroy)
209    w.pack()
210
211    fb = Font(font=w["font"]).copy()
212    fb.config(weight=BOLD)
213
214    w.config(font=fb)
215
216    Tkinter.mainloop()