blob: 169c5299b018967729d34060fc1c007142e77873 [file] [log] [blame]
Guido van Rossum3d16d3e1998-08-11 19:07:58 +00001#
2# Tkinter
3# $Id$
4#
5# font wrapper
6#
7# written by Fredrik Lundh <fredrik@pythonware.com>, February 1998
8#
9# FIXME: should add 'displayof' option where relevant (actual, families,
10# measure, and metrics)
Fred Draked038ca82000-10-23 18:31:14 +000011#
Guido van Rossum3d16d3e1998-08-11 19:07:58 +000012# Copyright (c) Secret Labs AB 1998.
13#
14# info@pythonware.com
15# http://www.pythonware.com
16#
17
18__version__ = "0.9"
19
20import Tkinter
Guido van Rossum3d16d3e1998-08-11 19:07:58 +000021
22# weight/slant
23NORMAL = "normal"
24BOLD = "bold"
25ITALIC = "italic"
26
27class Font:
28
29 """Represents a named font.
30
31 Constructor options are:
32
33 font -- font specifier (name, system font, or (family, size, style)-tuple)
34
35 or any combination of
36
37 family -- font 'family', e.g. Courier, Times, Helvetica
38 size -- font size in points
39 weight -- font thickness: NORMAL, BOLD
40 slant -- font slant: NORMAL, ITALIC
41 underline -- font underlining: false (0), true (1)
42 overstrike -- font strikeout: false (0), true (1)
43 name -- name to use for this font configuration (defaults to a unique name)
44 """
45
46 def _set(self, kw):
47 options = []
48 for k, v in kw.items():
49 options.append("-"+k)
50 options.append(str(v))
51 return tuple(options)
52
53 def _get(self, args):
Fred Draked038ca82000-10-23 18:31:14 +000054 options = []
55 for k in args:
56 options.append("-"+k)
57 return tuple(options)
Guido van Rossum3d16d3e1998-08-11 19:07:58 +000058
59 def _mkdict(self, args):
60 options = {}
61 for i in range(0, len(args), 2):
62 options[args[i][1:]] = args[i+1]
63 return options
64
65 def __init__(self, root=None, font=None, name=None, **options):
66 if not root:
67 root = Tkinter._default_root
68 if font:
69 # get actual settings corresponding to the given font
70 font = root.tk.splitlist(root.tk.call("font", "actual", font))
71 else:
72 font = self._set(options)
73 if not name:
74 name = "font" + str(id(self))
75 self.name = name
76 apply(root.tk.call, ("font", "create", name) + font)
77 # backlinks!
78 self._root = root
79 self._split = root.tk.splitlist
80 self._call = root.tk.call
81
82 def __str__(self):
83 return self.name
84
85 def __del__(self):
86 try:
87 self._call("font", "delete", self.name)
88 except (AttributeError, Tkinter.TclError):
89 pass
90
91 def copy(self):
92 "Return a distinct copy of the current font"
93 return apply(Font, (self._root,), self.actual())
94
95 def actual(self, option=None):
96 "Return actual font attributes"
97 if option:
98 return self._call("font", "actual", self.name, "-"+option)
99 else:
100 return self._mkdict(
101 self._split(self._call("font", "actual", self.name))
102 )
103
104 def cget(self, option):
105 "Get font attribute"
106 return self._call("font", "config", self.name, "-"+option)
107
108 def config(self, **options):
109 "Modify font attributes"
110 if options:
111 apply(self._call, ("font", "config", self.name) +
112 self._set(options))
113 else:
114 return self._mkdict(
115 self._split(self._call("font", "config", self.name))
116 )
117
118 configure = config
Fred Draked038ca82000-10-23 18:31:14 +0000119
Guido van Rossum3d16d3e1998-08-11 19:07:58 +0000120 def measure(self, text):
121 "Return text width"
Eric S. Raymondfc170b12001-02-09 11:51:27 +0000122 return int(self._call("font", "measure", self.name, text))
Guido van Rossum3d16d3e1998-08-11 19:07:58 +0000123
124 def metrics(self, *options):
125 """Return font metrics.
126
127 For best performance, create a dummy widget
128 using this font before calling this method."""
129
130 if options:
Eric S. Raymondfc170b12001-02-09 11:51:27 +0000131 return int(
Guido van Rossum3d16d3e1998-08-11 19:07:58 +0000132 self._call("font", "metrics", self.name, self._get(options))
133 )
134 else:
135 res = self._split(self._call("font", "metrics", self.name))
136 options = {}
137 for i in range(0, len(res), 2):
Eric S. Raymondfc170b12001-02-09 11:51:27 +0000138 options[res[i][1:]] = int(res[i+1])
Guido van Rossum3d16d3e1998-08-11 19:07:58 +0000139 return options
140
141def families(root=None):
142 "Get font families (as a tuple)"
143 if not root:
144 root = Tkinter._default_root
Fred Draked038ca82000-10-23 18:31:14 +0000145 return root.tk.splitlist(root.tk.call("font", "families"))
Guido van Rossum3d16d3e1998-08-11 19:07:58 +0000146
147def names(root=None):
148 "Get names of defined fonts (as a tuple)"
149 if not root:
150 root = Tkinter._default_root
151 return root.tk.splitlist(root.tk.call("font", "names"))
152
153# --------------------------------------------------------------------
154# test stuff
Fred Draked038ca82000-10-23 18:31:14 +0000155
Guido van Rossum3d16d3e1998-08-11 19:07:58 +0000156if __name__ == "__main__":
157
158 root = Tkinter.Tk()
159
160 # create a font
161 f = Font(family="times", size=30, weight=NORMAL)
162
163 print f.actual()
164 print f.actual("family")
165 print f.actual("weight")
166
167 print f.config()
168 print f.cget("family")
169 print f.cget("weight")
170
171 print names()
172
173 print f.measure("hello"), f.metrics("linespace")
174
175 print f.metrics()
176
177 f = Font(font=("Courier", 20, "bold"))
178 print f.measure("hello"), f.metrics("linespace")
179
180 w = Tkinter.Label(root, text="Hello, world", font=f)
181 w.pack()
182
183 w = Tkinter.Button(root, text="Quit!", command=root.destroy)
184 w.pack()
185
186 fb = Font(font=w["font"]).copy()
187 fb.config(weight=BOLD)
Fred Draked038ca82000-10-23 18:31:14 +0000188
Guido van Rossum3d16d3e1998-08-11 19:07:58 +0000189 w.config(font=fb)
190
191 Tkinter.mainloop()