94 lines
3.4 KiB
Python
94 lines
3.4 KiB
Python
#
|
|
# 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)
|