Lightningbeam/PyGUI-2.5.3/GUI/Win32/Font.py

220 lines
6.6 KiB
Python

#--------------------------------------------------------------------
#
# PyGUI - Font - Win32
#
#--------------------------------------------------------------------
import win32con as wc, win32gui as gui, win32ui as ui, win32api as api
from GUI import export
from WinUtils import win_none
import GUI.GDI as gdi
import GUI.GDIPlus as gdip
from GUI.GFonts import Font as GFont
#win_family_map = {
# "Decorative": wc.FF_DECORATIVE | wc.DEFAULT_PITCH,
# "Fixed": wc.FF_MODERN | wc.FIXED_PITCH,
# "Courier": wc.FF_MODERN | wc.FIXED_PITCH,
# "Modern": wc.FF_MODERN | wc.DEFAULT_PITCH,
# "Serif": wc.FF_ROMAN | wc.VARIABLE_PITCH,
# "Roman": wc.FF_ROMAN | wc.VARIABLE_PITCH,
# "Times": wc.FF_ROMAN | wc.VARIABLE_PITCH,
# "Sans": wc.FF_SWISS | wc.VARIABLE_PITCH,
# "Helvetica": wc.FF_SWISS | wc.VARIABLE_PITCH,
# "Script": wc.FF_SCRIPT | wc.DEFAULT_PITCH,
# "Cursive": wc.FF_SCRIPT | wc.DEFAULT_PITCH,
#}
#win_default_pf = wc.FF_DONTCARE | wc.DEFAULT_PITCH
def win_create_font(**kwds):
# Work around bug in CreateFont
for name in 'italic', 'underline':
if name in kwds and not kwds[name]:
del kwds[name]
return ui.CreateFont(kwds)
#def win_pf_to_name(pf):
# if pf & 0x3 == wc.FIXED_PITCH:
# return "Fixed"
# for name, npf in win_family_map.iteritems():
# if pf & 0xf0 == npf & 0xf0:
# return name
# return "Unknown"
win_generic_family_map = {
"Sans": "Arial",
"Serif": "Times New Roman",
"Fixed": "Courier New",
"Times": "Times New Roman",
"Courier": "Courier New",
}
# PyWin32 build 212 and earlier negate the value of the height
# passed to CreateFont.
pywin32_info = api.GetFileVersionInfo(api.__file__, '\\')
pywin32_build = pywin32_info['FileVersionLS'] >> 16
if pywin32_build <= 212:
win_height_sign = 1
else:
win_height_sign = -1
#--------------------------------------------------------------------
class Font(GFont):
# _win_font PyCFont
# _win_gfont GDIPlus.Font
def __init__(self, family = "Times", size = 12, style = []):
win_family = win_generic_family_map.get(family, family)
self._family = family
self._win_family = win_family
self._size = size
self._style = style
if 'bold' in style:
win_weight = wc.FW_BOLD
else:
win_weight = wc.FW_NORMAL
#print "Font: calling win_create_font" ###
height = int(round(size))
#print "Font: height =", height ###
win_font = win_create_font(
name = win_family,
height = win_height_sign * height,
weight = win_weight,
italic = 'italic' in style)
#pitch_and_family = 0) ###win_family_map.get(family, win_default_pf))
self._win_font = win_font
self._win_update_metrics()
#global dc ###
#dc = win_none.GetDC()
#dc.SelectObject(win_font)
#self._win_gfont = gdip.Font.from_hdc(dc.GetSafeHdc())
#win_none.ReleaseDC(dc)
# def __init__(self, family = "Times", size = 12, style = []):
# self._family = family
# self._size = size
# self._style = style
# hfont = gdi.create_hfont(family, size, style)
# self._win_hfont = hfont
# self._win_update_metrics()
def get_family(self):
return self._family
def get_size(self):
return self._size
def get_style(self):
return self._style
def get_ascent(self):
return self._ascent
def get_descent(self):
return self._descent
def get_leading(self):
return self._leading
def get_cap_height(self):
return self._ascent - self._internal_leading
def get_x_height(self):
return self._ascent - self._internal_leading - self._descent
def get_height(self):
return self._ascent + self._descent
def get_line_height(self):
return self._ascent + self._descent + self._leading
def _win_update_metrics(self):
dc = win_none.GetDC()
dc.SelectObject(self._win_font)
met = dc.GetTextMetrics()
self._ascent = met['tmAscent']
self._descent = met['tmDescent']
self._internal_leading = met['tmInternalLeading']
self._leading = met['tmExternalLeading']
self._win_overhang = met['tmOverhang']
#print "Font: tmOverhang =", self._win_overhang ###
win_none.ReleaseDC(dc)
self._win_gdip_font = gdip.Font(self._win_family, self._size, self._style)
def _width(self, s):
dc = win_none.GetDC()
dc.SelectObject(self._win_font)
w, h = dc.GetTextExtent(s)
win_none.ReleaseDC(dc)
return w
# def _width(self, s):
# dc = win_none.GetDC()
# g = gdip.Graphics.from_hdc(dc.GetSafeHdc())
# w = g.MeasureStringWidth(s, self._win_gdip_font)
# win_none.ReleaseDC(dc)
# return w
def info(self):
return "<Font family=%r size=%s style=%s ascent=%s descent=%s " \
"leading=%s height=%s cap_height=%s x_height=%s line_height=%s>" % \
(self.family, self.size, self.style, self.ascent, self.descent,
self.leading, self.height, self.cap_height, self.x_height,
self.line_height)
def tm_info(self):
win = ui.CreateWnd()
dc = win.GetDC()
dc.SelectObject(self._win_font)
tm = dc.GetTextMetrics()
win.ReleaseDC(dc)
return tm
# def _from_win_logfont(cls, lf):
# #print "Font._from_win_logfont:", lf ###
# #for name in dir(lf): ###
# # print name, "=", getattr(lf, name) ###
# font = cls.__new__(cls)
# font._family = win_pf_to_name(lf.lfPitchAndFamily)
# font._size = abs(lf.lfHeight)
# style = []
# if lf.lfWeight >= wc.FW_BOLD:
# style.append('bold')
# if lf.lfItalic:
# style.append('italic')
# font._style = style
# font._win_font = win_create_font(
# width = lf.lfWidth,
# #height = abs(lf.lfHeight),
# height = lf.lfHeight,
# weight = lf.lfWeight,
# italic = lf.lfItalic,
# underline = lf.lfUnderline,
# pitch_and_family = lf.lfPitchAndFamily,
# charset = lf.lfCharSet)
# font._win_update_metrics()
# return font
#
# _from_win_logfont = classmethod(_from_win_logfont)
def _from_win(cls, win):
dc = win.GetDC()
family = dc.GetTextFace()
tm = dc.GetTextMetrics()
#print family, tm
size = tm['tmAscent'] - tm['tmInternalLeading'] + tm['tmDescent']
style = []
if tm['tmWeight'] >= wc.FW_BOLD:
style.append('bold')
if tm['tmItalic']:
style.append('italic')
win.ReleaseDC(dc)
return Font(family, size, style)
_from_win = classmethod(_from_win)
export(Font)