如何从 Mac 上的显示名称找到字体的完整路径?

发布于 2024-07-03 23:43:14 字数 261 浏览 7 评论 0原文

我正在使用 Photoshop 的 javascript API 来查找给定 PSD 中的字体。

给定 API 返回的字体名称,我想找到该字体名称在光盘上对应的实际物理字体文件。

这一切都发生在 OSX 上运行的 python 程序中,所以我想我正在寻找以下之一:

  • 一些 Photoshop javascript
  • 一个 Python 函数
  • 一个我可以从 python 调用的 OSX API

I am using the Photoshop's javascript API to find the fonts in a given PSD.

Given a font name returned by the API, I want to find the actual physical font file that font name corresponds to on the disc.

This is all happening in a python program running on OSX so I guess I'm looking for one of:

  • Some Photoshop javascript
  • A Python function
  • An OSX API that I can call from python

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

过去的过去 2024-07-10 23:43:15

我遇到了类似的要求,最终采用了这种方法:

def get_font_path(font):
    ttf_filename = os.path.basename(font)
    dirs = []
    if sys.platform == "win32":
        # check the windows font repository
        # NOTE: must use uppercase WINDIR, to work around bugs in
        # 1.5.2's os.environ.get()
        windir = os.environ.get("WINDIR")
        if windir:
            dirs.append(os.path.join(windir, "fonts"))
    elif sys.platform in ("linux", "linux2"):
        lindirs = os.environ.get("XDG_DATA_DIRS", "")
        if not lindirs:
            # According to the freedesktop spec, XDG_DATA_DIRS should
            # default to /usr/share
            lindirs = "/usr/share"
        dirs += [
            os.path.join(lindir, "fonts") for lindir in lindirs.split(":")
        ]
    elif sys.platform == "darwin":
        dirs += [
            "/Library/Fonts",
            "/System/Library/Fonts",
            os.path.expanduser("~/Library/Fonts"),
        ]

    ext = os.path.splitext(ttf_filename)[1]
    first_font_with_a_different_extension = None
    for directory in dirs:
        for walkroot, walkdir, walkfilenames in os.walk(directory):
            for walkfilename in walkfilenames:
                if ext and walkfilename == ttf_filename:
                    return os.path.join(walkroot, walkfilename)
                elif (
                    not ext
                    and os.path.splitext(walkfilename)[0] == ttf_filename
                ):
                    fontpath = os.path.join(walkroot, walkfilename)
                    if os.path.splitext(fontpath)[1] == ".ttf":
                        return fontpath
                    if (
                        not ext
                        and first_font_with_a_different_extension is None
                    ):
                        first_font_with_a_different_extension = fontpath
    if first_font_with_a_different_extension:
        return first_font_with_a_different_extension

请注意,原始代码来自 PIL

I had encountered similar requirements and I ended up by this method:

def get_font_path(font):
    ttf_filename = os.path.basename(font)
    dirs = []
    if sys.platform == "win32":
        # check the windows font repository
        # NOTE: must use uppercase WINDIR, to work around bugs in
        # 1.5.2's os.environ.get()
        windir = os.environ.get("WINDIR")
        if windir:
            dirs.append(os.path.join(windir, "fonts"))
    elif sys.platform in ("linux", "linux2"):
        lindirs = os.environ.get("XDG_DATA_DIRS", "")
        if not lindirs:
            # According to the freedesktop spec, XDG_DATA_DIRS should
            # default to /usr/share
            lindirs = "/usr/share"
        dirs += [
            os.path.join(lindir, "fonts") for lindir in lindirs.split(":")
        ]
    elif sys.platform == "darwin":
        dirs += [
            "/Library/Fonts",
            "/System/Library/Fonts",
            os.path.expanduser("~/Library/Fonts"),
        ]

    ext = os.path.splitext(ttf_filename)[1]
    first_font_with_a_different_extension = None
    for directory in dirs:
        for walkroot, walkdir, walkfilenames in os.walk(directory):
            for walkfilename in walkfilenames:
                if ext and walkfilename == ttf_filename:
                    return os.path.join(walkroot, walkfilename)
                elif (
                    not ext
                    and os.path.splitext(walkfilename)[0] == ttf_filename
                ):
                    fontpath = os.path.join(walkroot, walkfilename)
                    if os.path.splitext(fontpath)[1] == ".ttf":
                        return fontpath
                    if (
                        not ext
                        and first_font_with_a_different_extension is None
                    ):
                        first_font_with_a_different_extension = fontpath
    if first_font_with_a_different_extension:
        return first_font_with_a_different_extension

Note that the original code is from PIL

鹿港小镇 2024-07-10 23:43:15

打开一个终端(应用程序->实用程序->终端)并输入以下内容:

locate InsertFontHere

这将吐出具有您想要的名称的每个文件。

警告:可能有很多事情需要费力。

open up a terminal (Applications->Utilities->Terminal) and type this in:

locate InsertFontHere

This will spit out every file that has the name you want.

Warning: there may be alot to wade through.

沉鱼一梦 2024-07-10 23:43:15

