使用 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)