99 Commits

Author SHA1 Message Date
Miguel Sousa
5e115c1d2a [CFF2] Report the correct number of regions in the font
This change also makes the processing of the blend operator to be as described at https://www.microsoft.com/typography/otspec/cff2charstr.htm#section4.5
2017-03-23 17:12:31 -07:00
Miguel Sousa
bba1d9f225 [CFF2] Support ‘maxstack’ 2017-03-13 00:02:13 -07:00
Miguel Sousa
64d5119642 whitespace 2017-03-09 21:30:28 -08:00
Cosimo Lupo
2e46476671
[cffLib] fix IndexError when dumping toXML empty deltas
$ ttx -t CFF "font.otf"
Dumping "font.otf" to "font.ttx"...
Dumping 'CFF ' table...
ERROR: Unhandled exception has occurred
Traceback (most recent call last):
  File "fonttools/Lib/fontTools/ttx.py", line 384, in main
    process(jobs, options)
  File "fonttools/Lib/fontTools/ttx.py", line 358, in process
    action(input, output, options)
  File "fonttools/Lib/fontTools/misc/loggingTools.py", line 372, in wrapper
    return func(*args, **kwds)
  File "fonttools/Lib/fontTools/ttx.py", line 258, in ttDump
    newlinestr=options.newlinestr)
  File "fonttools/Lib/fontTools/ttLib/__init__.py", line 311, in saveXML
    self._tableToXML(tableWriter, tag, progress)
  File "fonttools/Lib/fontTools/ttLib/__init__.py", line 348, in _tableToXML
    table.toXML(writer, self, progress)
  File "fonttools/Lib/fontTools/ttLib/tables/C_F_F_.py", line 42, in toXML
    self.cff.toXML(writer, progress)
  File "fonttools/Lib/fontTools/cffLib.py", line 135, in toXML
    font.toXML(xmlWriter, progress)
  File "fonttools/Lib/fontTools/cffLib.py", line 2178, in toXML
    BaseDict.toXML(self, xmlWriter, progress)
  File "fonttools/Lib/fontTools/cffLib.py", line 2128, in toXML
    conv.xmlWrite(xmlWriter, name, value, progress)
  File "fonttools/Lib/fontTools/cffLib.py", line 1120, in xmlWrite
    value.toXML(xmlWriter, progress)
  File "fonttools/Lib/fontTools/cffLib.py", line 2128, in toXML
    conv.xmlWrite(xmlWriter, name, value, progress)
  File "fonttools/Lib/fontTools/cffLib.py", line 1089, in xmlWrite
    if isinstance(value[0], list):
IndexError: list index out of range
2017-03-09 15:40:52 +00:00
Cosimo Lupo
33b42f47b6
[cffLib/psCharStrings] fix IndexError with empty deltas
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
``
2017-03-09 14:21:38 +00:00
Cosimo Lupo
ca235ea8a1
[cffLib] fix "TypeError: cannot use a string pattern on a bytes-like object"
This is just to make the tests pass, otherwise the following re.sub call fails with TypeError on Python 3.

However, I wonder why we need to replace all newlines with spaces in 'Notice' and 'Copyright' fields?

```
if name in ['Notice', 'Copyright']:
    value = re.sub(r"[\r\n]\s+", " ", value)
```

We shall ask Read about this.
2017-03-05 23:11:41 +00:00
ReadRoberts
f208bf3421
1) Fold back in the changes introduced by Just van Possum in patch 744
2) Moved the C_F_F__2_test.py files and script under Tests/, paralleling what was done the C_F_F test  files.
2017-03-05 22:53:05 +00:00
ReadRoberts
2b2aca1290
Add CFF2 support. 2017-03-05 22:53:04 +00:00
Cosimo Lupo
0b7da14b41
[cffLib] always write "charset is dumped separately..." comment 2017-03-02 12:50:18 +00:00
justvanrossum
4d92fcb9be do a bare 'raise' so the original traceback doesn't get lost 2017-02-20 10:03:16 +01:00
justvanrossum
f713c93340 made warning even more specific 2016-11-26 14:05:23 +01:00
justvanrossum
7eff97e08b made warning more specific 2016-11-26 14:05:23 +01:00
justvanrossum
4a5c838b5b Improve the warnings issued when 'useless' FontDict key/value pairs are provided either by an OTF, or a TTX file; It now warns reliably in both those cases. 2016-11-26 14:05:23 +01:00
justvanrossum
ce73bba3f3 use log.warning() instead of log.log(logging.WARNING, ...) 2016-11-26 14:05:23 +01:00
justvanrossum
cce31c9950 Also warn when keys are ignored upon compile. 2016-11-26 14:05:23 +01:00
justvanrossum
8d22c39d0b Output an XML comment with the keys that were ignored; Added references to the other issues involved. 2016-11-26 14:05:23 +01:00
justvanrossum
f9d265d1e6 This commit fixes #740.
Commits 3063def and 5b47971 introduced a separate fontDictOperators list for FontDict, only listing those TopDict key/value pairs that are actually used in the FontDict context. It provided a fallback that TTX files containing such "useless" key/value pairs would not be rejected.

