Patches: Xft and i18n enhancements

Mike FABIAN mfabian at
Wed Apr 2 19:44:43 EST 2003

Here are some patches to improve Xft support and Internationalisation of

Please review.

I found the following problems which I tried to solve:

1) None of the translations work in UTF-8 locales,
   and Japanese, Chinese, Korean never work with Xft

When Xft is disabled and XmbDrawString is used, UTF-8 strings are
expected by XmbDrawString but as the Japanese translations in are in EUC-JP encoding and no conversion to UTF-8 is
performed in this case, Japanese just displays as Garbage in
ja_JP.UTF-8 locale. The same problem exists in other UTF-8 locales
like de_DE.UTF-8 for example.

If Xft is enabled, it doesn't work either, because XftDrawString8 is
always used, which will work neither for EUC-JP encoded Japanese
strings nor for UTF-8 encoded strings. Currently it works only for
8bit locales when Xft is enabled.

There are already XftDrawStringUtf8() functions in the source code,
but they are all within

     #ifdef XFT_UTF8

and XFT_UTF8 is never defined because there is no proper configure
check for XftDrawStringUtf8 yet. There were already some comments
in about XftDrawStringUtf8, but not working check was

I fixed this with the attached openbox-2.2.3-configure-utf8.diff.

Now, when Xft is enabled and XFT_UTF8 is defined, XftDrawStringUtf8 is
used, but the translations still display as garbage because the files are not in UTF-8 and no translation is performed.

I fixed this by converting all translations to UTF-8 before building
openbox with the attached script nls-iconv.

Now the translations work in all locales with Xft enabled when
XftDrawStringUtf8 is supported.

But now it won't work anymore in non-UTF-8 locales with Xft disabled
when only XmbDrawString is available. To fix this, I added some helper
functions which convert from UTF-8 to locale encoding and the other
way round.

I implemented these conversions using iconv and nl_langinfo(CODESET)
which may not be available on every platform.
I have not yet added a configure check for iconv and nl_langinfo,
it may be necessary to improve this to make it more portable.

But somehow conversion is necessary.

One could of course switch to using gettext instead of catgets for the
translations. gettext can automatically convert to locale encoding.
But locale encoding wouldn't work with XftDrawStringUtf8() and there
is no locale specific variant of XftDrawString. Even if one 
switched to gettext it would probably still be easiest to keep the strings
which are fed into BFont::drawString in UTF-8 always
(bind_textdomain_codeset() could be used to set the output of gettext
to UTF-8).

But apart from translations there are other files read by openbox, for
example ~/.openbox/menu. I have Japanese and in UTF-8 encoding in
~/.openbox/menu which always works fine when XftDrawStringUtf8() is used
but needs to converted to EUC-JP when XmbDrawString() is used and the
locale is ja_JP.eucJP. Here a conversion function is needed as well.

It is probably best to require files like ~/.openbox/menu to be either
UTF-8 or ASCII only, because this makes it much easier. Allowing other
encodings would make it necessary to introduce tags in these files to
indicate the encoding parse these tags and convert. I believe it is
much simpler just to require all files read by openbox to be UTF-8
encoded (or ASCII only) always.

Other remaining stuff where a conversion is necessary:

The time string printed in the Toolbar is created in by

    if (! strftime(tlocal, 1024, screen->getStrftimeFormat(), tt))

and strftime creates it's output in locale encoding. I.e.  "10:48 PM"
in a Japanese locale will have "AM" replaced by the Japanese word for
"Afternoon", which will be in EUC-JP encoding when running in
ja_JP.eucJP locale and UTF-8 encoding when running in ja_JP.UTF-8

I fixed this by converting the output of strftime from locale encoding
to UTF-8.

The inverse problem occurs with the output when the "--help" option
is used

    openbox --help


    bsetroot --help 

also use translated messages from As I have converted all files to UTF-8, these messages looked OK in UTF-8 locales
but not in non-UTF-8 locales.  I fixed this by converting from UTF-8
to locale encoding here.

2) harcoded fonts for Xft won't work automatically for many languages.

