<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
(I am sending this to <a class="moz-txt-link-abbreviated" href="mailto:cairo@cairographics.org">cairo@cairographics.org</a> rather than
<a class="moz-txt-link-abbreviated" href="mailto:cairo-bugs@cairographics.org">cairo-bugs@cairographics.org</a> because that's what the contact page
told me, I hope this is correct)<br>
<br>
I recently encountered a bug in GIMP where the edge pixels of text
would become greenish rather than the intended color:<br>
<br>
<img alt="incorrect antialiasing in GIMP"
src="cid:part1.09000803.04080101@hotmail.com" width="152"
height="156"><br>
<br>
By coincidence, this bug doesn't affect Ubuntu and some other
distributions, because it only appears when the fontconfig file
explicitly defines the pixel layout of the display. Ubuntu doesn't
do this, but it does enable 'lcdfilter', and apparently this causes
cairo to use RGB by default. But if you explicitly define the layout
as RGB or anything else (which seems to be required for Qt 5
applications to get any subpixel antialiasing at all), this bug
appears.<br>
<br>
I thought this was a bug in GIMP (it doesn't disable subpixel
rendering, so this problem was to be expected), but when I tried to
fix it, I discovered that cairo simply ignores what the application
says and forces subpixel rendering even when you explicitly disable
it. This makes no sense. The documentation states:<br>
<br>
<table border="0">
<tbody>
<tr>
<td>
<p><span class="term"><code class="literal">CAIRO_ANTIALIAS_DEFAULT</code></span></p>
</td>
<td>Use the default antialiasing for the subsystem and target
device, since 1.0
</td>
</tr>
<tr>
<td>
<p><span class="term"><code class="literal">CAIRO_ANTIALIAS_NONE</code></span></p>
</td>
<td>Use a bilevel alpha mask, since 1.0
</td>
</tr>
<tr>
<td>
<p><span class="term"><code class="literal">CAIRO_ANTIALIAS_GRAY</code></span></p>
</td>
<td>Perform single-color antialiasing (using shades of gray
for black text on a white background, for example), since
1.0
</td>
</tr>
<tr>
<td>
<p><span class="term"><code class="literal">CAIRO_ANTIALIAS_SUBPIXEL</code></span></p>
</td>
<td>Perform antialiasing by taking advantage of the order of
subpixel elements on devices such as LCD panels, since 1.0
</td>
</tr>
<tr>
<td>
<p><span class="term"><code class="literal">CAIRO_ANTIALIAS_FAST</code></span></p>
</td>
<td>Hint that the backend should perform some
antialiasing but prefer speed over quality, since 1.12
</td>
</tr>
<tr>
<td>
<p><span class="term"><code class="literal">CAIRO_ANTIALIAS_GOOD</code></span></p>
</td>
<td>The backend should balance quality against
performance, since 1.12
</td>
</tr>
<tr>
<td>
<p><span class="term"><code class="literal">CAIRO_ANTIALIAS_BEST</code></span></p>
</td>
<td>Hint that the backend should render at the highest
quality, sacrificing speed if necessary, since 1.12
</td>
</tr>
</tbody>
</table>
<br>
In my tests, CAIRO_ANTIALIAS_GRAY actually results in subpixel
rendering. And ironically, <span class="term"><code class="literal"><font
face="sans-serif">CAIRO_ANTIALIAS_GOOD results in no subpixel
rendering. I could fix the bug in GIMP by using
CAIRO_ANTIALIAS_GOOD rather than CAIRO_ANTIALIAS_GRAY, but
that seems like a bad idea as it could easily break in the
future, or on other platforms. Besides, the documentation also
states:</font></code></span><br>
<blockquote><span class="term"><code class="literal"><font
face="sans-serif">In the case of glyph rendering,
<em class="parameter"><code>CAIRO_ANTIALIAS_FAST</code></em>
and <em class="parameter"><code>CAIRO_ANTIALIAS_GOOD</code></em>
will be mapped to
<em class="parameter"><code>CAIRO_ANTIALIAS_GRAY</code></em>,
with <em class="parameter"><code>CAIRO_ANTALIAS_BEST</code></em>
being equivalent to
<em class="parameter"><code>CAIRO_ANTIALIAS_SUBPIXEL</code></em>.</font></code></span><br>
<span class="term"><code class="literal"></code></span></blockquote>
<span class="term"><code class="literal"><font face="sans-serif">This
is simply wrong, my test clearly shows different results for
CAIRO_ANTIALIAS_GOOD and CAIRO_ANTIALIAS_GRAY.<br>
<br>
So I would like to propose this patch:<br>
</font></code></span><span class="term"><code class="literal"></code></span>
<pre>diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 1ab56be..6ceec03 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -1768,8 +1768,7 @@ _cairo_ft_options_merge (cairo_ft_options_t *options,
}
if (other->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL &&
- (options->base.antialias == CAIRO_ANTIALIAS_DEFAULT ||
- options->base.antialias == CAIRO_ANTIALIAS_GRAY)) {
+ options->base.antialias == CAIRO_ANTIALIAS_DEFAULT) {
options->base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
options->base.subpixel_order = other->base.subpixel_order;
}
</pre>
<span class="term"><code class="literal"><font face="sans-serif">The
effect is minimal: CAIRO_ANTIALIAS_GRAY will be respected when
the fontconfig file specifies subpixel antialiasing. I've
tested this patch for a few weeks on my computer, and I don't
see any issues whatsoever.</font></code></span> Most
applications just use CAIRO_ANTIALIAS_DEFAULT - the only situation
where an application would ever specify <span class="term"><code
class="literal"><font face="sans-serif">CAIRO_ANTIALIAS_GRAY is
when it's actually required, so the system settings should
never override this.<br>
<br>
I know that similar bugs have already been reported years ago,
and apparently not everyone agrees on how
_cairo_ft_options_merge() should behave. But this bug is
obviously a problem, since it makes it impossible to write an
application like GIMP which requires subpixel rendering to be
disabled reliably. I hope this can get fixed soon, so I can
fix this bug in GIMP.<br>
<br>
Maarten Baert<br>
</font></code></span>
</body>
</html>