Commit cdd9e11
Store fallback font in database
Changed files (6)
modifiedlibbirdfont/CharDatabase.valamodifiedlibbirdfont/CharDatabaseParser.valamodifiedlibbirdfont/OverView.valamodifiedlibbirdfont/OverViewItem.valamodifiedlibbirdfont/Renderer/FallbackFont.valamodifiedlibbirdfont/SpacingData.vala
Diff
@@ -108,7 +108,7 @@ public class CharDatabase { return result; }-+ public static bool has_ascender (unichar c) { if (!c.islower()) return true; @@ -173,7 +173,7 @@ public class CharDatabaseParser : GLib.Object { d = t.split (" "); foreach (string token in d) { if (token != "") {- insert_lookup ((int64)ch, token);+ insert_lookup ((int64) ch, token); } } }@@ -535,6 +535,7 @@ public class OverView : FontDisplay { default_position (); first_visible = (int) r;+ update_item_list (); } public override void scroll_to (double position) requires (items_per_row > 0) {@@ -554,7 +555,7 @@ public class OverView : FontDisplay { r *= items_per_row; scroll_to_position ((int64) r);- + update_item_list (); GlyphCanvas.redraw (); } @@ -578,12 +579,16 @@ public class OverView : FontDisplay { view_offset_y = 0; first_visible += items_per_row; }+ + update_item_list (); } public void scroll_top () { selected = 0; first_visible = 0; + update_item_list ();+ if (visible_items.size != 0) { selected_item = get_selected_item (); }@@ -623,6 +628,7 @@ public class OverView : FontDisplay { } selected_item = get_selected_item ();+ update_item_list (); } public void key_right () {@@ -648,6 +654,7 @@ public class OverView : FontDisplay { selected = (int) (len - first_visible - 1); selected_item = get_selected_item (); }+ update_item_list (); } public void key_up () {@@ -661,6 +668,7 @@ public class OverView : FontDisplay { if (first_visible < 0) { first_visible = 0; }+ update_item_list (); } public void key_left () {@@ -675,6 +683,7 @@ public class OverView : FontDisplay { if (first_visible < 0) { scroll_top (); }+ update_item_list (); } public string get_selected_char () {@@ -693,6 +702,7 @@ public class OverView : FontDisplay { public override void key_press (uint keyval) { hide_menu ();+ update_item_list (); GlyphCanvas.redraw (); if (KeyBindings.modifier == CTRL) {@@ -786,6 +796,8 @@ public class OverView : FontDisplay { if (selected_item.glyphs != null) { selected_items.add ((!) selected_item.glyphs); }+ + update_item_list (); } public void delete_selected_glyph () {@@ -1038,6 +1050,7 @@ public class OverView : FontDisplay { public override void button_press (uint button, double x, double y) { int index = 0; int selected_index = -1;+ bool update = false; if (character_info != null) { character_info = null;@@ -1069,10 +1082,16 @@ public class OverView : FontDisplay { selected_items.add ((!) selected_item.glyphs); } }+ + update = !i.version_menu.menu_visible; } index++; } + if (update) {+ update_item_list ();+ }+ // FIXME: update_item_list (); GlyphCanvas.redraw (); }@@ -35,7 +35,7 @@ public class OverViewItem : GLib.Object { public static double glyph_scale = 1.0; - VersionList version_menu;+ public VersionList version_menu; Text icon; public OverViewItem (GlyphCollection? glyphs, unichar character, double x, double y) { @@ -18,6 +18,7 @@ using Bird; namespace BirdFont { +// TODO: use font config public class FallbackFont : GLib.Object { static unowned Database db; static Database? database = null;@@ -31,22 +32,25 @@ public class FallbackFont : GLib.Object { fallback_fonts = new Gee.ArrayList<File> (); font_directories = new Gee.ArrayList<File> (); + open_database ();+ 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");- + add_font_folder (home + "/.fonts");+ add_font_folder ("C:\\Windows\\Fonts"); //FIXME: MAC - open_fallback_fonts ();+ add_fallback_fonts (); } - void open_fallback_fonts () {+ void add_fallback_fonts () { add_font ("times.ttf"); add_font ("arial.ttf"); add_font ("verdana.ttf"); add_font ("calibri.ttf");- ++ add_font ("DejaVuSans.ttf"); add_font ("Ubuntu-R.ttf"); add_font ("DroidKufi.ttf");@@ -111,121 +115,86 @@ public class FallbackFont : GLib.Object { } public Font get_single_glyph_font (unichar c) {- Font f = load_glyph_from_ttf (c);- return f;+ BirdFontFile bf_parser;+ Font bf_font;+ StringBuilder? glyph_data;+ string data;+ + glyph_data = find_cached_glyph (c);+ + if (glyph_data == null) {+ print (@"Load from TTF $((!) c.to_string ())\n");+ glyph_data = load_glyph_from_ttf (c);+ } else print (@"Found cached gd $((!) c.to_string ())\n");+ + bf_font = new Font ();+ + if (glyph_data != null) {+ bf_parser = new BirdFontFile (bf_font);+ data = ((!) glyph_data).str;+ + if (data != "") {+ bf_parser.load_data (data);+ }+ }++ return bf_font; } - public Font load_glyph_from_ttf (unichar c) {- Font? bf_font;+ public StringBuilder? load_glyph_from_ttf (unichar c) {+ StringBuilder? glyph_data;+ string data;+ + glyph_data = load_glyph_data_from_ttf (c);+ + if (glyph_data != null) {+ cache_glyph (c, ((!) glyph_data).str);+ } else {+ cache_glyph (c, "");+ }+ + return glyph_data;+ }++ public StringBuilder? load_glyph_data_from_ttf (unichar c) { File f; FontFace* font;+ StringBuilder? data = null; - bf_font = new Font ();- for (int i = fallback_fonts.size - 1; i >= 0; i--) { f = fallback_fonts.get (i); font = open_font ((!) f.get_path ());- bf_font = get_glyph_in_font ((!) font, c);- + data = get_glyph_in_font (font, c); close_font (font); - if (bf_font != null) {- return (!) bf_font;+ if (data != null) {+ return data; } } - return bf_font != null ? (!) bf_font : new Font ();+ return null; } - public Font? get_glyph_in_font (FontFace font, unichar c) {+ public StringBuilder? get_glyph_in_font (FontFace font, unichar c) { StringBuilder? glyph_data = null; GlyphCollection gc;- BirdFontFile bf_parser; Font bf_font = new Font (); gc = new GlyphCollection (c, (!)c.to_string ()); glyph_data = load_glyph (font, (uint) c); - if (glyph_data == null) {- return null;- }-- bf_parser = new BirdFontFile (bf_font);- bf_parser.load_data (((!) glyph_data).str);- - return bf_font;- }-- public File get_database_file () {- return SearchPaths.find_file (null, "fallback-font.sqlite");+ return glyph_data; } - public File get_new_database_file () {- string? fn = BirdFont.get_argument ("--fallback-font");- - if (fn != null && ((!) fn) != "") {- return File.new_for_path ((!) fn);- }- - return File.new_for_path ("fallback-font.sqlite");- }- - public void generate_fallback_font () {- File f = get_new_database_file ();- string? fonts = BirdFont.get_argument ("--fonts");- string fallback;- - if (fonts == null) {- stderr.printf ("Add a list of fonts to use as fallback to the \"--fonts\" argument.\n");- stderr.printf ("Separate each font file with \":\"\n");- return;- }- - fallback = (!) fonts;- - stdout.printf ("Generating fallback font: %s\n", (!) f.get_path ());- - try {- if (f.query_exists ()) {- f.delete ();- }- - open_database (f);- create_tables ();- - foreach (string font in fallback.split (":")) {- add_font (font);- } - } catch (GLib.Error e) {- warning (e.message);- }- + File get_fallback_database () {+ File f = BirdFont.get_settings_directory ();+ return get_child (f, "fallback_font.sqlite"); }--/* //FIXME:DELETE- public void add_font (string font_file) {- Font font;- Glyph g;- BirdFontFile bf;- File single_glyph_font;- - font = new Font ();- single_glyph_font = File.new_for_path ("/tmp/fallback_glyph.bf");- - font.set_file (font_file);- if (!font.load ()) {- stderr.printf ("Failed to load font: " + font_file);- return;- }- - for (int i = 0; i < font.length (); i++) {- g = (!) font.get_glyph_indice (i);- bf = new BirdFontFile (font);- }- } */-- public void open_database (File db_file) {+ + public void open_database () {+ File db_file = get_fallback_database ();+ bool create_table = !db_file.query_exists (); int rc = Database.open ((!) db_file.get_path (), out database); db = (!) database;@@ -233,8 +202,12 @@ public class FallbackFont : GLib.Object { if (rc != Sqlite.OK) { stderr.printf ("Can't open database: %d, %s\n", rc, db.errmsg ()); }- } + if (create_table) {+ create_tables ();+ }+ }+ public void create_tables () { int ec; string? errmsg;@@ -250,6 +223,61 @@ public class FallbackFont : GLib.Object { warning ("Error: %s\n", (!) errmsg); } }+ + void cache_glyph (unichar c, string glyph_data) {+ int64 character;+ int ec;+ string? errmsg;+ string insert;+ + character = (int64) c;+ insert = "INSERT INTO FallbackFont (unicode, font_data) "+ + @"VALUES ('$character', '" + glyph_data.replace ("'", "''") + "');";+ + ec = db.exec (insert, null, out errmsg);+ if (ec != Sqlite.OK) {+ warning ("Error: %s\n", (!) errmsg);+ }+ }++ StringBuilder? find_cached_glyph (unichar c) {+ int rc, cols;+ Statement statement;+ string select;+ StringBuilder? font_data = null;+ + select = "SELECT font_data FROM FallbackFont "+ + "WHERE unicode = '" + @"$((int64) c)" + "';";+ + rc = db.prepare_v2 (select, select.length, out statement, null);+ + if (rc == Sqlite.OK) {+ cols = statement.column_count();+ + if (cols != 1) {+ warning ("Expecting one column.");+ return font_data;+ }++ while (true) {+ rc = statement.step ();+ + if (rc == Sqlite.DONE) {+ break;+ } else if (rc == Sqlite.ROW) {+ font_data = new StringBuilder ();+ ((!) font_data).append (statement.column_text (0));+ } else {+ warning ("Error: %d, %s\n", rc, db.errmsg ());+ break;+ }+ } + } else {+ warning ("SQL error: %d, %s\n", rc, db.errmsg ());+ }+ + return font_data;+ } } }@@ -32,13 +32,16 @@ public class SpacingData : GLib.Object { } public Gee.ArrayList<string> get_all_connections (string glyph) {+ string t; Gee.ArrayList<string> c = new Gee.ArrayList<string> (); connections.clear (); add_connections (glyph); - foreach (string t in connections) {+ for (int i = 0; i < connections.size; i++) {+ return_val_if_fail (0 <= i < connections.size, c);+ t = connections.get (i); c.add (t.dup ()); }