Blame SOURCES/freetype-2.8-bw-rendering.patch

ae68a7
From a0455468fdb8dd1959596d0c8c8a3ff07ee495a3 Mon Sep 17 00:00:00 2001
ae68a7
From: Nikolaus Waxweiler <madigens@gmail.com>
ae68a7
Date: Sat, 20 May 2017 07:28:46 +0200
ae68a7
Subject: [truetype] Always use interpreter v35 for B/W rendering (#51051).
ae68a7
ae68a7
* src/truetype/ttgload.c (tt_loader_init)
ae68a7
[TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL]: Adjust
ae68a7
`subpixel_hinting_lean', `grayscale_cleartype', and
ae68a7
`vertical_lcd_lean' accordingly.
ae68a7
ae68a7
* src/truetype/ttinterp.c (Ins_GETINFO): Updated.
ae68a7
(TT_RunIns): Update `backward_compatibility' flag.
ae68a7
ae68a7
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
ae68a7
index 68a9b4ad5..e5a3da37a 100644
ae68a7
--- a/src/truetype/ttgload.c
ae68a7
+++ b/src/truetype/ttgload.c
ae68a7
@@ -2339,13 +2339,19 @@
ae68a7
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
ae68a7
       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
ae68a7
       {
ae68a7
-        subpixel_hinting_lean   = TRUE;
ae68a7
-        grayscale_cleartype     = !FT_BOOL( load_flags         &
ae68a7
-                                            FT_LOAD_TARGET_LCD     ||
ae68a7
-                                            load_flags           &
ae68a7
-                                            FT_LOAD_TARGET_LCD_V   );
ae68a7
-        exec->vertical_lcd_lean = FT_BOOL( load_flags           &
ae68a7
-                                           FT_LOAD_TARGET_LCD_V );
ae68a7
+        subpixel_hinting_lean =
ae68a7
+          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
ae68a7
+                   FT_RENDER_MODE_MONO               );
ae68a7
+        grayscale_cleartype =
ae68a7
+          FT_BOOL( subpixel_hinting_lean         &&
ae68a7
+                   !( ( load_flags         &
ae68a7
+                        FT_LOAD_TARGET_LCD )   ||
ae68a7
+                      ( load_flags           &
ae68a7
+                        FT_LOAD_TARGET_LCD_V ) ) );
ae68a7
+        exec->vertical_lcd_lean =
ae68a7
+          FT_BOOL( subpixel_hinting_lean    &&
ae68a7
+                   ( load_flags           &
ae68a7
+                     FT_LOAD_TARGET_LCD_V ) );
ae68a7
       }
ae68a7
       else
