Clone in a terminal:
Commit 9bb0fe4
Johan Mattsson - 2015-12-19T11:10:08+00:00
9bb0fe4b441553a44ea0d983d3cab01360387604johan.mattsson.m@gmail.com

Fix a bug in fallback font rendering with cairo The freetype library and the font face must be keep open for as long as cairo uses it.

Changed files (3)

Diff

diff --git a/libbirdfont/OverView.vala b/libbirdfont/OverView.valaindex 4b3a671..f532294 100644--- a/libbirdfont/OverView.vala+++ b/libbirdfont/OverView.vala@@ -616,8 +616,8 @@ public class OverView : FontDisplay { 			selected_item |= (i == selected); 			item.selected = selected_item; 			-			item.x = x + view_offset_y;-			item.y = y + view_offset_x;+			item.x = x + view_offset_x;+			item.y = y + view_offset_y; 			 			x += full_width; 			diff --git a/libbirdfont/OverViewItem.vala b/libbirdfont/OverViewItem.valaindex 16e4723..2bbaf33 100644--- a/libbirdfont/OverViewItem.vala+++ b/libbirdfont/OverViewItem.vala@@ -177,7 +177,11 @@ public class OverViewItem : GLib.Object { 				font_file = find_font (FallbackFont.font_config, (!) character.to_string ()); 				 				if (font_file != null) {-					draw_overview_glyph (c, (!) font_file, width, height, character);+					string path = (!) font_file;+					+					if (!path.has_suffix("LastResort.ttf")) {+						draw_overview_glyph (c, (!) font_file, width, height, character);+					} 				} 			} 			diff --git a/libbirdfont/overview_glyph.c b/libbirdfont/overview_glyph.cindex b66f5e9..4972f35 100644--- a/libbirdfont/overview_glyph.c+++ b/libbirdfont/overview_glyph.c@@ -16,17 +16,17 @@ #include <glib.h>
 #include <stdio.h>
 #include <cairo.h>
+#include <cairo-ft.h>
 #include <stdlib.h>
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #include FT_GLYPH_H
 
+FT_Library freetype_library = NULL;
+
 gboolean draw_overview_glyph (cairo_t* context, const char* font_file, gdouble width, gdouble height, gunichar character) {
-	FT_Library library;
 	FT_Face face;
 	int error;
-	FT_Glyph glyph;
-	FT_UInt glyph_index;
 	gdouble units_per_em;
 	gdouble units;
 	gdouble advance;
@@ -42,15 +42,20 @@ gboolean draw_overview_glyph (cairo_t* context, const char* font_file, gdouble w 		return FALSE;
 	}
 
-	error = FT_Init_FreeType (&library);
-	if (error) {
-		g_warning ("Freetype init error %d.\n", error);
-		return FALSE;
+	gchar text[7];
+	int length = g_unichar_to_utf8 (character, text);
+	text[length] = '\0';
+	
+	if (freetype_library == NULL) {
+		error = FT_Init_FreeType (&freetype_library);
+		if (error) {
+			g_warning ("Freetype init error %d.\n", error);
+			return FALSE;
+		}
 	}
-
-	error = FT_New_Face (library, font_file, 0, &face);
+	
+	error = FT_New_Face (freetype_library, font_file, 0, &face);
 	if (error) {
-		FT_Done_FreeType (library);
 		g_warning ("Freetype font face error %d\n", error);
 		return FALSE;
 	}
@@ -62,7 +67,6 @@ gboolean draw_overview_glyph (cairo_t* context, const char* font_file, gdouble w 	if (error) {
 		g_warning ("Freetype can not use Unicode, error: %d\n", error);
 		FT_Done_Face (face);
-		FT_Done_FreeType (library);
 		return FALSE;
 	}
 
@@ -70,22 +74,16 @@ gboolean draw_overview_glyph (cairo_t* context, const char* font_file, gdouble w 	if (error) {
 		g_warning ("FT_Set_Char_Size, error: %d.\n", error);
 		FT_Done_Face (face);
-		FT_Done_FreeType (library);
 		return FALSE;
 	}
-
+	
 	error = FT_Set_Pixel_Sizes (face, 0, (int) (height * 0.5));
 	if (error) {
 		g_warning ("FT_Set_Pixel_Sizes, error: %d.\n", error);
 		FT_Done_Face (face);
-		FT_Done_FreeType (library);
 		return FALSE;
 	}
 
-	gchar text[7];
-	int length = g_unichar_to_utf8 (character, text);
-	text[length] = '\0';
-
 	gid = FT_Get_Char_Index (face, character);
 	advance = 0;
 	if (gid != 0) {
@@ -94,13 +92,29 @@ gboolean draw_overview_glyph (cairo_t* context, const char* font_file, gdouble w 		advance *= units;
 	} else {
 		FT_Done_Face (face);
-		FT_Done_FreeType (library);
 		return FALSE;
 	}
 
+	static const cairo_user_data_key_t key;
+
 	cairo_save (context);
+	
 	cairo_font_face_t* cairo_face = cairo_ft_font_face_create_for_ft_face (face, 0);
 	
+	if (cairo_face == NULL) {
+		g_warning("cairo font face is null");
+		FT_Done_Face (face);
+		return FALSE;
+	}
+	
+	int status = cairo_font_face_set_user_data (cairo_face, &key, face, (cairo_destroy_func_t) FT_Done_Face);
+	
+	if (status != CAIRO_STATUS_SUCCESS) {		
+		cairo_font_face_destroy (cairo_face);
+		FT_Done_Face (face);
+		return FALSE;
+	}
+
 	cairo_set_font_face (context, cairo_face);
 	cairo_set_font_size (context, height * 0.5);
 	
@@ -116,8 +130,7 @@ gboolean draw_overview_glyph (cairo_t* context, const char* font_file, gdouble w 	cairo_font_face_destroy (cairo_face);
 	cairo_restore (context);
 	
-	FT_Done_Face (face);
-	FT_Done_FreeType (library);
+	// cairo closes the font face and the library must be kept open
 	
 	return TRUE;
 }

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112