220 lines
6.6 KiB
Python
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)
|