Pages

July 09, 2010

Ubuntu font rendering in Debian Squeeze

[Update 2011-06-25: Confirmed. Updating Iceweasel from http://mozilla.debian.net/ fixes fonts. See this post for more info. So there's no longer any real need to do what's below.]
[Update 2011-06-24: This whole business may be unnecessary as it appears installing a recent version of Iceweasel from http://mozilla.debian.net/ also installs new libcairo2 with decent font rendering. I've yet to do careful comparisons, but it's possible that this solves both "ugly rendering in general" as well as "ugly rendering in Firefox" issues.]
[Update 2011-03-08:]  Reader datSilencer points out that the location of the Arch patch has moved. Therefore, the process for extracting and applying the Arch patch won't work. I am updating the script but I won't be updating this post. If you want to do things manually, please consult the script for the needed changes.]
[Update 2010-09-23: I made a script to semi-automate a lot of the following.]

I love Debian. I really do. But one thing I don't love about Debian is the way it renders fonts in GTK. Or rather, the way Ubuntu renders fonts has spoiled me. After reading about how some people have successfully patched their libraries to use the same changes used by Ubuntu, I've finally succeeded myself. It's been so gratifying and such a good learning experience that I wanted to share.

The process below is based on information from the CrunchBang Linux Forums and from one quanliking. Huge, huge thanks to those people.

To get Ubuntu font rendering in Debian Squeeze, we need to download, patch, rebuild, and reinstall the libcairo2 package. If this breaks your system don't sue me. I am not an expert nor do I play one on TV.

Pre-production
Begin by making sure downloading of package sources is enabled for apt. The line below should be in /etc/apt/sources.list and not commented out:

deb-src http://ftp.us.debian.org/debian/ squeeze main non-free contrib

The actual address will differ depending on which mirror you set up your system to use, but there should be a line that begins "deb-src", has a mirror's address in the middle, and ends with "squeeze main non-free contrib" or "testing main non-free contrib".

Install the needed build tools (as root):

# apt-get install build-essential devscripts fakeroot
# apt-get build-dep cairo


As a regular user, create a new directory called patched-packages in your home directory.

Get the patches
Open the patched-packages directory you created above in a terminal (i.e., the prompt should read something like username@computername:~/patched-packages$).

At the command prompt:

mkdir libcairo2
cd libcairo2
mkdir downloaded-patches


We now need to get two sets of patches, one from Ubuntu and the other from Arch Linux. To get the Ubuntu patches, go to http://packages.ubuntu.com/lucid/libcairo2 and look at the list of links on the right. We want the file cairo_1.8.10-{#}ubuntu1.debian.tar.gz. Download it into ~/patched-packages/downloaded-patches and expand it. This should produce a new directory inside ~/patched-packages/downloaded-patches called debian (i.e., you should now have a ~/patched-packages/downloaded-patches/debian).

I'm not yet sure what the original source of the Arch Linux patch is, but apparently we need it. So go to http://aur.archlinux.org/packages.php?ID=17327 and download the file cairo-respect-fontconfig.patch into ~/patched-packages/downloaded-patches

You're done getting patches.

Get the sources
We now need to get the Debian source package for libcairo2. In a terminal inside ~/patched-packages/libcario2,

mkdir deb-sources
cd deb-sources
apt-get source cairo
cd ./cairo-*


Then copy the patches we downloaded earlier to the Debian package's patches directory:

cp ../../downloaded-patches/cairo-respect-fontconfig.patch ./debian/patches/
cp ../../downloaded-patches/debian/patches/04_lcd_filter.patch ./debian/patches/
cp ../../downloaded-patches/debian/patches/06_Xlib-Xcb-Hand-off-EXTEND_PAD-to-XRender.patch ./debian/patches/


Next, apply the patches to the sources:

patch -p1 -i ./debian/patches/cairo-respect-fontconfig.patch
patch -p1 -i ./debian/patches/04_lcd_filter.patch
patch -p1 -i ./debian/patches/06_Xlib-Xcb-Hand-off-EXTEND_PAD-to-XRender.patch


We now need to modify the changelog to indicate that we've diddled with the package and set a version increment:

dch -i

This will open a text editor. Once there, add

David Turner's ClearType-like LCD filtering patch and fix.

after the asterisk at the top and then save and exit.

(Note: Instead of dch -i above you can also use dch -l {your initials}.)

Build and install
Time to build it. Continuing from where we were in the terminal above (i.e., inside something like ~/patched-packages/libcairo2/deb-sources/cairo-1.8.10) do

dpkg-buildpackage -rfakeroot -us -uc

The result should be a bunch of new packages inside ~/patched-packages/libcairo2/deb-sources/

Look if you don't believe me. All that's left is to install. Open a root terminal and go to the ~/patched-packages/libcairo2/deb-sources/ directory. Then do:

# dpkg -i *.deb

This will install all the debs that were made, of which you may actually only need a subset. Apart from taking up some disk space the extra packages won't hurt anything, and if you install a package in the future that needs one of these, you'l be glad you installed them now.

Congrats. You should now have (IMHO) much improved font rendering. This should hold you until Debian releases a new libcairo2. If the new libcairo2 release doesn't have the "Ubuntu patches" already built in, you'll have to repeat the above process, making sure you get patches that are appropriate for the new version and that there are no additional patch files. (If there are, you will need to copy/add them before rebuilding.)

Rolling back your system to the original Debian packages should be as easy as using Synaptic to "Package -> Force Version..." to the original libcairo2 packages.

Happy building.

13 comments:

Deibu said...

Thanks for the walk-through! Any of the other methods I tried improved the font rendering in Debian, but didn't quite get it right.

Anonymous said...

To avoid "color fringing" (AKA "rainbow blur"), you also have to enable LCD filtering. One way is to install Ubuntu's fontconfig-config package, which puts the needed settings in /etc/fonts/conf.d. Alternatively, see if you already have the following files in /etc/fonts/conf.avail:

10-antialias.conf
10-hinting.conf
10-hinting-slight.conf
11-lcd-filter-lcddefault.conf
53-monospace-lcd-filter.conf

If so, you can just create symlinks from the first directory to the other:

ln -s /etc/fonts/conf.avail/10-antialias.conf /etc/fonts/conf.d/10-antialias.conf
ln -s /etc/fonts/conf.avail/10-hinting.conf /etc/fonts/conf.d/10-hinting.conf
ln -s /etc/fonts/conf.avail/10-hinting-slight.conf /etc/fonts/conf.d/10-hinting-slight.conf
ln -s /etc/fonts/conf.avail/11-lcd-filter-lcddefault.conf /etc/fonts/conf.d/11-lcd-filter-lcddefault.conf
ln -s /etc/fonts/conf.avail/53-monospace-lcd-filter.conf /etc/fonts/conf.d/53-monospace-lcd-filter.conf

If you don't have these files, either unpack the Ubuntu .deb file and copy them over, or create a /etc/fonts/local.conf file which sets "lcdfilter" to "lcddefault". This file is XML, so I'm unable to show it here - see ArchWiki for details.

http://wiki.archlinux.org/index.php/Font_Configuration#LCD_Type

For more on the importance of filtering, see Freddie Witherden's Treatise on Font Rasterisation.

https://freddie.witherden.org/pages/font-rasterisation/

Mithat said...

@Marius

Thanks for the info! I won't have access to my Squeeze box for about two weeks, but I do remember having to tweak my ~/.fonts.conf file to get consistent rendering in all apps (lcdfilter set to default and hintstyle set to hintslight).

However, I did not do anything with /etc/fonts/conf.d. Your suggestion is also suggested in the Debian Forums:

http://forums.debian.net/viewtopic.php?f=10&t=38534&start=15#p235887

I'll see what happens on my Squeeze box with those links as soon as I'm back in front of it.

Mithat said...

@Marius

I just added the bits you suggested -- with two modifications:

1. I added *all* the /etc/fonts/conf.avail and /etc/fonts/conf.d files from Lucid's fontconfig-config that were not already present.

2. Configured as such, I was no longer able to change the slight/full hinting from GNOME's Appearances (the radio buttons would change, but there was no change in how fonts were rendered). I therefore removed the 10-* links in /etc/fonts/conf.d, and that seems to have solved that problem.

Wilbert said...

I installed the Ubuntu fontconfig*.deb and surprisingly Debian updater notified me of an update.

Curious to see what would happen, I let the update install and basically that removed the Ubuntu files and replaced them with the set of Debian config files.

Which encourages me to leave the /etc/fonts structure untouched and just create the /etc/fonts/local.conf with the content of the missing Ubuntu files.

Local.conf is suggested for systemwide modifications and my experiment shows it's a wise approach.

Anonymous said...

Please provide before and after screenshots, if possible. I always find that most articles that talk about font rendering misses this.

Mehdi said...

Great tutorial! Can I share the debs I made with my friends?

Mithat said...

@Mahdi

I build+install packages on one 32-bit system and install them on two others. So far, no problems.

Unknown said...

Thx for sharing, it works!

Actually there is an alternative to patching cairo for Debian by hand. The Mozilla Debian Team ships and updated (and patched, as I can see) libcairo2.

The link is http://mozilla.debian.net/ , the sources and the key you will find there.

They ship an updated libcairo2 package alongside with their iceweasel v.4. Try this after adding the new sources:

apt-get apdate
apt-get install iceweasel

The following packages will be updated:
libcairo2 (1.8.10-6) to 1.10.2-1.1~bpo60+1
libnss3-1d (3.12.8-1+squeeze1) to 3.12.9-2~bpo60+1
libpixman-1-0 (0.16.4-1) to 0.21.4-2~bpo60+1

The following packages will be installed:
iceweasel (4.0.1-1~bpo60+1)
libmozjs4d (2.0.1-1~bpo60+1)
libxcb-shm0 (1.6-1)
xulrunner-2.0 (2.0.1-1~bpo60+1)

Now my fonts look pretty Ubuntu-like (after the relevant changes on fonts.conf and ~/.Xresources).

It's amazing! Zero effort.

Mithat said...

@woo555!: This is great. The libcairo2 (1.10) currently being shipped with Wheezy seems not to implement the (latest?) lcd filtering -- resulting in *almost* Ubuntu-like (and slightly inferior) font rendering out-of-the-box. If the mozilla.debian.net versions fix that, it may be good news for both Squeeze and Wheezy users.

I will give it a shot on a couple of my machines and report back.

Anonymous said...

Thanks for the post. This had another positive side effect, black artefacts left on the screen by Docky have now disappeared!

Unknown said...

This how-to works on Debian 6.0.4. Google chrome however seems not following the system font rendering but a workaround is to have bigger fonts and 100 percent zoom level.

Look at my post here. http://kamayadsinlinux.blogspot.com/2012/05/more-debian-font-rendering-tips.html

Артур said...

Link to cairo-respect-fontconfig.patch is not available on
http://aur.archlinux.org/packages.php?ID=17327
:(