howto change font in linux using fontconfig

To those who are not familier to fontconfig, it is the library which provides fonts to each program in your linux desktop (atleast in gnome3). It maintains the details about all the font files available in your linux box and provides best matched font when your program requests a specific type of font.

If you use only english in day-to-day activities, fontconfig dont come in your way, but its a nightmare if you are a multilingual user. Even if you are a multilingual user, fontconfig tries its best to make your life easy by matching the best font for your language automatically, but the pain starts if you don’t like what fontconfig provides and want to change the default font for your language to something which looks good in the editor.

I went through the pain and want to share what I did to fix. For me, fontconfig said “TAMu_Kadambari” is the best font for “Tamil” and gedit by default shows tamil fonts using “TAMu_Kadambari”. But, this font doesn’t look good in gedit. After much research, I’m able to change the default font for “Tamil” language from “TAMu_Kadambari” to “TAMu_Kalyani” using this xml file.


<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<!--save this file as ~/.config/fontconfig/fonts.conf-->
<fontconfig>
<match>
<test name="lang">
<string>ta</string>
</test>
<edit name="family" mode="assign">
<string>TAMu_Kalyani</string>
</edit>
</match>
</fontconfig>

Here, the <match> tag contains one test which checks if the provided language is “Tamil” (lang=ta). If it is, then edit the original request coming from the application and assign family name as “TAMu_Kalyani”(family=TAMu_Kalyani) so that fontconfig matching algorithm will match only “TAMu_Kalyani”.

Thats it, my gedit now picks “TAMu_Kalyani” and it looks good. More details about fontconfig is available here.

fontconfig uses patterns for its matching algorithm, and it goes like this


<families>-<point sizes>:<name1>=<values1>:<name2>=<values2>..

for example, here is how you can check which is the best matched font available in your system for language “Tamil”. Output also contains top 10 ranked fonts for tamil. The first preferred font is “TAMu_Kalyani”, because I have overridden in ~/.config/fontconfig/fonts.conf


[mohan@mohanlaptop0 ~]$ fc-match -s 'monospace-10:lang=ta' | head
TAMu_Kalyani.ttf: "TAMu_Kalyani" "Regular"
TSCu_Comic.ttf: "TSCu_Comic" "Normal"
DejaVuSans.ttf: "DejaVu Sans" "Book"
DejaVuSansMono.ttf: "DejaVu Sans Mono" "Book"
DejaVuSerif.ttf: "DejaVu Serif" "Book"
Pothana2000.ttf: "Pothana2000" "Pothana2000"
MalOtf.ttf: "MalOtf" "Book"
TSCu_Paranar.ttf: "TSCu_Paranar" "Regular"
SyrCOMAdiabene.otf: "East Syriac Adiabene" "Regular"
SyrCOMKharput.otf: "Serto Kharput" "Regular"
[mohan@mohanlaptop0 ~]$

If I remove ~/.config/fontconfig/fonts.conf, it goes back to the original behaviour and provides “TAMu_Kadambari” as preferred font for “Tamil”


[mohan@mohanlaptop0 ~]$ fc-match -s 'monospace-10:lang=ta' | head
TAMu_Kadampari.ttf: "TAMu_Kadambri" "Regular"
TAMu_Kalyani.ttf: "TAMu_Kalyani" "Regular"
DejaVuSansMono.ttf: "DejaVu Sans Mono" "Book"
DejaVuSansMono-Bold.ttf: "DejaVu Sans Mono" "Bold"
DejaVuSans.ttf: "DejaVu Sans" "Book"
DejaVuSerif.ttf: "DejaVu Serif" "Book"
Pothana2000.ttf: "Pothana2000" "Pothana2000"
MalOtf.ttf: "MalOtf" "Book"
TSCu_Comic.ttf: "TSCu_Comic" "Normal"
TSCu_Paranar.ttf: "TSCu_Paranar" "Regular"
[mohan@mohanlaptop0 ~]$

fontconfig configuration files are very versatile and one can do lot of things, but we need to first understand its patterns to do anything useful. Anyway, I hope this article provide good example for fc-match command-line tool and fontconfig patterns.

Advertisements

Setup Gnome Development Environment in Archlinux

Many people who want to contribute to Gnome will go with Fedora, because it is the best suitable for gnome developer. But, Archlinux is as good as Fedora in terms of providing latest gnome libraries. Here I’ll explain how I setup my development environment in Archlinux using pacstrap, jhbuild and arch-chroot.

Setup Base

In your home directory, create a folder for gnome and install archlinux packages

$ mkdir -p ~/Devel/gnome/runtime
$ cd ~/Devel/gnome
$ su
# pacstrap -d runtime base base-devel
# chown -R <username>:<groupname> runtime
# exit
$

Here, <username>:<groupname> must be your username and groupname to make sure you are able to modify the files inside ~/Devel/gnome/runtime without any issues. The above steps will install Archlinux base packages. Now, we need to install jhbuild,

Jhbuild

$ cd ~/Devel/gnome/checkout
$ git clone git://git.gnome.org/jhbuild
$ cd jhbuild
$ PYTHON=/usr/bin/python2 ./autogen.sh --prefix="${HOME}/Devel/gnome/runtime/usr"
$ make install