However, the code still rejected binary fonts that contained such values, even though it didn't before, and yes, such fonts exist. Also: such fonts are not broken per spec, they just contain some fields that otherwise no one ever looks at, so it's a little harsh to reject them.

This patch removes most of the special FontDict code, and uses everything from TopDict, *except* the order attribute: it sets that to a list of the relevant keys for the FontDict. The effect of this is that "useless" key/value pairs are ignored, not just upon reading XML, but also upon decompilation and compilation of binary fonts. It improves on the previous XML reading behavior in that it no longer silently ignores key typos in the TTX input.

Ideally, we would *output* everything that is actually in the FontDict to TTX, and only ignore the values when compiling, but I didn't find a clean solution for that, so I decided to just fix the issue.
2016-11-26 14:05:23 +01:00
Behdad Esfahbod
3ec06df194 Fix failing tests 2016-09-27 19:53:58 +02:00
ReadRoberts
5b479716bc Fix bugs in cffLib.py. 1) In the last commit, I added logic to use a CFF predefined charset when possible. This is not allowed In CID fonts. Added a test to NOT do this when font is CD. 2) Added exception handler when reading FontDict XML to skip unknown fields. In previous versions, all the default key/value pairs for the TopDict were (incorrectly) written to FDArray FontDicts. New logic does not do that, but also should not fail when it sees any of these key/value pairs. 3) Changed the expected txt files for some of the subset tests. For the CID example, this meant removing the unnecessary key/value pairs from the FDArray FontDicts. For all, it meant adding the major.minor CFF version fields. 2016-09-27 19:49:41 +02:00
ReadRoberts
99394d90bb Fix bug in processing charset info. When predefined charset is specified in an OTF CFF ( TopDict.charset < 2),, the charset was always filled with the entire predefined charset, instead of charset[:nGlyphs]. Also added logic to write a predefined charset code instead of a custom charset when that is possible: this was not happening before. 2016-09-27 19:49:41 +02:00
ReadRoberts
edbee6e4cb Write major/minor fields to XML. Now that we have CFF2, it is worth being explicit about this 2016-09-27 19:49:41 +02:00
ReadRoberts
3063def35b Fixed writing FDArray FontDict structures for CID-keyed CFF fonts. Old logic was reading/writing using TopDict methods, and items like the CIDFontName and Encoding were getting written to XML, and back into the compiled FontDict data. Fixed by defining a list of operators supported in FontDict objects, which is a subset of the TopDict operators, and referencing these in the FontDict object methods. 2016-09-27 19:49:41 +02:00
ReadRoberts
8dc4edceda Fix bug in writing an empty INDEX table. This is supposed to contain only the two-bye count field. Code was also writing the final sentinel offset in the offset list, even though there were no items. This is harmless, but adds a couple useless bytes. Also fixed the calculation of the offset size in the CFF header. Again harmless, since this value isn't used anywhere, but makes it harder to compare CFF's built by different tools. 2016-09-27 19:49:41 +02:00
Miguel Sousa
8bf1bd4f30 [cff] fix fetching of fdSelectIndex value 2016-07-06 10:27:02 -06:00
Miguel Sousa
c04a6d922c [cff] fdSelect array only exists in CID fonts, so test for the presence of fdArray and set the selector value to None otherwise 2016-07-06 04:23:43 -06:00
Cosimo Lupo
6c1c2a44d1 cffLib: use tostr() when getting SID of indexed string (or we end up with duplicates in py3)
I noticed this issue while porting compreffor to py3. In my test fonts, the binary
CFF tables as generated with python 2 sometimes were slightly different from the
ones generated with python 3, although the TTX dump was identical!

It turns out, when running in Python 3, cffLib adds extra entries to the
list of CFF indexed strings, because of bytes vs str.

