[gs-cvs] rev 8631 - in trunk/gs: doc lib src

ken at ghostscript.com ken at ghostscript.com
Wed Apr 9 08:28:46 PDT 2008

Author: ken
Date: 2008-04-09 08:28:45 -0700 (Wed, 09 Apr 2008)
New Revision: 8631

Fix (PDF interpreter): Optionally omit rendering of /.notdef glyphs
from TrueType fonts.

Bug #689757 "Extra square characters rendering PDF file".

When rendering glyphs in a TrueType font, and the glyph is not present
in the font, GS (correctly) draws the /.notdef glyph (or glyph ID 0)
instead. Under some conditions, however, Acrobat does not do so, but
does leave a 'gap' apparently corresponding to the width of the
original glyph (if a /Widths array is present), or the width of the
/.notdef glyph.

Exactly what causes Acrobat to do this is unclear. In the thread for
bug 687929 it was suggested that Acrobat was substituting a standard
font with a /.notdef defined as an empty glyph. However changing the
font name had no effect.

Using a pdfwrite-produced PDF file, if I remove the symbolic flag
from the font, and any direct reference to /.notdef in the Encoding
/Differences array, then Acrobat does not display the /.notdef 
glyph. However, starting with a Distiller-produced PDF file, and
either altering the font to symbolic, or adding a direct /.notdef
to the Encoding, or both, makes no difference, Acrobat still does
not render the /.notdef glyph.

The behaviour of Acrobat is probably technically incorrect, but
we need to attempt to render files similarly, if at all possible.
However, since the appearance of a /.notdef is usually indicative
of an error, this has been made optional.

We can't substitute a space glyph for the /.notdef as has been
suggested, because we can't guarantee the existence of a space glyph
(eg Arabic, which has no space) and can't guarantee that the space
makes no marks even if present.

However, we still want to apply the Width of the glyph, so that
spacing works out correctly, if we simply skip the /.notdef glyph
then words may collide, as in the case of the file for this bug.
This means we must run the glyph through the text routines, as the
width is applied there.

A new user parameter '/RenderTTNotdef' controls whether glyphs
named /.notdef in a TrueType font should be rendered or not. This
is also controlled by a systemdict parameter /RENDERTTNOTDEF. The
PDF interpreter will set the user parameter to the same value as
the systemdict parameter, allowing this to be controlled from the
GS command line.

The user parameter defaults to 'true' which renders TrueType /.notdef
glyphs (so that these are properly rendered in PostScript), the 
RENDERTTNOTDEF systemdict parameter defaults to 'false', which is
used by the PDF interpreter to set the user parameter, and therefore
disables rendering of TT /.notdef glyphs in PDF files.


Modified: trunk/gs/doc/Use.htm
--- trunk/gs/doc/Use.htm	2008-04-09 06:16:50 UTC (rev 8630)
+++ trunk/gs/doc/Use.htm	2008-04-09 15:28:45 UTC (rev 8631)
@@ -647,6 +647,18 @@
 that otherwise exceed implementation limits.
+If a glyph is not present in a font the normal behaviour is to use the /.notdef
+glyph instead. On TrueType fonts, this is often a hollow sqaure. Under some
+conditions Acrobat does not do this, instead leaving a gap equivalent to the 
+width of the missing glyph, or the width of the /.notdef glyph if no /Widths
+array is present. Ghostscript now attempts to mimic this undocumented feature
+using a user parameter <b><tt>RenderTTNotdef</tt></b>. The PDF interpreter sets this
+user paramter to the value of <b><tt>RENDERTTNOTDEF</tt></b> in systemdict,
+when rendering PDF files. To restore rendering of /.notdef glyphs from TrueType fonts in PDF files, set this parameter to true.
 <h3><a name="PDF_problems"></a>Problems interpreting a PDF file</h3>

Modified: trunk/gs/lib/gs_init.ps
--- trunk/gs/lib/gs_init.ps	2008-04-09 06:16:50 UTC (rev 8630)
+++ trunk/gs/lib/gs_init.ps	2008-04-09 15:28:45 UTC (rev 8631)
@@ -185,6 +185,7 @@
 currentdict /STRICT known   /STRICT exch def
 currentdict /TTYPAUSE known   /TTYPAUSE exch def
 currentdict /WRITESYSTEMDICT known   /WRITESYSTEMDICT exch def
+currentdict /RENDERTTNOTDEF known /RENDERTTNOTDEF exch def
 % Acquire environment variables.
 currentdict /DEVICE known not

