Lightningbeam/PyGUI-2.5.3/build/lib.linux-i686-2.6/GUI/Font.py

156 lines
4.7 KiB
Python

#
# Python GUI - Fonts - Gtk
#
from __future__ import division
import sys
import pango, gtk
from gtk import gdk
from GUI import export
from GUI.GFonts import Font as GFont
class Font(GFont):
#_gdk_font = None
_pango_font = None
_pango_metrics = None
_pango_layout = None
# def _from_gdk_font(cls, gdk_font):
# font = cls.__new__(cls)
# font._gdk_font = gdk_font
# return font
#
# _from_gdk_font = classmethod(_from_gdk_font)
def _from_pango_description(cls, pango_description):
font = cls.__new__(cls)
font._pango_description = pango_description
return font
_from_pango_description = classmethod(_from_pango_description)
def __init__(self, family, size = 12, style = []):
if 'italic' in style:
pango_style = pango.STYLE_ITALIC
else:
pango_style = pango.STYLE_NORMAL
if 'bold' in style:
pango_weight = pango.WEIGHT_BOLD
else:
pango_weight = pango.WEIGHT_NORMAL
jigger = _find_size_correction_factor(family, pango_style, pango_weight)
pfd = pango.FontDescription()
pfd.set_family(family)
pfd.set_size(int(round(jigger * size * pango.SCALE)))
pfd.set_style(pango_style)
pfd.set_weight(pango_weight)
self._pango_description = pfd
def get_family(self):
return self._pango_description.get_family()
def get_size(self):
return self._pango_description.get_size() / pango.SCALE
def get_style(self):
style = []
pfd = self._pango_description
if pfd.get_weight() > pango.WEIGHT_NORMAL:
style.append('bold')
if pfd.get_style() <> pango.STYLE_NORMAL:
style.append('italic')
return style
def get_ascent(self):
self._get_pango_metrics()
result = self._ascent
return result
def get_descent(self):
self._get_pango_metrics()
return self._descent
def get_height(self):
self._get_pango_metrics()
return self._ascent + self._descent
def get_line_height(self):
return self.get_height()
def _get_pango_metrics(self):
#print "Font._get_pango_metrics: enter" ###
pfm = self._pango_metrics
if not pfm:
pf = self._get_pango_font()
pfm = pf.get_metrics()
self._pango_metrics = pfm
self._ascent = pfm.get_ascent() / pango.SCALE
self._descent = pfm.get_descent() / pango.SCALE
return pfm
def _get_pango_font(self):
pf = self._pango_font
if not pf:
pf = _pango_context.load_font(self._pango_description)
if not pf:
raise ValueError("Unable to load Pango font for %s" % self)
self._pango_font = pf
return pf
def width(self, s, start = 0, end = sys.maxint):
layout = self._get_pango_layout(s[start:end], True)
return layout.get_pixel_size()[0]
def text_size(self, text):
layout = self._get_pango_layout(text, False)
return layout.get_pixel_size()
#w, h = layout.get_size()
#u = pango.SCALE
#return (w / u, h / u)
def x_to_pos(self, s, x):
layout = self._get_pango_layout(s, True)
return pango_layout.xy_to_index(x, 0)
def _get_pango_layout(self, text, single_paragraph_mode):
layout = self._pango_layout
if not layout:
layout = pango.Layout(_pango_context)
layout.set_font_description(self._pango_description)
self._pango_layout = layout
layout.set_single_paragraph_mode(single_paragraph_mode)
layout.set_text(text)
return layout
_pango_context = gtk.Label().create_pango_context()
_jigger_cache = {}
def _find_size_correction_factor(family, pango_style, pango_weight):
# Unlike the rest of the world, Pango seems to consider the point
# size of a font to only include the ascent. So we first ask for
# a 1-point font, find the ratio of its ascent to its descent,
# and use that to adjust the size requested by the user.
key = (family, pango_style, pango_weight)
result = _jigger_cache.get(key)
if result is None:
pd = pango.FontDescription()
pd.set_family(family)
pd.set_size(pango.SCALE)
pd.set_style(pango_style)
pd.set_weight(pango_weight)
pf = _pango_context.load_font(pd)
pm = pf.get_metrics()
a = pm.get_ascent()
d = pm.get_descent()
result = a / (a + d)
#print "Jigger factor for font:", family, pango_style, pango_weight ###
#print "ascent =", a, "descent =", d, "factor =", result ###
_jigger_cache[key] = result
return result
export(Font)