ae68a7
       {
ae68a7
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
ae68a7
index af31408cb..0c48c2562 100644
ae68a7
--- a/src/truetype/ttinterp.c
ae68a7
+++ b/src/truetype/ttinterp.c
ae68a7
@@ -7345,7 +7345,7 @@
ae68a7
       /*                              */
ae68a7
       /* The only smoothing method FreeType supports unless someone sets */
ae68a7
       /* FT_LOAD_TARGET_MONO.                                            */
ae68a7
-      if ( ( args[0] & 2048 ) != 0 )
ae68a7
+      if ( ( args[0] & 2048 ) != 0 && exc->subpixel_hinting_lean )
ae68a7
         K |= 1 << 18;
ae68a7
 
ae68a7
       /********************************/
ae68a7
@@ -7589,11 +7589,21 @@
ae68a7
 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
ae68a7
 
ae68a7
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
ae68a7
-    /* Toggle backward compatibility according to what font says, except   */
ae68a7
-    /* when it's a `tricky' font that heavily relies on the interpreter to */
ae68a7
-    /* render glyphs correctly, e.g. DFKai-SB.  Backward compatibility     */
ae68a7
-    /* hacks may break it.                                                 */
ae68a7
+    /*
ae68a7
+     *  Toggle backward compatibility according to what font wants, except
ae68a7
+     *  when
ae68a7
+     *
ae68a7
+     *  1) we have a `tricky' font that heavily relies on the interpreter to
ae68a7
+     *     render glyphs correctly, for example DFKai-SB, or
ae68a7
+     *  2) FT_RENDER_MODE_MONO (i.e, monochome rendering) is requested.
ae68a7
+     *
ae68a7
+     *  In those cases, backward compatibility needs to be turned off to get
ae68a7
+     *  correct rendering.  The rendering is then completely up to the
ae68a7
+     *  font's programming.
ae68a7
+     *
ae68a7
+     */
ae68a7
     if ( SUBPIXEL_HINTING_MINIMAL          &&
ae68a7
+         exc->subpixel_hinting_lean        &&
ae68a7
          !FT_IS_TRICKY( &exc->face->root ) )
ae68a7
       exc->backward_compatibility = !( exc->GS.instruct_control & 4 );
ae68a7
     else
ae68a7
diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h
ae68a7
index 55e472091..abbecfcee 100644
ae68a7
--- a/src/truetype/ttinterp.h
ae68a7
+++ b/src/truetype/ttinterp.h
ae68a7
@@ -253,23 +253,38 @@ FT_BEGIN_HEADER
ae68a7
 
ae68a7
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
ae68a7
     /*
ae68a7
-     * Modern TrueType fonts are usually rendered through Microsoft's
ae68a7
-     * collection of rendering techniques called ClearType (e.g., subpixel
ae68a7
-     * rendering and subpixel hinting).  When ClearType was introduced, most
ae68a7
-     * fonts were not ready.  Microsoft decided to implement a backward
ae68a7
-     * compatibility mode that employed several simple to complicated
ae68a7
-     * assumptions and tricks that modified the interpretation of the
ae68a7
-     * bytecode contained in these fonts to make them look ClearType-y
ae68a7
-     * somehow.  Most (web)fonts that were released since then have come to
ae68a7
-     * rely on these hacks to render correctly, even some of Microsoft's
ae68a7
-     * flagship ClearType fonts (Calibri, Cambria, Segoe UI).
ae68a7
+     * FreeType supports ClearType-like hinting of TrueType fonts through
ae68a7
+     * the version 40 interpreter.  This is achieved through several hacks
ae68a7
+     * in the base (v35) interpreter, as detailed below.
ae68a7
      *
ae68a7
-     * The minimal subpixel hinting code (interpreter version 40) employs a
ae68a7
-     * small list of font-agnostic hacks to bludgeon non-native-ClearType
ae68a7
-     * fonts (except tricky ones[1]) into submission.  It will not try to
ae68a7
-     * toggle hacks for specific fonts for performance and complexity
ae68a7
-     * reasons.  The focus is on modern (web)fonts rather than legacy fonts
ae68a7
-     * that were made for black-and-white rendering.
ae68a7
+     * ClearType is an umbrella term for several rendering techniques
ae68a7
+     * employed by Microsoft's various GUI and rendering toolkit
ae68a7
+     * implementations, most importantly: subpixel rendering for using the
ae68a7
+     * RGB subpixels of LCDs to approximately triple the perceived
ae68a7
+     * resolution on the x-axis and subpixel hinting for positioning stems
ae68a7
+     * on subpixel borders.  TrueType programming is explicit, i.e., fonts
ae68a7
+     * must be programmed to take advantage of ClearType's possibilities.
ae68a7
+     *
ae68a7
+     * When ClearType was introduced, it seemed unlikely that all fonts
ae68a7
+     * would be reprogrammed, so Microsoft decided to implement a backward
ae68a7
+     * compatibility mode.  It employs several simple to complicated
ae68a7
+     * assumptions and tricks, many of them font-dependent, that modify the
ae68a7
+     * interpretation of the bytecode contained in these fonts to retrofit
ae68a7
+     * them into a ClearType-y look.  The quality of the results varies.
ae68a7
+     * Most (web)fonts that were released since then have come to rely on
ae68a7
+     * these hacks to render correctly, even some of Microsoft's flagship
ae68a7
+     * fonts (e.g., Calibri, Cambria, Segoe UI).
ae68a7
+     *
ae68a7
+     * FreeType's minimal subpixel hinting code (interpreter version 40)
ae68a7
+     * employs a small list of font-agnostic hacks loosely based on the
ae68a7
+     * public information available on Microsoft's compatibility mode[2].
ae68a7
+     * The focus is on modern (web)fonts rather than legacy fonts that were
ae68a7
+     * made for monochrome rendering.  It will not match ClearType rendering
ae68a7
+     * exactly.  Unlike the `Infinality' code (interpreter version 38) that
ae68a7
+     * came before, it will not try to toggle hacks for specific fonts for
ae68a7
+     * performance and complexity reasons.  It will fall back to version 35
ae68a7
+     * behavior for tricky fonts[1] or when monochrome rendering is
ae68a7
+     * requested.
ae68a7
      *
ae68a7
      * Major hacks
ae68a7
      *
ae68a7
@@ -347,7 +362,8 @@ FT_BEGIN_HEADER
ae68a7
      *
ae68a7
      */
ae68a7
 
ae68a7
-    /* Using v40 implies subpixel hinting.  Used to detect interpreter */
ae68a7
+    /* Using v40 implies subpixel hinting, unless FT_RENDER_MODE_MONO has been
ae68a7
+     * requested.  Used to detect interpreter */
ae68a7
     /* version switches.  `_lean' to differentiate from the Infinality */
ae68a7
     /* `subpixel_hinting', which is managed differently.               */
ae68a7
     FT_Bool            subpixel_hinting_lean;