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.
Load font metrix in for each fallback glyph
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 return load_glyph_from_ttf (c); 115 } 116 117 public Font load_glyph_from_ttf (unichar c) { 118 Font? bf_font; 119 File f; 120 FontFace* font; 121 122 bf_font = new Font (); 123 for (int i = fallback_fonts.size - 1; i >= 0; i--) { 124 f = fallback_fonts.get (i); 125 126 font = open_font ((!) f.get_path ()); 127 bf_font = get_glyph_in_font ((!) font, c); 128 close_font (font); 129 130 if (bf_font != null) { 131 return (!) bf_font; 132 } 133 } 134 135 return bf_font != null ? (!) bf_font : new Font (); 136 } 137 138 public Font? get_glyph_in_font (FontFace font, unichar c) { 139 StringBuilder? glyph_data = null; 140 GlyphCollection gc; 141 BirdFontFile bf_parser; 142 Font bf_font = new Font (); 143 144 gc = new GlyphCollection (c, (!)c.to_string ()); 145 glyph_data = load_glyph (font, (uint) c); 146 147 if (glyph_data == null) { 148 return null; 149 } 150 151 bf_parser = new BirdFontFile (bf_font); 152 bf_parser.load_data (((!) glyph_data).str); 153 154 return bf_font; 155 } 156 157 public File get_database_file () { 158 return SearchPaths.find_file (null, "fallback-font.sqlite"); 159 } 160 161 public File get_new_database_file () { 162 string? fn = BirdFont.get_argument ("--fallback-font"); 163 164 if (fn != null && ((!) fn) != "") { 165 return File.new_for_path ((!) fn); 166 } 167 168 return File.new_for_path ("fallback-font.sqlite"); 169 } 170 171 public void generate_fallback_font () { 172 File f = get_new_database_file (); 173 string? fonts = BirdFont.get_argument ("--fonts"); 174 string fallback; 175 176 if (fonts == null) { 177 stderr.printf ("Add a list of fonts to use as fallback to the \"--fonts\" argument.\n"); 178 stderr.printf ("Separate each font file with \":\"\n"); 179 return; 180 } 181 182 fallback = (!) fonts; 183 184 stdout.printf ("Generating fallback font: %s\n", (!) f.get_path ()); 185 186 try { 187 if (f.query_exists ()) { 188 f.delete (); 189 } 190 191 open_database (f); 192 create_tables (); 193 194 foreach (string font in fallback.split (":")) { 195 add_font (font); 196 } 197 } catch (GLib.Error e) { 198 warning (e.message); 199 } 200 201 } 202 203 /* //FIXME:DELETE 204 public void add_font (string font_file) { 205 Font font; 206 Glyph g; 207 BirdFontFile bf; 208 File single_glyph_font; 209 210 font = new Font (); 211 single_glyph_font = File.new_for_path ("/tmp/fallback_glyph.bf"); 212 213 font.set_file (font_file); 214 if (!font.load ()) { 215 stderr.printf ("Failed to load font: " + font_file); 216 return; 217 } 218 219 for (int i = 0; i < font.length (); i++) { 220 g = (!) font.get_glyph_indice (i); 221 bf = new BirdFontFile (font); 222 } 223 } */ 224 225 public void open_database (File db_file) { 226 int rc = Database.open ((!) db_file.get_path (), out database); 227 228 db = (!) database; 229 230 if (rc != Sqlite.OK) { 231 stderr.printf ("Can't open database: %d, %s\n", rc, db.errmsg ()); 232 } 233 } 234 235 public void create_tables () { 236 int ec; 237 string? errmsg; 238 string create_font_table = """ 239 CREATE TABLE FallbackFont ( 240 unicode INTEGER PRIMARY KEY NOT NULL, 241 font_data TEXT NOT NULL 242 ); 243 """; 244 245 ec = db.exec (create_font_table, null, out errmsg); 246 if (ec != Sqlite.OK) { 247 warning ("Error: %s\n", (!) errmsg); 248 } 249 } 250 } 251 252 } 253