README for gdkxft (aka libgdkxft.so)
====================================
Gdkxft transparently adds anti-aliased font support to gtk+-1.2. Once
you have installed it, you can run any (well, nearly any) existing
gtk+ binary and see anti-aliased fonts in the gtk widgets. You don't
need to recompile gtk+ or your applications.
This README file contains five sections: a disclaimer; quickstart
instructions for those who are keen to have gdkxft working without
knowing how it works; trouble-shooting information; lengthy
installation instructions for those who want to know what is going on;
and some caveats.
For the latest, see http://gdkxft.sourceforge.net
To contact me, email josh@philosophy.org.au
I. Disclaimer
=============
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
In particular, a botched install of gdkxft has the potential to make
your X configuration unworkable. That is why I ask you to read the
README through to at least the end of the Quickstart section before
you try installing. Yes, even if you are installing from an rpm
package.
II. QuickStart Instructions
===========================
1. Read these instructions through to the end before you start.
2. Make sure you have the Xft library (comes with XFree86 4.x and
higher). I also recommend that you upgrade to the latest version
of Xft / XFree86 (I am using XFree86 4.1). Make sure you have perl
(needed for step 5 - if you don't have perl, follow the Lengthy
Instructions).
3. Configure and build gdkxft in the usual manner. "./configure &&
make" should work. (See INSTALL for more on this bit).
4. As root, make install
5. As root, type
gdkxft_sysinstall
at the shell prompt. This will configure Xft correctly, and arrange
for gdkxft to be used when X starts up.
6. If you were running X, log out and log back in, to allow changes to
your X configuration to take effect.
7. If you run Gnome, choose the Gdkxft theme from the "Theme Selector"
in the Gnome control center.
8. If you do not run Gnome, copy the Gdkxft theme to your .gtkrc. You
can do this by typing
cp `gtk-config --prefix`/themes/Gdkxft/gtk/gtkrc $HOME/.gtkrc
at the shell prompt.
9. If anything has gone wrong, you can reverse changes gdkxft has made
to your X configuration by typing (as root)
gdkxft_sysinstall -u
at the shell prompt.
III. Troubleshooting
====================
Here are some common problems:
During install, I get the message "I couldn't find an xftcache binary.
This means that I can't automatically configure your XftConfig."
----------------------------------------------------------------------
xftcache is a part of libXft. libXft is required for gdkxft to work
at all, but xftcache is only required for gdkxft to automatically
create an XftConfig. You will only see the message above if gdkxft
thought it needed to create an XftConfig (because you were running
with the vanilla XftConfig distributed with X) AND it couldn't
(because there was no xftcache binary).
Gdkxft will try to dumbly install a XFtConfig that works on my system.
This may work fine. If it does not, there are a number of things you
can do about it:
a) Make sure you are running the latest version of libXft. I use the
version distributed with XFree86 4.1.0
or, b) Install a packaged X setup that has a pre-configured XftConfig (I
gather that Mandrake Linux 8 includes such a thing).
or, c) Edit XftConfig yourself. man Xft for more on this.
Gdkxft installs, but nothing happens. Everything runs as usual, and I
don't see any anti-aliased fonts.
----------------------------------------------------------------------
There are, of course, a number of things that can produce these
symptoms. First, the obvious:
1. Make sure that you followed the installation instructions. If not,
re-install.
2. Make sure that you are running some gtk or gnome app. gdkxft will
only affect them.
Now, the, less obvious:
3. Check that LD_PRELOAD is set. Open an xterm window with
"xterm -ls" and type "echo $LD_PRELOAD". You should see
"/usr/lib/libgdkxft.so", or something similar.
If you don't, the problem is either that LD_PRELOAD is not getting
set, or that LD_PRELOAD is subsequently being cleared (see next
question).
Normally, this variable is set in a file called
/etc/X11/Xsession.d/90gdkxft or /etc/X11/xinit/xinitrc.d/gdkxft (or
one of those but replacing /etc/X11 with a different directory).
Check that that file exists (gdkxft_sysinstall tries to create it; run
gdkxft_sysinstall -x, which will both re-write the file and also tell
you where it created the file). Then check that that file gets run
during X startup. For example, look in you ~/.xsession-errors (there
should be a line `Preloading /usr/lib/libgdkxft.so.0'), or modify the
above-mentioned startup file to create a file (e.g. insert a line
`date > /tmp/gdkxft-env-test.$$').
Note that the method of putting shell scripts in xinitrc.d or
Xsession.d to be sourced during X initialisation is not portable -
there is no perfectly portable way of doing this. If your system has
neither of these directories you will need to figure things out for
yourself: the manual pages for startx, xinit, and xdm are a good place
to start.
4. Check that LD_PRELOAD has any effect. Choose a gtk binary (say,
/usr/bin/gimp) and run "ldd /usr/bin/gimp". If the first line
output is not
/usr/lib/libgdkxft.so => /usr/lib/libgdkxft.so (0x40018000)
Then there is a problem with your dynamic linker. "man ld.so" for more
information (though see caveat 3, below).
5. It may be that you don't have the fonts that gdkxft's default
configuration assumes you do. Create an empty file called .gdkxft
in your home directory. Now run a gtk app and see if fonts are
anti-aliased. If they are, you will have to tune your gdkxft setup
yourself. Read section IV. "Lengthy Instructions" below to find
out how.
Xterm/rxvt/... clears the value of LD_PRELOAD.
----------------------------------------------
Some versions of rxvt and xterm wipe LD_PRELOAD from the environment
of that terminal. (So e.g. gfontsel run from the window manager would
use anti-aliased fonts, but gfontsel run from an xterm does not,
unless you re-set LD_PRELOAD.)
Workarounds:
i) Use a different terminal emulator. gnome-terminal seems not to
clear LD_PRELOAD.
ii) Start gtk apps from your window manager directly (e.g. using the
menus) rather than using rxvt/xterm.
iii) In your .bashrc (or .cshrc etc.), source
/etc/X11/Xsession.d/90gdkxft (or whatever filename it is, see
previous section) (perhaps conditionally on whether PS1 is
defined and TERM is xterm).
Gdkxft installs, and now my gtk apps crash / X won't start.
-----------------------------------------------------------
Go to a console session (i.e. without running X) and enter the
following shell commands:
unset LD_PRELOAD
gdkxft_sysinstall -x
It should say `Creating /some/directory/gdkxft' as part of its
output. Now get your shell to execute that gdkxft file in its
current environment, using either
. /some/directory/gdkxft
(for Bourne-derived shells), or (for csh-derived shells):
source /some/directory/gdkxft
(Some shells, such as bash, accept either syntax.)
You should see a message like this:
Preloading /usr/lib/libgdkxft.so
Now type choose some gtk app (such as /usr/bin/gimp) and type:
ldd /usr/bin/gimp
You should see
/usr/lib/libgdkxft.so => /usr/lib/libgdkxft.so (0x40018000)
followed by a lot of other lines, none of which say "not found". If
any of them do, the problem will be with that library. gdkxft
requires the Xft and Xrender libraries, and your dynamic linker must
be able to find them at run-time.
If ldd is quite happy with your gtk binaries, then the problem, sad to
say, is probably with gdkxft itself. Submit a bug report in as much
detail as you can.
IV. Lengthy Instructions
========================
I assume that you are familiar with the general process of building
and installing autoconf based packages. (For a primer, see the file
INSTALL).
There is one extra configure option you might want to know about:
--enable-trap-errors will cause gdkxft to trap X errors before
performing any font-manipulation, and fall back to core font support
if an error occurs. This makes gdkxft more reliable when used with
applications that do strange things with gdk, at a cost in efficiency
(gdkxft has to synchronise with the X server to check that no errors
have occured each time it renders any text). At the time of writing,
there are no known applications that require this.
So, configure and build, and get gdkxft installed wherever you want
it. You now have a working libgdkxft.so. Suppose it is in /usr/lib
(as it will be if you configured with configure --prefix=/usr). There
are three more hurdles before you can actually use it: you must 1) get
libXft configured and working (which it probably isn't); 2) get your
gtk+ binaries to link with libgdkxft.so at run time; and 3) configure
gdkxft itself.
XftConfig
---------
libXft handles the actual rendering of anti-aliased fonts. However,
it uses a different set of fonts to the X server itself, and even
knows them by different names! It can be configured to recognise the
X-style names, and to find all the fonts that the X server knows
about. Unfortunately, it does not normally come so configured when
distributed.
You can configure Xft yourself - its configuration file is normally
found at /usr/X11R6/lib/X11/XftConfig. "man Xft" for more information.
Alternatively gdkxft can do it for you: run "gdkxft_sysinstall -f" as
root. This will search your system for font directories, and generate
an appropriate XftConfig based on what it finds.
gdkxft_sysinstall is a perl script, so you will need perl.
Linking with libdkxft.so
------------------------
Gdkxft is a shared library that contains API functions with the same
names as some gdk functions. When a gtk+ widget in an application
that's linked with it goes to call those functions in libgdk, it calls
the gdkxft function instead. Because the gdkxft functions looks just
like gdk, neither the application nor gtk+ notice the difference.
For more information on how this works, "man ld.so".
The trick is getting applications to link with gdkxft at run time.
There are two ways to do this:
First Way: Define LD_PRELOAD=<your path to libgdkxft.so> before
running the binary you want to use it. For example,
LD_PRELOAD=/usr/lib/libgdkxft.so gfontsel
runs gfontsel with anti-aliased fonts (if you installed gdkxft in
/usr)
The advantage of this is that you don't need to recompile anything.
Because LD_PRELOAD is an environment variable, you can even use
LD_PRELOAD=/usr/lib/libgdkxft.so startx
to start your whole X session using gdkxft for every gtk app.
On many systems it is possible to arrange for this to happen
automatically by adding a script to a directory called Xsession.d or
xinitrc.d. gdkxft_sysinstall can do this for you, if you run
"gdkxft_sysinstall -x"
Second Way: Link libgdkxft to binaries at compile time. For example,
if you configure any gtk app that uses GNU autoconf like this,
LDFLAGS="-lgdkxft" ./configure
that app will end up always using gdkxft. Note that (with Gnu ld at
least) it is important that -lgdkxft be earlier in the linker
commandline than -lgdk, so that gdkxft gets priority when undefined
symbols in libgtk are resolved.
Configuring gdkxft at run-time
------------------------------
Gdkxft has a config file that it reads to determine which fonts to try
to render with anti-aliasing. This file is looked for in three
places:
~/.gdkxft
SYSCONFDIR/gdkxft.conf
DATADIR/gdkxft.conf
(where SYSCONFDIR and DATADIR are whatever values you specified to
the configure script).
The file will be read from the first location it's found in.
The file consists of lines, each of which consists of a name of a
font, with * as a wildcard (matching any sequence of characters),
optionally preceded by the character ! (exclamation mark), or &
(ampersand).
For each font it loads, gdkxft decides whether to use anti-aliasing on
the following basis: 1) If the font matches a line that doesn't begin
with !, then it is anti-aliased. 2) Otherwise, if the font matches a
line that does begin with !, it is not anti-aliased. 3) Otherwise (if
the font matches no lines at all), it is anti-aliased.
Additionally, when gdkxft first starts, if the name of the application
binary that gdkxft was loaded as part of matches any configuration
line beginning with &, then gdkxft will never try to use anti-aliased
fonts with that application.
Anti-aliased fonts are rendered by Xft. Other fonts will be rendered
by the traditional Xlib calls (actually, gdkxft passes control back
over to libgdk to do that).
The default configuration that make install sets up is this:
!*
-urw-*
-b&h-lucidux*
-abisource-*
-abiword-*
-freefont-*
-sharefont-*
-macromedia-*
So, on the default configuration, fonts from the foundries urw,
abisource, abiword, freefont, sharefont, and macromedia, and the
lucidux fonts from the b&h foundry are anti-aliased, and no others
are. If you create an empty file called .gdkxft in your home
directory, however, gdkxft will have a field day, and try to
anti-alias every font loaded from now on. (This is probably a bad
idea, see the Caveats).
You probably want to be more discriminating than this - to control
font anti-aliasing on a widget by widget basis, you will need to
configure gtk+ by means of gtk resource files (ie. gtkrc files). The
best way is to set those widgets you would like to have anti-aliased
fonts to use a font that matches one of the non-! lines from your
gdkxft.conf, and those widgets you want not anti-aliases to a font
that matches a !-line.
For example, with the default configuration, you could tell GtkLabel
to use the urw helvetica font, while GtkCList uses the adobe version,
so that GtkLabel will be anti-aliased, GtkClist will not. In fact, a
version of this setup will be installed for you as a gtk+ theme if you
run "gdkxft_sysinstall -t".
Capplet
-------
If you have Gnome, libcapplet, and libglade installed, the build and
install procedure will create a simple capplet to allow you to
manipulate Gdkxft's configuration. You can find it in the Gnome
control center under "Look and Feel".
V. Caveats
==========
1. Ill-behaved widgets and applications
---------------------------------------
At the time of writing, some very common widgets do not like
anti-aliased fonts. Affected widgets include GtkCList and GtkText
from gtk+-1.2.10, and the gnome tasklist from gnome-core-1.4.0.4.
This is why it is a bad idea to let gdkxft anti-alias every font on
your system.
The trouble is that these widgets assume that drawing text over a
drawable twice is equivalent to drawing it once. The symptoms of this
ill-behaviour are bits of text getting bolder and bolder over time as
they are redrawn. It should be possible to fix this by patching the
widgets, and I hope that later versions of these packages will not
have the same problems.
Some large applications that use gdk calls in unusual ways may cause
problems. This affected some versions of mozilla prior to version
0.9.5. gkrellm caused problems with earlier versions of gdkxft (fixed
as of gdkxft versions 1.2). Gdkxft produces some quirks in gimp's
font rendering which I have not been completely able to fix. I have
also had reports of problems with abiword, though I have been unable
to reproduce them. If you find other apps that won't work with
gdkxft, you can disable gdkxft for these apps by editing your .gdkxft,
or using the gnome control center.
2. Buggy libraries
------------------
Gdkxft exposes bugs in some versions of freetype, libXft and
libXrender. Symptoms include crashes with gnome-terminal and gimp,
problems with Xinerama, and internal errors in Xlib.
If you suspect these problems may be affecting you, try upgrading to
the latest freetype and XFree86.
3. Multibyte characters and fontsets
------------------------------------
Gdkxft does not fully support multibyte characters, wide characters,
or fontsets. If it encounters these, they will be rendered without
anti-aliasing. There are serious technical problems lying in the way
of international font support with gdk-1.2; this is why the gtk+ team
are developing their new font handling package, pango.
4. Portability
--------------
Gdkxft only works on systems that support dlopen() and LD_PRELOAD.
This includes, but is not limited to, Solaris and GNU/Linux. It
doesn't include HPUX or (heaven forbid) MS Windows. It would be nice
to port Gdkxft to GNU libtool's libltdl, but there's still the problem
of having no portable LD_PRELOAD mechanism.