>> I looked at the example that Ewald gave, ztm-Reg.pfb gid 479
>> 'shade'.  While the [hv]stem operators are used 344 times in this
>> charstring, the hints are not all unique.  There are just 10 unique
>> hstems and 10 unique vstems.  When converted to CFF, this font would
>> therefore declare just 20 hints, easily within the limit.
>
> This is a very good point.  It seems that T1 support could be improved
> by adding one additional step, namely to make hints unique.  However,
> such an extra step costs time.  If an arbitrary number of hints is
> allowed (using dynamic allocation) – which we eventually have to
> support anyway – this extra step might not be necessary.

Actually, the hintmap already does this - overlapping hints are not
inserted. So I went with a different approach, to switch off hinting
only if the hintmap is full. Compare attached patches.

With this, none of the fonts across TeXLive fail (as in fall back to
non-hinted). However, I wonder if the hinted output of such glyphs are
actually better. See attached pictures.

`stems.png' is the result of turning off hinting since 344 hints is
more than the allowed 96 (I'm not sure why the outline shifts a
little).

`hintmap.png' does not, since there are only 20 hints in the initial
hintmap. However, it introduces some jagged edges on the output due to
the alignment. Likewise with the "4111 hints" glyph, hinted output
sort of stretches the uniform grid of circles outwards on the ends.
Although, these may be isolated cases...

Ewald
From 2959d7315824012416b22fa76f1b5aa112cdffb8 Mon Sep 17 00:00:00 2001
From: Ewald Hew <ewald...@gmail.com>
Date: Wed, 3 Jan 2018 10:09:45 +0800
Subject: [PATCH] off hinting if hintmap full

---
 src/psaux/pshints.c | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/src/psaux/pshints.c b/src/psaux/pshints.c
index b53ca6745..3d77b0a5d 100644
--- a/src/psaux/pshints.c
+++ b/src/psaux/pshints.c
@@ -760,6 +760,7 @@
       if ( iDst >= CF2_MAX_HINT_EDGES )
       {
         FT_TRACE4(( "cf2_hintmap_insertHint: too many hintmaps\n" ));
+        hintmap->hinted = FALSE;
         return;
       }
 
@@ -836,7 +837,7 @@
                          TRUE );
     }
 
-    if ( !cf2_hintmask_isValid( hintMask ) )
+    if ( !cf2_hintmask_isValid( hintMask ) && !font->isT1 )
     {
       /* without a hint mask, assume all hints are active */
       cf2_hintmask_setAll( hintMask,
@@ -858,7 +859,7 @@
     bitCount = cf2_arrstack_size( hStemHintArray );
 
     /* Defense-in-depth.  Should never return here. */
-    if ( bitCount > hintMask->bitCount )
+    if ( bitCount > hintMask->bitCount && !font->isT1 )
       return;
 
     /* synthetic embox hints get highest priority */
@@ -884,7 +885,7 @@
     /* priority)                                                      */
     for ( i = 0, maskByte = 0x80; i < bitCount; i++ )
     {
-      if ( maskByte & *maskPtr )
+      if ( font->isT1 || ( maskByte & *maskPtr ) )
       {
         /* expand StemHint into two `CF2_Hint' elements */
         CF2_HintRec  bottomHintEdge, topHintEdge;
@@ -918,14 +919,17 @@
         }
       }
 
-      if ( ( i & 7 ) == 7 )
+      if ( !font->isT1 )
       {
-        /* move to next mask byte */
-        maskPtr++;
-        maskByte = 0x80;
+        if ( ( i & 7 ) == 7 )
+        {
+          /* move to next mask byte */
+          maskPtr++;
+          maskByte = 0x80;
+        }
+        else
+          maskByte >>= 1;
       }
-      else
-        maskByte >>= 1;
     }
 
     /* initial hint map includes only captured hints plus maybe one at 0 */
@@ -985,7 +989,7 @@
 
       for ( i = 0, maskByte = 0x80; i < bitCount; i++ )
       {
-        if ( maskByte & *maskPtr )
+        if ( font->isT1 || ( maskByte & *maskPtr ) )
         {
           CF2_HintRec  bottomHintEdge, topHintEdge;
 
@@ -1008,14 +1012,17 @@
           cf2_hintmap_insertHint( hintmap, &bottomHintEdge, &topHintEdge );
         }
 
-        if ( ( i & 7 ) == 7 )
+        if ( !font->isT1 )
         {
-          /* move to next mask byte */
-          maskPtr++;
-          maskByte = 0x80;
+          if ( ( i & 7 ) == 7 )
+          {
+            /* move to next mask byte */
+            maskPtr++;
+            maskByte = 0x80;
+          }
+          else
+            maskByte >>= 1;
         }
-        else
-          maskByte >>= 1;
       }
     }
 
-- 
2.11.0

From 2b20d1e641a9b036d04d0e9239f2dc8ea9ede377 Mon Sep 17 00:00:00 2001
From: Ewald Hew <ewald...@gmail.com>
Date: Wed, 3 Jan 2018 10:32:53 +0800
Subject: [PATCH] off hinting if too many stems

---
 src/psaux/pshints.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/psaux/pshints.c b/src/psaux/pshints.c
index b53ca6745..31cca146d 100644
--- a/src/psaux/pshints.c
+++ b/src/psaux/pshints.c
@@ -843,7 +843,15 @@
                            cf2_arrstack_size( hStemHintArray ) +
                              cf2_arrstack_size( vStemHintArray ) );
       if ( !cf2_hintmask_isValid( hintMask ) )
+      {
+        if ( font->isT1 )
+        {
+          /* no error, just continue unhinted */
+          *hintMask->error = FT_Err_Ok;
+          hintmap->hinted  = FALSE;
+        }
         return;                   /* too many stem hints */
+      }
     }
 
     /* begin by clearing the map */
@@ -858,7 +866,7 @@
     bitCount = cf2_arrstack_size( hStemHintArray );
 
     /* Defense-in-depth.  Should never return here. */
-    if ( bitCount > hintMask->bitCount )
+    if ( bitCount > hintMask->bitCount && !font->isT1 )
       return;
 
     /* synthetic embox hints get highest priority */
-- 
2.11.0

_______________________________________________
Freetype-devel mailing list
Freetype-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/freetype-devel

Reply via email to