我有以下脚本:
import fontforge
import os.path
import sys
if len(sys.argv) < 3:
print("Usage: [FONT] [OUTPUTDIR]")
exit(1)
fontpath = sys.argv[1]
font = fontforge.open(fontpath)
outdir = sys.argv[2]
if os.path.exists(outdir):
pass
elif os.access(os.path.dirname(outdir), os.W_OK):
os.makedirs(outdir)
else:
exit(1)
for name in font:
filename = name + ".svg"
outfull = os.path.join(outdir,filename)
font[name].export(outfull)
脚本将所有glyphs转储到文件夹中的各个SVG文件。
不管怎样,我已经安装了最新的Windows版本的FontForge。
据我所知,FontForge嵌入了python,二进制代码是ffpython.exe
,所以应该可以调用ffpython myscript.py {arg1 arg2 arg3}
问题是这行不通。
当我执行ffpython myscript.py arg1 arg2
时,我得到一个错误:ImportError: DLL load failed while importing fontforge: The specified procedure could not be found.
调用ffpython
,然后直接在解释器中键入import fontforge
,也可能导致相同的错误。
FontForge附带的批处理文件位于C:\Program Files (x86)\FontForgeBuilds\fontforge-console.bat
。
如果我运行这个批处理文件,它会设置一些变量,然后打开一个控制台窗口,如果我 then 在那个控制台窗口调用ffpython并输入import fontforge
,所有的事情都会像预期的那样神奇地工作。
但这是一个非常有限和不恰当的解决方案,我不想每次运行与FontForge接口的Python脚本时都必须打开这个神奇的批处理文件。
所以我的问题是:
如何将FontForge作为Python中的一个模块正确安装?如何获得一个python脚本来导入通过ffpython运行的fontforge模块?
我将非常感激任何帮助。
编辑:
通过@CristiFati从管理PowerShell提示符运行测试脚本,其中PWD与ffpython不同(失败):
03-14 20:06:09 D:\> & 'C:\Program Files (x86)\FontForgeBuilds\bin\ffpython.exe' .\code00.py
Executable: C:\Program Files (x86)\FontForgeBuilds\bin\ffpython.exe
Version: 3.10.9 (main, Dec 10 2022, 09:16:22) [GCC 12.2.0 32 bit]
CWD: D:\
UName: None
PATH: C:\Program Files\PowerShell\7;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\libnvvp;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64_win\compiler;C:\Program Files (x86)\Common Files\Intel\Shared Files\cpp\bin\Intel64;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64_win\compiler;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\ia32_win\compiler;C:\Python\Python310\Scripts\;C:\Python\Python310\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\BIN;C:\Program Files\Git\cmd;C:\Program Files\GitHub CLI\;C:\Program Files\7-Zip;C:\Program Files\NVIDIA Corporation\Nsight Compute 2020.1.1;C:\Program Files\dotnet\;C:\Program Files\CMake\bin;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\PowerShell\7\;C:\Program Files (x86)\FontForgeBuilds\bin;C:\Users\myusername\AppData\Local\Microsoft\WindowsApps;C:\Users\myusername\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\myusername\.dotnet\tools;C:\Program Files (x86)\FontForgeBuilds\bin\
PYTHONHOME: None
PYTHONPATH: None
sys.path: ['D:\\', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python310.zip', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10\\lib-dynload', 'D:\\', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10\\site-packages']
Traceback (most recent call last):
File "D:\code00.py", line 12, in <module>
import fontforge as ff
ImportError: DLL load failed while importing fontforge: The specified procedure could not be found.
03-14 20:06:24 D:\>
如果我使用CMD,会出现相同的结果。
通过@CristiFati从管理PowerShell提示符运行测试脚本,其中PWD为C:\Program Files (x86)\FontForgeBuilds\bin
(成功):
03-14 20:16:08 C:\Program Files (x86)\FontForgeBuilds\bin> ffpython D:\code00.py
Executable: C:\Program Files (x86)\FontForgeBuilds\bin\ffpython.exe
Version: 3.10.9 (main, Dec 10 2022, 09:16:22) [GCC 12.2.0 32 bit]
CWD: C:\Program Files (x86)\FontForgeBuilds\bin
UName: None
PATH: C:\Program Files\PowerShell\7;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\libnvvp;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64_win\compiler;C:\Program Files (x86)\Common Files\Intel\Shared Files\cpp\bin\Intel64;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64_win\compiler;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\ia32_win\compiler;C:\Python\Python310\Scripts\;C:\Python\Python310\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\BIN;C:\Program Files\Git\cmd;C:\Program Files\GitHub CLI\;C:\Program Files\7-Zip;C:\Program Files\NVIDIA Corporation\Nsight Compute 2020.1.1;C:\Program Files\dotnet\;C:\Program Files\CMake\bin;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\PowerShell\7\;C:\Program Files (x86)\FontForgeBuilds\bin;C:\Users\myusername\AppData\Local\Microsoft\WindowsApps;C:\Users\myusername\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\myusername\.dotnet\tools;C:\Program Files (x86)\FontForgeBuilds\bin\
PYTHONHOME: None
PYTHONPATH: None
sys.path: ['D:\\', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python310.zip', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10\\lib-dynload', 'C:\\Program Files (x86)\\FontForgeBuilds\\bin', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10\\site-packages']
Python 3.10.9 (main, Dec 10 2022, 09:16:22) [GCC 12.2.0 32 bit] 032bit on win32
<module 'fontforge' from 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10\\site-packages\\fontforge.pyd'>
['SpiroVersion', 'UnicodeAnnotationFromLib', 'UnicodeBlockCountFromLib', 'UnicodeBlockEndFromLib', 'UnicodeBlockNameFromLib', 'UnicodeBlockStartFromLib', 'UnicodeNameFromLib', 'UnicodeNames2FromLib', 'UnicodeNamesListVersion', '__date__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', 'activeFont', 'activeFontInUI', 'activeGlyph', 'activeLayer', 'ask', 'askChoices', 'askMulti', 'askString', 'awcontext', 'awglyph', 'configurePlugins', 'contour', 'cvt', 'defaultOtherSubrs', 'font', 'fonts', 'fontsInFile', 'getConvexNib', 'getPluginInfo', 'getPrefs', 'glyph', 'glyphPen', 'hasSpiro', 'hasUserInterface', 'hooks', 'layer', 'layer_array', 'layerinfo', 'layerinfo_array', 'loadEncodingFile', 'loadNamelist', 'loadNamelistDir', 'loadPlugins', 'loadPrefs', 'logWarning', 'math', 'mathKern', 'nameFromUnicode', 'onAppClosing', 'open', 'openFilename', 'parseTTInstrs', 'point', 'postError', 'postNotice', 'preloadCidmap', 'printSetup', 'private', 'readOtherSubrsFile', 'references', 'registerGlyphSeparationHook', 'registerImportExport', 'registerMenuItem', 'runInitScripts', 'saveFilename', 'savePrefs', 'scriptFromUnicode', 'scriptPath', 'selection', 'setConvexNib', 'setPrefs', 'spiroCorner', 'spiroG2', 'spiroG4', 'spiroLeft', 'spiroOpen', 'spiroRight', 'splineCorner', 'splineCurve', 'splineHVCurve', 'splineTangent', 'unParseTTInstrs', 'unicodeFromName', 'unitShape', 'unspecifiedMathValue', 'userConfigPath', 'version']
Done.
所以我需要弄清楚为什么只有当我的PWD是C:\Program Files (x86)\FontForgeBuilds\bin
时才能正常工作,我不明白为什么它不能正常工作。
1条答案
按热度按时间iezvtpos1#
刚刚安装了 FontForge 20230101。使用以下测试脚本。
输出:
以及(扩展)模块 * 依赖项 *([GitHub]: lucasg/Dependencies)窗口:
显然,一切正常,唯一合乎逻辑的结论是,你的环境一团糟。
然后我注意到一个“小”细节:您使用的是虚拟环境。
输出(另一个(Cmd)端子):
查看 sys.path 的最后一个条目(在两种情况下),就会明白为什么会发生这种情况。
因此,这是一个与虚拟环境相关的问题。更准确地说,这是一个虚拟环境访问 Python 示例(系统)的 site-packages 目录的问题。
为了解决这个问题,在创建虚拟环境时,传递 --system-site-packages 标记,如中所述:
产出(续):
重要提示:
因此,尝试通过其中一个(或基于它们的虚拟环境)加载 .pyd 可能会产生UndefinedBehavior
更多调试信息
如图所示,它也可以在 PS 下运行,不需要(或很少)手动干预。如果您这边不起作用,请尝试运行:
1.上述步骤
1.FFPython,但从其目录
ffpython -c "import os, sys;os.add_dll_directory(os.path.dirname(sys.executable));import fontforge"
在调试以下类型的错误时非常有用:
更新 #0
最后一次发现后,很可能 fontforge.pyd 的一些(旧/新版本)dependent .dll 位于 %PATH% 中列出的某些目录中,并且它们在正确版本(从 FontForge 的 bin 目录)之前加载。这要解决一些问题:
1.从上面的列表中读取第一个 URL 并安装 Dependencies。
1.然后,当从以下位置启动(Dependencies 工具)时,您必须比较 fontforge.pyd 的依赖 .dll:
1.FontForge 的 bin 目录
1.另一个
任何 .dlls在以前的位置不应该出现在(或者如果他们是,他们应该有相同的版本)在任何其他(在 %PATH% 中它之前)。你可以使用 GUI 版本或 CmdLine 版本(如下图- FontForge 的 bin 目录在右边):
我用来列出相关 .dll 的命令(显然,您必须调整路径):
另一种方法是在通过 FFPython 启动脚本时使用 ProcMon([MS.Learn]: Process Monitor),如[SO]: C DLL loads in C++ program, not in python Ctypes (@MarkTolonen's answer)所示
这样,加载 .dll(s)发生在一个沙箱环境中(关于 %PATH%),不受任何目录的影响。
cd ${FONTFORGE_BIN_DIR}
)