override SFNTReader __deepcopy__ for 'file' isn't copyable; use it in varLib

This commit is contained in:
Cosimo Lupo 2018-12-20 14:18:59 +00:00
parent 9b4509496f
commit 4001ded199
No known key found for this signature in database
GPG Key ID: 59D54DB0C9976482
4 changed files with 29 additions and 15 deletions

View File

@ -123,6 +123,31 @@ class SFNTReader(object):
def close(self):
self.file.close()
def __deepcopy__(self, memo):
"""Overrides the default deepcopy of SFNTReader object, to make it work
in the case when TTFont is loaded with lazy=True, and thus reader holds a
reference to a file object which is not pickleable.
We work around it by manually copying the data into a in-memory stream.
"""
from copy import deepcopy
cls = self.__class__
obj = cls.__new__(cls)
for k, v in self.__dict__.items():
if k == "file":
f = self.file
start = f.tell()
f.seek(0)
buf = BytesIO(f.read())
f.seek(start)
buf.seek(start)
if hasattr(f, "name"):
buf.name = f.name
obj.file = buf
else:
obj.__dict__[k] = deepcopy(v, memo)
return obj
# default compression level for WOFF 1.0 tables and metadata
ZLIB_COMPRESSION_LEVEL = 6

View File

@ -693,19 +693,6 @@ class TTFont(object):
"""
return self["cmap"].getBestCmap(cmapPreferences=cmapPreferences)
def copy(self):
"""Return a new TTFont instance containing the same data.
>>> f1 = TTFont()
>>> f2 = f1.copy()
>>> f2 is not f1
True
"""
buf = BytesIO()
self.save(buf)
buf.seek(0)
return TTFont(buf)
class _TTGlyphSet(object):

View File

@ -40,6 +40,7 @@ from fontTools.designspaceLib import DesignSpaceDocument, AxisDescriptor
from collections import OrderedDict, namedtuple
import os.path
import logging
from copy import deepcopy
from pprint import pformat
log = logging.getLogger("fontTools.varLib")
@ -764,7 +765,7 @@ def build(designspace, master_finder=lambda s:s, exclude=[], optimize=True):
master_ttfs.append(None) # in-memory fonts have no path
# Copy the base master to work from it
vf = master_fonts[ds.base_idx].copy()
vf = deepcopy(master_fonts[ds.base_idx])
# TODO append masters as named-instances as well; needs .designspace change.
fvar = _add_fvar(vf, ds.axes, ds.instances)

View File

@ -8,6 +8,7 @@ from fontTools.varLib import models, VarLibError, load_designspace, load_masters
from fontTools.varLib.merger import InstancerMerger
import os.path
import logging
from copy import deepcopy
from pprint import pformat
log = logging.getLogger("fontTools.varLib.interpolate_layout")
@ -37,7 +38,7 @@ def interpolate_layout(designspace, loc, master_finder=lambda s:s, mapped=False)
log.info("Loading master fonts")
master_fonts = load_masters(designspace, master_finder)
font = master_fonts[ds.base_idx].copy()
font = deepcopy(master_fonts[ds.base_idx])
log.info("Location: %s", pformat(loc))
if not mapped: