Very well done analysis of the options and very thorough testing of the
effects
on the different libraries/platforms.
> There are some alternatives to setting the filter:
> • Bundle the FreeType library by default
Although the build makes this easy to set as an option, we decided we
prefer to
use the platform library on Linux - and Solaris for that matter - in our
releases.
So setting this option is going to be needed for some years to come, until
even a Linux current release like Ubuntu 18.04 is obsolete.
We can't re-use the OpenJavaFX bug ID, and surprisingly I can't find an open
bug on this for 2D. So I've submitted
https://bugs.openjdk.java.net/browse/JDK-8212071
And I've attached John's images to the bug report and pasted his email
in there.
-phil.
On 10/11/2018 10:56 AM, John Neffenger wrote:
On 10/10/2018 11:15 AM, Laurent Bourgès wrote:
It looks awesome & promising.
Thank you, Laurent, for looking into it so quickly!
PS: It is better to send plain text (long) email than sending
external links (github).
Thanks for the tip. Right, Web pages and repositories can be deleted,
so here it is, for the record ...
The symptoms of the problem are the same as in the link below, but
they appear in AWT and Swing applications instead of JavaFX applications.
JDK-8188810: Fonts are blurry on Ubuntu 16.04 and Debian 9
https://bugs.openjdk.java.net/browse/JDK-8188810
The description of the problem on the Java side follows.
Synopsis: Reduce color fringes in FreeType subpixel rendering
The text in Java applications often has severe color fringes when
using OpenJDK on Ubuntu and other Debian-based distributions because
the JDK fails to set the LCD filter. Adding two lines of code to the
file freetypeScaler.c fixed the problem in my tests, without any
regression errors for other Linux distributions. The patch is attached
to this message as the file freetypeScaler.diff.
There are some alternatives to setting the filter:
• Bundle the FreeType library by default and always use the new
Harmony subpixel rendering technique. This option removes the
uncertainty in the library at the expense of an additional 4.6
megabytes to the installed size — an increase of less than one
percent. OpenJDK 12 even includes the latest FreeType 2.9.1, a newer
version than the one found on most systems.
• Wait another year and see what changes are made to FreeType, if
any, when the ClearType patents expire. This option, though, doesn’t
solve the problem that users of Ubuntu and other Debian-based
distributions have now.
The problem originates in decisions made by the developers of
FreeType, Debian, Fedora, and OpenJDK concerning the Microsoft
ClearType patents [1].
• In 2007, FreeType 2.3.0 added a compiler configuration macro to
the file ftoption.h named FT_CONFIG_OPTION_SUBPIXEL_RENDERING. If
defined, the FreeType library includes patented ClearType techniques
in its subpixel rendering.
But there’s a catch. When the ClearType methods are enabled, the
subpixel rendering is not filtered, which results in severe color
fringes. Clients of the FreeType library must make an explicit call to
the function FT_Library_SetLcdFilter to apply color filtering. The
filter was disabled by default, explained one of its authors, “to
avoid major surprises to existing clients, including libXft and Cairo
which already perform some wacky color filtering on top of FreeType.”
• In 2009, Debian created a patch to FreeType 2.3.9, named
enable-subpixel-rendering.patch, that defines the macro and enables
ClearType-style rendering. The change log states, “This is considered
no more or less evil than the bytecode interpreter which we also
enable.” Ubuntu, based on Debian, applies the patch as well. Fedora
created the same patch in 2007, named freetype-2.3.0-enable-spr.patch,
but does not apply the patch by default.
• In 2017, FreeType 2.8.1 included a new subpixel rendering
technique, called Harmony, that is nearly identical in output to the
ClearType technique but uses a different algorithm, avoiding the
patents. FreeType now uses Harmony subpixel rendering when the
ClearType methods are disabled, with no need for clients to set the
LCD filter. (This would have been a good time for Debian to remove its
subpixel rendering patch.) The latest Fedora Workstation 28 runs
FreeType 2.8.0, which does not include Harmony.
• In 2019, the Microsoft ClearType patents expire.
So now we have two variants of the FreeType library: one that requires
a function call to set the LCD filter in Ubuntu and other
distributions based on Debian, and another that doesn’t require the
function call in Red Hat Enterprise Linux, Oracle Linux, and other
distributions based on Fedora.
To demonstrate the problem, I built four versions of the JDK from the
latest OpenJDK sources. I built a version that uses the system
FreeType library and another that uses the bundled FreeType library.
Then I changed the OpenJDK code to set the default LCD filter and
built the two versions again. The four builds were named:
jdk-12-system-lcdnone
jdk-12-system-lcddefault
jdk-12-bundled-lcdnone
jdk-12-bundled-lcddefault
The system library is FreeType 2.8.1 in Ubuntu 18.04.1 LTS, which has
the Debian patch applied (ClearType methods enabled), while the
bundled library is FreeType 2.9.1 in OpenJDK 12, which uses the
library default (ClearType methods disabled). I wrote a simple Java
Swing application called FontDemo [2] that displays two text areas
with the Adobe Source Code Pro font [3] in TTF and OTF formats (the
latest non-variable download).
The results are shown in the two images attached to this message:
fontdemo.png
Three screenshots of the FontDemo program
fontdemo-detail.png
Details from the screenshots scaled by 800 percent
When using the Ubuntu system FreeType library, setting the LCD filter
is critical. The screenshots show the ClearType-style rendering
without setting the LCD filter, and after adding the change to set the
filter. The ClearType configuration macro is defined in the Ubuntu
build of FreeType, so the function to set the filter returns success
(0) when called and applies color filtering.
When using the OpenJDK bundled FreeType library, setting the LCD
filter does nothing. The screenshots show the FreeType Harmony
rendering, which is the same whether or not the LCD filter is set. The
ClearType configuration macro is not defined in the OpenJDK build of
FreeType, so the function to set the filter returns
FT_Err_Unimplemented_Feature (7) when called and does nothing.
The test system I used is a QEMU/KVM guest virtual machine running
Ubuntu 18.04.1 LTS (Bionic Beaver) with the details shown below. The
display is a 27-inch Dell UltraSharp U2717D monitor with a resolution
of 2560 × 1440 pixels at 109 pixels per inch.
ubuntu@bionic:~$ uname -a
Linux bionic 4.15.0-36-generic #39-Ubuntu SMP
Mon Sep 24 16:19:09 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
ubuntu@bionic:~$ ldd --version
ldd (Ubuntu GLIBC 2.27-3ubuntu1) 2.27
ubuntu@bionic:~$ getconf GNU_LIBPTHREAD_VERSION
NPTL 2.27
ubuntu@bionic:~$ $HOME/opt/jdk-12-system-lcdnone/bin/java -version
openjdk version "12-internal" 2019-03-19
OpenJDK Runtime Environment (build 12-internal+0-adhoc.ubuntu.jdk)
OpenJDK 64-Bit Server VM (build 12-internal+0-adhoc.ubuntu.jdk, mixed
mode)
Below are the full test results using five versions of FreeType built
first with the ClearType methods disabled (the default) and then again
with them enabled. I ran all 10 libraries under OpenJDK 12, first with
no LCD filter and then again after adding the code to set the default
LCD filter.
No LCD Filter
2008 FreeType 2.3.5 (libfreetype.so.6.3.16) in Ubuntu 8.04 LTS
ClearType Off: Grayscale, ClearType On: Mild fringes
2014 FreeType 2.5.2 (libfreetype.so.6.11.1) in Ubuntu 14.04 LTS
ClearType Off: Grayscale, ClearType On: Severe fringes
2016 FreeType 2.6.1 (libfreetype.so.6.12.1) in Ubuntu 16.04 LTS
ClearType Off: Grayscale, ClearType On: Severe fringes
2018 FreeType 2.8.1 (libfreetype.so.6.15.0) in Ubuntu 18.04 LTS
ClearType Off: Harmony, ClearType On: Severe fringes
2019 FreeType 2.9.1 (libfreetype.so.6.16.1) in OpenJDK 12
ClearType Off: Harmony, ClearType On: Severe fringes
The OpenJDK does not set the FreeType LCD filter, so there are severe
color fringes when using a FreeType library built with the ClearType
methods enabled. The only reason the older FreeType 2.3.5 shows mild
color fringes is because it uses full hinting, so the glyphs are
simply too skinny to see their colors.
Default LCD Filter
2008 FreeType 2.3.5 (libfreetype.so.6.3.16) in Ubuntu 8.04 LTS
ClearType Off: Grayscale, ClearType On: ClearType filtered
2014 FreeType 2.5.2 (libfreetype.so.6.11.1) in Ubuntu 14.04 LTS
ClearType Off: Grayscale, ClearType On: ClearType filtered
2016 FreeType 2.6.1 (libfreetype.so.6.12.1) in Ubuntu 16.04 LTS
ClearType Off: Grayscale, ClearType On: ClearType filtered
2018 FreeType 2.8.1 (libfreetype.so.6.15.0) in Ubuntu 18.04 LTS
ClearType Off: Harmony, ClearType On: ClearType filtered
2019 FreeType 2.9.1 (libfreetype.so.6.16.1) in OpenJDK 12
ClearType Off: Harmony, ClearType On: ClearType filtered
After changing the OpenJDK to set the default LCD filter, there is no
version of the FreeType library that shows the severe color fringes.
Note that Fedora Workstation 28 includes FreeType 2.8.0 with the
ClearType methods disabled, so it displays grayscale anti-aliasing for
the OpenJDK whether it sets the LCD filter or not. (FreeType 2.8.0
does not include Harmony.)
For background information on LCD filters see Section 2.2.1 [4] of The
Raster Tragedy at Low-Resolution, which has an interactive
demonstration of the filters used in ClearType (Microsoft), CoolType
(Adobe), FreeType (open source), and Quartz 2D (Apple). Hover your
mouse over each of the samples in the illustration to remove the filter.
Below is the relevant section of the file ftoption.h in FreeType 2.9.1
bundled with OpenJDK 12, edited for formatting:
java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h
/*
Uncomment the line below if you want to activate LCD rendering
technology similar to ClearType in this build of the library. This
technology triples the resolution in the direction color subpixels.
To mitigate color fringes inherent to this technology, you also need
to explicitly set up LCD filtering.
Note that this feature is covered by several Microsoft patents
and should not be activated in any default build of the library.
When this macro is not defined, FreeType offers alternative LCD
rendering technology that produces excellent output without LCD
filtering.
*/
/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
[1] http://david.freetype.org/cleartype-patents.html
[2]
https://github.com/jgneff/openjdk-freetype/blob/master/src/org/status6/FontDemo.java
[3] https://github.com/adobe-fonts/source-code-pro
[4] http://rastertragedy.com/RTRCh2.htm#Sec21