2014-09-26 86 views
0

此問題與此相關。 Font file loaded from temp file seems incorrect將字體數據保存在內存中

pygame似乎有閱讀後關閉字體文件的習慣,但當它在磁盤上,因爲它可以一遍又一遍地讀取。我們如何將讀取的字體數據保存到內存中,以便可以多次調用它,但是不會丟失其格式?在這種情況下,保存到磁盤的數據應保持爲文件對象?我嘗試了深度複製而沒有成功。下面

def xor(message, key): 
    cryptedMessage = ''.join(chr(ord(c)^ord(k)) for c,k in izip(message, cycle(key))) 

    return cryptedMessage 

#------------------------------------------------------------------------------- 
def decode_fonts(fnt = fnt): 

    """extracts and returns the font files from fnt.py in a dictionary""" 
    coder = "QZY0r[CIlVwq1O#SxBt_2eij%b;3$vJK4,FN&[email protected]!LX8gufh=y9A^UaMsn-oW6" 
    font_fh = {} 
    font_obj = {} 
    point_size = 5 

    for key in fnt.keys(): 

     xorfont = base64.b64decode(fnt[key]) 

     tempbuffer = StringIO() 
     tempbuffer.write(xor(xorfont, coder)) 
     tempbuffer.seek(0) 
     font_fh[key] = tempbuffer 
     #print type(temp), type(font_fh) 

    for key in font_fh.keys(): 
     font_obj[key] = pygame.font.Font(font_fh[key], point_size) 


    return font_fh, font_obj 

給出在打印側

font_fh, font_obj = gs.fontstore.decode_fonts() 

def maketext(msg, fontsize, colour, bgcolour, underline, FONTNAME): 
    """returns the text supplied as an image with x and y diamentions of the image""" 

    mafont = font_obj[FONTNAME] 
    font_fh[FONTNAME].seek(0) 
    mafont = pygame.font.Font(font_fh[FONTNAME], fontsize) 

    mafont.set_underline(underline) 

    fontxy = mafont.size(msg) # get image size x, y for print formatting 

    if bgcolour is None: 

     matext = mafont.render(msg, True, colour) 
    else: 
     matext = mafont.render(msg, True, colour, bgcolour) 

    matext = matext.convert_alpha() 

    return [matext, fontxy] 

    text1 = maketext(msg1, 40, WHITE, None, False, FONT1) 
    text2 = maketext(msg2, 40, WHITE, None, False, FONT2) 
    text3 = maketext(msg2, 40, WHITE, None, False, FONT3) 
    text4 = maketext(msg2, 40, WHITE, None, False, FONT4) 
    text5 = maketext(msg2, 40, WHITE, None, False, FONT5) 
    text6 = maketext(msg2, 40, WHITE, None, False, FONT6) 


    def update_all(): 
     SCREEN.fill((BLACK)) 
     SCREEN.blit(text1[0], (0, 0)) 
     SCREEN.blit(text2[0], (0, 50)) 
     SCREEN.blit(text3[0], (0, 100)) 
     SCREEN.blit(text4[0], (0, 150)) 
     SCREEN.blit(text5[0], (0, 200)) 
     SCREEN.blit(text6[0], (0, 250)) 


     pygame.display.update() 

    def get_keys(): 
     global run 
     for event in pygame.event.get(): 

      MOUSEPOS = pygame.mouse.get_pos() 

      if event.type is KEYDOWN: 
       if event.key is K_ESCAPE: 
        run = False 

    while run: 

     clock.tick(60) 
     get_keys() 
     #text6 = maketext(msg2, 40, WHITE, None, False, FONT6) 

     update_all() 

if __name__=='__main__': 
    main() 

這工作完全的代碼,但如果我去掉了 '#text6 = maketext(MSG2,40%,白色,無,假,FONT6)' 行在while循環中,程序停止投擲錯誤

ValueError: I/O operation on closed file 

需要支持。

+3

你爲什麼在意?只需讀一次字體並保留對'pygame.font.Font'的引用,而不需要再次讀取字體文件。 – 2014-09-26 07:43:00

+0

True,但是該引用指向stringIO位置,該位置由從存儲在pyfile中的字典中加載的字體數據引用。以任何常規方式在磁盤上沒有字體。所以一旦讀取文件就關閉了,我必須再次通過整個過程來獲取字體。這是我想要避免的。 – wookie 2014-09-26 07:54:53

+1

查看代碼:每次調用'maketext'時,都會創建一個新的'Font'實例。爲什麼不簡單地緩存實例,而不是每次從頭開始創建字體? – 2014-09-26 15:35:43

回答

0

在考慮了上面的建議後,下面的代碼是成功的。 將字體構建例程移至單獨的函數。

def makefont(FONTNAME, fontsize): 
     """the font type and size given the custom made font is returned""" 

     encryptedfont = base64.b64decode(fntdata[FONTNAME]) 

     tempbuffer = StringIO() 
     tempbuffer.write(XOR(encryptedfont, coder)) 
     tempbuffer.seek(0) 

     madefont = pygame.font.Font(tempbuffer, fontsize) 

     return madefont 

def maketext(msg, colour, bgcolour, underline, madefont): 
    """returns the text supplied as an image with x and y diamentions of the image""" 

    madefont.set_underline(underline) 

    fontxy = madefont.size(msg) # get image size x, y for print formatting 

    if bgcolour is None: 

     matext = madefont.render(msg, True, colour) 
    else: 
     matext = madefont.render(msg, True, colour, bgcolour) 

    matext = matext.convert_alpha() 

    return [matext, fontxy] 

調用maketext()當我需要改變字體大小,否則maketext從以前的時間重用madefont