The Birdfont Source Code


All Repositories / birdfont.git / commitdiff – RSS feed

Embed SVG files in BF fonts

These changes was commited to the Birdfont repository Sat, 09 Jan 2016 21:51:37 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
[Sat, 09 Jan 2016 21:51:37 +0000]

Updated Files

README.md
dodo.py
libbirdfont/BirdFontFile.vala
libbirdfont/EmbeddedSvg.vala
libbirdfont/Glyph.vala
libbirdfont/MoveTool.vala
libbirdfont/OpenFontFormat/SvgTable.vala
libbirdfont/OverViewItem.vala
libbirdfont/PathObject.vala
libbirdfont/Svg/Defs.vala
libbirdfont/Svg/Object.vala
libbirdfont/Svg/Rectangle.vala
libbirdfont/Svg/SvgDrawing.vala
libbirdfont/Svg/SvgFile.vala
libbirdfont/Svg/SvgParser.vala
libbirdfont/Svg/SvgPath.vala
--- a/README.md +++ b/README.md @@ -27,7 +27,6 @@ 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,7 +78,6 @@ --pkg webkitgtk-3.0 \ --pkg libnotify \ --pkg xmlbird \ - --pkg librsvg-2.0 \ --pkg libbirdfont """ @@ -94,7 +93,6 @@ $(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", "") + """ \ @@ -109,7 +107,6 @@ $(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 @@ -163,7 +160,6 @@ $(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 @@ -217,7 +213,6 @@ $(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 @@ -272,7 +267,6 @@ $(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 @@ -311,7 +305,6 @@ --pkg libbirdgems \ --pkg sqlite3 \ --pkg gdk-pixbuf-2.0 \ - --pkg librsvg-2.0 \ """ cc_command = config.CC + " " + config.CFLAGS.get("libbirdfont", "") + """ \ @@ -327,7 +320,6 @@ $(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", "") + """ \ @@ -474,7 +466,6 @@ $(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/BirdFontFile.vala +++ b/libbirdfont/BirdFontFile.vala @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 2014 2015 Johan Mattsson + Copyright (C) 2013 2014 2015 2016 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 @@ -435,49 +435,44 @@ foreach (Layer layer in g.layers.subgroups) { write_layer (layer, os); } - - write_embedded_svg (g, os); write_glyph_background (g, os); os.put_string ("\t</glyph>\n"); } - void write_embedded_svg (Glyph g, DataOutputStream os) throws GLib.Error { + void write_embedded_svg (EmbeddedSvg svg, DataOutputStream os) throws GLib.Error { + XmlParser xml = new XmlParser ((!) svg.svg_data); - if (g.color_svg_data != null) { - XmlParser xml = new XmlParser ((!) g.color_svg_data); + if (xml.validate ()) { + os.put_string (@"<embedded "); + os.put_string (@"type=\"svg\" "); + os.put_string (@"x=\"$(round (svg.x))\""); + os.put_string (@"y=\"$(round (svg.y))\""); + os.put_string (@">\n"); - if (xml.validate ()) { - os.put_string (@"<embedded "); - os.put_string (@"type=\"svg\" "); - os.put_string (@"x=\"$(round (g.svg_x))\""); - os.put_string (@"y=\"$(round (g.svg_y))\""); - os.put_string (@">\n"); - - Tag tag = xml.get_root_tag (); - - os.put_string ("<"); - os.put_string (tag.get_name ()); - - os.put_string (" "); - write_tag_attributes (os, tag); - - string content = tag.get_content (); - - if (content == "") { - os.put_string (" /"); - } - - os.put_string (">"); - - os.put_string (content); - - os.put_string ("</"); - os.put_string (tag.get_name ()); - os.put_string (">\n"); - - os.put_string ("</embedded>"); + Tag tag = xml.get_root_tag (); + + os.put_string ("<"); + os.put_string (tag.get_name ()); + + os.put_string (" "); + write_tag_attributes (os, tag); + + string content = tag.get_content (); + + if (content == "") { + os.put_string (" /"); } + + os.put_string (">"); + + os.put_string (content); + + os.put_string ("</"); + os.put_string (tag.get_name ()); + os.put_string (">\n"); + + os.put_string ("</embedded>\n"); } } @@ -507,37 +502,48 @@ } void write_layer (Layer layer, DataOutputStream os) throws GLib.Error { - string data; - - // FIXME: name etc. os.put_string (@"\t\t<layer name= \"$(layer.name)\" visible=\"$(layer.visible)\">\n"); - foreach (Path p in layer.get_all_paths ().paths) { - data = get_point_data (p); - if (data != "") { - os.put_string (@"\t\t\t<path "); - - if (p.stroke != 0) { - os.put_string (@"stroke=\"$(double_to_string (p.stroke))\" "); - } - - if (p.line_cap != LineCap.BUTT) { - if (p.line_cap == LineCap.ROUND) { - os.put_string (@"cap=\"round\" "); - } else if (p.line_cap == LineCap.SQUARE) { - os.put_string (@"cap=\"square\" "); - } - } - - if (p.skew != 0) { - os.put_string (@"skew=\"$(double_to_string (p.skew))\" "); - } - - os.put_string (@"data=\"$(data)\" />\n"); + foreach (Object o in layer.get_all_objects ().objects) { + + if (o is EmbeddedSvg) { + write_embedded_svg ((EmbeddedSvg) o, os); } + + if (o is PathObject) { + Path p = ((PathObject) o).get_path (); + write_path_object (p, os); + } } os.put_string ("\t\t</layer>\n"); + } + + void write_path_object (Path p, DataOutputStream os) throws GLib.Error { + string data; + + data = get_point_data (p); + if (data != "") { + os.put_string (@"\t\t\t<path "); + + if (p.stroke != 0) { + os.put_string (@"stroke=\"$(double_to_string (p.stroke))\" "); + } + + if (p.line_cap != LineCap.BUTT) { + if (p.line_cap == LineCap.ROUND) { + os.put_string (@"cap=\"round\" "); + } else if (p.line_cap == LineCap.SQUARE) { + os.put_string (@"cap=\"square\" "); + } + } + + if (p.skew != 0) { + os.put_string (@"skew=\"$(double_to_string (p.skew))\" "); + } + + os.put_string (@"data=\"$(data)\" />\n"); + } } public static string double_to_string (double n) { @@ -1447,11 +1453,7 @@ foreach (Tag t in tag) { if (t.get_name () == "background") { parse_background_scale (glyph, t); - } - - if (t.get_name () == "embedded") { - parse_embedded_svg (glyph, t); - } + } } foreach (Path p in glyph.get_all_paths ()) { @@ -1464,10 +1466,11 @@ master.insert_glyph (glyph, selected || selected_id == id); } - void parse_embedded_svg (Glyph glyph, Tag tag) { + void parse_embedded_svg (Layer layer, Tag tag) { string type = ""; double x = 0; double y = 0; + EmbeddedSvg svg; foreach (Attribute attribute in tag.get_attributes ()) { if (attribute.get_name () == "x") { @@ -1484,9 +1487,9 @@ } if (type == "svg") { - glyph.svg_x = x; - glyph.svg_y = y; - glyph.color_svg_data = tag.get_content (); + SvgFile svg_file = new SvgFile (); + svg = svg_file.parse_data (tag.get_content ()); + layer.add_object (svg); } } @@ -1508,6 +1511,10 @@ if (t.get_name () == "path") { path = parse_path (t); layer.add_path (path); + } + + if (t.get_name () == "embedded") { + parse_embedded_svg (layer, t); } } @@ -1542,7 +1549,7 @@ } } - return path; + return path; } private static void line (Path path, string px, string py) {
--- /dev/null +++ b/libbirdfont/EmbeddedSvg.vala @@ -1,1 +1,129 @@ + /* + Copyright (C) 2016 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; + using Math; + using Cairo; + + namespace BirdFont { + + public class EmbeddedSvg : Object { + public string svg_data = ""; + public SvgDrawing drawing = new SvgDrawing (); + + public double x { + get { + return drawing.x; + } + + set { + drawing.x = value; + } + } + + public double y { + get { + return drawing.y; + } + + set { + drawing.y = value; + } + } + + // FIXME: boundaries for embedded SVG + + public override double xmin { + get { + Glyph g = MainWindow.get_current_glyph (); + return g.left_limit; + } + + set { + } + } + + public override double xmax { + get { + Glyph g = MainWindow.get_current_glyph (); + return g.right_limit; + } + + set { + } + } + + + public override double ymin { + get { + Font font = BirdFont.get_current_font (); + return font.bottom_position; + } + + set { + } + } + + public override double ymax { + get { + Font font = BirdFont.get_current_font (); + return font.top_position; + } + + set { + } + } + + public EmbeddedSvg (SvgDrawing drawing) { + this.drawing = drawing; + } + + public override void update_region_boundaries () { + drawing.update_region_boundaries (); + } + + public override bool is_over (double x, double y) { + return drawing.is_over (x, y); + } + + public override void draw (Context cr) { + drawing.draw (cr); + } + + public override Object copy () { + EmbeddedSvg svg = new EmbeddedSvg (drawing); + svg.svg_data = svg_data; + return svg; + } + + public override void move (double dx, double dy) { + drawing.move (dx, dy); + } + + public override void rotate (double theta, double xc, double yc) { + drawing.rotate (theta, xc, yc); + } + + public override bool is_empty () { + return drawing.is_empty (); + } + + public override void resize (double ratio_x, double ratio_y) { + drawing.resize (ratio_x, ratio_y); + } + + } + + }
--- a/libbirdfont/Glyph.vala +++ b/libbirdfont/Glyph.vala @@ -141,40 +141,6 @@ public double bottom_limit = 0; public Surface? overview_thumbnail = 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) { - XmlParser xml = new XmlParser ((!) value); - - if (!xml.validate ()) { - warning("Invalid SVG data, skipping import."); - return; - } - - 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; @@ -1713,7 +1679,11 @@ cr.new_path (); foreach (Object o in get_visible_objects ()) { - o.draw (cr, c); + if (o is PathObject) { + ((PathObject) o).draw_path (cr, c); + } else { + o.draw (cr); + } } cr.fill (); @@ -1891,10 +1861,8 @@ } draw_background_glyph (allocation, cmp); - - if (svg_drawing != null) { - juxtapose (allocation, cmp); - } + + juxtapose (allocation, cmp); if (BirdFont.show_coordinates) { draw_coordinate (cmp); @@ -1906,19 +1874,11 @@ cmp.restore (); } - if (svg_drawing != null) { - cmp.save (); - cmp.scale (view_zoom, view_zoom); - cmp.translate (-view_offset_x, -view_offset_y); - draw_svg (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.save (); + cmp.scale (view_zoom, view_zoom); + cmp.translate (-view_offset_x, -view_offset_y); + draw_path (cmp); + cmp.restore (); cmp.save (); tool = MainWindow.get_toolbox ().get_current_tool (); @@ -1926,16 +1886,6 @@ cmp.restore (); } - public void draw_svg (Context cr) { - if (svg_drawing != null) { - cr.save (); - cr.translate (xc () + svg_x, yc () - svg_y); - Rsvg.Handle svg_handle = (!) svg_drawing; - svg_handle.render_cairo (cr); - cr.restore (); - } - } - private void zoom_in_at_point (double x, double y, double amount = 15) { int n = (int) (-amount); zoom_at_point (x, y, n);
--- a/libbirdfont/MoveTool.vala +++ b/libbirdfont/MoveTool.vala @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 2013 2015 Johan Mattsson + Copyright (C) 2012 2013 2015 2016 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 @@ -127,24 +127,19 @@ delta_x = -dx; delta_y = -dy; - - 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 (Object object in glyph.active_paths) { - object.move (delta_x, delta_y); + + 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 (Object object in glyph.active_paths) { + object.move (delta_x, delta_y); } } @@ -208,35 +203,33 @@ glyph.store_undo_state (); group_selection = false; + + group = glyph.get_path_at (x, y); - if (glyph.color_svg_data == null) { - group = glyph.get_path_at (x, y); + if (group != null) { + g = (!) group; + return_if_fail (g.objects.objects.size > 0); + object = g.objects.objects.get (0); + selected = glyph.active_paths_contains (object); - if (group != null) { - g = (!) group; - return_if_fail (g.objects.objects.size > 0); - object = g.objects.objects.get (0); - selected = glyph.active_paths_contains (object); - - if (!selected && !KeyBindings.has_shift ()) { - glyph.clear_active_paths (); - } - - foreach (Object lp in g.objects) { - if (selected && KeyBindings.has_shift ()) { - glyph.selected_groups.remove ((!) group); - glyph.active_paths.remove (lp); - } else { - glyph.add_active_object ((!) group, lp); - } - } - } else if (!KeyBindings.has_shift ()) { + if (!selected && !KeyBindings.has_shift ()) { glyph.clear_active_paths (); - } + } - update_selection_boundaries (); + foreach (Object lp in g.objects) { + if (selected && KeyBindings.has_shift ()) { + glyph.selected_groups.remove ((!) group); + glyph.active_paths.remove (lp); + } else { + glyph.add_active_object ((!) group, lp); + } + } + } else if (!KeyBindings.has_shift ()) { + glyph.clear_active_paths (); } + update_selection_boundaries (); + move_path = true; last_x = x; @@ -293,25 +286,6 @@ update_selection_boundaries (); objects_moved (); GlyphCanvas.redraw (); - } - - static void draw_selection_box (Context cr) { - double x = Math.fmin (selection_x, last_x); - double y = Math.fmin (selection_y, last_y); - - double w = Math.fabs (selection_x - last_x); - double h = Math.fabs (selection_y - last_y); - - Glyph glyph = MainWindow.get_current_glyph (); - - 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) { @@ -525,8 +499,25 @@ update_selection_boundaries (); objects_moved (); + } + + static void draw_selection_box (Context cr) { + double x = Math.fmin (selection_x, last_x); + double y = Math.fmin (selection_y, last_y); + + double w = Math.fabs (selection_x - last_x); + double h = Math.fabs (selection_y - last_y); + + Glyph glyph = MainWindow.get_current_glyph (); + + cr.save (); + Theme.color (cr, "Foreground 1"); + cr.set_line_width (2); + cr.rectangle (x, y, w, h); + cr.stroke (); + cr.restore (); } } }
--- a/libbirdfont/OpenFontFormat/SvgTable.vala +++ b/libbirdfont/OpenFontFormat/SvgTable.vala @@ -36,17 +36,53 @@ GlyphCollection glyphs; string? svg_data; int gid; + Gee.ArrayList<EmbeddedSvg> embedded_svg; 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 ().color_svg_data; + embedded_svg = get_embedded_svg (glyphs); - if (svg_data != null) { + if (embedded_svg.size > 0) { gid = glyf_table.get_gid (glyphs.get_name ()); - add_svg_glyph ((!) svg_data, gid, glyphs); + + StringBuilder svg = new StringBuilder (); + svg.append ("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); + + foreach (EmbeddedSvg embedded in embedded_svg) { + svg.append ("<svg>"); + svg.append ("\n\n"); + svg.append ("<g id="); + svg.append ("\""); + svg.append ("glyph"); + svg.append (@"$gid"); + svg.append ("\" "); + + // 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 + Glyph glyph = glyphs.get_current (); + double scale = HeadTable.UNITS; + double x = embedded.x - glyph.left_limit; + double y = font.base_line - embedded.y; + svg.append (@"transform=\"scale($scale) translate($x, $y)\""); + + svg.append (">"); + svg.append ("\n\n"); + + append_svg_glyph (svg, embedded.svg_data, glyphs); + + svg.append ("\n\n"); + svg.append ("</g>\n"); + svg.append ("</svg>"); + } + + SvgTableEntry entry; + entry = new SvgTableEntry ((uint16) gid, svg.str); + entries.add (entry); + glyphs_in_table++; } } @@ -55,8 +91,19 @@ process_svg_data (); } - void add_svg_glyph (string svg_data, int glyph_id, GlyphCollection glyphs) { - SvgTableEntry entry; + Gee.ArrayList<EmbeddedSvg> get_embedded_svg (GlyphCollection glyphs) { + Gee.ArrayList<EmbeddedSvg> svg = new Gee.ArrayList<EmbeddedSvg> (); + + foreach (Object object in glyphs.get_current ().get_visible_objects ()) { + if (object is EmbeddedSvg) { + svg.add ((EmbeddedSvg) object); + } + } + + return svg; + } + + void append_svg_glyph (StringBuilder svg, string svg_data, GlyphCollection glyphs) { Gee.ArrayList<Tag> layer_content; Gee.ArrayList<Tag> svg_tags; Gee.ArrayList<Tag> meta; @@ -94,8 +141,6 @@ } } - 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 (" "); @@ -105,40 +150,14 @@ 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 ("\" "); - - // 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 - Glyph glyph = glyphs.get_current (); - double scale = HeadTable.UNITS; - double x = glyph.svg_x - glyph.left_limit; - double y = font.base_line - glyph.svg_y; - svg.append (@"transform=\"scale($scale) translate($x, $y)\""); - - 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); + svg.append (">\n"); } public void append_tag (StringBuilder svg, Tag tag) {
--- a/libbirdfont/OverViewItem.vala +++ b/libbirdfont/OverViewItem.vala @@ -127,31 +127,18 @@ c.save (); g.boundaries (out x1, out y1, out x2, out y2); - if (g.color_svg_data != null) { - font = BirdFont.get_current_font (); - glyph_width = g.right_limit - g.left_limit; - glyph_height = font.top_position - font.bottom_position; - } else { - glyph_width = x2 - x1; - glyph_height = y2 - y1; - } + glyph_width = x2 - x1; + glyph_height = y2 - y1; c.save (); c.scale (glyph_scale * Screen.get_scale (), glyph_scale * Screen.get_scale ()); g.add_help_lines (); - if (g.color_svg_data != null) { - gx = 10; - gy = (h / glyph_scale) - 25 / glyph_scale; - c.translate (gx - Glyph.xc () - g.get_lsb (), g.get_baseline () + gy - Glyph.yc ()); - g.draw_svg (c); - } else { - gx = ((w / glyph_scale) - glyph_width) / 2 - g.get_left_side_bearing (); - gy = (h / glyph_scale) - 25 / glyph_scale; - c.translate (gx - Glyph.xc () - g.get_lsb (), g.get_baseline () + gy - Glyph.yc ()); - g.draw_paths (c, color); - } + gx = ((w / glyph_scale) - glyph_width) / 2 - g.get_left_side_bearing (); + gy = (h / glyph_scale) - 25 / glyph_scale; + c.translate (gx - Glyph.xc () - g.get_lsb (), g.get_baseline () + gy - Glyph.yc ()); + g.draw_paths (c, color); c.restore ();
--- a/libbirdfont/PathObject.vala +++ b/libbirdfont/PathObject.vala @@ -155,8 +155,12 @@ public override bool is_over (double x, double y) { return path.is_over (x, y); } - - public override void draw (Context cr, Color? c = null) { + + public override void draw (Context cr) { + draw_path (cr); + } + + public void draw_path (Context cr, Color? c = null) { PathList path_stroke; Color path_color; bool open;
--- a/libbirdfont/Svg/Defs.vala +++ b/libbirdfont/Svg/Defs.vala @@ -80,7 +80,18 @@ return ((!) attribute).has_prefix ("url"); } + + public Defs copy () { + Defs d = new Defs (); + + foreach (Gradient g in gradients) { + d.add (g); + } + + return d; + } + } }
--- a/libbirdfont/Svg/Object.vala +++ b/libbirdfont/Svg/Object.vala @@ -56,7 +56,7 @@ public abstract void update_region_boundaries (); public abstract bool is_over (double x, double y); - public abstract void draw (Context cr, Color? c = null); + public abstract void draw (Context cr); public abstract Object copy (); public abstract void move (double dx, double dy); public abstract void rotate (double theta, double xc, double yc); @@ -126,11 +126,7 @@ if (gradient != null) { g = (!) gradient; - pattern = new Cairo.Pattern.linear ( - g.x1, - g.y1, - g.x2, - g.y2); + pattern = new Cairo.Pattern.linear (g.x1, g.y1, g.x2, g.y2); Matrix gradient_matrix = g.get_matrix (); gradient_matrix.invert ();
--- a/libbirdfont/Svg/Rectangle.vala +++ b/libbirdfont/Svg/Rectangle.vala @@ -33,7 +33,7 @@ return false; } - public override void draw (Context cr, Color? c = null) { + public override void draw (Context cr) { cr.save (); apply_transform (cr);
--- a/libbirdfont/Svg/SvgDrawing.vala +++ b/libbirdfont/Svg/SvgDrawing.vala @@ -11,16 +11,59 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ + using B; + using Cairo; using Math; namespace BirdFont { - public class SvgDrawing { + public class SvgDrawing : Object { public Layer root_layer = new Layer (); public Defs defs = new Defs (); + + public double x = 0; + public double y = 0; + public double width = 0; + public double height = 0; + + public override void update_region_boundaries () { + } + + public override bool is_over (double x, double y) { + return (this.x <= x <= this.x + width) + && (this.y <= y <= this.y + height); + } + + public override void draw (Context cr) { + foreach (Object o in root_layer.get_visible_objects ().objects) { + o.draw (cr); + } + } + + public override Object copy () { + SvgDrawing drawing = new SvgDrawing (); + drawing.root_layer = root_layer.copy (); + drawing.defs = defs.copy (); + return drawing; + } + + public override void move (double dx, double dy) { + x += dx; + y += dy; + } + + public override void rotate (double theta, double xc, double yc) { + } + + public override bool is_empty () { + return false; + } + + public override void resize (double ratio_x, double ratio_y) { + } } }
--- a/libbirdfont/Svg/SvgFile.vala +++ b/libbirdfont/Svg/SvgFile.vala @@ -13,6 +13,7 @@ */ using B; + using Cairo; namespace BirdFont { @@ -23,29 +24,50 @@ public SvgFile () { } - public SvgDrawing parse (string path) { + public EmbeddedSvg parse (string path) { string xml_data; try { FileUtils.get_contents (path, out xml_data); - XmlParser xmlparser = new XmlParser (xml_data); - - if (xmlparser.validate ()) { - Tag root = xmlparser.get_root_tag (); - return parse_svg_file (root); - } else { - warning ("Invalid xml file."); - } + return parse_data (xml_data); } catch (GLib.Error error) { warning (error.message); } - return new SvgDrawing (); + SvgDrawing drawing = new SvgDrawing (); + return new EmbeddedSvg (drawing); + } + + public EmbeddedSvg parse_data (string xml_data) { + XmlParser xmlparser = new XmlParser (xml_data); + SvgDrawing drawing = new SvgDrawing (); + + if (xmlparser.validate ()) { + Tag root = xmlparser.get_root_tag (); + drawing = parse_svg_file (root); + EmbeddedSvg svg = new EmbeddedSvg (drawing); + svg.svg_data = xml_data; + return svg; + } else { + warning ("Invalid xml file."); + } + + return new EmbeddedSvg (drawing); } private SvgDrawing parse_svg_file (Tag tag) { drawing = new SvgDrawing (); - + + foreach (Attribute attr in tag.get_attributes ()) { + if (attr.get_name () == "width") { + drawing.width = parse_number (attr.get_content ()); + } + + if (attr.get_name () == "height") { + drawing.height = parse_number (attr.get_content ()); + } + } + foreach (Tag t in tag) { string name = t.get_name ();
--- a/libbirdfont/Svg/SvgParser.vala +++ b/libbirdfont/Svg/SvgParser.vala @@ -64,8 +64,15 @@ public static void import_color_svg (Glyph glyph, string path) { SvgFile svg_file = new SvgFile (); - SvgDrawing drawing = svg_file.parse (path); - glyph.add_layer (drawing.root_layer); + EmbeddedSvg drawing = svg_file.parse (path); + + Layer layer = new Layer (); + layer.name = "SVG"; + layer.add_object (drawing); + + glyph.add_layer (layer); + + // FIXME: update GUI } public static void import_folder (SvgType type) {
--- a/libbirdfont/Svg/SvgPath.vala +++ b/libbirdfont/Svg/SvgPath.vala @@ -30,7 +30,7 @@ return false; } - public override void draw (Context cr, Color? c = null) { + public override void draw (Context cr) { cr.save (); cr.new_path ();