【发布时间】:2011-05-15 14:29:03
【问题描述】:
我发现此脚本附加到a thread in the fontforge-users mailing list。 正是我想要的。但是,它似乎只适用于 32 位系统,我真的很想在我的 64 位系统上使用它。
我做了一些阅读,但我不知道应该如何修改这个脚本(大概是 stuct?)以使其在 64 位架构下工作。有人可以帮忙吗?
干杯!
#!/usr/bin/python
# vim:ts=8:sw=4:expandtab:encoding=utf-8
# Export named font from PDF file using fontforge and ctypes
import sys
from ctypes import *
STRING = c_char_p
real = c_longdouble
# We need the `map` attribute of SplineFont, so declear an incomplete struct.
# see: http://sourceforge.net/projects/wqy/files/misc/
# file: fontforge-bindctypes-0.1.tar.bz2
class splinefont(Structure):
pass
SplineFont = splinefont
splinefont._fields_ = [
('fontname', STRING),
('fullname', STRING),
('familyname', STRING),
('weight', STRING),
('copyright', STRING),
('filename', STRING),
('defbasefilename', STRING),
('version', STRING),
('italicangle', real),
('upos', real),
('uwidth', real),
('ascent', c_int),
('descent', c_int),
('uniqueid', c_int),
('glyphcnt', c_int),
('glyphmax', c_int),
('glyphs', POINTER(c_void_p)),
('changed', c_uint, 1),
('changed_since_autosave', c_uint, 1),
('changed_since_xuidchanged', c_uint, 1),
('display_antialias', c_uint, 1),
('display_bbsized', c_uint, 1),
('dotlesswarn', c_uint, 1),
('onlybitmaps', c_uint, 1),
('serifcheck', c_uint, 1),
('issans', c_uint, 1),
('isserif', c_uint, 1),
('hasvmetrics', c_uint, 1),
('loading_cid_map', c_uint, 1),
('dupnamewarn', c_uint, 1),
('encodingchanged', c_uint, 1),
('multilayer', c_uint, 1),
('strokedfont', c_uint, 1),
('new', c_uint, 1),
('compacted', c_uint, 1),
('backedup', c_uint, 2),
('use_typo_metrics', c_uint, 1),
('weight_width_slope_only', c_uint, 1),
('save_to_dir', c_uint, 1),
('head_optimized_for_cleartype', c_uint, 1),
('ticked', c_uint, 1),
('internal_temp', c_uint, 1),
('complained_about_spiros', c_uint, 1),
('use_xuid', c_uint, 1),
('use_uniqueid', c_uint, 1),
('fv', c_void_p),
('metrics', c_void_p),
('uni_interp', c_int),
('for_new_glyphs', c_void_p),
('map', c_void_p),
# ...
]
def main():
if len(sys.argv) != 3:
print "Usage: %s doc.pdf fontname" % sys.argv[0]
sys.exit(2)
pdfname = sys.argv[1]
fontname = sys.argv[2]
fontfile = fontname + '.ttf'
# ctypes functions
libc = CDLL("libc.so.6")
libc.fopen.restype = c_void_p
libc.fopen.argtype = [c_char_p, c_char_p]
lib_ff = CDLL('libfontforge.so.1')
# SplineFont *_SFReadPdfFont(FILE *pdf,char *filename,
# char *select_this_font, enum openflags openflags)
lib_ff._SFReadPdfFont.argtypes = [c_void_p, c_char_p, c_char_p, c_int]
lib_ff._SFReadPdfFont.restype = POINTER(SplineFont)
# int GenerateScript(SplineFont *sf, char *filename, char *bitmaptype,
# int fmflags, int res, char *subfontdefinition, struct sflist *sfs,
# EncMap *map, NameList *rename_to,int layer)
lib_ff.GenerateScript.argytpes = [POINTER(SplineFont), c_char_p, c_char_p,
c_int, c_int, c_char_p, c_void_p, c_void_p, c_void_p, c_int]
lib_ff.GenerateScript.restype = c_int
# need to somehow initialize libfontforge or it will segfault somewhere.
lib_ff.doinitFontForgeMain()
fobj = libc.fopen(pdfname, "rb")
if not fobj:
print "%s not found" % pdfname
sys.exit(1)
font = lib_ff._SFReadPdfFont(fobj, pdfname, fontname, 0)
ret = 0
if bool(font):
ret = lib_ff.GenerateScript(font, fontfile, None, -1, -1, None, None,
font.contents.map, None, 1)
if ret:
print 'Font export to "%s".' % fontfile
else:
print "** Error ** Failed to export font!!"
if __name__ == '__main__':
main()
【问题讨论】:
-
为什么有人用 Python 编写代码?这是我在 C 语言中为数不多的几件事之一。
-
@Sven Marnach - 我明白你的意思。从我自己的角度来看,我正在寻找一种从更复杂的 python 脚本中调用它的方法,所以这种方法,如果我能让它工作的话,对我很有吸引力。如果我能够用 C 重写它,我会对此持开放态度,但我想我仍然必须处理相同的架构问题?
-
我看不出出现 64 位问题的原因,无论是在上面的 Python 代码中还是在 C 中重新编码的情况下。但是这个脚本的 C 版本会很短。您可以从 Python 中将其作为子进程或通过 ctypes 调用。
-
你可以只运行 32 位版本的 Python
-
@David Heffernan:是的,这就是我目前正在做的事情,但这很尴尬而且完全不满意...... :)
标签: python struct 32bit-64bit ctypes