Clone in a terminal:
Commit 9e7fb91
Johan Mattsson - 2015-05-21T12:39:24+00:00
9e7fb91684a9ab59493fb9fbf343ef235b113a71johan.mattsson.m@gmail.com

Fallback font

Changed files (7)

Diff

diff --git a/libbirdfont/BirdFontFile.vala b/libbirdfont/BirdFontFile.valaindex 87f1bc0..5df1cef 100644--- a/libbirdfont/BirdFontFile.vala+++ b/libbirdfont/BirdFontFile.vala@@ -1163,7 +1163,7 @@ class BirdFontFile : GLib.Object { 		return id; 	} -	private void parse_glyph (Tag tag, GlyphCollection gc, string name, +	public void parse_glyph (Tag tag, GlyphCollection gc, string name,  			unichar unicode, int selected_id, bool unassigned) {	 		Glyph glyph = new Glyph (name, unicode); 		Path path;diff --git a/libbirdfont/FallbackFont.vala b/libbirdfont/FallbackFont.valaindex 9a0a7a6..11f634d 100644--- a/libbirdfont/FallbackFont.vala+++ b/libbirdfont/FallbackFont.vala@@ -14,6 +14,7 @@  using Gee; using Sqlite;+using Bird;  namespace BirdFont { @@ -21,7 +22,139 @@ public class FallbackFont : GLib.Object { 	static unowned Database db; 	static Database? database = null; +	Gee.ArrayList<FontFace> fallback_fonts;+	Gee.ArrayList<File> font_directories;+ 	public FallbackFont () {	+		string home = Environment.get_home_dir ();+		+		fallback_fonts = new Gee.ArrayList<FontFace> ();+		font_directories = new Gee.ArrayList<File> ();+		+		add_font_folder ("/usr/share/fonts/");+		add_font_folder ("/usr/local/share/fonts/");+		add_font_folder (home + "/.local/share/fonts");+		add_font_folder ("C:\\Windows\\Fonts");+		+		open_fallback_fonts ();+	}++	~FallbackFont () {+		foreach (FontFace f in fallback_fonts) {+			close_font (f);+		}+	}+	+	void open_fallback_fonts () {+		add_font ("times.ttf");+		add_font ("verdana.ttf");+		add_font ("arial.ttf");+		add_font ("calibri.ttf");+		+		add_font ("Ubuntu-R.ttf");+		+		add_font ("DroidKufi.ttf");+		add_font ("DroidSansGeorgian.ttf");+		add_font ("DroidSansHebrew.ttf");+		add_font ("DroidNaskh.ttf");+		add_font ("DroidSansJapanese.ttf");+		add_font ("DroidSansArabic.ttf");+		add_font ("DroidSansArmenian.ttf");+		add_font ("DroidSans.ttf");+		add_font ("DroidSansEthiopic.ttf");+		add_font ("DroidSansFallbackFull.ttf");++		add_font ("Roboto-Regular.ttf");+	}++	void add_font (string font) {+		File f = find_font_file (font);+		+		if (f.query_exists ()) {+			add_font_file (f);+		}+	}++	void add_font_file (File font_file) {+		FontFace f = open_font ((!) font_file.get_path ());+		fallback_fonts.add (f);+	}++	File find_font_file (string font_file) {+		File d, f;+		+		for (int i = font_directories.size - 1; i >= 0; i--) {+			d = font_directories.get (i);+			f = get_child (d, font_file);+			+			if (f.query_exists ()) {+				return f;+			}+		}+		+		return File.new_for_path (font_file);+	}+		+	void add_font_folder (string f) {+		File folder = File.new_for_path (f);+		FileInfo? file_info;+		string fn;+		+		try {+			if (folder.query_exists ()) {+				font_directories.add (folder);+				+				var enumerator = folder.enumerate_children (FileAttribute.STANDARD_NAME + "," + FileAttribute.STANDARD_TYPE, 0);+				+				while ((file_info = enumerator.next_file ()) != null) {+					fn = ((!) file_info).get_name ();++					if (((!)file_info).get_file_type () == FileType.DIRECTORY) {+						add_font_folder ((!) get_child (folder, fn).get_path ());+					}+				}+			}+		} catch (GLib.Error e) {+			warning (e.message);+		}+	}+	+	public Glyph get_glyph (unichar c) {+		Glyph? g;+		FontFace f;+		+		for (int i = fallback_fonts.size - 1; i >= 0; i--) {+			f = fallback_fonts.get (i);+			g = get_glyph_in_font (f, c);+			+			if (g != null) {+				return (!) g;+			}+		}+		+		return new Glyph ("");+	}+	+	public Glyph? get_glyph_in_font (FontFace font, unichar c) {+		StringBuilder? glyph_data;+		GlyphCollection gc;+		XmlParser parser;+		BirdFontFile bf_parser;+		+		gc = new GlyphCollection (c, (!)c.to_string ());		+		glyph_data = load_glyph (font, (uint) c);+		+		if (glyph_data == null) {+			return null;+		}+		+		parser = new XmlParser (((!) glyph_data).str);	+		bf_parser = new BirdFontFile (new Font ());+		+		bf_parser.parse_glyph (parser.get_root_tag (),+			gc, gc.get_name (), gc.get_unicode_character (), 0, false);+		+		return gc.get_current (); 	}  	public File get_database_file () {@@ -70,6 +203,7 @@ public class FallbackFont : GLib.Object { 		 	} +/* //FIXME:DELETE 	public void add_font (string font_file) { 		Font font; 		Glyph g;@@ -89,7 +223,7 @@ public class FallbackFont : GLib.Object { 			g = (!) font.get_glyph_indice (i); 			bf = new BirdFontFile (font); 		}-	}+	} */  	public void open_database (File db_file) { 		int rc = Database.open ((!) db_file.get_path (), out database);diff --git a/libbirdfont/Glyph.vala b/libbirdfont/Glyph.valaindex 02161bb..64dde7e 100644--- a/libbirdfont/Glyph.vala+++ b/libbirdfont/Glyph.vala@@ -1497,17 +1497,18 @@ public class Glyph : FontDisplay { 	} 	 	/** Draw filled paths. */-	public void draw_paths (Context cr) {+	public void draw_paths (Context cr, Color? c = null) { 		PathList stroke;-+		Color color = c == null ? Color.black () : (!) c;+		 		cr.save (); 		cr.new_path (); 		foreach (Path p in path_list) { 			if (p.stroke > 0) { 				stroke = p.get_stroke_fast ();-				draw_path_list (stroke, cr, Color.black ());+				draw_path_list (stroke, cr, color); 			} else {-				p.draw_path (cr, this, Color.black ());+				p.draw_path (cr, this, color); 			} 		} 		cr.fill ();diff --git a/libbirdfont/OpenFontFormat/OpenFontFormatReader.vala b/libbirdfont/OpenFontFormat/OpenFontFormatReader.valaindex e4d81bd..c7e5480 100644--- a/libbirdfont/OpenFontFormat/OpenFontFormatReader.vala+++ b/libbirdfont/OpenFontFormat/OpenFontFormatReader.vala@@ -12,12 +12,26 @@     Lesser General Public License for more details. */ +[SimpleType]+[CCode (cname = "FontFace")]+public extern class FontFace {+}+ [CCode (cname = "load_freetype_font")] public extern static StringBuilder? load_freetype_font (string file, out int error);  [CCode (cname = "validate_freetype_font")] public extern static bool validate_freetype_font (string file); +[CCode (cname = "load_glyph")]+public extern static StringBuilder? load_glyph (FontFace font, uint unicode);++[CCode (cname = "open_font")]+public extern static FontFace open_font (string font_file);++[CCode (cname = "close_font")]+public extern static FontFace close_font (FontFace font);+ namespace BirdFont {  [SimpleType]diff --git a/libbirdfont/OpenFontFormat/load_font.c b/libbirdfont/OpenFontFormat/load_font.cindex 5a8182f..86c19be 100644--- a/libbirdfont/OpenFontFormat/load_font.c+++ b/libbirdfont/OpenFontFormat/load_font.c@@ -1,5 +1,5 @@ /*-    Copyright (C) 2013 2014 Johan Mattsson+    Copyright (C) 2013 2014 2015 Johan Mattsson      This library is free software; you can redistribute it and/or modify      it under the terms of the GNU Lesser General Public License as @@ -34,6 +34,11 @@ #define DOUBLE_CURVE 4 #define HIDDEN_CURVE 8 +typedef struct FontFace {+	FT_Face face;+	FT_Library library;+} FontFace;+ /** Convert units per em in font file format to the BirdFont format. */ double get_units (double units_per_em) { 	return 100.0 / units_per_em;@@ -513,7 +518,7 @@ GString* get_bf_contour_data (guint unicode, FT_Vector* points, char* flags, int 			i += 1; 		} else { 			contour = g_string_new ("");-			g_warning ("WARNING Can not parse outline.\n");+			g_warning ("WARNING Can't parse outline.\n"); 			*err = 1; 			i++; 		}@@ -553,6 +558,88 @@ GString* get_bf_path (guint unicode, FT_Face face, double units_per_em, int* err 	return bf; } +FontFace* open_font (const char* file) {+	FT_Library library;+	FT_Face face;+	int error;+	FontFace* font;+	+	error = FT_Init_FreeType (&library);+	if (error != OK) {+		g_warning ("Freetype init error %d.\n", error);+		return NULL;+	}++	error = FT_New_Face (library, file, 0, &face);+	if (error) {+		g_warning ("Freetype font face error %d\n", error);+		return NULL;+	}++	error = FT_Select_Charmap (face , FT_ENCODING_UNICODE);+	if (error) {+		g_warning ("Freetype can not use Unicode, error: %d\n", error);+		return NULL;+	}+	+	font = malloc (sizeof (FontFace));+	font->face = face;+	font->library = library;+}++void close_font (FontFace* font) {+	if (font != NULL) {+		FT_Done_Face (font->face);+		FT_Done_FreeType (font->library);+		free (font);+	}+}++GString* load_glyph (FontFace* font, guint unicode) {+	GString* glyph;+	GString* paths;+	int err = OK;+	int gid;+	FT_ULong charcode = (FT_ULong) unicode;+	double units;+	+	if (font == NULL || font->face == NULL) {+		g_warning ("No font in load_glyph");+		return NULL;+	}+	+	gid = FT_Get_Char_Index (font->face, charcode);+	+	if (gid == 0) {+		return NULL;+	}+	+	glyph = g_string_new ("");+	FT_Load_Glyph(font->face, gid, FT_LOAD_DEFAULT | FT_LOAD_NO_SCALE);+	+	paths = get_bf_path (unicode, font->face, font->face->units_per_EM, &err);+		+	if (err != OK) {+		g_warning ("WARNING Can't load glyph.");+	}+	+	units = get_units (font->face->units_per_EM);+	+	g_string_append_printf (glyph, "\t<glyph left=\"%f\" right=\"%f\" selected=\"true\">\n", +		0.0, font->face->glyph->metrics.horiAdvance * units);+		+	g_string_append_printf (glyph, "%s", paths->str);+	g_string_append_printf (glyph, "%s", "\t</glyph>");+	+	g_string_free (paths, 0);+	+	if (err != OK) {+		g_warning ("Can't load glyph data.");+	}+	+	return glyph;+}+ /** Get char code for a glyph.  * @gid glyph id  * @return character code@@ -680,9 +767,6 @@ GString* get_bf_font (FT_Face face, char* file, int* err) { 	} 	 	g_string_append (bf, "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n");-	-	// libxml2 fails on doctype declaration in windows.-	 	g_string_append (bf, "<font>\n");  	g_string_append_printf (bf, "<postscript_name>%s</postscript_name>\n", g_markup_escape_text (FT_Get_Postscript_Name(face), -1));diff --git a/libbirdfont/OverView.vala b/libbirdfont/OverView.valaindex d7bfda5..b6eaaf1 100644--- a/libbirdfont/OverView.vala+++ b/libbirdfont/OverView.vala@@ -53,9 +53,15 @@ public class OverView : FontDisplay { 	 	double scroll_size = 1; 	+	public static FallbackFont fallback_font;+	 	public OverView (GlyphRange? range = null, bool open_selected = true) { 		GlyphRange gr; +		if (is_null (fallback_font)) {+			fallback_font = new FallbackFont ();+		}+ 		if (range == null) { 			gr = new GlyphRange (); 			set_glyph_range (gr);diff --git a/libbirdfont/OverViewItem.vala b/libbirdfont/OverViewItem.valaindex 61ad14e..8b71009 100644--- a/libbirdfont/OverViewItem.vala+++ b/libbirdfont/OverViewItem.vala@@ -166,6 +166,8 @@ public class OverViewItem : GLib.Object { 		Context c; 		Text fallback; 		double font_size;+		OverView o;+		Color color = Color.black ();  		font = BirdFont.get_current_font (); 		w = width;@@ -178,37 +180,30 @@ public class OverViewItem : GLib.Object { 			 		if (gl != null) { 			g = ((!) gl).get_current ();-			g.boundaries (out x1, out y1, out x2, out y2);+		} else {+			o = MainWindow.get_overview ();+			g = o.fallback_font.get_glyph (character);+			color = Theme.get_color ("Overview Glyph");+		} 		-			glyph_width = x2 - x1;-			glyph_height = y2 - y1;-			-			gx = ((w / glyph_scale) - glyph_width) / 2;-			gy = (h / glyph_scale) - 25 / glyph_scale;+		g.boundaries (out x1, out y1, out x2, out y2);+	+		glyph_width = x2 - x1;+		glyph_height = y2 - y1;+		+		gx = ((w / glyph_scale) - glyph_width) / 2;+		gy = (h / glyph_scale) - 25 / glyph_scale; -			c.save ();-			c.scale (glyph_scale, glyph_scale);	+		c.save ();+		c.scale (glyph_scale, glyph_scale);	 -			g.add_help_lines ();-			-			c.translate (gx - g.get_lsb () - Glyph.xc (), g.get_baseline () + gy - Glyph.yc ());-			-			g.draw_paths (c);-			c.restore ();-		} else {-			c.save ();-			fallback = new Text ();-			Theme.text_color (fallback, "Overview Glyph");-			fallback.set_text ((!) character.to_string ());-			font_size = height * 0.8;-			fallback.set_font_size (font_size);-			gx = (width - fallback.get_extent ()) / 2.0;-			gy = height - 30;-			fallback.set_font_size (font_size);-			fallback.draw_at_baseline (c, gx, gy);-			c.restore ();-		}-				+		g.add_help_lines ();+		+		c.translate (gx - g.get_lsb () - Glyph.xc (), g.get_baseline () + gy - Glyph.yc ());+		+		g.draw_paths (c, color);+		c.restore ();+		 		cr.save (); 		cr.set_source_surface (s, x, y - h); 		cr.paint ();

Contact

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