The Birdfont Source Code


All Repositories / birdfont.git / commit – RSS feed

Create SVG table in OpenType fonts

These changes was commited to the Birdfont repository Sun, 20 Dec 2015 15:08:28 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
author Johan Mattsson <johan.mattsson.m@gmail.com>
Sun, 20 Dec 2015 15:08:28 +0000 (16:08 +0100)
committer Johan Mattsson <johan.mattsson.m@gmail.com>
Sun, 20 Dec 2015 15:08:28 +0000 (16:08 +0100)
commit 78295dad93c93a63bb55269b0e3be4fa51ae9ee3
tree 9d466d006f214a2cfa604dd3c38f27932a4fdc7b
parent 109c24ef6ff8b7d692e555dd109e3dd5cc4031fb
Create SVG table in OpenType fonts

README.md
dodo.py
libbirdfont/Glyph.vala
libbirdfont/OpenFontFormat/DirectoryTable.vala
libbirdfont/OpenFontFormat/Os2Table.vala
libbirdfont/OpenFontFormat/PostTable.vala
libbirdfont/OpenFontFormat/SvgTable.vala [new ]
libbirdfont/OpenFontFormat/SvgTableEntry.vala [new ]
--- a/README.md +++ b/README.md @@ -19,15 +19,16 @@ packages with a -dev or -devel affix: valac - python3-doit font-roboto - libxmlbird-dev + python3-doit libgee-dev libglib2.0-dev libgtk-3-dev libwebkitgtk-3.0-dev libnotify-dev libsqlite3-dev + librsvg2-dev + libxmlbird-dev XML Bird is available from [birdfont.org][xmlbird].
diff --git a/dodo.py b/dodo.py
--- a/dodo.py +++ b/dodo.py @@ -78,6 +78,7 @@ --pkg webkitgtk-3.0 \ --pkg libnotify \ --pkg xmlbird \ + --pkg librsvg-2.0 \ --pkg libbirdfont """ @@ -93,6 +94,7 @@ $(pkg-config --cflags gdk-pixbuf-2.0) \ $(pkg-config --cflags webkitgtk-3.0) \ $(pkg-config --cflags libnotify) \ + $(pkg-config --cflags librsvg-2.0) \ -o OBJECT_FILE""" linker_command = config.CC + " " + config.LDFLAGS.get("birdfont", "") + """ \ @@ -107,6 +109,7 @@ $(pkg-config --libs webkitgtk-3.0) \ $(pkg-config --libs xmlbird) \ $(pkg-config --libs libnotify) \ + $(pkg-config --libs librsvg-2.0) \ -L./build -L./build/bin -l birdgems\ -o build/bin/""" + target_binary @@ -160,6 +163,7 @@ $(pkg-config --libs cairo) \ $(pkg-config --libs glib-2.0) \ $(pkg-config --libs xmlbird) \ + $(pkg-config --libs librsvg-2.0) \ -L./build -L./build/bin -l birdgems\ -o ./build/bin/""" + target_binary @@ -189,7 +193,7 @@ --pkg gio-2.0 \ --pkg cairo \ --pkg xmlbird \ - --pkg libbirdfont + --pkg libbirdfont \ """ cc_command = config.CC + " " + config.CFLAGS.get("birdfont-import", "") + """ \ @@ -213,6 +217,7 @@ $(pkg-config --libs cairo) \ $(pkg-config --libs glib-2.0) \ $(pkg-config --libs xmlbird) \ + $(pkg-config --libs librsvg-2.0) \ -L./build -L./build/bin -l birdgems\ -o ./build/bin/""" + target_binary @@ -267,6 +272,7 @@ $(pkg-config --libs cairo) \ $(pkg-config --libs glib-2.0) \ $(pkg-config --libs xmlbird) \ + $(pkg-config --libs librsvg-2.0) \ -L./build -L./build/bin -l birdgems\ -o ./build/bin/""" + target_binary @@ -302,6 +308,8 @@ --pkg xmlbird \ --pkg libbirdgems \ --pkg sqlite3 \ + --pkg gdk-pixbuf-2.0 \ + --pkg librsvg-2.0 \ """ cc_command = config.CC + " " + config.CFLAGS.get("libbirdfont", "") + """ \ @@ -317,6 +325,7 @@ $(pkg-config --cflags cairo) \ $(pkg-config --cflags glib-2.0) \ $(pkg-config --cflags xmlbird) \ + $(pkg-config --cflags librsvg-2.0) \ -o OBJECT_FILE""" linker_command = config.CC + " " + config.LDFLAGS.get("libbirdfont", "") + """ \ @@ -440,7 +449,7 @@ --pkg gio-2.0 \ --pkg cairo \ --pkg xmlbird \ - --pkg libbirdfont + --pkg libbirdfont \ """ cc_command = config.CC + " " + config.CFLAGS.get("birdfont-test", "") + """ \ @@ -463,6 +472,7 @@ $(pkg-config --libs cairo) \ $(pkg-config --libs glib-2.0) \ $(pkg-config --libs xmlbird) \ + $(pkg-config --libs librsvg-2.0) \ -L./build -L./build/bin -l birdgems\ -o build/bin/""" + target_binary
--- a/libbirdfont/Glyph.vala +++ b/libbirdfont/Glyph.vala @@ -134,17 +134,33 @@ public Gee.ArrayList<Path> active_paths = new Gee.ArrayList<Path> (); public Gee.ArrayList<Layer> selected_groups = new Gee.ArrayList<Layer> (); - // used if this glyph is fetched from a fallback font + // used if this glyph originates from a fallback font public double top_limit = 0; public double baseline = 0; public double bottom_limit = 0; public Surface? overview_thumbnail = null; + Rsvg.Handle? svg_drawing = null; + public string? 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 (); left_limit = -28; @@ -1811,7 +1827,10 @@ } draw_background_glyph (allocation, cmp); - juxtapose (allocation, cmp); + + if (svg_drawing != null) { + juxtapose (allocation, cmp); + } if (BirdFont.show_coordinates) { draw_coordinate (cmp); @@ -1823,14 +1842,19 @@ cmp.restore (); } - if (!is_empty ()) { - cmp.save (); - cmp.scale (view_zoom, view_zoom); - cmp.translate (-view_offset_x, -view_offset_y); + cmp.save (); + cmp.scale (view_zoom, view_zoom); + cmp.translate (-view_offset_x, -view_offset_y); + + if (svg_drawing != null) { + Rsvg.Handle svg_handle = (!) svg_drawing; + svg_handle.render_cairo (cmp); + } else if (!is_empty ()) { draw_path (cmp); - cmp.restore (); } - + + cmp.restore (); + cmp.save (); tool = MainWindow.get_toolbox ().get_current_tool (); tool.draw_action (tool, cmp, this);
--- a/libbirdfont/OpenFontFormat/DirectoryTable.vala +++ b/libbirdfont/OpenFontFormat/DirectoryTable.vala @@ -33,6 +33,7 @@ public Os2Table os_2_table; public PostTable post_table; public LocaTable loca_table; + public SvgTable svg_table; public OffsetTable offset_table; @@ -57,6 +58,7 @@ name_table = new NameTable (); os_2_table = new Os2Table (glyf_table, hmtx_table, hhea_table); post_table = new PostTable (glyf_table); + svg_table = new SvgTable (); id = "Directory table"; @@ -81,6 +83,7 @@ post_table.process (); kern_table.process (); gpos_table.process (glyf_table); + svg_table.process (glyf_table); offset_table.process (); process_directory (); // this table @@ -101,6 +104,10 @@ tables.add (gsub_table); tables.add (os_2_table); + + if (svg_table.has_glyphs ()) { + tables.add (svg_table); + } // tables.append (gdef_table); // invalid table
--- a/libbirdfont/OpenFontFormat/Os2Table.vala +++ b/libbirdfont/OpenFontFormat/Os2Table.vala @@ -104,7 +104,6 @@ fd.add_u32 (0); // ulUnicodeRange3 Bits 64-95 fd.add_u32 (0); // ulUnicodeRange4 Bits 96-127 } else { - warning(@"unicodeRange1: $unicodeRange1 unicodeRange2: $unicodeRange2 unicodeRange3 $unicodeRange3 unicodeRange4: $unicodeRange4"); fd.add_u32 (unicodeRange1); // ulUnicodeRange1 Bits 0-31 fd.add_u32 (unicodeRange2); // ulUnicodeRange2 Bits 32-63 fd.add_u32 (unicodeRange3); // ulUnicodeRange3 Bits 64-95
--- a/libbirdfont/OpenFontFormat/PostTable.vala +++ b/libbirdfont/OpenFontFormat/PostTable.vala @@ -1101,8 +1101,6 @@ assert (names.size == 0); add_standard_names (); - - print ("Adding post names\n"); for (int i = 1; i < glyf_table.glyphs.size; i++) { gc = glyf_table.glyphs.get (i);
--- /dev/null +++ b/libbirdfont/OpenFontFormat/SvgTable.vala @@ -1,1 +1,208 @@ + /* + Copyright (C) 2015 Johan Mattsson + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + */ + + using B; + + namespace BirdFont { + + public class SvgTable : OtfTable { + + int glyphs_in_table = 0; + Gee.ArrayList<SvgTableEntry> entries; + + public SvgTable () { + id = "SVG "; + entries = new Gee.ArrayList<SvgTableEntry> (); + } + + public bool has_glyphs () { + return glyphs_in_table > 0; + } + + public void process (GlyfTable glyf_table) throws GLib.Error { + Font font = OpenFontFormatWriter.get_current_font (); + GlyphCollection? glyph_collection; + GlyphCollection glyphs; + string? svg_data; + int gid; + + for (int index = 0; index < font.length (); index++) { + glyph_collection = font.get_glyph_collection_index (index); + + if (glyph_collection != null) { + glyphs = (!) glyph_collection; + svg_data = glyphs.get_current ().svg_data; + + if (svg_data != null) { + gid = glyf_table.get_gid (glyphs.get_name ()); + add_svg_glyph ((!) svg_data, gid); + glyphs_in_table++; + } + } + } + + process_svg_data (); + } + + void add_svg_glyph (string svg_data, int glyph_id) { + SvgTableEntry entry; + Gee.ArrayList<Tag> layer_content; + Gee.ArrayList<Tag> svg_tags; + Gee.ArrayList<Tag> meta; + XmlParser xml; + Tag svg_root_tag; + + layer_content = new Gee.ArrayList<Tag> (); + svg_tags = new Gee.ArrayList<Tag> (); + meta = new Gee.ArrayList<Tag> (); + xml = new XmlParser (svg_data); + svg_root_tag = xml.get_root_tag (); + + if (!xml.validate ()) { + warning("Invalid SVG data in TTF table."); + return; + } + + foreach (Tag tag in svg_root_tag) { + string name = tag.get_name(); + + if (name == "defs") { + svg_tags.add (tag); + } else if (name == "style") { + svg_tags.add (tag); + } else if (name == "metadata") { + meta.add (tag); + } else if (name == "sodipodi") { + meta.add (tag); + } else { + layer_content.add (tag); + } + } + + StringBuilder svg = new StringBuilder (); + svg.append ("<"); + svg.append (svg_root_tag.get_name ()); + svg.append (" "); + append_tag_attributes (svg, svg_root_tag); + svg.append (">"); + + foreach (Tag tag in svg_tags) { + append_tag (svg, tag); + } + + svg.append ("\n\n"); + svg.append ("<g id="); + svg.append ("\""); + svg.append ("glyph"); + svg.append (@"$glyph_id"); + svg.append ("\""); + svg.append (">"); + svg.append ("\n\n"); + + foreach (Tag tag in layer_content) { + append_tag (svg, tag); + } + + svg.append ("\n\n"); + svg.append ("</g>"); + svg.append ("\n\n"); + + svg.append ("</"); + svg.append (svg_root_tag.get_name ()); + svg.append (">\n"); + + entry = new SvgTableEntry ((uint16) glyph_id, svg.str); + entries.add (entry); + } + + public void append_tag (StringBuilder svg, Tag tag) { + string content = tag.get_content (); + + svg.append ("<"); + svg.append (tag.get_name ()); + + if (content == "") { + svg.append ("/"); + } + + svg.append (">"); + + if (content != "") { + svg.append (content); + svg.append ("</"); + svg.append (tag.get_name ()); + svg.append (">"); + } + } + + public void append_tag_attributes (StringBuilder svg, Tag tag) { + bool first = true; + + foreach (Attribute attribute in tag.get_attributes ()) { + string ns = attribute.get_namespace (); + + if (!first) { + svg.append (" "); + } + + if (ns != "") { + svg.append (ns); + svg.append (":"); + } + + svg.append (attribute.get_name ()); + svg.append ("="); + svg.append ("\""); + svg.append (attribute.get_content ()); + svg.append ("\""); + + first = false; + } + } + + public void process_svg_data () throws GLib.Error { + FontData fd = new FontData (); + + int32 svg_index_offset = 10; + + fd.add_ushort (0); // version + fd.add_ulong (svg_index_offset); + fd.add_ulong (0); // reserved + + uint32 document_offset = 2 + 12 * entries.size; + + // SVG Documents Index + fd.add_ushort ((uint16) entries.size); + + foreach (SvgTableEntry entry in entries) { + fd.add_ushort (entry.glyph_id); // start + fd.add_ushort (entry.glyph_id); // end + fd.add_ulong (document_offset); // offset + fd.add_ulong (entry.data.length_with_padding ()); // length + + document_offset += entry.data.length_with_padding (); + } + + foreach (SvgTableEntry entry in entries) { + fd.append (entry.data); + } + + fd.pad (); + + this.font_data = fd; + } + } + + }
--- /dev/null +++ b/libbirdfont/OpenFontFormat/SvgTableEntry.vala @@ -1,1 +1,30 @@ + /* + Copyright (C) 2015 Johan Mattsson + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + */ + + namespace BirdFont { + + public class SvgTableEntry : GLib.Object { + public FontData data; + public uint16 glyph_id; + + public SvgTableEntry (uint16 gid, string svg) { + print (svg); + glyph_id = gid; + data = new FontData (); + data.add_str (svg); + } + } + + }