Modified: trunk/gs/lib/pdf_main.ps
--- trunk/gs/lib/pdf_main.ps	2008-04-09 06:16:50 UTC (rev 8630)
+++ trunk/gs/lib/pdf_main.ps	2008-04-09 15:28:45 UTC (rev 8631)
@@ -176,6 +176,8 @@
 /dopdfpages {   % firstpage# lastpage# dopdfpages -
   << /PDFScanRules //true >> setuserparams	% set scanning rules for PDF vs. PS
+  << /RenderTTNotdef systemdict 
+     /RENDERTTNOTDEF get >> setuserparams	% Should we render TT /.notdef
   1 exch
     { dup /Page# exch store
       QUIET not { (Page ) print dup == flush } if

Modified: trunk/gs/src/icontext.c
--- trunk/gs/src/icontext.c	2008-04-09 06:16:50 UTC (rev 8630)
+++ trunk/gs/src/icontext.c	2008-04-09 15:28:45 UTC (rev 8631)
@@ -151,6 +151,7 @@
     pcst->scanner_options = 0;
     pcst->LockFilePermissions = false;
     pcst->starting_arg_file = false;
+    pcst->RenderTTNotdef = true;
     /* The initial stdio values are bogus.... */
     make_file(&pcst->stdio[0], a_readonly | avm_invalid_file_entry, 1,

Modified: trunk/gs/src/icstate.h
--- trunk/gs/src/icstate.h	2008-04-09 06:16:50 UTC (rev 8630)
+++ trunk/gs/src/icstate.h	2008-04-09 15:28:45 UTC (rev 8631)
@@ -56,6 +56,7 @@
     int scanner_options;	/* derived from userparams */
     bool LockFilePermissions;	/* accessed from userparams */
     bool starting_arg_file;	/* starting a file specified in command line. */
+    bool RenderTTNotdef;	/* accessed from userparams */
     gs_file_path_ptr lib_path;	/* library search list (GS_LIB) */
     ref stdio[3];		/* t_file */
     /* Put the stacks at the end to minimize other offsets. */

Modified: trunk/gs/src/zchar42.c
--- trunk/gs/src/zchar42.c	2008-04-09 06:16:50 UTC (rev 8630)
+++ trunk/gs/src/zchar42.c	2008-04-09 15:28:45 UTC (rev 8631)
@@ -31,6 +31,7 @@
 #include "icharout.h"
 #include "ifont.h"		/* for font_param */
 #include "igstate.h"
+#include "iname.h"
 #include "store.h"
 #include "zchar42.h"
@@ -225,6 +226,19 @@
 		       pfont->FontType != ft_CID_TrueType)
+    if (!i_ctx_p->RenderTTNotdef) {
+	if (r_has_type(op - 1, t_name)) {
+	    ref gref;
+	    name_string_ref(imemory, op - 1, &gref);
+	    if (gref.tas.rsize >= 7 && strncmp(gref.value.const_bytes, ".notdef", 7) == 0) {
+		pop((psbpt == 0 ? 4 : 6));
+		return (*cont)(igs);
+	    }
+	}
+    }
      * We have to disregard penum->pis and penum->path, and render to
      * the current gstate and path.  This is a design bug that we will

Modified: trunk/gs/src/zusparam.c
--- trunk/gs/src/zusparam.c	2008-04-09 06:16:50 UTC (rev 8630)
+++ trunk/gs/src/zusparam.c	2008-04-09 15:28:45 UTC (rev 8631)
@@ -509,11 +509,23 @@
     i_ctx_p->LockFilePermissions = val;
     return 0;
+static bool
+current_RenderTTNotdef(i_ctx_t *i_ctx_p)
+    return i_ctx_p->RenderTTNotdef;
+static int
+set_RenderTTNotdef(i_ctx_t *i_ctx_p, bool val)
+    i_ctx_p->RenderTTNotdef = val;
+    return 0;
 static const bool_param_def_t user_bool_params[] =
     {"AccurateScreens", current_AccurateScreens, set_AccurateScreens},
     {"UseWTS", current_UseWTS, set_UseWTS},
-    {"LockFilePermissions", current_LockFilePermissions, set_LockFilePermissions}
+    {"LockFilePermissions", current_LockFilePermissions, set_LockFilePermissions},
+    {"RenderTTNotdef", current_RenderTTNotdef, set_RenderTTNotdef}
 /* The user parameter set */

More information about the gs-cvs mailing list