[reportlab-users] ReportLab + Macintosh TTFs
Marius Gedminas
reportlab-users@reportlab.com
Tue, 2 Jul 2002 17:19:02 +0200
Dinu Gherman sent me a couple of Macintosh TTF files which did not work
with ReportLab 1.14. Here's the patch to make them work.
(BTW I don't know what kind of encoding MacRoman is, I just assumed it
was a superset of ASCII.)
Index: pdfbase/ttfonts.py
===================================================================
RCS file: /cvsroot/reportlab/reportlab/pdfbase/ttfonts.py,v
retrieving revision 1.1
diff -u -p -r1.1 ttfonts.py
--- pdfbase/ttfonts.py 28 May 2002 15:33:57 -0000 1.1
+++ pdfbase/ttfonts.py 2 Jul 2002 14:54:58 -0000
@@ -433,13 +433,28 @@ class TTFontFile(TTFontParser):
self.seek(string_data_offset + offset)
if length % 2 != 0:
raise TTFError, "PostScript name is UTF-16BE string of odd length"
+ length = length / 2
psName = ""
- while length > 1:
+ while length > 0:
char = self.read_ushort()
- if char < 0x20 or char > 0x7E:
+ if char < 33 or char > 126 or chr(char) in \
+ ('[', ']', '(', ')', '{', '}', '<', '>', '/', '%'):
raise TTFError, "PostScript contains invalid character U+%04X" % char
psName = psName + chr(char)
- length = length - 2
+ length = length - 1
+ break
+ elif platformId == 1 and encodingId == 0 and languageId == 0 \
+ and nameId == 6: # Macintosh, Roman, English, PS Name
+ # According to OpenType spec, if PS name exists, it must exist
+ # both in MS Unicode and Macintosh Roman formats. Apparently,
+ # you can find live TTF fonts which only have Macintosh format.
+ psName = self.get_chunk(string_data_offset + offset, length)
+ for char in psName:
+ char = ord(char)
+ if char < 33 or char > 126 or chr(char) in \
+ ('[', ']', '(', ')', '{', '}', '<', '>', '/', '%'):
+ raise TTFError, "PostScript contains invalid character %02X" % char
+ break
if not psName:
raise TTFError, "Could not find PostScript font name"
self.name = psName
@@ -556,8 +571,14 @@ class TTFontFile(TTFontParser):
format = self.get_ushort(cmap_offset + offset)
if format == 4:
unicode_cmap_offset = cmap_offset + offset
+ break
+ elif platformID == 0: # Unicode -- assume all encodings are compatible
+ format = self.get_ushort(cmap_offset + offset)
+ if format == 4:
+ unicode_cmap_offset = cmap_offset + offset
+ break
if unicode_cmap_offset is None:
- raise TTFError, 'Font does not have cmap for Unicode (platform 3, encoding 1, format 4)'
+ raise TTFError, 'Font does not have cmap for Unicode (platform 3, encoding 1, format 4 or platform 0 any encoding format 4)'
self.seek(unicode_cmap_offset + 6)
segCount = self.read_ushort() / 2
self.skip(6)
Marius Gedminas
--
If you are smart enough to know that you're not smart enough to be an
Engineer, then you're in Business.