Fonts: 5 ways to change the gtk+-2.0 text label font



Hello,
To change the default text label font in gtk+-2.0 you can:

0. Use gtk_widget_modify_font().
1. pango_layout_set_font_description().
2. ".rc" file.
3. gtk_label_set_attributes().
4. Pango markup language and gtk_label_set_markup().

There's a little demo in attach.

Olexiy

/*
	A little demo how to change the default font of label in 5 ways.
	Be aware: a couple of bugs can be found here.

Olexiy Avramchenko
*/

#include <gtk/gtk.h>


/*
	gtk_widget_modify_font
	This's the simpliest way to change the label's font :)
*/
static void font_set_way0(GtkEntry *entry, gpointer data)
{
GtkLabel		*label;
PangoFontDescription	*pfd;

	g_return_if_fail(GTK_IS_ENTRY(entry));
	g_return_if_fail(GTK_IS_LABEL(data));

	label = GTK_LABEL(data);

	/* creating PangoFontDescription from string, specified in entry */
	pfd = pango_font_description_from_string(gtk_entry_get_text(entry));
	/* setting label's font */
	gtk_widget_modify_font(GTK_WIDGET(label), pfd);
	/* freeing PangoFontDescription, cause it has been copied by prev. call */
	pango_font_description_free(pfd);
}

/*
	pango_layout_set_font_description
	Chaning the label's font with one more step.
*/
static void font_set_way1(GtkEntry *entry, gpointer data)
{
GtkLabel		*label;
PangoFontDescription	*pfd;

	g_return_if_fail(GTK_IS_ENTRY(entry));
	g_return_if_fail(GTK_IS_LABEL(data));

	label = GTK_LABEL(data);

	/* creating PangoFontDescription from string, specified in entry */
	pfd = pango_font_description_from_string(gtk_entry_get_text(entry));
	/* setting PangoFontDescription to label's layout */
	pango_layout_set_font_description(gtk_label_get_layout(label), pfd);
	/* asking label to resize/redraw itself, without this you'll not see the changes */
	gtk_widget_queue_resize(GTK_WIDGET(label));
	/* freeing PangoFontDescription, cause it has been copied by prev. call */
	pango_font_description_free(pfd);
}

/*
	Changing the font of label's text symbols 12..<end of text>.
	More complicated, but more powerfull way. Doesn't work if
	label is using underline or markup.
*/
static void font_set_way3(GtkEntry *entry, gpointer data)
{
GtkLabel		*label;
PangoAttrList		*pal;
PangoAttribute		*pa;
PangoAttrFontDesc	*pafd;
PangoFontDescription	*pfd;


	g_return_if_fail(GTK_IS_ENTRY(entry));
	g_return_if_fail(GTK_IS_LABEL(data));

	label = GTK_LABEL(data);

	/* creating PangoFontDescription from string, specified in entry */
	pfd = pango_font_description_from_string(gtk_entry_get_text(entry));

	/* creating empty PangoAttrList */
	pal = pango_attr_list_new();

	/* creating new PangoAttribute for font description */
	pafd = (PangoAttrFontDesc*)pa = pango_attr_font_desc_new(pfd);
	/* we want to apply this font only to chars from 12 to end of text */
	pa->start_index = 12;
	pa->end_index = g_utf8_strlen(gtk_label_get_text(label), -1); /* dont't forget the text is in utf8 */

	/* inserting attribute we created into the list */
	pango_attr_list_insert(pal, pa);

	/* setting label's attributes list */
	gtk_label_set_attributes(label, pal);

	/* list was referenced by label, so drop our reference */
	pango_attr_list_unref(pal);

	/* we dont need this, case it was already copied */
	pango_font_description_free(pfd);
}


/*
	Setting up widgets: setup_way[01234]
*/
static void setup_way0(GtkBox *box)
{
char      *font;
GtkWidget *hbox;
GtkWidget *entry;
GtkWidget *label;

	hbox = gtk_hbox_new(FALSE, 4);
	gtk_box_pack_start(box, hbox, TRUE,TRUE, 0);

	label = gtk_label_new("Font name");
	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE,FALSE, 0);

	entry = gtk_entry_new();
	gtk_entry_set_width_chars(GTK_ENTRY(entry), 10);
	gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE,FALSE, 0);

	label = gtk_label_new(" 0. The font of this label is changing via gtk_widget_modify_font ");
	gtk_box_pack_start(GTK_BOX(hbox), label, TRUE,TRUE, 0);

	font = pango_font_description_to_string(
		pango_context_get_font_description(
			gtk_widget_get_pango_context(label)
		)
	);
	gtk_entry_set_text(GTK_ENTRY(entry), font);
	g_free(font);
	g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(font_set_way0), (gpointer)label);
}

static void setup_way1(GtkBox *box)
{
char      *font;
GtkWidget *hbox;
GtkWidget *entry;
GtkWidget *label;

	hbox = gtk_hbox_new(FALSE, 4);
	gtk_box_pack_start(box, hbox, TRUE,TRUE, 0);

	label = gtk_label_new("Font name");
	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE,FALSE, 0);

	entry = gtk_entry_new();
	gtk_entry_set_width_chars(GTK_ENTRY(entry), 10);
	gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE,FALSE, 0);

	label = gtk_label_new(" 1. The font of this label is changing via pango_layout_set_font_description ");
	gtk_box_pack_start(GTK_BOX(hbox), label, TRUE,TRUE, 0);

	font = pango_font_description_to_string(
		pango_context_get_font_description(
			gtk_widget_get_pango_context(label)
		)
	);
	gtk_entry_set_text(GTK_ENTRY(entry), font);
	g_free(font);
	g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(font_set_way1), (gpointer)label);
}

static void setup_way2(GtkBox *box)
{
GtkWidget *label;

	label = gtk_label_new(" 2. The font of this label set via .rc file ");

	/* in .rc file there's a font definition for widgets with this name */
	gtk_widget_set_name(label, "the_name_of_the_label");

	gtk_box_pack_start(box, label, TRUE,TRUE, 0);
}

static void setup_way3(GtkBox *box)
{
char      *font;
GtkWidget *hbox;
GtkWidget *entry;
GtkWidget *label;

	hbox = gtk_hbox_new(FALSE, 4);
	gtk_box_pack_start(box, hbox, TRUE,TRUE, 0);

	label = gtk_label_new("Font name");
	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE,FALSE, 0);

	entry = gtk_entry_new();
	gtk_entry_set_width_chars(GTK_ENTRY(entry), 10);
	gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE,FALSE, 0);

	label = gtk_label_new(" 3. The font of part of this label is changing via gtk_label_set_attributes ");
	gtk_box_pack_start(GTK_BOX(hbox), label, TRUE,TRUE, 0);

	font = pango_font_description_to_string(
		pango_context_get_font_description(
			gtk_widget_get_pango_context(label)
		)
	);
	gtk_entry_set_text(GTK_ENTRY(entry), font);
	g_free(font);
	g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(font_set_way3), (gpointer)label);
}

static void setup_way4(GtkBox *box)
{
GtkWidget *label;

	label = gtk_label_new(NULL);
	gtk_label_set_markup(GTK_LABEL(label), "<span font_desc=\"sans 10\">4. This label using</span><span foreground=\"red\" font_desc=\"fixed 14\"> Pango markup</span> ");
	gtk_widget_set_name(label, "the_name_of_the_label");
	gtk_box_pack_start(box, label, TRUE,TRUE, 0);
}


int main(int argc, char **argv)
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *label;
GtkWidget *button;
GtkWidget *sep;

	gtk_init(&argc, &argv);

	/* process rc file, contains the font description */
	gtk_rc_parse("fonts.rc");

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_container_set_border_width(GTK_CONTAINER(window), 8);
	g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(gtk_main_quit), NULL);

	vbox = gtk_vbox_new(FALSE, 2);
	gtk_container_add(GTK_CONTAINER(window), vbox);

	label = gtk_label_new("Type font description in entry and press <Enter>");
	gtk_box_pack_start(GTK_BOX(vbox), label, TRUE,TRUE, 4);

	sep = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(vbox), sep, TRUE,TRUE, 4);

	setup_way0(GTK_BOX(vbox));
	setup_way1(GTK_BOX(vbox));
	setup_way2(GTK_BOX(vbox));
	setup_way3(GTK_BOX(vbox));
	setup_way4(GTK_BOX(vbox));

	sep = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(vbox), sep, TRUE,TRUE, 4);

	button = gtk_button_new_with_label(" QuIt ");
	gtk_box_pack_start(GTK_BOX(vbox), button, TRUE,TRUE, 0);
	g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_main_quit), NULL);

	gtk_widget_show_all(window);
	
	gtk_main();

	return 0;
}
style "label-style" {
	font_name = "fixed 14"
}

widget "*.the_name_of_the_label" style "label-style"
fonts: fonts.c
	gcc -Wall `pkg-config gtk+-2.0 --cflags --libs` $< -o $@
	strip -s fonts


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]