2010-11-25 28 views
0

我发现这个脚本附加到a thread in the fontforge-users mailing list。它确实我想要的。但是,它似乎只适用于32位系统,我真的很想在我的64位系统上使用它。帮助转换python ctypes结构为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() 
+0

为什么有人用Python编码?这是我在C中会做的很少的事情之一。 – 2010-11-25 10:28:48

+0

@Sven Marnach - 我可以看到你的观点。从我自己的角度来看,我正在寻找一种在更复杂的python脚本中调用此方法的方法,所以如果我能够实现它,这种方法会吸引我。如果我能够用C重写这个,我会对此敞开心扉,但是我想我仍然需要处理相同的体系结构问题? – simon 2010-11-26 03:22:53

回答

2

问题是FONTFORGE_CONFIG_USE_LONGDOUBLE是否定义在/usr/include/fontforge/config.h中。如果它被定义,那么代码的定义是正确的。在我的AMD64 Linux安装,既不FONTFORGE_CONFIG_USE_LONGDOUBLE也不FONTFORGE_CONFIG_USE_DOUBLE定义,所以我需要改变

real = c_float 

随着这种变化,它工作正常。