使用 Windows api Python 加载字体文件
Load font file with Windows api Python
我正在寻找一种方法来加载 ttf 文件并使用该字体打印文本。在查找一些信息时,我发现了这个问题:load a ttf font with the Windows API
在那个问题中,他们建议使用 AddFontResourceEx 添加私有字体。但是我没有找到任何方法来使用 pywin32 模块和 ctypes.windll 访问此类功能。有什么方法可以访问此功能?或者失败了,另一种不使用 Pillow 的 ttf 字体打印文本的方法???
接下来,我会留下一个代码,以便您进行测试:
import win32print
import win32gui
import win32ui
hprinter = win32print.OpenPrinter("Microsoft Print to Pdf")
devmode = win32print.GetPrinter(hprinter, 2)["pDevMode"]
hdc = win32gui.CreateDC("WINSPOOL", printer, devmode)
dc = win32ui.CreateDCFromHandle(Self.hdc)
编辑
我设法通过
访问了该功能
ctypes.windll.gdi32.AddFontResourceExA
但现在我想访问 FR_PRIVATE
常量。我该怎么做?
编辑 2
我发现即使没有那个常量,这个函数也不起作用。
我改编了 this answer 的代码并得到了答案!
我会把代码放在下面:
def add_font_file(file):
FR_PRIVATE = 0x10
file = ctypes.byref(ctypes.create_unicode_buffer(file))
font_count = gdi32.AddFontResourceExW(file, FR_PRIVATE, 0)
if(font_count == 0):
raise RuntimeError("Error durante la carga de la fuente.")
万一原来的link挂了,原代码如下:
from ctypes import windll, byref, create_unicode_buffer, create_string_buffer
FR_PRIVATE = 0x10
FR_NOT_ENUM = 0x20
def loadfont(fontpath, private=True, enumerable=False):
'''
Makes fonts located in file `fontpath` available to the font system.
`private` if True, other processes cannot see this font, and this
font will be unloaded when the process dies
`enumerable` if True, this font will appear when enumerating fonts
See https://msdn.microsoft.com/en-us/library/dd183327(VS.85).aspx
'''
# This function was taken from
# https://github.com/ifwe/digsby/blob/f5fe00244744aa131e07f09348d10563f3d8fa99/digsby/src/gui/native/win/winfonts.py#L15
# This function is written for Python 2.x. For 3.x, you
# have to convert the isinstance checks to bytes and str
if isinstance(fontpath, str):
pathbuf = create_string_buffer(fontpath)
AddFontResourceEx = windll.gdi32.AddFontResourceExA
elif isinstance(fontpath, unicode):
pathbuf = create_unicode_buffer(fontpath)
AddFontResourceEx = windll.gdi32.AddFontResourceExW
else:
raise TypeError('fontpath must be of type str or unicode')
flags = (FR_PRIVATE if private else 0) | (FR_NOT_ENUM if not enumerable else 0)
numFontsAdded = AddFontResourceEx(byref(pathbuf), flags, 0)
return bool(numFontsAdded)
我正在寻找一种方法来加载 ttf 文件并使用该字体打印文本。在查找一些信息时,我发现了这个问题:load a ttf font with the Windows API
在那个问题中,他们建议使用 AddFontResourceEx 添加私有字体。但是我没有找到任何方法来使用 pywin32 模块和 ctypes.windll 访问此类功能。有什么方法可以访问此功能?或者失败了,另一种不使用 Pillow 的 ttf 字体打印文本的方法???
接下来,我会留下一个代码,以便您进行测试:
import win32print
import win32gui
import win32ui
hprinter = win32print.OpenPrinter("Microsoft Print to Pdf")
devmode = win32print.GetPrinter(hprinter, 2)["pDevMode"]
hdc = win32gui.CreateDC("WINSPOOL", printer, devmode)
dc = win32ui.CreateDCFromHandle(Self.hdc)
编辑
我设法通过
访问了该功能ctypes.windll.gdi32.AddFontResourceExA
但现在我想访问 FR_PRIVATE
常量。我该怎么做?
编辑 2
我发现即使没有那个常量,这个函数也不起作用。
我改编了 this answer 的代码并得到了答案!
我会把代码放在下面:
def add_font_file(file):
FR_PRIVATE = 0x10
file = ctypes.byref(ctypes.create_unicode_buffer(file))
font_count = gdi32.AddFontResourceExW(file, FR_PRIVATE, 0)
if(font_count == 0):
raise RuntimeError("Error durante la carga de la fuente.")
万一原来的link挂了,原代码如下:
from ctypes import windll, byref, create_unicode_buffer, create_string_buffer
FR_PRIVATE = 0x10
FR_NOT_ENUM = 0x20
def loadfont(fontpath, private=True, enumerable=False):
'''
Makes fonts located in file `fontpath` available to the font system.
`private` if True, other processes cannot see this font, and this
font will be unloaded when the process dies
`enumerable` if True, this font will appear when enumerating fonts
See https://msdn.microsoft.com/en-us/library/dd183327(VS.85).aspx
'''
# This function was taken from
# https://github.com/ifwe/digsby/blob/f5fe00244744aa131e07f09348d10563f3d8fa99/digsby/src/gui/native/win/winfonts.py#L15
# This function is written for Python 2.x. For 3.x, you
# have to convert the isinstance checks to bytes and str
if isinstance(fontpath, str):
pathbuf = create_string_buffer(fontpath)
AddFontResourceEx = windll.gdi32.AddFontResourceExA
elif isinstance(fontpath, unicode):
pathbuf = create_unicode_buffer(fontpath)
AddFontResourceEx = windll.gdi32.AddFontResourceExW
else:
raise TypeError('fontpath must be of type str or unicode')
flags = (FR_PRIVATE if private else 0) | (FR_NOT_ENUM if not enumerable else 0)
numFontsAdded = AddFontResourceEx(byref(pathbuf), flags, 0)
return bool(numFontsAdded)