The `IndexedStrings.getSID` method takes an input string 's' and and returns
the SID integer for that string. If it's a new string, it gets appended to the
list, as well as to an internal strings-to-SID mapping, so that the same SID
value is returned for any given string.

The problem with python 3 was that, if the input string was of `bytes` type
instead of `str`, then the test for inclusion (the dict's `__contains__`)
would return False, and as a result the "same" string (e.g. "Regular" and
b"Regular") could be encoded twice in the list of CFF strings.

(yes, we desperately need unit tests for cffLib...)
2016-05-16 13:11:46 +01:00
Cosimo Lupo
e68e7332a4 [cffLib] replace print with logger (but keep debug messages off)
All these debug messages were disabled, and I don't wish to re-enable them
while running TTX in verbose mode. So here I use a custom level less than
logging.DEBUGm to make sure they will be muted even when the logger's level
is equal to logging.DEBUG.
2016-01-27 19:02:48 +00:00
mashabow
57e7a6b7a7 [cffLib] Fix encoding of Notice and Copyright values in XML on Python 2 2015-07-03 22:33:17 +09:00
Behdad Esfahbod
df2906b0ad Fix a few issues found by landscape.io 2015-04-26 02:17:13 -04:00
Behdad Esfahbod
b30e12ae00 More whitespace 2015-04-26 02:01:01 -04:00
Behdad Esfahbod
bd67253118 Some more whitespace fixes from pep8 tool 2015-04-26 01:59:01 -04:00
Behdad Esfahbod
bc7cf1fd5d [cffLib] Packing charset with only .notdef glyph fails
Fixes https://github.com/behdad/fonttools/issues/136
2014-07-09 14:30:06 -04:00
Behdad Esfahbod
ade1972557 Remove CFF Index.count member
Clean up.  len(index) should be used instead.
2014-06-16 15:35:15 -04:00
Behdad Esfahbod
b7367012e4 Add __contains__ to cffLib 2014-06-13 12:47:55 -04:00
Behdad Esfahbod
3012076942 Minor 2014-05-19 12:43:37 -06:00
Behdad Esfahbod
1ae29591ef from __future__ import absolute_import
Such that our Python 2 is closer to Python 3.

Part of https://github.com/behdad/fonttools/issues/77
2014-01-14 15:07:50 +08:00
Khaled Hosny
522cd11d51 Remove unnecessary new line after <CFF> tag
No other table does that.
2013-12-16 01:29:16 -05:00
Behdad Esfahbod
85a64db541 py23 Another cff encoding fix 2013-12-16 00:05:10 -05:00
Behdad Esfahbod
617ec41d4c Fix encoding conversion in CFF
Was broken with Python 3 and Salsa-Regular.otf for example.
2013-12-10 18:54:26 -05:00
Behdad Esfahbod
9e6ef94b55 Use "is None" instead of "== None"
The latter hits the __eq__ method and can fail because we now
do not allow comparing objects of different types.

For example, was failing subsetting Andika-R.ttf.
2013-12-04 16:35:10 -05:00
Behdad Esfahbod
153ec40209 Fix a few pychecker warnings
Fixes https://github.com/behdad/fonttools/issues/58
2013-12-04 01:15:46 -05:00
Behdad Esfahbod
e388db566b py23 Use new-style classes
Such that we get the same semantics in both Python 2 and 3.
2013-11-28 18:53:30 -05:00
Behdad Esfahbod
d1ba7b53a4 ps23 Fix CFF glyphname encodings 2013-11-28 17:32:44 -05:00
Behdad Esfahbod
024d15317f py23 Fix CFF string encodings 2013-11-28 17:32:44 -05:00
Behdad Esfahbod
c076261598 s/latin-1/latin1/g 2013-11-28 17:32:44 -05:00
Behdad Esfahbod
18316aa769 ps23 More bytes fixes. All ''join()'s fixed 2013-11-28 17:32:43 -05:00
Behdad Esfahbod
319c5fd10e py23 introduce byteord() and use it 2013-11-28 17:32:42 -05:00
Behdad Esfahbod
32c10eecff py23 from __future__ import division and adjust divisions 2013-11-28 17:32:42 -05:00
Behdad Esfahbod
30e691edd0 py23 from __future__ import print_function 2013-11-27 17:27:45 -05:00
Behdad Esfahbod
b7a2d797a4 py23 Use bytechr() instead of chr() 2013-11-27 15:25:00 -05:00