python-2.5.2/win32/Lib/lib-tk/tkFont.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     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 
       
    11 import Tkinter
       
    12 
       
    13 # weight/slant
       
    14 NORMAL = "normal"
       
    15 ROMAN = "roman"
       
    16 BOLD   = "bold"
       
    17 ITALIC = "italic"
       
    18 
       
    19 def nametofont(name):
       
    20     """Given the name of a tk named font, returns a Font representation.
       
    21     """
       
    22     return Font(name=name, exists=True)
       
    23 
       
    24 class 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 
       
   166 def 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 
       
   172 def 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 
       
   181 if __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()