我还没有找到任何可以直接执行此操作的东西。 我认为您必须遍历系统上的各种字体文件夹:/System/Library/Fonts/Library/Fonts,并且可能有一个用户-级目录以及~/Library/Fonts

I haven't been able to find anything that does this directly. I think you'll have to iterate through the various font folders on the system: /System/Library/Fonts, /Library/Fonts, and there can probably be a user-level directory as well ~/Library/Fonts.

旧梦荧光笔 2024-07-10 23:43:15

Cocoa 中必须有一个方法来获取字体列表,然后您必须使用 PyObjC 绑定来调用它。

根据您需要它们的用途,您可能只使用类似以下的内容。

import os
def get_font_list():
    fonts = []
    for font_path in ["/Library/Fonts", os.path.expanduser("~/Library/Fonts")]:
        if os.path.isdir(font_path):
            fonts.extend(
                [os.path.join(font_path, cur_font) 
                 for cur_font in os.listdir(font_path)
                ]
            )
    return fonts

There must be a method in Cocoa to get a list of fonts, then you would have to use the PyObjC bindings to call it..

Depending on what you need them for, you could probably just use something like the following..

import os
def get_font_list():
    fonts = []
    for font_path in ["/Library/Fonts", os.path.expanduser("~/Library/Fonts")]:
        if os.path.isdir(font_path):
            fonts.extend(
                [os.path.join(font_path, cur_font) 
                 for cur_font in os.listdir(font_path)
                ]
            )
    return fonts
维持三分热 2024-07-10 23:43:15

使用 matplotlibpip3 install -U matplotlib):

from matplotlib import font_manager

fontmap = {font.name: font for font in font_manager.fontManager.ttflist}
fontmap.update({font.name: font for font in font_manager.fontManager.afmlist})

print(f'Total fonts: {len(fontmap.keys())}')

for family in sorted(fontmap.keys()):
    font = fontmap[family]
    print(f'{family:<30}: {font.fname}')

示例输出

Total fonts: 312
.Aqua Kana                    : /System/Library/Fonts/AquaKana.ttc
Academy Engraved LET          : /System/Library/Fonts/Supplemental/Academy Engraved LET Fonts.ttf
Al Bayan                      : /System/Library/Fonts/Supplemental/AlBayan.ttc
American Typewriter           : /System/Library/Fonts/Supplemental/AmericanTypewriter.ttc
...
Zapf Dingbats                 : /System/Library/Fonts/ZapfDingbats.ttf
ZapfDingbats                  : /usr/local/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/ZapfDingbats.afm
Zapfino                       : /System/Library/Fonts/Supplemental/Zapfino.ttf

注意:matplotlib 中的字体系列似乎不包含所有可用的系统字体,例如 PyQt5 库:

从 PyQt5.QtGui 导入 QFontDatabase 
  从 PyQt5.QtWidgets 导入 QApplication 

  应用程序 = QApplication([]) 
  print('\n'.join(QFontDatabase().families())) 
  

With matplotlib (pip3 install -U matplotlib):

from matplotlib import font_manager

fontmap = {font.name: font for font in font_manager.fontManager.ttflist}
fontmap.update({font.name: font for font in font_manager.fontManager.afmlist})

print(f'Total fonts: {len(fontmap.keys())}')

for family in sorted(fontmap.keys()):
    font = fontmap[family]
    print(f'{family:<30}: {font.fname}')

Sample output

Total fonts: 312
.Aqua Kana                    : /System/Library/Fonts/AquaKana.ttc
Academy Engraved LET          : /System/Library/Fonts/Supplemental/Academy Engraved LET Fonts.ttf
Al Bayan                      : /System/Library/Fonts/Supplemental/AlBayan.ttc
American Typewriter           : /System/Library/Fonts/Supplemental/AmericanTypewriter.ttc
...
Zapf Dingbats                 : /System/Library/Fonts/ZapfDingbats.ttf
ZapfDingbats                  : /usr/local/lib/python3.9/site-packages/matplotlib/mpl-data/fonts/pdfcorefonts/ZapfDingbats.afm
Zapfino                       : /System/Library/Fonts/Supplemental/Zapfino.ttf

NOTE: The font families from matplotlib do not seem to include all system fonts that are available for example to the PyQt5 library:

from PyQt5.QtGui import QFontDatabase
from PyQt5.QtWidgets import QApplication

app = QApplication([])
print('\n'.join(QFontDatabase().families()))
囍笑 2024-07-10 23:43:14

不幸的是,唯一未弃用的 API 位于 ApplicationServices 框架中,该框架没有桥支持文件,因此在桥中不可用。 如果您想使用 ctypes,可以在查找 ATSFontRef 后使用 ATSFontGetFileReference。

Cocoa 没有任何本机支持(至少从 10.5 开始),用于获取字体的位置。

Unfortunately the only API that isn't deprecated is located in the ApplicationServices framework, which doesn't have a bridge support file, and thus isn't available in the bridge. If you're wanting to use ctypes, you can use ATSFontGetFileReference after looking up the ATSFontRef.

Cocoa doesn't have any native support, at least as of 10.5, for getting the location of a font.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文