Xlib tutorial part 7 -- FontSets

by Alan at Mon 23rd Feb 2009 1:00AM EST


This section is for dealing with languages that require multiple fonts. Depending on how your computer is set up it may not work properly. First thing that we must do is make sure that XLib knows what locale we are using.

	setlocale(LC_ALL, getenv("LANG"));

That should set up various locale specific pieces. Make sure that the LANG environment variable is set to something suitable for your system. If you are using a system that supports it you can set it to en_CA.utf8. A RHEL 4 box will support that without complaint. On the other hand my debian 4.0 seems to cough; although, I may have it set up wrong.

Next, let's start talking about FontSets. Rather than, as we did starting in section 4, calling XLoadQueryFont and getting back an XFontStruct pointer, we'll now call XCreateFontSet and get back a XFontSet, so one of the first changes is everywhere we had XFontStruct * we replace that with XFontSet.

Of course, if that's all we did, our compiler would complain. We need to change a few calls. Let's start with the getFont helper function.

XFontSet getFont(Display *dpy, XrmDatabase db, char *name,
		char *cl, char *def){
	XrmValue v;
	char * type;
	XFontSet font = NULL;
	int nmissing;
	char **missing;
	char *def_string;

	if (XrmGetResource(db, name, cl, &type, &v)){
		if (v.addr)
			font = XCreateFontSet(dpy, v.addr, &missing, &nmissing, &def_string);
	if (!font) {
		if (v.addr)
		fprintf(stderr, "unable to load preferred font: %s using fixed
", v.addr);
		fprintf(stderr, "couldn't figure out preferred font
		font = XCreateFontSet(dpy, def, &missing, &nmissing, &def_string);
	return font;

It also changes how we dealing with creating a pen. We can no longer get a font id from the returned value.

	/*values.font = font->fid; */
	pen = XCreateGC(dpy, win, GCForeground|GCLineWidth|GCLineStyle,&values);

Instead, we will call Xutf8DrawString() to respond to Expose events.

 			Xutf8DrawString(dpy, ev.xany.window, font, pen, textx, texty, text, strlen(text));

And we'll have to update XTextWdith() with Xutf8TextEscapement() and calculate the font ascent for the FontSet.

 	text_width = Xutf8TextEscapement(font, text, strlen(text));
 	font_ascent = 0;
 	nfonts = XFontsOfFontSet(font, &fonts, &font_names);
 	for(j = 0; j < nfonts; j += 1){
 		if (font_ascent < fonts[j]->ascent) font_ascent = fonts[j]->ascent;
 		printf("Font: %s
", font_names[j]);

The last two changes are passing setting the window name at the top of the window and the text to display in the center of the window as an argument from the command line.

 		Xutf8SetWMProperties(dpy, win, "XTut7", "xtut7", argv, argc,
 	if (argv[1] && argv[1][0]) text = argv[1];
 	return main_loop(dpy, font, pen, width, height, text);

Download the complete code

Things to try:

Comments are closed.