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