The Birdfont Source Code


All Repositories / birdfont.git / commitdiff – RSS feed

Import SVG files for color fonts

These changes was commited to the Birdfont repository Sun, 20 Dec 2015 21:09:27 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
[Sun, 20 Dec 2015 21:09:27 +0000]

Updated Files

birdfont-test/TestRunner.vala
libbirdfont/Glyph.vala
libbirdfont/ImportUtils.vala
libbirdfont/Menu.vala
libbirdfont/MoveTool.vala
libbirdfont/OpenFontFormat/SvgTable.vala
libbirdfont/SvgFont.vala
libbirdfont/SvgParser.vala
resources/linux/birdfont-import.1
--- a/birdfont-test/TestRunner.vala +++ b/birdfont-test/TestRunner.vala @@ -37,7 +37,7 @@ if (type == "SVG") { File f = File.new_for_path (file); Font font = new Font (); - import_svg_file (font, f); + import_svg_file (font, f, SvgType.REGULAR); } else if (type == "BF") { Font font = new Font (); font.set_font_file (file);
--- a/libbirdfont/Glyph.vala +++ b/libbirdfont/Glyph.vala @@ -140,26 +140,37 @@ public double bottom_limit = 0; public Surface? overview_thumbnail = null; - Rsvg.Handle? svg_drawing = null; - public string? svg_data = null; + + public double svg_x = 0; + public double svg_y = 0; + private Rsvg.Handle? svg_drawing = null; + + public string? color_svg_data { + get { + return _color_svg_data; + } + + set { + try { + if (value != null) { + uint8[] svg_array = ((!) value).data; + svg_drawing = new Rsvg.Handle.from_data (svg_array); + } else { + svg_drawing = null; + } + + _color_svg_data = value; + } catch (GLib.Error e) { + warning (e.message); + } + } + } + + private string? _color_svg_data = null; public Glyph (string name, unichar unichar_code = 0) { this.name = name; this.unichar_code = unichar_code; - - try { - string data; - FileUtils.get_contents ("/home/johan/birdfont/attic/test.svg", out data); - svg_data = data; - - if (svg_data != null) { - uint8[] svg_array = ((!) svg_data).data; - svg_drawing = new Rsvg.Handle.from_data (svg_array); - // FIXME: DELETE svg_drawing = new Rsvg.Handle.from_file ("/home/johan/birdfont/attic/test.svg"); - } - } catch (GLib.Error e) { - warning (e.message); - } add_help_lines (); @@ -1842,19 +1853,21 @@ cmp.restore (); } - cmp.save (); - cmp.scale (view_zoom, view_zoom); - cmp.translate (-view_offset_x, -view_offset_y); - if (svg_drawing != null) { + cmp.save (); + cmp.scale (view_zoom, view_zoom); + cmp.translate (xc () + svg_x - view_offset_x, yc () - svg_y - view_offset_y); Rsvg.Handle svg_handle = (!) svg_drawing; svg_handle.render_cairo (cmp); - } else if (!is_empty ()) { - draw_path (cmp); + cmp.restore (); + } else { + cmp.save (); + cmp.scale (view_zoom, view_zoom); + cmp.translate (-view_offset_x, -view_offset_y); + draw_path (cmp); + cmp.restore (); } - - cmp.restore (); - + cmp.save (); tool = MainWindow.get_toolbox ().get_current_tool (); tool.draw_action (tool, cmp, this);
--- a/libbirdfont/ImportUtils.vala +++ b/libbirdfont/ImportUtils.vala @@ -34,6 +34,7 @@ BirdFont.current_font = new Font (); BirdFont.current_glyph_collection = new GlyphCollection.with_glyph ('\0', ""); MainWindow.init (); + SvgType type = SvgType.REGULAR; if (arg.length < 3) { print_import_help (arg); @@ -43,7 +44,11 @@ bf_file = build_absoulute_path (arg[1]); for (int i = 2; i < arg.length; i++) { - svg_files.add (arg[i]); + if (arg[i] == "--color") { + type = SvgType.COLOR; + } else { + svg_files.add (arg[i]); + } } bf = File.new_for_path (bf_file); @@ -79,7 +84,7 @@ foreach (string f in svg_files) { svg = File.new_for_path (f); - imported = import_svg_file (font, svg); + imported = import_svg_file (font, svg, type); if (!imported) { stdout.printf (t_("Failed to import") + " " + f + "\n"); @@ -93,7 +98,7 @@ return 0; } - public static bool import_svg_file (Font font, File svg_file) { + public static bool import_svg_file (Font font, File svg_file, SvgType type) { string file_name = (!) svg_file.get_basename (); string glyph_name; StringBuilder n; @@ -158,10 +163,14 @@ stdout.printf (@"$(glyph.version_id)"); stdout.printf ("\n"); - SvgParser.import_svg ((!) svg_file.get_path ()); + if (type == SvgType.COLOR) { + SvgParser.import_color_svg (glyph, (!) svg_file.get_path ()); + } else { + SvgParser.import_svg ((!) svg_file.get_path ()); + } return true; } }
--- a/libbirdfont/Menu.vala +++ b/libbirdfont/Menu.vala @@ -287,17 +287,35 @@ MenuItem import_svg = add_menu_item (t_("Import SVG file"), "import svg file", "Glyph"); import_svg.action.connect (() => { - SvgParser.import (); + SvgParser.import (SvgType.REGULAR); show_menu = false; }); export_menu.items.add (import_svg); - + MenuItem import_svg_folder = add_menu_item (t_("Import SVG folder"), "import svg folder", ""); import_svg_folder.action.connect (() => { - SvgParser.import_folder (); + SvgParser.import_folder (SvgType.REGULAR); show_menu = false; }); export_menu.items.add (import_svg_folder); + + MenuItem import_color_svg; + import_color_svg = add_menu_item (t_("Import SVG file") + ", " + t_("color"), + "import svg file color", "Glyph"); + import_color_svg.action.connect (() => { + SvgParser.import (SvgType.COLOR); + show_menu = false; + }); + export_menu.items.add (import_color_svg); + + MenuItem import_svg_color_folder; + import_svg_color_folder = add_menu_item (t_("Import SVG folder") + ", " + t_("color"), + "import svg folder color", ""); + import_svg_color_folder.action.connect (() => { + SvgParser.import_folder (SvgType.COLOR); + show_menu = false; + }); + export_menu.items.add (import_svg_color_folder); MenuItem import_background_image = add_menu_item (t_("Import Background Image"), "import background image"); import_background_image.action.connect (() => {
--- a/libbirdfont/MoveTool.vala +++ b/libbirdfont/MoveTool.vala @@ -123,19 +123,24 @@ delta_x = Glyph.ivz () * -dx * p; delta_y = Glyph.ivz () * dy * p; - - foreach (Layer group in glyph.selected_groups) { - if (group.gradient != null) { - Gradient g = (!) group.gradient; - g.x1 += delta_x; - g.x2 += delta_x; - g.y1 += delta_y; - g.y2 += delta_y; - } - } - foreach (Path path in glyph.active_paths) { - path.move (delta_x, delta_y); + if (glyph.color_svg_data != null) { + glyph.svg_x += delta_x; + glyph.svg_y += delta_y; + } else { + foreach (Layer group in glyph.selected_groups) { + if (group.gradient != null) { + Gradient g = (!) group.gradient; + g.x1 += delta_x; + g.x2 += delta_x; + g.y1 += delta_y; + g.y2 += delta_y; + } + } + + foreach (Path path in glyph.active_paths) { + path.move (delta_x, delta_y); + } } } @@ -197,34 +202,36 @@ glyph.store_undo_state (); group_selection = false; - group = glyph.get_path_at (x, y); - - if (group != null) { - g = (!) group; - return_if_fail (g.paths.paths.size > 0); - p = g.paths.paths.get (0); - selected = glyph.active_paths.contains (p); + if (glyph.color_svg_data == null) { + group = glyph.get_path_at (x, y); - if (!selected && !KeyBindings.has_shift ()) { + if (group != null) { + g = (!) group; + return_if_fail (g.paths.paths.size > 0); + p = g.paths.paths.get (0); + selected = glyph.active_paths.contains (p); + + if (!selected && !KeyBindings.has_shift ()) { + glyph.clear_active_paths (); + } + + foreach (Path lp in g.paths.paths) { + if (selected && KeyBindings.has_shift ()) { + glyph.selected_groups.remove ((!) group); + glyph.active_paths.remove (lp); + } else { + glyph.add_active_path ((!) group, lp); + } + } + } else if (!KeyBindings.has_shift ()) { glyph.clear_active_paths (); - } + } - foreach (Path lp in g.paths.paths) { - if (selected && KeyBindings.has_shift ()) { - glyph.selected_groups.remove ((!) group); - glyph.active_paths.remove (lp); - } else { - glyph.add_active_path ((!) group, lp); - } - } - } else if (!KeyBindings.has_shift ()) { - glyph.clear_active_paths (); + update_selection_boundaries (); } move_path = true; - - update_selection_boundaries (); - + last_x = x; last_y = y; @@ -289,14 +296,16 @@ double w = Math.fabs (selection_x - last_x); double h = Math.fabs (selection_y - last_y); - cr.save (); + Glyph glyph = MainWindow.get_current_glyph (); - Theme.color (cr, "Foreground 1"); - cr.set_line_width (2); - cr.rectangle (x, y, w, h); - cr.stroke (); - - cr.restore (); + if (glyph.color_svg_data == null) { + cr.save (); + Theme.color (cr, "Foreground 1"); + cr.set_line_width (2); + cr.rectangle (x, y, w, h); + cr.stroke (); + cr.restore (); + } } public static void get_selection_box_boundaries (out double x, out double y, out double w, out double h) {
--- a/libbirdfont/OpenFontFormat/SvgTable.vala +++ b/libbirdfont/OpenFontFormat/SvgTable.vala @@ -42,11 +42,11 @@ if (glyph_collection != null) { glyphs = (!) glyph_collection; - svg_data = glyphs.get_current ().svg_data; + svg_data = glyphs.get_current ().color_svg_data; if (svg_data != null) { gid = glyf_table.get_gid (glyphs.get_name ()); - add_svg_glyph ((!) svg_data, gid); + add_svg_glyph ((!) svg_data, gid, glyphs); glyphs_in_table++; } } @@ -55,7 +55,7 @@ process_svg_data (); } - void add_svg_glyph (string svg_data, int glyph_id) { + void add_svg_glyph (string svg_data, int glyph_id, GlyphCollection glyphs) { SvgTableEntry entry; Gee.ArrayList<Tag> layer_content; Gee.ArrayList<Tag> svg_tags; @@ -94,6 +94,7 @@ } StringBuilder svg = new StringBuilder (); + svg.append ("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); svg.append ("<"); svg.append (svg_root_tag.get_name ()); svg.append (" "); @@ -114,9 +115,12 @@ // scale the internal coordinates from 100 units per em to the // number of units per em in this font and move the glyph // in to the em box - double height = -1 * (font.top_position - font.base_line); + Glyph glyph = glyphs.get_current (); + //FIXME: DELETE double height = font.top_position - font.base_line; double scale = HeadTable.UNITS; - svg.append (@"transform=\"scale($scale) translate(0, $height)\""); + double x = glyph.svg_x - glyph.left_limit; + double y = -glyph.svg_y; + svg.append (@"transform=\"scale($scale) translate($x, $y)\""); svg.append (">"); svg.append ("\n\n");
--- a/libbirdfont/SvgFont.vala +++ b/libbirdfont/SvgFont.vala @@ -253,11 +253,6 @@ glyph.right_limit = glyph.left_limit + advance * units; // FIXME: add svg font ligatures - /* - if (ligature != "") { - glyph.set_ligature_substitution (ligature); - } - */ glyph_collection = new GlyphCollection (unicode_value, glyph_name); glyph_collection.insert_glyph (glyph, true);
--- a/libbirdfont/SvgParser.vala +++ b/libbirdfont/SvgParser.vala @@ -21,6 +21,11 @@ NONE, INKSCAPE, ILLUSTRATOR + } + + public enum SvgType { + COLOR, + REGULAR } public class SvgParser { @@ -34,7 +39,7 @@ format = f; } - public static void import () { + public static void import (SvgType type) { FileChooser fc = new FileChooser (); fc.file_selected.connect ((p) => { string path; @@ -44,14 +49,35 @@ } path = (!) p; - import_svg (path); + + if (type == SvgType.REGULAR) { + import_svg (path); + } else if (type == SvgType.COLOR) { + Glyph glyph = MainWindow.get_current_glyph (); + import_color_svg (glyph, path); + } }); fc.add_extension ("svg"); MainWindow.file_chooser (t_("Import"), fc, FileChooser.LOAD); + } + + public static void import_color_svg (Glyph glyph, string path) { + try { + string data; + FileUtils.get_contents (path, out data); + glyph.color_svg_data = data; + + if (glyph.color_svg_data != null) { + glyph.svg_x = glyph.left_limit; + glyph.svg_y = BirdFont.get_current_font ().top_position; + } + } catch (GLib.Error e) { + warning (e.message); + } } - public static void import_folder () { + public static void import_folder (SvgType type) { FileChooser fc = new FileChooser (); fc.file_selected.connect ((p) => { string path; @@ -78,7 +104,7 @@ if (file_name.has_suffix (".svg")) { svg = get_child (svg_folder, file_name); - imported = import_svg_file (font, svg); + imported = import_svg_file (font, svg, type); if (!imported) { warning ("Can't import %s.", (!) svg.get_path ());
--- a/resources/linux/birdfont-import.1 +++ b/resources/linux/birdfont-import.1 @@ -19,7 +19,12 @@ See also birdfont-export for creating SVG, EOT and TTF fonts from the birdfont file. + + .SH OPTIONS + .TP 5 + \--color + Preserve colors and create OpenType SVG table instead of using TrueType. .SH AUTHOR Johan Mattsson