Commit f2b64583cb2587373e126b06d8da9ac97b287681

Chris Liddell 2019-07-04T14:04:52

[psaux] (1/2) Handle fonts that use SEAC for ligatures (#56580). As originally intended, a Type 1 SEAC charstring would be used for an accented glyph (like `acaron' or `uumlaut'), where the advance width of the SEAC glyph is the same as that of the `base' glyph (like `a' or `u'). In this case it is not uncommon for the SEAC glyph to not use an (H)SBW opcode of its own but to rely on the value from the base glyph. However, out-of-spec fonts also use SEAC glyphs for ligatures (like `oe' or `fi'), and in those cases the overall advance width is greater than that of the `base' glyph. For this reason we have to allow that the SEAC glyph can have an (H)SBW value of its own, and if it has, retain this value, rather than the one from the base glyph. * src/psaux/psintrp.c (cf2_interpT2CharString) <cf2_escSEAC>: Implement it.

diff --git a/ChangeLog b/ChangeLog
index 6450a60..de4ea86 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2019-07-04  Chris Liddell <chris.liddell@artifex.com>
+
+	[psaux] (1/2) Handle fonts that use SEAC for ligatures (#56580).
+
+	As originally intended, a Type 1 SEAC charstring would be used for
+	an accented glyph (like `acaron' or `uumlaut'), where the advance
+	width of the SEAC glyph is the same as that of the `base' glyph
+	(like `a' or `u').  In this case it is not uncommon for the SEAC
+	glyph to not use an (H)SBW opcode of its own but to rely on the
+	value from the base glyph.
+
+	However, out-of-spec fonts also use SEAC glyphs for ligatures (like
+	`oe' or `fi'), and in those cases the overall advance width is
+	greater than that of the `base' glyph.  For this reason we have to
+	allow that the SEAC glyph can have an (H)SBW value of its own, and
+	if it has, retain this value, rather than the one from the base
+	glyph.
+
+	* src/psaux/psintrp.c (cf2_interpT2CharString) <cf2_escSEAC>:
+	Implement it.
+
 2019-07-01  Werner Lemberg  <wl@gnu.org>
 
 	* Version 2.10.1 released.
diff --git a/src/psaux/psintrp.c b/src/psaux/psintrp.c
index e2f3acc..0a84145 100644
--- a/src/psaux/psintrp.c
+++ b/src/psaux/psintrp.c
@@ -1433,6 +1433,13 @@
                       lastError = error2; /* pass FreeType error through */
                       goto exit;
                     }
+
+                    /* save the left bearing and width of the SEAC   */
+                    /* glyph as they will be erased by the next load */
+
+                    left_bearing = *decoder->builder.left_bearing;
+                    advance      = *decoder->builder.advance;
+
                     cf2_interpT2CharString( font,
                                             &component,
                                             callbacks,
@@ -1443,11 +1450,14 @@
                                             &dummyWidth );
                     cf2_freeT1SeacComponent( decoder, &component );
 
-                    /* save the left bearing and width of the base       */
-                    /* character as they will be erased by the next load */
+                    /* If the SEAC glyph doesn't have a (H)SBW of its */
+                    /* own use the values from the base glyph.        */
 
-                    left_bearing = *decoder->builder.left_bearing;
-                    advance      = *decoder->builder.advance;
+                    if ( !haveWidth )
+                    {
+                      left_bearing = *decoder->builder.left_bearing;
+                      advance      = *decoder->builder.advance;
+                    }
 
                     decoder->builder.left_bearing->x = 0;
                     decoder->builder.left_bearing->y = 0;
@@ -1473,8 +1483,8 @@
                                             &dummyWidth );
                     cf2_freeT1SeacComponent( decoder, &component );
 
-                    /* restore the left side bearing and   */
-                    /* advance width of the base character */
+                    /* restore the left side bearing and advance width   */
+                    /* of the SEAC glyph or base character (saved above) */
 
                     *decoder->builder.left_bearing = left_bearing;
                     *decoder->builder.advance      = advance;