J'ai trouvé ce script attaché à a thread in the fontforge-users mailing list. Il fait exactement ce que je veux. Cependant, il semble que pour travailler sur les systèmes 32 bits, et je voudrais vraiment l'utiliser sur mon système 64 bits.aide pour convertir python ctypes struct en 64bit
J'ai fait un peu de lecture mais je n'arrive pas à comprendre comment je devrais modifier ce script (probablement le code?) Pour le faire fonctionner sous une architecture 64 bits. Quelqu'un peut-il aider?
À la votre!
#!/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()
Pourquoi quelqu'un a-t-il codé ceci en Python? C'est l'une des rares choses que j'aurais fait en C. –
@Sven Marnach - Je peux voir votre point de vue. De mon point de vue, je cherche un moyen d'appeler cela à partir d'un script python plus compliqué, donc cette approche, si je peux le faire fonctionner, me plaît. Si j'étais capable de réécrire cela en C, je serais ouvert à cela, mais je suppose que je devrais encore faire face au même problème d'architecture? – simon
Je ne vois pas la raison d'un problème 64 bits, ni dans le code Python ci-dessus, ni dans le recodage en C. Mais la version C de ce script serait vraiment courte. Vous pouvez l'appeler à partir de Python en tant que sous-processus ou via des ctypes. –