The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

FallbackFont.vala in libbirdfont/Renderer

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git

Revisions

View the latest version of libbirdfont/Renderer/FallbackFont.vala.
Remove debug info
1 /* 2 Copyright (C) 2015 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 15 using Gee; 16 using Sqlite; 17 using Bird; 18 19 namespace BirdFont { 20 21 public class FallbackFont : GLib.Object { 22 static unowned Database db; 23 static Database? database = null; 24 25 Gee.ArrayList<File> fallback_fonts; 26 Gee.ArrayList<File> font_directories; 27 28 public FallbackFont () { 29 string home = Environment.get_home_dir (); 30 31 fallback_fonts = new Gee.ArrayList<File> (); 32 font_directories = new Gee.ArrayList<File> (); 33 34 add_font_folder ("/usr/share/fonts/"); 35 add_font_folder ("/usr/local/share/fonts/"); 36 add_font_folder (home + "/.local/share/fonts"); 37 add_font_folder ("C:\\Windows\\Fonts"); 38 39 //FIXME: MAC 40 41 open_fallback_fonts (); 42 } 43 44 void open_fallback_fonts () { 45 add_font ("times.ttf"); 46 add_font ("arial.ttf"); 47 add_font ("verdana.ttf"); 48 add_font ("calibri.ttf"); 49 50 add_font ("Ubuntu-R.ttf"); 51 52 add_font ("DroidKufi.ttf"); 53 add_font ("DroidSansGeorgian.ttf"); 54 add_font ("DroidSansHebrew.ttf"); 55 add_font ("DroidNaskh.ttf"); 56 add_font ("DroidSansJapanese.ttf"); 57 add_font ("DroidSansArabic.ttf"); 58 add_font ("DroidSansArmenian.ttf"); 59 add_font ("DroidSans.ttf"); 60 add_font ("DroidSansEthiopic.ttf"); 61 add_font ("DroidSansFallbackFull.ttf"); 62 63 add_font ("Roboto-Regular.ttf"); 64 } 65 66 void add_font (string font) { 67 File f = find_font_file (font); 68 69 if (f.query_exists ()) { 70 fallback_fonts.add (f); 71 } 72 } 73 74 File find_font_file (string font_file) { 75 File d, f; 76 77 for (int i = font_directories.size - 1; i >= 0; i--) { 78 d = font_directories.get (i); 79 f = get_child (d, font_file); 80 81 if (f.query_exists ()) { 82 return f; 83 } 84 } 85 86 return File.new_for_path (font_file); 87 } 88 89 void add_font_folder (string f) { 90 File folder = File.new_for_path (f); 91 FileInfo? file_info; 92 string fn; 93 94 try { 95 if (folder.query_exists ()) { 96 font_directories.add (folder); 97 98 var enumerator = folder.enumerate_children (FileAttribute.STANDARD_NAME + "," + FileAttribute.STANDARD_TYPE, 0); 99 100 while ((file_info = enumerator.next_file ()) != null) { 101 fn = ((!) file_info).get_name (); 102 103 if (((!)file_info).get_file_type () == FileType.DIRECTORY) { 104 add_font_folder ((!) get_child (folder, fn).get_path ()); 105 } 106 } 107 } 108 } catch (GLib.Error e) { 109 warning (e.message); 110 } 111 } 112 113 public Font get_single_glyph_font (unichar c) { 114 Font f = load_glyph_from_ttf (c); 115 print (@"font e1 : $(f.ref_count)\n"); 116 return f; 117 } 118 119 public Font load_glyph_from_ttf (unichar c) { 120 Font? bf_font; 121 File f; 122 FontFace* font; 123 124 bf_font = new Font (); 125 126 if (bf_font != null) 127 print (@"font e1 a : $(((!)bf_font).ref_count)\n"); 128 129 for (int i = fallback_fonts.size - 1; i >= 0; i--) { 130 f = fallback_fonts.get (i); 131 132 font = open_font ((!) f.get_path ()); 133 bf_font = get_glyph_in_font ((!) font, c); 134 135 if (bf_font != null) 136 print (@"font e1 b : $(((!)bf_font).ref_count)\n"); 137 138 close_font (font); 139 140 if (bf_font != null) { 141 if (((!)bf_font).get_glyph_by_name ((!) c.to_string ()) != null) 142 print (@"first: $(((!) ((!)bf_font).get_glyph_by_name ((!) c.to_string ())).ref_count)\n"); 143 144 return (!) bf_font; 145 } 146 } 147 148 return bf_font != null ? (!) bf_font : new Font (); 149 } 150 151 public Font? get_glyph_in_font (FontFace font, unichar c) { 152 StringBuilder? glyph_data = null; 153 GlyphCollection gc; 154 BirdFontFile bf_parser; 155 Font bf_font = new Font (); 156 157 print (@"font e1 before load : $(bf_font.ref_count)\n"); 158 159 gc = new GlyphCollection (c, (!)c.to_string ()); 160 glyph_data = load_glyph (font, (uint) c); 161 162 if (glyph_data == null) { 163 return null; 164 } 165 166 print (@"font e1 before parser : $(bf_font.ref_count)\n"); 167 bf_parser = new BirdFontFile (bf_font); 168 print (@"font e2 before parser1 : $(bf_font.ref_count)\n"); 169 bf_parser.load_data (((!) glyph_data).str); 170 print (@"font e1 before parser load : $(bf_font.ref_count)\n"); 171 172 if (((!)bf_font).get_glyph_by_name ((!) c.to_string ()) != null) 173 print (@"after parser: $(((!) ((!)bf_font).get_glyph_by_name ((!) c.to_string ())).ref_count)\n"); 174 175 bf_parser = new BirdFontFile (new Font ()); 176 print (@"font e1 after remove parser : $(bf_font.ref_count)\n"); 177 178 return bf_font; 179 } 180 181 public File get_database_file () { 182 return SearchPaths.find_file (null, "fallback-font.sqlite"); 183 } 184 185 public File get_new_database_file () { 186 string? fn = BirdFont.get_argument ("--fallback-font"); 187 188 if (fn != null && ((!) fn) != "") { 189 return File.new_for_path ((!) fn); 190 } 191 192 return File.new_for_path ("fallback-font.sqlite"); 193 } 194 195 public void generate_fallback_font () { 196 File f = get_new_database_file (); 197 string? fonts = BirdFont.get_argument ("--fonts"); 198 string fallback; 199 200 if (fonts == null) { 201 stderr.printf ("Add a list of fonts to use as fallback to the \"--fonts\" argument.\n"); 202 stderr.printf ("Separate each font file with \":\"\n"); 203 return; 204 } 205 206 fallback = (!) fonts; 207 208 stdout.printf ("Generating fallback font: %s\n", (!) f.get_path ()); 209 210 try { 211 if (f.query_exists ()) { 212 f.delete (); 213 } 214 215 open_database (f); 216 create_tables (); 217 218 foreach (string font in fallback.split (":")) { 219 add_font (font); 220 } 221 } catch (GLib.Error e) { 222 warning (e.message); 223 } 224 225 } 226 227 /* //FIXME:DELETE 228 public void add_font (string font_file) { 229 Font font; 230 Glyph g; 231 BirdFontFile bf; 232 File single_glyph_font; 233 234 font = new Font (); 235 single_glyph_font = File.new_for_path ("/tmp/fallback_glyph.bf"); 236 237 font.set_file (font_file); 238 if (!font.load ()) { 239 stderr.printf ("Failed to load font: " + font_file); 240 return; 241 } 242 243 for (int i = 0; i < font.length (); i++) { 244 g = (!) font.get_glyph_indice (i); 245 bf = new BirdFontFile (font); 246 } 247 } */ 248 249 public void open_database (File db_file) { 250 int rc = Database.open ((!) db_file.get_path (), out database); 251 252 db = (!) database; 253 254 if (rc != Sqlite.OK) { 255 stderr.printf ("Can't open database: %d, %s\n", rc, db.errmsg ()); 256 } 257 } 258 259 public void create_tables () { 260 int ec; 261 string? errmsg; 262 string create_font_table = """ 263 CREATE TABLE FallbackFont ( 264 unicode INTEGER PRIMARY KEY NOT NULL, 265 font_data TEXT NOT NULL 266 ); 267 """; 268 269 ec = db.exec (create_font_table, null, out errmsg); 270 if (ec != Sqlite.OK) { 271 warning ("Error: %s\n", (!) errmsg); 272 } 273 } 274 } 275 276 } 277