freetype-py icon indicating copy to clipboard operation
freetype-py copied to clipboard

reading stream returns an error

Open jansindl3r opened this issue 4 years ago • 5 comments

When initializing freetype.Face with a byte stream and not path I get this error freetype.ft_errors.FT_Exception: FT_Exception: (invalid stream operation). It happens both when parsing it opened file and BytesIO instance. I had a look into freetype.__init__.py:1091 and adding this if statement and changing previous if to elif helped me out. I guess it will need proper solution to come up with, but at least something.

if hasattr(path_or_stream, "getvalue"):
    error = self._init_from_memory(library, face, index, path_or_stream.getvalue())
elif hasattr(path_or_stream, "read"):

jansindl3r avatar Apr 27 '21 08:04 jansindl3r

Oh thanks for the report. Do you think there's a better (i.e. more specific) test for testing if this is a BytesIO? Also, can you make a PR?

rougier avatar May 03 '21 06:05 rougier

Well, after researching a bit on that matter it's mine as the user's fault that the program failed. When you write to BytesIO and pass it to freetype.Face, the stream is on its end after the writing, so no value can be read. You have to go to the beginning with BytesIO.seek(0).

It was a bit frustrating to get no useful feedback from freetype. I would suggest to return error to the user saying that no value could be read instead of navigating to the beginning of the stream. It feels like it would do too much for the user and maybe it's not desired to go to the beginning in every single case when passing BytesIO as a argument.

What do you think?

jansindl3r avatar May 03 '21 12:05 jansindl3r

Does setting "FT2_DEBUG=any:7" help? Don't know how much of freetype's debugging facility works in normal builds, but this is the catch-all for tracing the internals of freetype (and likely requires a debug build, I think).

The message though cryptic, is correct though: reading beyond the end of stream is invalid stream operation...

HinTak avatar May 03 '21 13:05 HinTak

@HinTak It sounds a bit too much to just find out that I did a mistake

It is indeed correct but not very helpful. I was about to give up on my project until I got a bit braver to have a deeper look. I think that it could be a bit more accessible than just passing freetype library's errors. This error to me, as someone who can only code in python and such, sounds like "hey, I can't add these two numbers, I operate base64 and your stream is base128 or whatever". I believe that this is also one of the points of this wrapper - making freetype accessible to more people who are not primarily programmers themselves.

jansindl3r avatar May 03 '21 22:05 jansindl3r

@jansindl3r while in general freetype-py can help by checking / conversing arguments are of the correct type or to the correct type before passing to python's ctypes module which in turn passes to freetype, and indeed freetype-py does in many cases, in this case there is not much one can do in the middle. An opened file / byteio is a pointer to an area of memory supposedly contain valid font data . Other than diving into such a pointer / memory block and examining it as somewhat valid font / stream - and effectively implements/duplicates freetype's own read() operation - there is not much one can do, or should do in this case. There are 5 "invalid steam ..." errors, handle/seek/skip/read/operation.

As a programming exercise, now that you know what's wrong, why don't you have a thought on how to detect a stream that'a already at its end? Note that according to the documentation, fseek() clears the end-of-file indicator. I.e. the moment you try to determine where you are in the stream, the end-of-file state is gone (you are at a position at the end but not "at the end"). This is not freetype specific - it is that standard c library's. If you write such a bit of python code, we'll include it.

You may be surprised to learn that even the main developer of freetype for two+ decades is not "primarily programmers". He is a professional concert pianist/musician. Not bad for somebody who is "not primarily a programmer" to maintain a piece of software that billions of Linux users use for two decades?

HinTak avatar May 04 '21 00:05 HinTak