Commit 497ef67
Generate a font from several SVG files This commit add a new command that lets you import a set of SVG files to an existing font or generate a new font from the command line.
Changed files (17)
addedbirdfont-import.shaddedbirdfont-import/BirdFontImport.valamodifieddodo.pymodifiedlibbirdfont/BirdFont.valamodifiedlibbirdfont/Font.valamodifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/GlyphCanvas.valamodifiedlibbirdfont/GlyphCollection.valamodifiedlibbirdfont/MainWindow.valamodifiedlibbirdfont/Path.valamodifiedlibbirdfont/Preview.valamodifiedlibbirdfont/VersionList.valaaddedresources/linux/birdfont-import.1modifiedscripts/bsd_build.pymodifiedscripts/build.pymodifiedscripts/linux_build.pymodifiedscripts/mac_build.py
Diff
new file mode 100755@@ -0,0 +1,6 @@+#!/bin/sh+export LD_LIBRARY_PATH="./build/:$LD_LIBRARY_PATH"+PKG_PATH=$(dirname "$(readlink -f "$0")")+cd "${PKG_PATH}"++./build/bin/birdfont-import "$@"new file mode 100644@@ -0,0 +1,24 @@+/*+ Copyright (C) 2014 Johan Mattsson++ This program is free software: you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation, either version 3 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU General Public License for more details.++ You should have received a copy of the GNU General Public License+ along with this program. If not, see <http://www.gnu.org/licenses/>.+*/++using BirdFont;++/** Import multiple SVG files to a BF file. */+public static int main (string[] arg) {+ return run_import (arg);+}+@@ -1,5 +1,5 @@ """-Copyright (C) 2012, 2013 Eduardo Naufel Schettino and Johan Mattsson+Copyright (C) 2012, 2013, 2014 Eduardo Naufel Schettino and Johan Mattsson This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -33,6 +33,7 @@ DOIT_CONFIG = { 'libbirdfont', 'birdfont', 'birdfont_export',+ 'birdfont_import', 'compile_translations', 'man' ],@@ -87,18 +88,25 @@ def task_libbirdfont(): yield libbird.gen_ln() -def task_birdfont ():+def task_birdfont(): bird = Vala(src='birdfont', build='build', pkg_libs=LIBS, vala_deps=[libbird]) yield bird.gen_c(valac_options) yield bird.gen_bin(["""-D 'GETTEXT_PACKAGE="birdfont"' """]) -def task_birdfont_export ():+def task_birdfont_export(): exp = Vala(src='birdfont-export', build='build', pkg_libs=LIBS, vala_deps=[libbird]) yield exp.gen_c(valac_options) yield exp.gen_bin(["""-D 'GETTEXT_PACKAGE="birdfont"' """]) +def task_birdfont_import():+ exp = Vala(src='birdfont-import', build='build', pkg_libs=LIBS, vala_deps=[libbird])+ yield exp.gen_c(valac_options)+ yield exp.gen_bin(["""-D 'GETTEXT_PACKAGE="birdfont"' """])+++ def task_compile_translations ():@@ -15,11 +15,167 @@ using BirdFont; public const string GETTEXT_PACKAGE = "birdfont"; namespace BirdFont {++static void print_import_help (string[] arg) {+ stdout.printf (t_("Usage:"));+ stdout.printf (arg[0]);+ stdout.printf (" " + t_("BF-FILE") + " " + t_("SVG-FILES ...") +"\n");+ stdout.printf ("\n");+}++public static int run_import (string[] arg) {+ string bf_file = "";+ Gee.ArrayList<string> svg_files = new Gee.ArrayList<string> ();+ File bf;+ File svg;+ Font font;+ bool imported;+ + Preferences.load ();+ BirdFont.args = new Argument ("");+ BirdFont.current_font = new Font ();+ BirdFont.current_glyph = new Glyph ("");+ MainWindow.init ();++ LogLevelFlags levels = LogLevelFlags.LEVEL_ERROR | LogLevelFlags.LEVEL_CRITICAL | LogLevelFlags.LEVEL_WARNING;+ Log.set_handler (null, levels, BirdFont.fatal_warning); + + if (arg.length < 3) {+ print_import_help (arg);+ return -1;+ }+ + bf_file = build_absoulute_path (arg[1]);+ + for (int i = 2; i < arg.length; i++) {+ svg_files.add (arg[i]);+ }+ + bf = File.new_for_path (bf_file);+ foreach (string f in svg_files) {+ svg = File.new_for_path (f);+ + if (!svg.query_exists ()) {+ stdout.printf (@"$f " + t_("does not exist.") + "\n");+ return -1;+ }+ }+ + font = BirdFont.get_current_font ();++ if (!bf.query_exists ()) {+ stdout.printf (@"$bf_file " + t_("does not exist.") + " ");+ stdout.printf (t_("A new font will be created.") + "\n");+ font.set_file (bf_file);+ } else {+ font.set_file (bf_file);+ if (!font.load ()) {+ warning (@"Failed to load font $bf_file.\n");+ + if (!bf_file.has_suffix (".bf")) {+ warning (@"Is it a .bf file?\n");+ }+ + return -1;+ }+ }++ font.save_backup ();++ foreach (string f in svg_files) {+ svg = File.new_for_path (f);+ imported = import_svg_file (font, svg);+ + if (!imported) {+ stdout.printf (t_("Failed to import") + " " + f + "\n");+ stdout.printf (t_("Aborting") + "\n");+ return -1;+ }+ }+ + font.save_bf ();+ + return 0;+}++internal static string build_absoulute_path (string file_name) {+ File f = File.new_for_path (file_name);+ return (!) f.get_path ();+}++static bool import_svg_file (Font font, File svg_file) {+ string file_name = (!) svg_file.get_basename ();+ string glyph_name;+ StringBuilder n;+ Glyph glyph;+ GlyphCollection? gc = null;+ GlyphCollection glyph_collection;+ unichar character;+ GlyphCanvas canvas;+ + glyph_name = file_name.replace (".svg", "");+ glyph_name = glyph_name.replace (".SVG", "");+ + if (glyph_name.char_count () > 1) {+ if (glyph_name.has_prefix ("U+")) {+ n = new StringBuilder ();+ n.append_unichar (Font.to_unichar (glyph_name));+ gc = font.get_glyph_collection (n.str);+ } else {+ gc = font.get_glyph_collection_by_name (glyph_name);+ + if (gc == null) {+ stdout.printf (file_name + " " + t_("is not the name of a glyph or a unicode value.") + "\n");+ stdout.printf (t_("Unicode values must start with U+.") + "\n");+ return false;+ }+ } + } else {+ gc = font.get_glyph_collection (glyph_name);+ }++ if (gc != null) {+ glyph_collection = (!) gc;+ character = glyph_collection.get_unicode_character ();+ glyph = new Glyph (glyph_collection.get_name (), character);+ glyph.version_id = glyph_collection.get_last_id () + 1;+ glyph_collection.insert_glyph (glyph, true);+ } else {+ return_val_if_fail (glyph_name.char_count () == 1, false);+ character = glyph_name.get_char (0);+ glyph_collection = new GlyphCollection (character, glyph_name);+ glyph = new Glyph (glyph_name, character);+ glyph_collection.insert_glyph (glyph, true);+ font.add_glyph_collection (glyph_collection);+ }++ canvas = MainWindow.get_glyph_canvas ();+ canvas.set_current_glyph (glyph);++ stdout.printf (t_("Adding"));+ stdout.printf (" ");+ stdout.printf ((!) svg_file.get_basename ());+ stdout.printf (" ");+ stdout.printf (t_("to"));+ stdout.printf (" ");+ stdout.printf (t_("Glyph"));+ stdout.printf (": ");+ stdout.printf (glyph.get_name ());+ stdout.printf (" ");+ stdout.printf (t_("Version"));+ stdout.printf (": ");+ stdout.printf (@"$(glyph.version_id)");+ stdout.printf ("\n"); + SvgParser.import_svg ((!) svg_file.get_path ());+ + return true;+}+ static void print_export_help (string[] arg) { stdout.printf (t_("Usage:")); stdout.printf (arg[0]);- stdout.printf (" [OPTION ...] FILE\n");+ stdout.printf (" [" + t_("OPTION") + "...] " + t_("FILE") +"\n"); stdout.printf ("-h, --help " + t_("print this message\n")); stdout.printf ("-o, --output [DIRECTORY] " + t_("write files to this directory\n")); stdout.printf ("-s, --svg " + t_("write svg file\n"));@@ -154,16 +154,24 @@ public class Font : GLib.Object { /** Full path to this font file. */ public string get_path () { int i = 0;+ string fn;+ File f; if (font_file != null) {- return (!) font_file;+ fn = (!) font_file;+ + if (fn.index_of ("/") == -1 && fn.index_of ("\\") == -1) {+ warning ("Relative path.");+ }+ + return fn; } StringBuilder sb = new StringBuilder (); sb.append (Environment.get_home_dir ()); sb.append (@"/$(get_name ()).bf"); - File f = File.new_for_path (sb.str);+ f = File.new_for_path (sb.str); while (f.query_exists ()) { sb.erase ();@@ -196,6 +204,10 @@ public class Font : GLib.Object { i = p.last_index_of ("\\"); } + if (i == -1) {+ warning (@"Can not find folder in $p.");+ }+ p = p.substring (0, i); return File.new_for_path (p);@@ -352,7 +352,10 @@ public class Glyph : FontDisplay { add_help_lines (); KeyBindings.set_require_modifier (false); glyph_sequence = Preferences.get ("glyph_sequence");- MainWindow.native_window.set_scrollbar_size (0);+ + if (!is_null (MainWindow.native_window)) {+ MainWindow.native_window.set_scrollbar_size (0);+ } } private void remove_lines () {@@ -57,10 +57,6 @@ public class GlyphCanvas : GLib.Object { BirdFont.current_glyph = g; BirdFont.current_glyph.resized (allocation); - - if (g.allocation.width == 0 || g.allocation.height == 0) { - warning ("area is zero in glyph canvas"); - } } current_display = fd; @@ -72,8 +68,10 @@ public class GlyphCanvas : GLib.Object { }); redraw (); - - MainWindow.native_window.update_window_size (); + + if (!is_null (MainWindow.native_window)) { + MainWindow.native_window.update_window_size (); + } } public static Glyph get_current_glyph () { @@ -50,7 +50,11 @@ public class GlyphCollection : GLib.Object { unicode.append_unichar (unicode_character); return unicode.str; }- ++ public unichar get_unicode_character () {+ return unicode_character;+ }+ public string get_name () { return name; }@@ -59,6 +63,10 @@ public class GlyphCollection : GLib.Object { return versions.get_current ().version_id; } + public int get_last_id () {+ return versions.get_last_id ();+ }+ public void set_selected_version (int version_id) { versions.set_selected_version (version_id); }@@ -43,6 +43,10 @@ public class MainWindow : GLib.Object { character_database = new CharDatabase (); ligature_display = new LigatureList (); } + + public static void init () { + singleton = new MainWindow (); + } public static FileTab get_recent_files_tab () { return file_tab;@@ -1168,7 +1168,6 @@ public class Path { private void add_quadratic_points (EditPoint start, EditPoint stop) { int steps;- EditPoint prev = new EditPoint (); int added_points = 0; if (points.size < 2) {@@ -158,6 +158,7 @@ public class Preview : FontDisplay { warning (e.message); warning ("Failed to load html into canvas."); sb.append (@"Error: $(e.message)<br>\n");+ sb.append (@"($((!) get_file ().get_path ()))<br>\n"); } return sb.str; }@@ -121,7 +121,7 @@ public class VersionList : DropMenu { add_glyph (new_version); } - private int get_last_id () {+ public int get_last_id () { return_val_if_fail (glyphs.size > 0, 1); return glyphs.get (glyphs.size - 1).version_id; }new file mode 100644@@ -0,0 +1,19 @@+.TH BIRDFONT-IMPORT 1 LOCAL++.SH NAME+birdfont-import - Add several SVG files to a font file+.SH SYNOPSIS+.B birdfont-import birdfont-file svg-files ...+.SH DESCRIPTION+birdfont-import +birdfont-import will generate a birdfont file from a set of SVG images. +The command assumes that the file name denotes either a single character+or a Unicode value on the form U+XX where XX is the Unicode number in+hexadecimal format.++See also birdfont-export for creating SVG, EOT and TTF fonts from the+birdfont file.++See http://birdfont.org for use cases.+.SH AUTHOR+Johan Mattsson@@ -33,6 +33,7 @@ configfile.write_config (prefix) compile_translations() build.libbirdfont(prefix, cc, cflags, library_ldflags, valac, valaflags, library) build.birdfont_export(prefix, cc, cflags, ldflags, valac, valaflags, library)+build.birdfont_import(prefix, cc, cflags, ldflags, valac, valaflags, library) build.birdfont_gtk(prefix, cc, cflags, ldflags, valac, valaflags, library) print ("Done")@@ -161,7 +161,54 @@ def birdfont_export(prefix, cc, cflags, ldflags, valac, valaflags, library, nonN run("touch build/installed") run("touch build/configured")- ++def birdfont_import(prefix, cc, cflags, ldflags, valac, valaflags, library, nonNull = True):+ # birdfont-import+ run("mkdir -p build/birdfont-import")++ experimentalNonNull = ""+ if nonNull:+ experimentalNonNull = "--enable-experimental-non-null"+ + run(valac + """ \+ -C \+ """ + experimentalNonNull + """ \+ --enable-experimental \+ --define=MAC birdfont-import/* \+ --vapidir=./ \+ --pkg """ + config.GEE + """ \+ --pkg libxml-2.0 \+ --pkg gio-2.0 \+ --pkg cairo \+ --pkg gdk-pixbuf-2.0 \+ --pkg gtk+-2.0 \+ --pkg libbirdfont""")+ run("mv birdfont-import/*.c build/birdfont-import/")++ run(cc + " " + cflags + """ \+ -c ./build/libbirdfont/birdfont.h build/birdfont-import/*.c \+ -D 'GETTEXT_PACKAGE="birdfont"' \+ $(pkg-config --cflags """ + config.GEE + """) \+ $(pkg-config --cflags libxml-2.0) \+ $(pkg-config --cflags gio-2.0) \+ $(pkg-config --cflags cairo) \+ $(pkg-config --cflags glib-2.0) \+ $(pkg-config --cflags gdk-pixbuf-2.0) \+ -I ./build/libbirdfont/""")+ run("mv ./*.o build/birdfont-import/")++ run(cc + " " + ldflags + " \+ build/birdfont-export/*.o \+ -Lbuild/bin/ -lbirdfont \+ -lm \+ $(pkg-config --libs """ + config.GEE + """) \+ $(pkg-config --libs libxml-2.0) \+ $(pkg-config --libs gio-2.0) \+ $(pkg-config --libs cairo) \+ $(pkg-config --libs glib-2.0) \+ $(pkg-config --libs gdk-pixbuf-2.0) \+ -o ./build/bin/birdfont-import""")+ def birdfont_gtk(prefix, cc, cflags, ldflags, valac, valaflags, library, nonNull = True): # birdfont run("mkdir -p build/birdfont")@@ -55,6 +55,7 @@ configfile.write_config (prefix) compile_translations() build.libbirdfont(prefix, cc, cflags, library_ldflags, valac, valaflags, library, False) build.birdfont_export(prefix, cc, cflags, ldflags, valac, valaflags, library, False)+build.birdfont_import(prefix, cc, cflags, ldflags, valac, valaflags, library, False) build.birdfont_gtk(prefix, cc, cflags, ldflags, valac, valaflags, library, False) print ("Done")@@ -57,6 +57,7 @@ configfile.write_config (prefix) compile_translations() build.libbirdfont(prefix, cc, library_cflags, library_ldflags, valac, valaflags, library, False) build.birdfont_export(prefix, cc, cflags, ldflags, valac, valaflags, library, False)+build.birdfont_import(prefix, cc, cflags, ldflags, valac, valaflags, library, False) if not options.nogtk: build.birdfont_gtk(prefix, cc, cflags, ldflags, valac, valaflags, library, False)