[reportlab-users] Chinese Custom Glyphs

Robin Becker robin at reportlab.com
Wed Jul 1 11:33:02 EDT 2015


Hi Daniel,

The code that reads the PS name is below; effectively we're looking for a name 
to use further down the line; in particular we use it in the subset naming.

I don't think you need to care about the exact name, but I managed to use a 
completely made up name using this patch

diff -r c903815560d1 src/reportlab/pdfbase/ttfonts.py
--- a/src/reportlab/pdfbase/ttfonts.py  Wed Jun 24 14:13:27 2015 +0100
+++ b/src/reportlab/pdfbase/ttfonts.py  Wed Jul 01 16:31:05 2015 +0100
@@ -57,6 +57,7 @@
  from reportlab import rl_config
  from reportlab.lib.rl_accel import hex32, add32, calcChecksum, 
instanceStringWidthTTF
  from collections import namedtuple
+import time

  class TTFError(pdfdoc.PDFError):
      "TrueType font exception"
@@ -395,6 +396,7 @@

  class TTFontFile(TTFontParser):
      "TTF file parser and generator"
+    _ninc = 0

      def __init__(self, file, charInfo=1, validate=0,subfontIndex=0):
          """Loads and parses a TrueType font file.
@@ -490,7 +492,9 @@

          # Don't just assume, check for None since some shoddy fonts cause 
crashes here...
          if not psName:
-            raise TTFError("Could not find PostScript font name")
+            self.name = '_rl_%s_%s_ttf' % (time.time(), self.__class__._ninc)
+            self.__class__._ninc += 1
+            #raise TTFError("Could not find PostScript font name")
          for c in psName:
              if char2int(c)>126 or c in b' [](){}<>/%':
                  raise TTFError("psName=%r contains invalid character %s" % 
(psName,ascii(c)))

ie instead of raising an error just fake a name based on current time.



> 		# name - Naming table
> 		name_offset = self.seek_table("name")
> 		format = self.read_ushort()
> 		if format != 0:
> 			raise TTFError("Unknown name table format (%d)" % format)
> 		numRecords = self.read_ushort()
> 		string_data_offset = name_offset + self.read_ushort()
> 		names = {1:None,2:None,3:None,4:None,6:None}
> 		K = list(names.keys())
> 		nameCount = len(names)
> 		for i in xrange(numRecords):
> 			platformId = self.read_ushort()
> 			encodingId = self.read_ushort()
> 			languageId = self.read_ushort()
> 			nameId = self.read_ushort()
> 			length = self.read_ushort()
> 			offset = self.read_ushort()
> 			if nameId not in K: continue
> 			N = None
> 			if platformId == 3 and encodingId == 1 and languageId == 0x409: # Microsoft, Unicode, US English, PS Name
> 				opos = self._pos
> 				try:
> 					self.seek(string_data_offset + offset)
> 					if length % 2 != 0:
> 						raise TTFError("PostScript name is UTF-16BE string of odd length")
> 					length /= 2
> 					N = []
> 					A = N.append
> 					while length > 0:
> 						char = self.read_ushort()
> 						A(bytes([char]) if isPy3 else chr(char))
> 						length -= 1
> 					N = b''.join(N)
> 				finally:
> 					self._pos = opos
> 			elif platformId == 1 and encodingId == 0 and languageId == 0: # 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.
> 				N = self.get_chunk(string_data_offset + offset, length)
> 			if N and names[nameId]==None:
> 				names[nameId] = N
> 				nameCount -= 1
> 				if nameCount==0: break
> 		if names[6] is not None:
> 			psName = names[6].replace(b" ", b"-")  #Dinu Gherman's fix for font names with spaces
> 		elif names[4] is not None:
> 			psName = names[4].replace(b" ", b"-")
> 		# Fine, one last try before we bail.
> 		elif names[1] is not None:
> 			psName = names[1].replace(b" ", b"-")
> 		else:
> 			psName = None



On 01/07/2015 15:26, Daniel Casper wrote:
> To whom it may concern,
>
>
>
> I wanted to reach out and discuss the state of custom character set /
> custom glyph support for the ReportLab libraries.  We currently use the
> open source package in PDF Generation utilities that are used in many
> countries.  In China specifically, our users make use of the Private
> Character Editor to provide custom glyphs for fonts on their systems.  They
> then choose the font EUDC to include those custom glyphs for their
> documents.  Unfortunately, when attempting to register this font with the
> ReportLab library we receive the following traceback:
>
>
>
> Traceback (most recent call last):
>
>    File reportlab\pdfbase\ttfonts.pyo, line 1009, in __init__
>
>    File reportlab\pdfbase\ttfonts.pyo, line 915, in __init__
>
>    File reportlab\pdfbase\ttfonts.pyo, line 413, in __init__
>
>    File reportlab\pdfbase\ttfonts.pyo, line 499, in extractInfo
>
> TTFError: Could not find PostScript font name
>
>
> Has anyone else worked with fonts that don't contain these PostScript
> names, or is there some other way to go about getting them embedded?
>
I think it's possible there is a name, but we are looking for the wrong one.



> Thanks in advance,
>
>
>
> --Dan
...........
-- 
Robin Becker


More information about the reportlab-users mailing list