-
Notifications
You must be signed in to change notification settings - Fork 457
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
font.save() fails when trying to overwrite a loaded font #302
Comments
currently it's not possible to overwrite a TTFont, because the reader's file is already open for reading, and can't be also written from the writer at the same time. import tempfile
import shutil
tf = tempfile.TemporaryFile()
with open(path, 'rb') as f:
shutil.copyfileobj(f, tf)
tf.seek(0)
font = TTFont(tf) |
Alright, thanks for confirming and for providing a workaround. |
if there's demand for it, maybe we could do something like this by default upon loading a TTFont? /cc @behdad |
This is definitely in the right direction. Alternatively we can just right the font into memory and wrap a stream around it. I think I like that even better. Note that the lazy parameter to TTFont() helps a bit with this, but I never got to implement non-lazy in sfnt.py. |
I did that in PR #308. |
Thanks. The name is indeed used by the bitmaps/ code that you fixed recently. |
Right now we do a lot of conversions between file-like object and actual data. Over time we can change all to keep reference to byte() only. |
Another nice thing about this change is that we can now load font from unseekable streams. |
Cool! |
Nice! Thanks guys. |
This is great. |
As discussed here: #580 (comment) Before: $ python -m timeit 'from fontTools.ttLib import TTFont; TTFont("sazanami-gothic.ttf")' 10 loops, best of 3: 66.9 msec per loop After: $ python -m timeit 'from fontTools.ttLib import TTFont; TTFont("sazanami-gothic.ttf")' 10000 loops, best of 3: 110 usec per loop That's a 600x speedup! Fixes #482 HOWEVER, it reintroduces #302 Or worse, we'll crash when overwriting: $ cp Lobster.ttf t.ttf $ ./ttx -o ./t.ttf ./t.ttf Dumping "./t.ttf" to "./t.ttf"... Dumping 'GlyphOrder' table... Bus error (core dumped) IMO we should fix this by changing both XML and font output routines to, instead of calling open, use os.tmpfile(), create output in a new file and then rename it to the final destination. It has the benefit of not leaving a half-written output file behind if an exception occurs. The tempfile.NamedTemporaryFile also comes handy. While checking those out, tempfile.SpooledTemporaryFile also comes handy, when it's available, to replace BytesIO in the following part of TTFont.save(): # write to a temporary stream to allow saving to unseekable streams tmp = BytesIO() Looks like we need to start misc.fileTools to abstract the details away.
As discussed here: #580 (comment) Before: $ python -m timeit 'from fontTools.ttLib import TTFont; TTFont("sazanami-gothic.ttf")' 10 loops, best of 3: 66.9 msec per loop After: $ python -m timeit 'from fontTools.ttLib import TTFont; TTFont("sazanami-gothic.ttf")' 10000 loops, best of 3: 110 usec per loop That's a 600x speedup! Fixes #482 HOWEVER, it reintroduces #302 Or worse, we'll crash when overwriting: $ cp Lobster.ttf t.ttf $ ./ttx -o ./t.ttf ./t.ttf Dumping "./t.ttf" to "./t.ttf"... Dumping 'GlyphOrder' table... Bus error (core dumped) IMO we should fix this by changing both XML and font output routines to, instead of calling open, use os.tmpfile(), create output in a new file and then rename it to the final destination. It has the benefit of not leaving a half-written output file behind if an exception occurs. The tempfile.NamedTemporaryFile also comes handy. While checking those out, tempfile.SpooledTemporaryFile also comes handy, when it's available, to replace BytesIO in the following part of TTFont.save(): # write to a temporary stream to allow saving to unseekable streams tmp = BytesIO() Looks like we need to start misc.fileTools to abstract the details away.
Take a look at this simple script:
Am I doing something wrong?
The text was updated successfully, but these errors were encountered: