← Back to team overview

ayatana-commits team mailing list archive

[Branch ~notify-osd-developers/notify-osd/main] Rev 408: Merge changes and fixes from the karmic branch back into trunk.

 

Merge authors:
  Mirco Müller (macslow)
------------------------------------------------------------
revno: 408 [merge]
committer: Mirco Müller <mirco.mueller@xxxxxxxxxx>
branch nick: notify-osd
timestamp: Fri 2010-02-05 09:33:33 -0800
message:
  Merge changes and fixes from the karmic branch back into trunk.
modified:
  configure.in
  src/bubble.c
  src/bubble.h
  src/defaults.c
  src/dialog.c
  src/display.c
  src/stack.c
  src/util.c
  src/util.h
  tests/test-text-filtering.c


--
lp:notify-osd
https://code.launchpad.net/~notify-osd-developers/notify-osd/main

Your team ayatana-commits is subscribed to branch lp:notify-osd.
To unsubscribe from this branch go to https://code.launchpad.net/~notify-osd-developers/notify-osd/main/+edit-subscription.
=== modified file 'configure.in'
--- configure.in	2009-10-01 08:59:24 +0000
+++ configure.in	2009-10-20 08:52:44 +0000
@@ -1,4 +1,4 @@
-AC_INIT(notify-osd, 0.9.23, dx-team@xxxxxxxxxxxxx)
+AC_INIT(notify-osd, 0.9.24, dx-team@xxxxxxxxxxxxx)
 
 AC_CONFIG_SRCDIR(src/main.c)
 AC_CONFIG_HEADERS(config.h)

=== modified file 'src/bubble.c'
--- src/bubble.c	2009-10-01 08:34:39 +0000
+++ src/bubble.c	2009-10-20 08:51:11 +0000
@@ -113,6 +113,12 @@
 	A
 };
 
+#define TEMPORARY_ICON_PREFIX_WORKAROUND 1
+#ifdef TEMPORARY_ICON_PREFIX_WORKAROUND
+#warning "--== Using the icon-name-substitution! This is a temp. workaround not going to be maintained for long! ==--"
+#define NOTIFY_OSD_ICON_PREFIX "notification"
+#endif
+
 // FIXME: this is in class Defaults already, but not yet hooked up so for the
 // moment we use the macros here, these values reflect the visual-guideline
 // for jaunty notifications
@@ -965,21 +971,19 @@
 
 	// create pango desc/layout
 	layout = pango_cairo_create_layout (cr);
-	desc = pango_font_description_new ();
+	text_font_face = defaults_get_text_font_face (d);
+	desc = pango_font_description_from_string (text_font_face);
+	g_free ((gpointer) text_font_face);
 
 	pango_font_description_set_size (desc,
 					 defaults_get_system_font_size (d) *
 					 defaults_get_text_title_size (d) *
 					 PANGO_SCALE);
 
-	text_font_face = defaults_get_text_font_face (d);
-	pango_font_description_set_family_static (desc, text_font_face);
 	pango_font_description_set_weight (desc,
 					   defaults_get_text_title_weight (d));
-	pango_font_description_set_style (desc, PANGO_STYLE_NORMAL);
 	pango_layout_set_font_description (layout, desc);
 	pango_font_description_free (desc);
-	g_free ((gpointer) text_font_face);
 
 	pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
 	pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
@@ -1008,6 +1012,7 @@
 			       TEXT_SHADOW_COLOR_G,
 			       TEXT_SHADOW_COLOR_B,
 			       TEXT_SHADOW_COLOR_A);
+	pango_cairo_show_layout (cr, layout);
 
 	// ... blur it
 	blur = raico_blur_create (RAICO_BLUR_QUALITY_HIGH);
@@ -1071,21 +1076,19 @@
 
 	// create pango desc/layout
 	layout = pango_cairo_create_layout (cr);
-	desc = pango_font_description_new ();
+	text_font_face = defaults_get_text_font_face (d);
+	desc = pango_font_description_from_string (text_font_face);
+	g_free ((gpointer) text_font_face);
 
 	pango_font_description_set_size (desc,
 					 defaults_get_system_font_size (d) *
 					 defaults_get_text_body_size (d) *
 					 PANGO_SCALE);
 
-	text_font_face = defaults_get_text_font_face (d);
-	pango_font_description_set_family_static (desc, text_font_face);
 	pango_font_description_set_weight (desc,
 					   defaults_get_text_body_weight (d));
-	pango_font_description_set_style (desc, PANGO_STYLE_NORMAL);
 	pango_layout_set_font_description (layout, desc);
 	pango_font_description_free (desc);
-	g_free ((gpointer) text_font_face);
 
 	pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
 	pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
@@ -2381,11 +2384,39 @@
 }
 
 void
+bubble_set_icon_from_path (Bubble*      self,
+			   const gchar* filepath)
+{
+	Defaults*      d;
+	BubblePrivate* priv;
+
+	if (!self || !IS_BUBBLE (self) || !g_strcmp0 (filepath, ""))
+		return;
+
+	priv = GET_PRIVATE (self);
+
+	if (priv->icon_pixbuf)
+	{
+		g_object_unref (priv->icon_pixbuf);
+		priv->icon_pixbuf = NULL;
+	}
+
+	d = self->defaults;
+	priv->icon_pixbuf = load_icon (filepath,
+				       EM2PIXELS (defaults_get_icon_size (d), d));
+
+	_refresh_icon (self);
+}
+
+void
 bubble_set_icon (Bubble*      self,
 		 const gchar* filename)
 {
 	Defaults*      d;
 	BubblePrivate* priv;
+#ifdef TEMPORARY_ICON_PREFIX_WORKAROUND
+	gchar*         notify_osd_iconname;
+#endif
 
  	if (!self || !IS_BUBBLE (self) || !g_strcmp0 (filename, ""))
 		return;
@@ -2399,9 +2430,20 @@
 	}
 
 	d = self->defaults;
-	priv->icon_pixbuf = load_icon (filename,
+
+#ifdef TEMPORARY_ICON_PREFIX_WORKAROUND
+	notify_osd_iconname = g_strdup_printf (NOTIFY_OSD_ICON_PREFIX "-%s",
+					       filename);
+	priv->icon_pixbuf = load_icon (notify_osd_iconname,
 				       EM2PIXELS (defaults_get_icon_size (d),
 						  d));
+	g_free (notify_osd_iconname);
+#endif
+
+	// fallback to non-notify-osd name
+	if (!priv->icon_pixbuf)
+		priv->icon_pixbuf = load_icon (filename,
+					       EM2PIXELS (defaults_get_icon_size (d), d));
 
 	_refresh_icon (self);
 }
@@ -2420,8 +2462,11 @@
 
 	max_edge = MAX (w, h);
 
-	new_width = size * (w / max_edge);
-	new_height = size * (h / max_edge);
+	// temporarily cast to float so we don't end up missing fractional parts
+	// from the division, especially nasty for 0.something :)
+	// e.g.: 99 / 100 = 0 but 99.0 / 100.0 = 0.99
+	new_width = size * ((gfloat) w / (gfloat) max_edge);
+	new_height =  size * ((gfloat) h / (gfloat) max_edge);
 
 	/* Scale the pixbuf down, preserving the aspect ratio */
 	scaled_icon = gdk_pixbuf_scale_simple (pixbuf,
@@ -2490,7 +2535,6 @@
 	{
 		scaled = scale_pixbuf (pixbuf, EM2PIXELS (defaults_get_icon_size (d), d));
 		g_object_unref (pixbuf);
-
 		pixbuf = scaled;
 	}
 
@@ -2835,7 +2879,7 @@
 		gtk_window_set_opacity (bubble_get_window (bubble),
 		                        WINDOW_MAX_OPACITY);
 
-	bubble_start_timer (bubble);
+	bubble_start_timer (bubble, TRUE);
 }
 
 void
@@ -2853,7 +2897,7 @@
 	    || msecs == 0)
 	{
 		bubble_show (self);
-		bubble_start_timer (self);
+		bubble_start_timer (self, TRUE);
 		return;
 	}
 
@@ -3006,7 +3050,8 @@
 }
 
 void
-bubble_start_timer (Bubble* self)
+bubble_start_timer (Bubble*  self,
+		    gboolean trigger)
 {
 	guint          timer_id;
 	BubblePrivate* priv;
@@ -3032,8 +3077,9 @@
 
 	/* if the bubble is displaying a value that is out of bounds
 	   trigger a dim/glow animation */
-	if (priv->value == -1 || priv->value == 101)
-		bubble_start_glow_effect (self, 500);
+	if (trigger)
+		if (priv->value == -1 || priv->value == 101)
+			bubble_start_glow_effect (self, 500);
 }
 
 void
@@ -3109,7 +3155,9 @@
 	}
 
 	layout = pango_cairo_create_layout (cr);
-	desc = pango_font_description_new ();
+	text_font_face = defaults_get_text_font_face (d);
+	desc = pango_font_description_from_string (text_font_face);
+	g_free ((gpointer) text_font_face);
 
 	// make sure system-wide font-options like hinting, antialiasing etc.
 	// are taken into account
@@ -3126,17 +3174,12 @@
 					 defaults_get_text_title_size (d) *
 					 PANGO_SCALE);
 
-	text_font_face = defaults_get_text_font_face (d);
-	pango_font_description_set_family_static (desc, text_font_face);
-
 	pango_font_description_set_weight (
 		desc,
 		defaults_get_text_title_weight (d));
 
-	pango_font_description_set_style (desc, PANGO_STYLE_NORMAL);
 	pango_layout_set_font_description (layout, desc);
 	pango_font_description_free (desc);
-	g_free ((gpointer) text_font_face);
 
 	pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
 	pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
@@ -3180,7 +3223,9 @@
 	}
 
 	layout = pango_cairo_create_layout (cr);
-	desc = pango_font_description_new ();
+	text_font_face = defaults_get_text_font_face (d);
+	desc = pango_font_description_from_string (text_font_face);
+	g_free ((gpointer) text_font_face);
 
 	// make sure system-wide font-options like hinting, antialiasing etc.
 	// are taken into account
@@ -3197,14 +3242,10 @@
 					 defaults_get_text_body_size (d) *
 					 PANGO_SCALE);
 
-	text_font_face = defaults_get_text_font_face (d);
-	pango_font_description_set_family_static (desc, text_font_face);
-
 	pango_font_description_set_weight (
 		desc,
 		defaults_get_text_body_weight (d));
 
-	pango_font_description_set_style (desc, PANGO_STYLE_NORMAL);
 	pango_layout_set_font_description (layout, desc);
 
 	pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
@@ -3259,7 +3300,6 @@
 	body_height = PANGO_PIXELS (log_rect.height);
 
 	pango_font_description_free (desc);
-	g_free ((gpointer) text_font_face);
 	g_object_unref (layout);
 	cairo_destroy (cr);
 
@@ -3639,39 +3679,52 @@
 bubble_append_message_body (Bubble*      self,
 			    const gchar* append_body)
 {
-	gboolean result;
-	gchar*   text;
-	GError*  error = NULL;
+	gboolean       result = FALSE;
+	gchar*         text   = NULL;
+	GError*        error  = NULL;
+	BubblePrivate* priv   = NULL;
 
-	if (!self || !IS_BUBBLE (self))
+	if (!self || !IS_BUBBLE (self) || !append_body)
 		return;
 
-	/* filter out any HTML/markup if possible */
+	priv = GET_PRIVATE (self);
+
+	// filter out any HTML/markup if possible
     	result = pango_parse_markup (append_body,
 				     -1,
-				     0,    /* no accel-marker needed */
-				     NULL, /* no PangoAttr needed */
+				     0,    // no accel-marker needed
+				     NULL, // no PangoAttr needed
 				     &text,
-				     NULL, /* no accel-marker-return needed */
+				     NULL, // no accel-marker-return needed
 				     &error);
-	if (error)
+	if (error && !result)
 	{
-		g_warning ("bubble_append_message_body(): Got error \"%s\"\n",
-		           error->message);
+		g_warning ("%s(): Got error \"%s\"\n",
+			   G_STRFUNC,
+			   error->message);
 		g_error_free (error);
 		error = NULL;
-	}
-
-	/* append text to current message-body */
-	g_string_append (GET_PRIVATE (self)->message_body, text);
-
-	g_signal_emit (self, g_bubble_signals[MESSAGE_BODY_INSERTED], 0, text);
-
-	g_object_notify (
-		G_OBJECT (gtk_widget_get_accessible (GET_PRIVATE(self)->widget)), 
-		"accessible-description");
-
-	g_free ((gpointer) text);
+
+		if (text)
+			g_free (text);
+	}
+
+	if (text)
+	{
+		// append text to current message-body
+		g_string_append (priv->message_body, text);
+
+		g_signal_emit (self,
+			       g_bubble_signals[MESSAGE_BODY_INSERTED],
+			       0,
+			       text);
+
+		g_object_notify (
+			G_OBJECT (gtk_widget_get_accessible (priv->widget)),
+				  "accessible-description");
+
+		g_free (text);
+	}
 }
 
 void
@@ -3682,6 +3735,6 @@
 
 	bubble_set_timeout (self,
 			    bubble_get_timeout (other));
-	bubble_start_timer (self);
-	bubble_start_timer (other);
+	bubble_start_timer (self, FALSE);
+	bubble_start_timer (other, FALSE);
 }

=== modified file 'src/bubble.h'
--- src/bubble.h	2009-08-27 09:52:34 +0000
+++ src/bubble.h	2009-10-20 08:51:11 +0000
@@ -109,6 +109,10 @@
 bubble_get_message_body (Bubble* self);
 
 void
+bubble_set_icon_from_path (Bubble*      self,
+			   const gchar* filepath);
+
+void
 bubble_set_icon (Bubble*      self,
 		 const gchar* filename);
 
@@ -185,7 +189,8 @@
 bubble_is_visible (Bubble* self);
 
 void
-bubble_start_timer (Bubble* self);
+bubble_start_timer (Bubble*  self,
+		    gboolean trigger);
 
 void
 bubble_get_position (Bubble* self,

=== modified file 'src/defaults.c'
--- src/defaults.c	2009-09-29 09:52:49 +0000
+++ src/defaults.c	2009-10-19 17:59:53 +0000
@@ -41,6 +41,7 @@
 #include <libwnck/workspace.h>
 
 #include "defaults.h"
+#include "util.h"
 
 G_DEFINE_TYPE (Defaults, defaults, G_TYPE_OBJECT);
 
@@ -171,15 +172,13 @@
 static void
 _get_font_size_dpi (Defaults* self)
 {
-	GString*   string        = NULL;
-	GError*    error         = NULL;
-	GScanner*  scanner       = NULL;
-	GTokenType token         = G_TOKEN_NONE;
-	gint       points        = 0;
-	GString*   font_face     = NULL;
-	gdouble    dpi           = 0.0f;
-	gdouble    pixels_per_em = 0;
-	gchar*     font_name     = NULL;
+	GString*    string        = NULL;
+	GError*     error         = NULL;
+	guint       points        = 0;
+	GString*    font_face     = NULL;
+	gdouble     dpi           = 0.0f;
+	gdouble     pixels_per_em = 0;
+	gchar*      font_name     = NULL;
 
 	if (!IS_DEFAULTS (self))
 		return;
@@ -192,7 +191,7 @@
 	string = g_string_new (font_name);
 	if (error)
 	{
-		/* if something went wrong, assume "Sans 10" and continue */
+		// if something went wrong, assume "Sans 10" and continue
 		string = g_string_assign (string, "Sans 10");
 
 		g_warning ("_get_font_size_dpi(): Got error \"%s\"\n",
@@ -201,41 +200,12 @@
 	}
 	g_free ((gpointer) font_name);
 
-	/* extract font-family-name and font-size */
-	scanner = g_scanner_new (NULL);
-	if (scanner)
-	{
-		g_scanner_input_text (scanner, string->str, string->len);
-		for (token = g_scanner_get_next_token (scanner);
-		     token != G_TOKEN_EOF;
-		     token = g_scanner_get_next_token (scanner))
-		{
-			switch (token)
-			{
-				case G_TOKEN_INT:
-					points = (gint) scanner->value.v_int;
-				break;
-
-				case G_TOKEN_IDENTIFIER:
-					if (!font_face)
-						font_face = g_string_new (scanner->value.v_string);
-					else
-					{
-						g_string_append (font_face,
-								 " ");
-						g_string_append (font_face,
-								 scanner->value.v_string);
-					}
-				break;
-
-				default:
-				break;
-			}
-		}
-		g_scanner_destroy (scanner);
-	}
-
-	/* clean up */
+	// extract text point-size
+	points = extract_point_size (string->str);
+
+	// extract font-face-name/style
+	font_face = extract_font_face (string->str);
+
 	if (string != NULL)
 		g_string_free (string, TRUE);
 

=== modified file 'src/dialog.c'
--- src/dialog.c	2009-08-26 11:17:55 +0000
+++ src/dialog.c	2009-10-16 12:39:14 +0000
@@ -153,10 +153,10 @@
 	GtkWidget* title;
 	GtkWidget* body;
 	GtkWidget* image;
-	gchar*     body_message;
-	gchar*     new_body_message;
+	gchar*     body_message = NULL;
+	gchar*     new_body_message = NULL;
 	guint      gap = EM2PIXELS (defaults_get_margin_size (d), d);
-	gboolean   success;
+	gboolean   success = FALSE;
 	GError*    error = NULL;
 
 	if (!IS_DEFAULTS (d) ||
@@ -201,25 +201,34 @@
 
 	body = gtk_label_new (NULL);
 	body_message = filter_text (_body_message);
-	success = pango_parse_markup (body_message,
-				      -1,
-				      0,
-				      NULL,
-				      &new_body_message,
-				      NULL,
-				      &error);
-
-	if (error)
-	{
-		g_warning ("fallback_dialog_show(): Got error \"%s\"\n",
-		           error->message);
-		g_error_free (error);
-		error = NULL;
-	}
-
-	gtk_label_set_text (GTK_LABEL (body), new_body_message);
+	if (body_message)
+	{
+		success = pango_parse_markup (body_message,
+					      -1,
+					      0,
+					      NULL,
+					      &new_body_message,
+					      NULL,
+					      &error);
+
+		if (error && !success)
+		{
+			g_warning ("fallback_dialog_show(): Got error \"%s\"\n",
+		        	   error->message);
+			g_error_free (error);
+			error = NULL;
+		}
+	}
+
+	if (new_body_message)
+	{
+		gtk_label_set_text (GTK_LABEL (body), new_body_message);
+		g_free (new_body_message);
+	}
+	else
+		gtk_label_set_text (GTK_LABEL (body), body_message);
+
 	g_free (body_message);
-	g_free (new_body_message);
 
 	gtk_label_set_line_wrap (GTK_LABEL (body), TRUE);
 

=== modified file 'src/display.c'
--- src/display.c	2009-09-23 13:14:20 +0000
+++ src/display.c	2009-10-20 08:51:11 +0000
@@ -215,7 +215,7 @@
 	/* is the notification reusing the current bubble? */
 	if (sync_bubble == bubble)
 	{
-		bubble_start_timer (bubble);
+		bubble_start_timer (bubble, TRUE);
 		bubble_refresh (bubble);
 		return;
 	}

=== modified file 'src/stack.c'
--- src/stack.c	2009-09-24 12:59:26 +0000
+++ src/stack.c	2009-10-20 08:51:11 +0000
@@ -389,7 +389,7 @@
 	/* check if this is just an update */
 	if (find_bubble_by_id (self, bubble_get_id (bubble)))
 	{
-		bubble_start_timer (bubble);
+		bubble_start_timer (bubble, TRUE);
 		bubble_refresh (bubble);
 
 		/* resync the synchronous bubble if it's at the top */
@@ -725,7 +725,7 @@
 		{
 			g_debug("Using image_path hint\n");
 			if ((data && G_VALUE_HOLDS_STRING (data)))
-				bubble_set_icon (bubble, g_value_get_string(data));
+				bubble_set_icon_from_path (bubble, g_value_get_string(data));
 			else
 				g_warning ("image_path hint is not a string\n");
 		}

=== modified file 'src/util.c'
--- src/util.c	2009-10-06 20:22:08 +0000
+++ src/util.c	2009-10-19 04:57:25 +0000
@@ -257,3 +257,84 @@
 
 	return (gchar*) buffer;
 }
+
+guint
+extract_point_size (const gchar* string)
+{
+	guint       point_size = 0;
+	GRegex*     regex      = NULL;
+	GMatchInfo* match_info = NULL;
+
+	// sanity check
+	if (!string)
+		return 0;
+
+	// setup regular expression to extract an integer from the end of string
+	regex = g_regex_new ("\\d+$", 0, 0, NULL);
+	if (!regex)
+		return 0;
+
+	// walk the string
+	g_regex_match (regex, string, 0, &match_info);
+	while (g_match_info_matches (match_info))
+	{
+		gchar* word = NULL;
+
+		word = g_match_info_fetch (match_info, 0);
+		if (word)
+		{
+			sscanf (word, "%d", &point_size);
+			g_free (word);
+		}
+
+		g_match_info_next (match_info, NULL);
+	}
+
+	// clean up
+	g_match_info_free (match_info);
+	g_regex_unref (regex);
+
+	return point_size;
+}
+
+GString*
+extract_font_face (const gchar* string)
+{
+	GRegex*     regex      = NULL;
+	GMatchInfo* match_info = NULL;
+	GString*    font_face  = NULL;
+
+	// sanity check
+	if (!string)
+		return NULL;
+
+	// extract font-face-name/style
+	font_face = g_string_new ("");
+	if (!font_face)
+		return NULL;
+
+	// setup regular expression to extract leading text before trailing int
+	regex = g_regex_new ("([A-Z a-z])+", 0, 0, NULL);
+
+	// walk the string
+	g_regex_match (regex, string, 0, &match_info);
+	while (g_match_info_matches (match_info))
+	{
+		gchar* word = NULL;
+
+		word = g_match_info_fetch (match_info, 0);
+		if (word)
+		{
+			g_string_append (font_face, word);
+			g_free (word);
+		}
+
+		g_match_info_next (match_info, NULL);
+	}
+
+	// clean up
+	g_match_info_free (match_info);
+	g_regex_unref (regex);
+
+	return font_face;
+}

=== modified file 'src/util.h'
--- src/util.h	2009-10-01 08:34:39 +0000
+++ src/util.h	2009-10-19 04:57:25 +0000
@@ -52,3 +52,8 @@
 gchar*
 get_wm_name (Display* dpy);
 
+guint
+extract_point_size (const gchar* string);
+
+GString*
+extract_font_face (const gchar* string);

=== modified file 'tests/test-text-filtering.c'
--- tests/test-text-filtering.c	2009-10-01 08:43:26 +0000
+++ tests/test-text-filtering.c	2009-10-19 04:57:25 +0000
@@ -34,6 +34,11 @@
 	const gchar *expected;
 } TextComparisons;
 
+typedef struct {
+	const gchar* before;
+	guint        expected;
+} IntegerExtraction;
+
 static void
 test_text_filter ()
 {
@@ -69,8 +74,8 @@
 		{ "<tt>Testing tag</tt>",                          "Testing tag"                             },
 		{ "<html>Surrounded by html</html>",               "Surrounded by html"                      },
 		{ "<qt>Surrounded by qt</qt>",                     "Surrounded by qt"                        },
-		{ "First line  <br dumb> \r \n Second line",       "First line Second line"                  },
-		{ "First line\n<br /> <br>\n2nd line\r\n3rd line", "First line 2nd line 3rd line"            },
+		{ "First line  <br dumb> \r \n Second line",       "First line\nSecond line"                  },
+		{ "First line\n<br /> <br>\n2nd line\r\n3rd line", "First line\n2nd line\n3rd line"            },
 		{ NULL, NULL }
 	};
 
@@ -97,6 +102,49 @@
 	}
 }
 
+static void
+test_extract_point_size ()
+{
+	static const IntegerExtraction tests[] = {
+		{ "", 0 },
+		{ "foobar", 0 },
+		{ "Bla Fasel -12.0", 0 },
+		{ "Sans 10", 10 },
+		{ "Candara 9", 9 },
+		{ "Bitstream Vera Serif Italic 1", 1 },
+		{ "Calibri Italic 100", 100 },
+		{ "Century Schoolbook L Italic 42", 42 },
+		{ NULL, 0 }
+	};
+
+	for (int i = 0; tests[i].before != NULL; i++)
+	{
+		guint extracted = extract_point_size (tests[i].before);
+		g_assert_cmpuint (extracted, ==, tests[i].expected);
+	}
+}
+
+static void
+test_extract_font_face ()
+{
+	static const TextComparisons tests[] = {
+		{ "", "" },
+		{ "Sans 10", "Sans " },
+		{ "Candara 9", "Candara " },
+		{ "Bitstream Vera Serif Italic 1", "Bitstream Vera Serif Italic " },
+		{ "Calibri Italic 100", "Calibri Italic " },
+		{ "Century Schoolbook L Italic 10", "Century Schoolbook L Italic " },
+		{ NULL, NULL }
+	};
+
+	for (int i = 0; tests[i].before != NULL; i++)
+	{
+		GString* filtered = extract_font_face (tests[i].before);
+		g_assert_cmpstr (filtered->str, ==, tests[i].expected);
+		g_string_free (filtered, TRUE);
+	}
+}
+
 GTestSuite *
 test_filtering_create_test_suite (void)
 {
@@ -108,6 +156,8 @@
 
 	g_test_suite_add(ts, TC(test_text_filter));
 	g_test_suite_add(ts, TC(test_newline_to_space));
+	g_test_suite_add(ts, TC(test_extract_point_size));
+	g_test_suite_add(ts, TC(test_extract_font_face));
 
 	return ts;
 }