done, next step is to configure jhbuild to setup the paths properly, to do this, we need to copy the sample jhbuildrc file from jhbuild source directory to ~/.config directory and edit that file,

$ cp ~/Devel/gnome/checkout/jhbuild/examples/sample.jhbuildrc ~/.config/jhbuildrc

Here is my .jhbuildrc modifications

# -*- mode: python -*-
--- /home/mohan/Devel/gnome/checkout/jhbuild/examples/sample.jhbuildrc   2015-01-17 11:38:40.055187155 +0800
+++ /home/mohan/.config/jhbuildrc       2015-01-06 09:07:34.493161676 +0800
@@ -10,22 +10,25 @@
 # jhbuild/defaults.jhbuildrc, but can be any file in the modulesets directory
 # or a URL of a module set file on a web server.
 # moduleset = 'gnome-apps-3.12'
-#
+moduleset = 'gnome-world'
+
 # A list of the modules to build.  Defaults to the GNOME core and tested apps.
 # modules = [ 'meta-gnome-core', 'meta-gnome-apps-tested' ]
 
 # Or to build the old GNOME 2.32:
 # moduleset = 'gnome2/gnome-2.32'
 # modules = ['meta-gnome-desktop']
+modules = ['gjs', 'farstream', 'gnome-online-accounts', 'polari', 'gnome-shell', 'glade', 'gnome-builder']
 
 # what directory should the source be checked out to?
-checkoutroot = '~/jhbuild/checkout'
+checkoutroot = '~/Devel/gnome/checkout'
 
 # the prefix to configure/install modules to (must have write access)
-prefix = '~/jhbuild/install'
+prefix = '~/Devel/gnome/runtime/usr'
 
 # custom CFLAGS / environment pieces for the build
 # os.environ['CFLAGS'] = '-Wall -g -O0'
+os.environ['PYTHON'] = '/usr/bin/python2'
 
 # extra arguments to pass to all autogen.sh scripts
 # to speed up builds of GNOME, try '--disable-static --disable-gtk-doc'

Here is the details of my changes,

  • moduleset – A moduleset is an xml file contains details (like modulename, version info, repo address, type of repo, how to build etc.,) of each and every project (we call it as module) needed for gnome environment. jhbuild maintains moduleset for each release, you can see the different modulesets inside your jhbuild directory (~/Devel/gnome/jhbuild/modulesets). “gnome-world” moduleset represent generic set which will be updated for every release. So, I use “gnome-world” to make my environment as latest as possible.
  • modules – when we execute “jhbuild build” command, jhbuild will compile only the modules listed in this place. make sure you build what you want instead of building all the gnome projects (aka “meta-gnome-desktop”)
  • checkoutroot – place where jhbuild will clone the gnome repositories. set this to ~/Devel/gnome/checkout.
  • prefix – place where jhbuild will put the compiled binaries, set this to ~/Devel/gnome/runtime/usr. If you notice, you will see that ~/Devel/gnome/runtime is the same path where we installed archlinux base, so, we basically put the gnome binaries (libraries & executables) on top of archlinux, I’ll tell you why we are doing this when I explain arch-chroot.
  • os.environ[‘PYTHON’] – set this to /usr/bin/python2 because, Archlinux’s default python is python3 but most of gnome modules don’t like python3 (especially jhbuild. see here – https://wiki.archlinux.org/index.php/JHBuild#Python_issues).

Compiling

All set, its time to compile.

$ ~/Devel/gnome/runtime/usr/bin/jhbuild build

If jhbuild finds any missing libraries to compile the modules listed in jhbuildrc, it will throw error, here comes the need of arch-chroot.

Installing missing Dependencies

The reason we setup archlinux base in ~/Devel/gnome/runtime is to install any missing libraries here from arch packages using arch-chroot and packman and make sure we don’t distrub the current system. Let say, jhbuild throws that ‘spotread’ is missing when compiling colord module. ‘spotread’ executable is provided by ‘argyllcms’ package and here is the simple way to fix the dependency issue,

$ cd ~/Devel/gnome
$ su
# arch-chroot runtime /usr/bin/bash
# pacman --sync --refresh
# pacman --sync --sysupgrade
# pacman --sync argyllcms
# exit
# chown -R <username>:<groupname> runtime
# exit
$

Now, we can start compiling again, I suggest to switch to jhbuild environment before we compile, because jhbuild will setup necessary environment variables (like LD_LIBRARY_PATH pointing to ~/Devel/gnome/runtime/usr/lib etc.,) to make sure dependency libraries are resolved from ~/Devel/gnome/runtime/usr.

$ ~/Devel/gnome/runtime/usr/bin/jhbuild shell
$ jhbuild build
$ exit

Now, to execute the latest compiled gnome-builder,  here is the commandline

$ ~/Devel/gnome/runtime/usr/bin/jhbuild run gnome-builder

Thats it, you have your gnome development environment ready.

gistnotes – a gnome shell extension

Well, I should probably say, its basically a gnome application disguised as a shell extension. written entirely using javascript.

Nothing much to say more than what the README say here, https://github.com/mohan43u/gistnotes

gistnotes

This is my first contribution to gnome. you can install it through https://extensions.gnome.org/extension/917/gistnotes/. Check it out, and provide feedback.