Update to freetype-doc-2.7.1
This commit is contained in:
parent
2c7d3378e2
commit
7a54dc44dc
@ -95,6 +95,11 @@
|
||||
rendering. Useful for better understanding the ‘big
|
||||
picture’.</p>
|
||||
|
||||
<h3><a href="subpixel-hinting.html">The v40 TrueType
|
||||
interpreter mode</a></h3>
|
||||
<p>This documents the new default hinting mode introduced
|
||||
with FreeType version 2.7.</p>
|
||||
|
||||
<h3><a href="rasterinfo/rasterinfo.html">The RasterInfo
|
||||
Font</a></h3>
|
||||
</div>
|
||||
@ -103,7 +108,7 @@
|
||||
<!-- ************************************************** -->
|
||||
|
||||
<div class="updated">
|
||||
<p>Last update: 11-Feb-2016</p>
|
||||
<p>Last update: 8-Sep-2016</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
BIN
lib/freetype/docs/image/freetype-27-consolas-v35-v40.png
Normal file
BIN
lib/freetype/docs/image/freetype-27-consolas-v35-v40.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
BIN
lib/freetype/docs/image/freetype-27-hinting-comparison.png
Normal file
BIN
lib/freetype/docs/image/freetype-27-hinting-comparison.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 86 KiB |
310
lib/freetype/docs/subpixel-hinting.html
Normal file
310
lib/freetype/docs/subpixel-hinting.html
Normal file
@ -0,0 +1,310 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=utf-8">
|
||||
<meta http-equiv="Content-Style-Type"
|
||||
content="text/css">
|
||||
<meta http-equiv="Content-Script-Type"
|
||||
content="text/javascript">
|
||||
<meta name="description"
|
||||
content="FreeType Documentation">
|
||||
|
||||
<link rel="icon"
|
||||
href="image/favicon_-90.ico">
|
||||
<link rel="shortcut icon"
|
||||
href="image/favicon_-90.ico">
|
||||
<link rel="stylesheet"
|
||||
type="text/css"
|
||||
href="css/freetype2_-90.css">
|
||||
|
||||
<script type="text/javascript"
|
||||
src="../../js/jquery-1.11.0.min.js">
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="../../js/jquery.ba-resize.min.js">
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="../../js/freetype2.js">
|
||||
</script>
|
||||
|
||||
<title>The new v40 TrueType interpreter mode</title>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<div id="top"
|
||||
class="bar">
|
||||
<h1><a href="http://freetype.org/index.html">FreeType</a> Subpixel Hinting</h1>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="wrapper">
|
||||
|
||||
<div class="colmask leftmenu">
|
||||
<div class="colright">
|
||||
<div class="col1wrap">
|
||||
<div class="col1">
|
||||
|
||||
<!-- ************************************************** -->
|
||||
|
||||
<div id="subpixel-hinting">
|
||||
<h2>The new v40 TrueType interpreter mode</h2>
|
||||
<div class="date">2016-09-08, contributed by Nikolaus
|
||||
Waxweiler</div>
|
||||
|
||||
<p>FreeType 2.7 ships the new v40 TrueType instructions
|
||||
interpreter version enabled by default. It finally brings
|
||||
DirectWrite/ClearType-like rendering to the screen, or
|
||||
‘subpixel hinting’ as some FreeType code calls
|
||||
it. Actually, there is no subpixel hinting. Read on.</p>
|
||||
|
||||
<p><img src="image/freetype-27-hinting-comparison.png"
|
||||
alt="Demonstration and comparison of the various
|
||||
hinting modes."></p>
|
||||
|
||||
<p>For the past years, the previous v35 interpreter did as
|
||||
the TrueType specification from the 90s said. The
|
||||
TrueType hinting machinery was originally conceived to
|
||||
make vector outlines render well as black-and-white
|
||||
bitmaps on the coarse-pixeled CRTs of back in the days.
|
||||
Look at screenshots of Windows 95 and you'll see pixely,
|
||||
bitmappy text. In reality, the single glyphs are scalable
|
||||
vector outlines beaten into the pixel grid by small
|
||||
programs run on them inside the font before being handed
|
||||
off to the rasterizer. Read: glyphs were designed to be
|
||||
reprogrammed on the fly, per size, for sharper on-screen
|
||||
display. Microsoft invested significant manpower into
|
||||
what is commonly called the core web fonts (Arial, Times
|
||||
New Roman, Courier New, etc.) to beat and re-beat each and
|
||||
every glyph to a full pixel grid at all commonly used
|
||||
sizes. If this sounds like a lot of sisyphean work,
|
||||
that's because it is. To this day, only few font families
|
||||
have had the same amount of work put into them.</p>
|
||||
|
||||
<p>Times changed, LCDs came along and Microsoft rediscovered
|
||||
subpixel rendering that exploits the physical structure of
|
||||
LCD subpixels, usually RGB stripes, to increase the
|
||||
horizontal resolution approximately three times (not quite
|
||||
actually since you need to apply a blurrying filter to
|
||||
lessen color fringes). More resolution meant that less
|
||||
work had to be put into a font and instead of snapping
|
||||
things to full pixels, they could now be snapped to one of
|
||||
those three subpixels or a fraction of that for a much
|
||||
finer appearance (‘subpixel hinting’) while
|
||||
still appearing sharper than with plain old grayscale
|
||||
antialiasing. Since fonts are explicitly programmed in
|
||||
the TrueType model, they now had a lot of older fonts that
|
||||
would need to be updated to take advantage of the new
|
||||
possibilities or to even render correctly. Knowing this
|
||||
would never happen, they implemented supersampling and a
|
||||
compatibility mode that contained several interpreter rigs
|
||||
and preventive measures for dirty hacks used in older
|
||||
fonts to achieve pixel perfection. Older fonts that were
|
||||
snapping things to full pixels all around could now at
|
||||
least benefit a little from the increased horizontal
|
||||
resolution. Beat Stamm describes this work in detail
|
||||
<a href="http://www.beatstamm.com/typography/RTRCh4.htm#Sec1">on
|
||||
his site</a>. Microsoft later released the ClearType
|
||||
collection fonts (Calibri, Cambria, Consolas, etc.) to
|
||||
demonstrate the new possibilities that just so happened
|
||||
to rely on this compatibility mode to render correctly.
|
||||
Many new fonts did and still do.</p>
|
||||
|
||||
<p>FreeType didn't implement a similar compatibility mode.
|
||||
This had two side effects.</p>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<p>It lead to glitches when rendering fonts that assumed
|
||||
a compatibility mode with supersampler and interpreter
|
||||
rigs is present, i.e., most modern fonts.</p>
|
||||
|
||||
<p><img src="image/freetype-27-consolas-v35-v40.png"
|
||||
alt="Hinting comparison of the Consolas font."></p>
|
||||
|
||||
<p>The same can happen on Windows if you disable
|
||||
ClearType in the system settings and look at random
|
||||
web pages with custom fonts.</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>Different fonts in a browser could look jarringly
|
||||
different next to each other. Older fonts like the
|
||||
core web fonts snap things to full hard pixels on both
|
||||
axes, newer fonts and especially web fonts often use a
|
||||
hinting strategy that snaps glyphs to the pixel grid
|
||||
mainly or only vertically and with varying
|
||||
strength.</p>
|
||||
|
||||
<p><img src="image/freetype-27-v35-v40-different-hinting.png"
|
||||
alt="Hinting comparison between Georgia and NotoSerif."></p>
|
||||
|
||||
<p>Snapping things to the grid on one axis instead of
|
||||
two greatly reduces the complexity and cost of
|
||||
hinting, looks smoother and comes with important
|
||||
spacing benefits for horizontal (Latin!) text. And
|
||||
it's just as readable.</p>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>For some time already, FreeType shipped with a v38
|
||||
interpreter, also known as ‘Infinality’. Its
|
||||
developer set out to make fonts render better than on
|
||||
Windows and give users the ability to configure font
|
||||
rendering to their liking. Out of the box, it made fonts
|
||||
look like they were rendered through ClearType instead of
|
||||
on Windows 95. It was disabled by default because it was
|
||||
painfully slow and the original developer lost interest in
|
||||
developing the code further. You'll find it used in
|
||||
several distribution repositories maintained by community
|
||||
members.</p>
|
||||
|
||||
<p>My work on stem darkening (incompatible with explicit
|
||||
horizontal hinting, i.e., TrueType) and frustration that
|
||||
v35 was still the default (I prefer what
|
||||
DirectWrite/ClearType puts on the screen) led me to strip
|
||||
the v38 Infinality code to the bare minimum and remove all
|
||||
configurability in the name of speed and simplicity. The
|
||||
result is called v40 and it's just as fast as v35. v38 is
|
||||
still there and usable, it just isn't compiled in by
|
||||
default. If you compile it in, you can switch between the
|
||||
different interpreters at runtime, using an environment
|
||||
variable (or using the property API of FreeType). There
|
||||
is currently no way to switch this from FontConfig or any
|
||||
other means. Packagers of ‘Infinality’
|
||||
packages will probably jump in and update the packages
|
||||
accordingly.</p>
|
||||
|
||||
<p>Here is the core secret to making fonts render like
|
||||
through DirectWrite/ClearType on Windows: There actually
|
||||
is no subpixel hinting going on here. Shock. The code
|
||||
simply ignores <em>all</em> horizontal hinting
|
||||
instructions. That's less work than supersampling and
|
||||
gets us almost identical results <em>and</em> additionally
|
||||
prevents changes to the advance width of glyphs. This
|
||||
greatly harmonizes the look of older and newer TrueType
|
||||
fonts and incidentally solves glyph spacing problems of
|
||||
less well instructed fonts. Switching to the new mode
|
||||
might take some getting used to though, so if you think
|
||||
your fonts are suddenly fat, fuzzy or weird, give your
|
||||
brain some time to adjust.</p>
|
||||
|
||||
<p>No upside without a downside, though. What made v38 so
|
||||
slow was its attempt to implement the hacks Microsoft
|
||||
describes in
|
||||
a <a href="https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx">whitepaper</a>
|
||||
for their interpreter and rasterizer <em>and</em> a
|
||||
configuration layer on top of that so fonts could be
|
||||
specially handled down to single glyphs. Given the bugs
|
||||
in and dirty hacks used by Arial and co., this was
|
||||
necessary to make them render better than on Windows. In
|
||||
my opinion, this is solid over-engineering in times where
|
||||
the web is full of good-quality typefaces that display
|
||||
well without horizontal hinting or don't even have it.</p>
|
||||
|
||||
<p>The v40 code does not use any whitelist or other means to
|
||||
handle certain fonts differently. It focuses on ignoring
|
||||
horizontal hinting and preventing the dirtiest hacks that
|
||||
dent more than they help. Modern fonts like Calibri,
|
||||
Cambria, Consolas, etc., render well with this approach,
|
||||
older fonts like Arial, Times New Roman, Georgia and
|
||||
Verdana display mostly fine with smaller details off. And
|
||||
that's okay. Basically, the harder a font tries to create
|
||||
pixel-perfect black and white bitmaps for old CRT
|
||||
monitors, the worse the results in the new mode. If
|
||||
someone finds ways to make older fonts render better
|
||||
without introducing lists or overly complex hacks, I'm
|
||||
interested.</p>
|
||||
|
||||
<p>PS: I recommend using the Liberation family of fonts
|
||||
(version 2 and up, important!) instead of Arial,
|
||||
Times New Roman, and Courier. The family harmonizes much
|
||||
better internally and is equipped with much better
|
||||
ClearType-ready hinting. Fedora still ships some 1.x
|
||||
version; you can get the newer 2.x with improved hinting
|
||||
and glyph coverage from
|
||||
<a href="https://fedorahosted.org/liberation-fonts">here</a>.</p>
|
||||
</div>
|
||||
|
||||
<!-- ************************************************** -->
|
||||
|
||||
<div class="updated">
|
||||
<p>Last update: 8-Sep-2016</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ************************************************** -->
|
||||
|
||||
<div class="col2">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ************************************************** -->
|
||||
|
||||
<div id="TOC">
|
||||
<ul>
|
||||
<li class="funding">
|
||||
<p><a href="https://pledgie.com/campaigns/24434">
|
||||
<img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!"
|
||||
src="https://pledgie.com/campaigns/24434.png?skin_name=chrome"
|
||||
border="0"
|
||||
align="middle">
|
||||
</a></p>
|
||||
|
||||
<p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr"
|
||||
target="_blank">
|
||||
<img class="with-border"
|
||||
src="http://api.flattr.com/button/flattr-badge-large.png"
|
||||
alt="Flattr this"
|
||||
title="Flattr this"
|
||||
border="0"
|
||||
align="middle">
|
||||
</a></p>
|
||||
</li>
|
||||
<li class="primary">
|
||||
<a href="http://freetype.org/index.html">Home</a>
|
||||
</li>
|
||||
<li class="primary">
|
||||
<a href="http://freetype.org/index.html#news">News</a>
|
||||
</li>
|
||||
<li class="primary">
|
||||
<a href="index.html">Overview</a>
|
||||
</li>
|
||||
<li class="primary">
|
||||
<a href="documentation.html">Documentation</a>
|
||||
</li>
|
||||
<li class="primary">
|
||||
<a href="http://freetype.org/developer.html">Development</a>
|
||||
</li>
|
||||
<li class="primary">
|
||||
<a href="http://freetype.org/contact.html"
|
||||
class="emphasis">Contact</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<!-- separate primary from secondary entries -->
|
||||
</li>
|
||||
|
||||
<li class="secondary">
|
||||
<a href="#subpixel-hinting" class="current">The v40 Hinting
|
||||
Mode</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div> <!-- id="wrapper" -->
|
||||
|
||||
<div id="TOC-bottom">
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
504
lib/freetype/docs/text-rendering-general.html
Normal file
504
lib/freetype/docs/text-rendering-general.html
Normal file
@ -0,0 +1,504 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=utf-8">
|
||||
<meta http-equiv="Content-Style-Type"
|
||||
content="text/css">
|
||||
<meta http-equiv="Content-Script-Type"
|
||||
content="text/javascript">
|
||||
<meta name="description"
|
||||
content="FreeType Documentation">
|
||||
|
||||
<link rel="icon"
|
||||
href="image/favicon_-90.ico">
|
||||
<link rel="shortcut icon"
|
||||
href="image/favicon_-90.ico">
|
||||
<link rel="stylesheet"
|
||||
type="text/css"
|
||||
href="css/freetype2_-90.css">
|
||||
|
||||
<script type="text/javascript"
|
||||
src="../../js/jquery-1.11.0.min.js">
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="../../js/jquery.ba-resize.min.js">
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="../../js/freetype2.js">
|
||||
</script>
|
||||
|
||||
<title>On slight hinting, proper text rendering, stem darkening and
|
||||
LCD filters</title>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<div id="top"
|
||||
class="bar">
|
||||
<h1><a href="http://freetype.org/index.html">FreeType</a> LCD Support</h1>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="wrapper">
|
||||
|
||||
<div class="colmask leftmenu">
|
||||
<div class="colright">
|
||||
<div class="col1wrap">
|
||||
<div class="col1">
|
||||
|
||||
<!-- ************************************************** -->
|
||||
|
||||
<div id="slight-hinting">
|
||||
<h2>On Slight Hinting, Proper Text Rendering, Stem Darkening
|
||||
and LCD Filters</h2>
|
||||
<div class="date">2015-11-30, contributed by Nikolaus
|
||||
Waxweiler (with corrections from Graham Asher), updated
|
||||
2015-12-08</div>
|
||||
|
||||
<p><em>This article was originally written for the 2.6.2
|
||||
release of FreeType and explains the technical
|
||||
background of several features. The information was
|
||||
deemed useful enough to be added to the documentation
|
||||
and has therefore been retitled.</em></p>
|
||||
|
||||
<p>FreeType 2.6.2 ships with three interesting details for
|
||||
users and developers of rendering libraries that deal with
|
||||
text.</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#slight-hinting-invokes-the-native-hinter-if-possible">(S)light
|
||||
hinting invokes the native hinter if possible</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#experimental-stem-darkening-for-the-auto-hinter">Experimental:
|
||||
Stem darkening for the auto-hinter</a>
|
||||
<ul>
|
||||
<li><a href="#background">Background</a></li>
|
||||
<li><a href="#back-to-stem-darkening">Back to stem
|
||||
darkening</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#disabled-stem-darkening-for-the-autohinter-and-adobes-cff-otf-engine">Disabled
|
||||
stem darkening for the autohinter and Adobe’s CFF
|
||||
(<code>.otf</code>) engine</a>
|
||||
</li>
|
||||
<li><a href="#the-default-lcd-filter-for-subpixel-rendering-has-been-changed">The
|
||||
default LCD filter for subpixel rendering has been
|
||||
changed</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3 id="slight-hinting-invokes-the-native-hinter-if-possible">(S)light
|
||||
hinting invokes the native hinter if possible</h3>
|
||||
|
||||
<p>In the past, setting ‘slight’ hinting via FontConfig or
|
||||
configuration GUIs meant that native hints within a font
|
||||
were ignored; FreeType’s auto-hinter would analyze the
|
||||
font on the fly and automatically do what the font
|
||||
designer would have to do at least semi-manually.
|
||||
Technically, the auto-hinter set to (s)light snaps glyphs
|
||||
to the pixel grid only vertically, just like Adobe’s
|
||||
proprietary font engine and in a certain way also
|
||||
Microsoft’s ClearType/DirectWrite. The result is a
|
||||
compromise between design fidelity and sharpness that
|
||||
preserves inter-glyph spacing, something very important
|
||||
for horizontal text such as what you are reading right
|
||||
now. The sharpness has usually been enhanced with
|
||||
‘subpixel rendering’ (ClearType on Windows), exploiting
|
||||
the physical properties of modern but low-resolution LCD
|
||||
panels.</p>
|
||||
|
||||
<p>This worked out well so far, Ubuntu has been using this
|
||||
setting for every font for years now. Werner Lemberg is
|
||||
adding support for more and more scripts and has also spun
|
||||
off the code
|
||||
into <a href="http://www.freetype.org/ttfautohint/">ttfautohint</a>,
|
||||
to help font designers ease the pain of manual
|
||||
hinting.</p>
|
||||
|
||||
<p>This also meant that the native hinting machinery of the
|
||||
font drivers went unused. Historically, this decision was
|
||||
sound because the native hinting mechanics for Postscript
|
||||
(<code>.pfa</code>, <code>.pfb</code>), TrueType
|
||||
(<code>.ttf</code>) and OpenType/CFF (<code>.otf</code>)
|
||||
were subpar for the longest time. The PostScript hinter
|
||||
still is, but with Adobe’s high-quality OpenType/CFF
|
||||
engine contributed to FreeType and recent advances of the
|
||||
TrueType driver towards full ClearType support, things
|
||||
have changed.</p>
|
||||
|
||||
<p>Setting ‘slight’ hinting usually leads
|
||||
to <code>FT_LOAD_TARGET_LIGHT</code>. This mode implied
|
||||
the auto-hinter before and has now been changed to mean
|
||||
“Use native vertical-grid-only-snapping if driver and font
|
||||
supports it and vertical-grid-only auto-hinter otherwise”.
|
||||
Right now, only the OpenType/CFF driver is supported. In
|
||||
the future, this will hopefully include the TrueType
|
||||
engine once full support for ClearType arrives.
|
||||
Technically, ClearType fonts can and will snap to the
|
||||
vertical <em>and</em> the horizontal
|
||||
grid <a href="http://www.beatstamm.com/typography/RTRCh4.htm#Sec12">depending
|
||||
on several details</a>, but the net result is going in the
|
||||
direction we want.</p>
|
||||
|
||||
<p>This decision was driven by my personal whim; I wanted
|
||||
native vertical grid-fitting if the font driver and font
|
||||
supports it, and the auto-hinter otherwise. I assume that
|
||||
native hints are made more carefully and take the
|
||||
(auto-hinting) guesswork out of the process. Instead of
|
||||
introducing per-format configuration in FontConfig and
|
||||
fighting <a href="http://www.gtk.org/">GTK</a>/<a href="https://www.gnome.org/">GNOME</a>
|
||||
that only support a single global hinting setting, it was
|
||||
found to make more sense to change the definition of light
|
||||
hinting in FreeType.</p>
|
||||
|
||||
<p>I also hope this change will make it easier for the
|
||||
non-Windows-and-Apple ecosystem to switch over to slight
|
||||
hinting as the default. Current full/medium native
|
||||
hinting, as is the default, tends to bring out the worst
|
||||
in many, many fonts that haven’t seen the same insane
|
||||
dedication to on-screen display and hinting as many
|
||||
popular Microsoft fonts, for example. And since ClearType
|
||||
is still not fully supported, you usually get a very poor
|
||||
default experience. Slight hinting gives a much better
|
||||
one, as Ubuntu has proven over the years.</p>
|
||||
|
||||
|
||||
<h3 id="experimental-stem-darkening-for-the-auto-hinter">Experimental:
|
||||
Stem darkening for the auto-hinter</h3>
|
||||
|
||||
<p><a href="image/freetype-262-autohinter-stem-darkening-demo1.png">
|
||||
<img src="image/freetype-262-autohinter-stem-darkening-demo1-thumbnail.png"
|
||||
alt="Demonstration and comparison of the
|
||||
emboldening autohinter."></a></p>
|
||||
|
||||
<p>Stem darkening emboldens glyphs at smaller sizes to make
|
||||
them more readable on common low-DPI screens. If this
|
||||
sounds familiar to you, that’s because Adobe’s CFF engine
|
||||
has been doing it since it was contributed in 2013. You
|
||||
might have noticed that OpenType/CFF fonts (commonly
|
||||
suffixed <code>.otf</code>) like GNOME 3’s default UI
|
||||
font <a href="https://en.wikipedia.org/wiki/Cantarell_%28typeface%29">Cantarell</a>
|
||||
appear bolder and fuzzier than other fonts, at least until
|
||||
this release. The auto-hinter can do the exact same thing
|
||||
now, it is just disabled by default.</p>
|
||||
|
||||
<p>But why would you do this if small glyphs are already
|
||||
fairly readable? It turns out that font rendering in the
|
||||
Linux ecosystem has been wrong since scalable fonts were
|
||||
introduced to it. Text must be rendered with linear alpha
|
||||
blending and gamma correction, which no toolkit or
|
||||
rendering library does by default on
|
||||
<a href="http://www.x.org/">X11</a>, even
|
||||
though <a href="http://www.qt.io/">Qt5</a>
|
||||
and <a href="https://skia.org/">Skia</a> (as used by
|
||||
Google Chrome and other browsers) can do it.</p>
|
||||
|
||||
|
||||
<h4 id="background">Background</h4>
|
||||
|
||||
<p>First, to understand why they are required, you must know
|
||||
that when FreeType outputs a grayscale glyph image, it
|
||||
really outputs a coverage bitmap. If a pixel is
|
||||
completely covered by a filled-in outline, the pixel is
|
||||
made 100% black (0% brightness, which is simply black).
|
||||
If a pixel is only 50% covered, the pixel is made 50%
|
||||
black (50% brightness or a middle shade of gray) and 0%
|
||||
covered means 0% black (100% brightness or white). On
|
||||
high-DPI screens like on smartphones and tablets, the
|
||||
pixels are so small that the chance of being completely
|
||||
covered and therefore completely black is fairly good. On
|
||||
low-DPI screens most of us are sadly stuck with, the
|
||||
situation is different. The pixels are too large for most
|
||||
of the details of a glyph and shades of gray are the norm
|
||||
rather than the exception.</p>
|
||||
|
||||
<p>This is relevant because all our screens have a second
|
||||
problem: they are not linear. 1 + 1 is
|
||||
not 2. Twice the value does not result in twice the
|
||||
brightness. When a pixel is only 50% covered, the
|
||||
coverage map says 50% black, and this translates to a
|
||||
pixel value of 128 when you use 8 bits per
|
||||
channel (0-255). However, this does not translate to 50%
|
||||
brightness for that pixel on our sRGB and gamma 2.2
|
||||
screens. Due to their non-linearity, they dwell longer in
|
||||
the darks and only a pixel value of about 186 results
|
||||
in 50% brightness – 128 ends up too dark on both
|
||||
bright and dark backgrounds. The net result is that dark
|
||||
text looks burnt-out, pixely and blotchy on bright
|
||||
background, bright text too frail on dark backgrounds, and
|
||||
colored text on colored background (for example, red on
|
||||
green) seems to have dark halos or ‘dirt’ around it. The
|
||||
situation is especially ugly for diagonal stems like in
|
||||
glyph ‘w’, where the quality of FreeType’s anti-aliasing
|
||||
depends on the correct display of grays. On high-DPI
|
||||
screens where smaller, fully black pixels reign supreme,
|
||||
this doesn’t matter, but on our low-DPI screens with all
|
||||
the gray shades, it does. 0% and 100% brightness are the
|
||||
same things in linear and non-linear space, just all the
|
||||
shades in-between are not.</p>
|
||||
|
||||
<p>The correct way of rendering a glyph image on a surface
|
||||
is
|
||||
to <a href="https://en.wikipedia.org/wiki/Alpha_compositing">alpha
|
||||
blend</a> it onto the surface in linear space and then
|
||||
apply <a href="https://en.wikipedia.org/wiki/Gamma_correction">gamma
|
||||
correction</a> to translate the linear coverage map to
|
||||
something that is correct for our screens.<sup>1</sup> No
|
||||
toolkit in the Linux ecosystem does it by default, even
|
||||
though Qt5 and Skia can and will do it on other platforms.
|
||||
Windows and Mac OS X do it natively. This procedure
|
||||
is especially important if glyphs should be
|
||||
subpixel-rendered (ClearType and Mac
|
||||
OS X) <a href="http://lists.nongnu.org/archive/html/freetype-devel/2015-11/msg00020.html">with
|
||||
as few color fringes as possible</a>.</p>
|
||||
|
||||
<p><sup>1</sup> This process can cost performance. There is
|
||||
an approximation that does not need to know about the
|
||||
background color.
|
||||
See <a href="https://bel.fi/alankila/lcd/">https://bel.fi/alankila/lcd/</a>
|
||||
and <a href="https://bel.fi/alankila/lcd/alpcor.html">https://bel.fi/alankila/lcd/alpcor.html</a>
|
||||
for details. There is a proof-of-concept pixman hack for
|
||||
cairo.</p>
|
||||
|
||||
|
||||
<h4 id="back-to-stem-darkening">Back to stem darkening</h4>
|
||||
|
||||
<p>Assume we render fonts correctly. Gamma correction
|
||||
essentially lightens fonts since shades of gray are
|
||||
shifted to higher pixel values (corresponding to higher
|
||||
brightness) to match the original intention to the reality
|
||||
of our screens. The side-effect is that glyphs that were
|
||||
rendered incorrectly but fairly readable suddenly thin
|
||||
out. Correctly rendered but hard-to-read text doesn’t do
|
||||
anyone a favor. So Mac OS X and Adobe’s proprietary
|
||||
font engine implement a counter-measure: stem darkening at
|
||||
smaller sizes where shades of gray dominate. By
|
||||
emboldening a glyph slightly in relation to its pixel
|
||||
size, individual pixels get higher coverage of filled-in
|
||||
outlines and are therefore blacker. This increases
|
||||
contrast and prevents thinning out of glyphs. Text
|
||||
remains readable at smaller sizes.</p>
|
||||
|
||||
<p><a href="image/BlendingExamples.png">
|
||||
<img src="image/BlendingExamples-thumbnail.png"
|
||||
alt="Comparison of different ways of
|
||||
blending."></a></p>
|
||||
|
||||
<p>“Gamma 1.0” shows what happens when you take a grayscale
|
||||
coverage bitmap from FreeType and blend it onto a surface
|
||||
in linear space. Black-on-white is heavier than
|
||||
white-on-black and red-on-green has dark halos or dirt
|
||||
around it. Note that this picture is unrealistic in the
|
||||
sense that no rendering system on X11 does linear alpha
|
||||
blending, so imagine something worse. “Gamma 1.8” is the
|
||||
result of linear alpha blending and gamma correction. It
|
||||
is much better, but text thins out, making it harder to
|
||||
read. Adding stem darkening gets us to “Gamma 1.8,
|
||||
darkened”. Note how it is the cleanest rendering of all.
|
||||
“Gamma 1.0, darkened”, meaning linear alpha blending
|
||||
without gamma correction but with stem darkening,
|
||||
exaggerates the effects of “Gamma 1.0”. Stem darkening
|
||||
should only be enabled when doing gamma correction, so
|
||||
ideally it should always be done.</p>
|
||||
|
||||
<p><a href="image/freetype-262-autohinter-stem-darkening-demo2.png">
|
||||
<img src="image/freetype-262-autohinter-stem-darkening-demo2-thumbnail.png"
|
||||
alt="Waterfall comparison of non-emboldening and
|
||||
emboldening autohinter."></a></p>
|
||||
|
||||
<p>The autohinter has a new toggleable stem darkening
|
||||
property that works like the stem darkener in Adobe’s CFF
|
||||
engine. Note how it makes text slightly bolder with the
|
||||
default parameters, down to small pixel sizes. Gamma
|
||||
correction is active to demonstrate the thinning out of
|
||||
text especially at smaller pixel sizes with lots of gray
|
||||
pixels.</p>
|
||||
|
||||
<p>And that is the story behind this feature.</p>
|
||||
|
||||
|
||||
<h3 id="disabled-stem-darkening-for-the-autohinter-and-adobes-cff-otf-engine">Disabled
|
||||
stem darkening for the autohinter and Adobe’s CFF
|
||||
(<code>.otf</code>) engine</h3>
|
||||
|
||||
<p>No library supports linear alpha blending and gamma
|
||||
correction out of the box on X11. Turning on stem
|
||||
darkening leads to heavy and fuzzy looking glyphs as in
|
||||
“Gamma 1.0, darkened” above, so it’s better to disable
|
||||
it.</p>
|
||||
|
||||
<p>Qt5 actually had gamma correction enabled for a short
|
||||
time while until someone complained that text was too
|
||||
light and unlike rendering in other toolkits, so the
|
||||
maintainers disabled it for
|
||||
the <a href="https://bugreports.qt.io/browse/QTBUG-41590">XCB-backend</a>.
|
||||
Skia (Chrome) can do gamma-correction, but turns it off
|
||||
for X11.</p>
|
||||
|
||||
<p>I see autohinter stem darkening as a technology preview
|
||||
for playing around with until we get stem darkening
|
||||
generic within FreeType. The plan is to provide it for
|
||||
all font drivers and make it toggleable
|
||||
per <code>FT_Library</code> just like
|
||||
<code>FT_Library_SetLcdFilter</code>. Libraries that
|
||||
support linear alpha blending and gamma correction can
|
||||
then just flip the switch and get appropriate glyphs no
|
||||
matter the font.</p>
|
||||
|
||||
<p>A notable side-effect of disabling all stem darkening by
|
||||
default is that natively hinted <code>.otf</code> fonts
|
||||
will render remarkably similar to the auto-hinter and are
|
||||
no longer heavy and fuzzy. Slight hinting will result in
|
||||
consistent font rendering.</p>
|
||||
|
||||
|
||||
<h3 id="the-default-lcd-filter-for-subpixel-rendering-has-been-changed">The
|
||||
default LCD filter for subpixel rendering has been
|
||||
changed</h3>
|
||||
|
||||
<p><a href="image/freetype-262-new-old-filter.png">
|
||||
<img src="image/freetype-262-new-old-filter-thumbnail.png"
|
||||
alt="Comparison of the old and new
|
||||
filter."></a></p>
|
||||
|
||||
<p>When you look at subpixel-rendered text, no matter
|
||||
whether it is on some kind of Unix, Windows, or Mac
|
||||
OS X, you might notice that it is slightly colored.
|
||||
Using subpixel rendering on LCD panels is a trade-off; you
|
||||
get three times higher resolution in the direction of the
|
||||
pixel-substripe (usually horizontal RGB) in exchange for
|
||||
color artifacts, also called color fringes. For this
|
||||
reason it is necessary to filter a subpixel-rendered glyph
|
||||
to reduce those color fringes before putting it somewhere
|
||||
on the screen. The filter distributes the values of a
|
||||
subpixel to its neighbors, sacrificing some of the higher
|
||||
resolution and making the resulting glyph image blurrier,
|
||||
but the positioning improvement remains! The ideal filter
|
||||
for you depends on your screen (gamma curves), the
|
||||
capabilities of the rendering system (linear alpha
|
||||
blending and gamma correction), your vision and your
|
||||
taste, probably in that order.</p>
|
||||
|
||||
<p>A filter should have two properties: it should be
|
||||
normalized, meaning the values used in the filter should
|
||||
sum up to a figurative 1 (here: 0x100 or 256) and it
|
||||
should be color-balanced, meaning that values for one
|
||||
subpixel are equally distributed to all other subpixels of
|
||||
a pixel to sacrifice some of the higher resolution to
|
||||
drastically reduce color fringes.</p>
|
||||
|
||||
<p>Previously, FreeType’s default LCD filter was neither
|
||||
normalized nor color-balanced. That was a deliberate
|
||||
choice because there is still no rendering system on
|
||||
Unix-like operating systems that does linear alpha
|
||||
blending and gamma correction by default to render glyphs
|
||||
correctly. Going above a filter sum of 1 increased
|
||||
contrast somewhat at the expense of slight distortions and
|
||||
increased color-fringing, so this can be seen as a hack.
|
||||
You might have noticed that thumbnails in various places
|
||||
on your computer that show text could be quite colorful.
|
||||
Now you know why.</p>
|
||||
|
||||
<p>The new default filter is both normalized and
|
||||
color-balanced. It is indeed ever so slightly blurrier
|
||||
than the previous default one, but also lacks its
|
||||
harshness and is less color-happy. The blurriness also
|
||||
means higher tolerance for non-ideal screen gamma (viewing
|
||||
angles) and rendering systems without linear alpha
|
||||
blending. Note that color fringes can only be really
|
||||
minimized when the rendering system will do linear alpha
|
||||
blending of text.</p>
|
||||
|
||||
<p>The ‘light’ filter that has accompanied the default one
|
||||
for so long stays unchanged: it already is normalized and
|
||||
color-balanced. It is sharper than the default one but
|
||||
less tolerant of uncalibrated screens and rendering
|
||||
systems without linear alpha blending, producing more
|
||||
color fringes.</p>
|
||||
</div>
|
||||
|
||||
<!-- ************************************************** -->
|
||||
|
||||
<div class="updated">
|
||||
<p>Last update: 12-Feb-2016</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ************************************************** -->
|
||||
|
||||
<div class="col2">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ************************************************** -->
|
||||
|
||||
<div id="TOC">
|
||||
<ul>
|
||||
<li class="funding">
|
||||
<p><a href="https://pledgie.com/campaigns/24434">
|
||||
<img alt="Click here to lend your support to the FreeType project and make a donation at pledgie.com!"
|
||||
src="https://pledgie.com/campaigns/24434.png?skin_name=chrome"
|
||||
border="0"
|
||||
align="middle">
|
||||
</a></p>
|
||||
|
||||
<p><a href="https://flattr.com/thing/421342/lemzwerg-on-Flattr"
|
||||
target="_blank">
|
||||
<img class="with-border"
|
||||
src="http://api.flattr.com/button/flattr-badge-large.png"
|
||||
alt="Flattr this"
|
||||
title="Flattr this"
|
||||
border="0"
|
||||
align="middle">
|
||||
</a></p>
|
||||
</li>
|
||||
<li class="primary">
|
||||
<a href="http://freetype.org/index.html">Home</a>
|
||||
</li>
|
||||
<li class="primary">
|
||||
<a href="http://freetype.org/index.html#news">News</a>
|
||||
</li>
|
||||
<li class="primary">
|
||||
<a href="index.html">Overview</a>
|
||||
</li>
|
||||
<li class="primary">
|
||||
<a href="documentation.html">Documentation</a>
|
||||
</li>
|
||||
<li class="primary">
|
||||
<a href="http://freetype.org/developer.html">Development</a>
|
||||
</li>
|
||||
<li class="primary">
|
||||
<a href="http://freetype.org/contact.html"
|
||||
class="emphasis">Contact</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<!-- separate primary from secondary entries -->
|
||||
</li>
|
||||
|
||||
<li class="secondary">
|
||||
<a href="#slight-hinting" class="current">On Slight
|
||||
Hinting, …</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div> <!-- id="wrapper" -->
|
||||
|
||||
<div id="TOC-bottom">
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user