SimpleCFF2DEcompiler
CFF2CharString
GlobalSubrsIndex2
SubrsIndex2
CharstringIndex2
Working towards using one set of classes for both CFF2 and CFF data.
This is useful to quickly add logging functionality to classes, and
to reduce boilerplate.
It adds a 'log' property to the class inheriting from it, which uses
logging.getLogger to get a logging.Logger (sigleton) object named after
<module>.<class> of self.
Can be useful for writing tests:
>>> with CapturingLogHandler(log, "WARNING") as captor:
... # do something with logging
>>> assert captor.match('some .* pattern')
After 2b2aca1, DictCompiler/Decompiler's `arg_delta` method unconditionally attempts to get the first item to check if it's a list, but this fails with `IndexError` when the value is empty.
```
Traceback (most recent call last):
[...]
File "/Users/cosimolupo/Documents/Github/ufo2ft/Lib/ufo2ft/otfPostProcessor.py", line 15, in __init__
otf.save(stream)
File "/Users/cosimolupo/Documents/Github/fonttools/Lib/fontTools/ttLib/__init__.py", line 219, in save
self._writeTable(tag, writer, done)
File "/Users/cosimolupo/Documents/Github/fonttools/Lib/fontTools/ttLib/__init__.py", line 658, in _writeTable
tabledata = self.getTableData(tag)
File "/Users/cosimolupo/Documents/Github/fonttools/Lib/fontTools/ttLib/__init__.py", line 669, in getTableData
return self.tables[tag].compile(self)
File "/Users/cosimolupo/Documents/Github/fonttools/Lib/fontTools/ttLib/tables/C_F_F_.py", line 20, in compile
self.cff.compile(f, otFont)
File "/Users/cosimolupo/Documents/Github/fonttools/Lib/fontTools/cffLib.py", line 124, in compile
writer.toFile(file)
File "/Users/cosimolupo/Documents/Github/fonttools/Lib/fontTools/cffLib.py", line 300, in toFile
endPos = pos + item.getDataLength()
File "/Users/cosimolupo/Documents/Github/fonttools/Lib/fontTools/cffLib.py", line 1858, in getDataLength
return len(self.compile("getDataLength"))
File "/Users/cosimolupo/Documents/Github/fonttools/Lib/fontTools/cffLib.py", line 1879, in compile
data.append(arghandler(value))
File "/Users/cosimolupo/Documents/Github/fonttools/Lib/fontTools/cffLib.py", line 1910, in arg_delta
val0 = value[0]
IndexError: list index out of range
``
On python2.7, the fonttools py23 module registers a 'lastResort' StreamHandler
similar to the one found in python3's logging module, that always writes
to the current value `sys.stderr`.
This also applies to any python library that imports from fontTools.misc.py23
under python2.7.
The logging module has a 'shutdown' atexit handler that flushes all the
logging handlers' streams just before the python interpreter exits.
Sometimes (e.g. when calling `python setup.py test` as in MutatorMath's test
suite), the interpreter termination ends with a traceback, which is
triggered by the atexit handler failing to flush the lastResort handler's
stream, sys.stderr
AttributeError: None has no attribute 'stderr'
This is because during module teardown, the globals (in this case 'sys')
are set to None, and the order in which modules are deleted is not
guaranteed.
See 58531934a8
We shall reuse it as base class for the _DehintingT2Decompiler in subset module,
as we need to save the width in order to re-insert it after dropping the hints.
Apparently b"string %s" % (b"interpolation") works on Python 3.5 but not on 3.4.
We whall maybe start thinking about dropping support for 3.4, now that 3.6 is out next week...
When writing unit tests for XML data, it is more convenient to compare
list of lines, instead of a single string without newlines.
This helps identifying which lines in the diff printed on the console
don't match the expected result.
So, getXML now returns a list of lines,
To allow passing the same list of lines to the complementary parseXML
function in the roundtrip tests, parseXML now also accepts a list of
strings, as well as a single string.
We also use unicode_literals, and ensure that if the test modules passes
unicode str, we first encode to UTF-8 before passing on to expat XML
parser. This is because on Python 2, expat only accepts bytes strings.
We only define 'round3' for PY2 and 'round2' for PY3, and also make sure 'round3' is always an alias of
the built-in 'round' on Python 3; and similarly 'round2' is an alias of built-in 'round' on Python 2.
Thus, for clarity, one can do:
from fontTools.misc.py23 import round3 as round
or
from fontTools.misc.py23 import round2 as round
and be certain that the fast built-in implementation will be used on the
respective python major version.
By default (newlinestr=None), the XMLWriter will still use the `os.linesep` as the
newline string.
Otherwise, it will use the specified `newlinestr`.
This is useful when TTX files under version control are being written from
multiple platforms; in which case, one usually wants to always use one
specific line ending (most likely LF, which is what the XML spec itself
normalizes it to).