[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Segfault on loading font from StringIO



Hi,

On 02/01/12 05:45 AM, Radomir Dopieralski wrote:
I think that this comment is related to this problem:
http://archives.seul.org/pygame/users/Jan-2004/msg00035.html
No, this is a different problem. pygame.font.Font probably could not find the default font file and segfaulted rather than throw a nice Python exception. This may have been fixed. I can check.

On Mon, Jan 2, 2012 at 13:46, Russell Jones<russell.jones@xxxxxxxxx>  wrote:
In summary, the font reading function in SDL relies on a filename, so as it
stands, reading from a file-like object won't work. Covering the buffer to a
string causes the data to be interpreted as a filename, which unsurprisingly
gives an IOError saying the font filename can't be read (line 600 of
font.c).

I had a look on Debian testing in a VM, and it seems to be happening in
SDL_RWFromFile, which is not in font.c, but is called by its functions. I
couldn't see where the error was happening in font.c as there are no pygame
debug symbols available. I'm guessing it's the line
rw = RWopsFromPython (fileobj)
(RWopsFromPython is from rwobject.c and calls get_standard_rwop, which calls
either SDL_RWFromFile or SDL_RWFromFP if it can't extract a name from
fileobj)

It seems likely to be related to this comment in font_init() : /*check if it
is a valid file, else SDL_ttf segfaults*/. I guess SDL_RWFromMem could be
used with some kind of translation from the buffer, or SDL_RWFromFile could
be altered to accept a file object. The SDL API spec for FromFile relies on
a filename, however, and FromFile does the opening of the file itself using
that.

Russell

On 1 January 2012 10:50, Radomir Dopieralski<pygame@xxxxxxxxxxxx>  wrote:
Hello everyone,

I'm having a problem loading a font file from a python file-like
object. According to the documentation at
http://www.pygame.org/docs/ref/font.html#pygame.font.Font this should
be possible, however, I get a segmentation fault every time I pass a
file-like object that is not created by opening a real file. I want to
load all my assets from a zip archive, so it's not possible to have a
real file in the filesystem.

A simple test case:

import pygame
import StringIO

pygame.font.init()

f = open("somefont.ttf", "r")
font = pygame.font.Font(f, 8) # Works fine
f.close()

f = open("somefont.ttf", "r")
buffer = StringIO.StringIO(f.read())
f.close()
font = pygame.font.Font(buffer, 8) # Segfault

Is there any way to make it work as documented? If the documentation
is wrong, is there any way to create a pygame font object without
creating a real file in the filesystem?

Thanks,
--
Radomir Dopieralski

The Font type should accept any Python object with read(), seek() and close() methods. However, Pygame 1.9.1 and earlier have a Font bug involving file like objects that are not actual file objects. Basically, threading is improperly handled. It probably worked if early versions of the freetype library were single threaded. But freetype now appears to be multithreaded. Therefore the segfault. I fixed this for Pygame 1.9.2 (still in development) so I get no segfault; it works as advertised.

Lenard Lindstrom