# # Python GUI - Fonts - Generic # import sys from GUI.Properties import overridable_property class Font(object): """A Font object represents a set of characters of a particular typeface, style and size. Font objects are immutable. Constructors: Font(family, size, style) family = family name size = size in points style = a list of 'bold', 'italic' Properties: family --> string size --> number style --> ['bold', 'italic'] ascent --> number descent --> number leading --> number height --> number cap_height --> number x_height --> number line_height --> number """ family = overridable_property('family', "Family name ('Times', 'Helvetica', etc.)") size = overridable_property('size', "Size in points") style = overridable_property('style', "A list of 'bold', 'italic'") ascent = overridable_property('ascent', "Distance from baseline to top of highest character") descent = overridable_property('descent', "Distance from baseline to bottom of lowest character") height = overridable_property('height', "Sum of ascent and descent") cap_height = overridable_property('cap_height', "Height above baseline of capital letters") x_height = overridable_property('x_height', "Height above baseline of lowercase letters without ascenders") leading = overridable_property('leading', "Recommended extra space between lines") line_height = overridable_property('line_height', "Recommended distance between baselines") def get_cap_height(self): # Approximation for platforms not supporting this return self.ascent def get_x_height(self): # Approximation for platforms not supporting this return self.ascent - self.descent def get_leading(self): return self.line_height - self.height def but(self, family = None, size = None, style = None, style_includes = None, style_excludes = None): """Return a new Font that is the same as this one except for the specified characteristics.""" if not family: family = self.family if not size: size = self.size if style is None: style = self.style style = style[:] if style_includes: for item in style_includes: style.append(item) if style_excludes: for item in style_excludes: if item in style: style.remove(item) return self.__class__(family, size, style) def width(self, s, start = 0, end = None): """width(s [,start [,end ]]) The width of the specified part of the given string in this font.""" if start or end is not None: if end is None: end = len(s) s = s[start:end] return self._width(s) def _width(self, s): raise NotImplementedError def x_to_pos(self, s, x): """Given a number of pixels measured from the left of the given string, returns the nearest inter-character position. Returns 0 if x is negative, and len(string) if x is beyond the right end of the string.""" raise NotImplementedError def __str__(self): return "Font(%r,%g,%s)" % (self.family, self.size, self.style)