Currently the Fonts are opened with XftFontOpen() when using Xft.

That way it is not possible to specify generic aliases for Fonts like
"sans", "serif" or "monospaced" in the openbox style files which has several

If you specify a really existing font family like "Luxi Sans", the
"Luxi Sans" font will be used if it exists, even if it doesn't have
enough glyphs for the language used. A family name specified directly
has highest priority. Therefore you will see garbage when using
Japanese and specifying a font like "Luxi Sans" or "Arial".

But if the following method to open a Xft font is used:

   XftPattern *pattern;
   pattern = XftNameParse(_family.c_str());
   pattern = XftFontMatch(_display, _screen->getScreenNumber(), pattern, NULL);
   _xftfont = XftFontOpenPattern(_display, pattern);

one can also specify one of the generic aliases "sans", "serif", or
"monospaced" as the family name and a font suitable for the language
used will be selected automatically according to the rules in
/etc/fonts/fonts.conf. For example if "sans" is specified and the
language is Japanese and /etc/fonts/fonts.conf contains 

      Accept deprecated 'sans' alias, replacing it with 'sans-serif'
            <match target="pattern">
                    <test qual="any" name="family">
                    <edit name="family" mode="assign">


                            <family>Bitstream Vera Sans</family>
                            <family>Nimbus Sans L</family>
                            <family>Luxi Sans</family>
                            <family>Kochi Gothic</family>
                            <family>AR PL KaitiM GB</family>
                            <family>AR PL KaitiM Big5</family>
                            <family>Baekmuk Gulim</family>
                            <family>Baekmuk Dotum</family>

The Japanese font "Kochi Gothic" will be selected automatically
because it is the first font in the list of preferred faces for
sans-serif which supports Japanese.  If the language is English and
the Microsoft Webfonts are installed, "Verdana" will be used, if they
are not installed, the next existing font in this list which supports
English is used.

I.e. apart from the advantage that a suitable font for the language
used is automatically selected, a generic alias like "sans" has also
the advantage that it selects the preferred sans-serif font
automatically. A user can easily add

into his personal ~/.fonts.conf file and will get "Arial" in all
applications which specify "sans" or "sans-serif". I.e. if all Openbox
style files specify "sans" and not specific fonts like "Arial", it is
much easier for a user to choose his favorite font and one will get
more consistent results throughout the system because other
applications like KDE3 or Gnome2 also usually use generic aliases like
"sans" by default, therfore editing a few lines into ~/.fonts.conf
affects almost everything.

I attached a patch for the openbox style files to use the generic
alias "sans" (openbox-2.2.3-styles.diff).

3) many options possible in Xft font patterns cannot be used currently

When fonts are opened using XftFontOpenPattern() as described above,
many options can easily be specified in the style files
which could not be used with the way Xft fonts were opened before.
For example one can specify a font like:

    *xft.font:	sans:size=20:slant=100:weight=200:antialiasing=false:hinting=true

I.e. the xft.size option and the "bold" and "italic" parameters of
xft.flags are superfluous. One can already specify that and more in
xft.font when XftFontOpenPattern() is used.

I think it makes sense to remove xft.size and keep xft.flags only for
extra options like "shadow" which cannot be expressed in the font
pattern directly.

My patch doesn't yet remove xft.size and the "bold" and "italic"
parameters of xft.flags, but effectively disables this already.


What do you think about these patches?

Maybe something like that can be applied to Openbox?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: nls-iconv
Type: application/octet-stream
Size: 1087 bytes
Desc: not available
URL: <>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: openbox-2.2.3-styles.diff
Type: text/x-patch
Size: 14971 bytes
Desc: not available
URL: <>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: openbox-2.2.3-configure-utf8.diff
Type: text/x-patch
Size: 1160 bytes
Desc: not available
URL: <>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: openbox-2.2.3-i18n.diff
Type: text/x-patch
Size: 18659 bytes
Desc: not available
URL: <>
-------------- next part --------------

Mike Fabian   <mfabian at>

More information about the openbox mailing list