The Birdfont Source Code


All Repositories / birdfont.git / commitdiff – RSS feed

Parse SVG files

These changes was commited to the Birdfont repository Wed, 06 Jan 2016 04:44:55 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
[Wed, 06 Jan 2016 04:44:55 +0000]

Updated Files

dodo.py
libbirdfont/BezierPoints.vala
libbirdfont/Doubles.vala
libbirdfont/FastPath.vala
libbirdfont/Glyph.vala
libbirdfont/Layer.vala
libbirdfont/Object.vala
libbirdfont/Svg/BezierPoints.vala
libbirdfont/Svg/Points.vala
libbirdfont/Svg/Svg.vala
libbirdfont/Svg/SvgFile.vala
libbirdfont/Svg/SvgParser.vala
libbirdfont/Svg/SvgPath.vala
libbirdfont/Svg/SvgTransform.vala
diff --git a/dodo.py b/dodo.py
--- a/dodo.py +++ b/dodo.py @@ -303,6 +303,7 @@ libbirdfont/OpenFontFormat/*.vala \ libbirdfont/TextRendering/*.vala \ libbirdfont/Svg/*.vala \ + --pkg posix \ --pkg """ + config.GEE + """ \ --pkg gio-2.0 \ --pkg cairo \
diff --git libbirdfont/BezierPoints.vala(deleted)
--- a/libbirdfont/BezierPoints.vala +++ /dev/null @@ -1,34 +1,1 @@ - /* - Copyright (C) 2014 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 { - - /** Bezier point container for the SVG parser. */ - public class BezierPoints { - public unichar type = '\0'; - public unichar svg_type = '\0'; - public double x0 = 0; - public double y0 = 0; - public double x1 = 0; - public double y1 = 0; - public double x2 = 0; - public double y2 = 0; - - public string to_string () { - return @"$((!)type.to_string ()) $x0,$y0 $x1,$y1 $x2,$y2 SVG:$((!)svg_type.to_string ())"; - } - } - - }
diff --git libbirdfont/Doubles.vala(new)
--- /dev/null +++ b/libbirdfont/Doubles.vala @@ -1,1 +1,55 @@ + /* + 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 Cairo; + + namespace BirdFont { + + public class Doubles : GLib.Object { + public double* data; + public int size = 10; + int capacity = 10; + + public Doubles () { + data = new double[capacity]; + } + + ~Doubles () { + delete data; + data = null; + } + + public Doubles.for_capacity (int capacity) { + data = new double[capacity]; + this.capacity = capacity; + } + + public void add(double d) { + if (size >= capacity) { + int new_capacity = 2 * capacity; + double* new_data = new double[new_capacity]; + Posix.memcpy (new_data, data, sizeof (double) * size); + delete data; + data = new_data; + capacity = new_capacity; + } + + data[size] = d; + size++; + } + } + + } +
--- a/libbirdfont/FastPath.vala +++ b/libbirdfont/FastPath.vala @@ -227,7 +227,12 @@ public override Object copy () { return new FastPath.create_copy (this); } + + public override string to_string () { + return "FastPath"; + } + } }
--- a/libbirdfont/Glyph.vala +++ b/libbirdfont/Glyph.vala @@ -242,6 +242,11 @@ current_layer = layers.subgroups.size - 1; } + public void add_layer (Layer layer) { + layers.add_layer (layer); + current_layer = layers.subgroups.size - 1; + } + public int get_layer_index (Layer layer) { return layers.index_of (layer); } @@ -1704,7 +1709,6 @@ /** Draw filled paths. */ public void draw_paths (Context cr, Color? c = null) { - cr.save (); cr.new_path (); @@ -1788,10 +1792,20 @@ cr.save (); cr.new_path (); - foreach (Path p in get_visible_paths ()) { - if (p.stroke == 0) { - color = p.color == null ? Color.black () : (!) p.color; - p.draw_path (cr, color); + + get_current_layer ().print(); + + foreach (Object o in get_visible_objects ()) { + print("visible obj\n"); + if (o is FastPath) { + Path p = ((FastPath) o).get_path (); + + if (p.stroke == 0) { + color = p.color == null ? Color.black () : (!) p.color; + p.draw_path (cr, color); + } + } else { + o.draw (cr); } } cr.close_path ();
--- a/libbirdfont/Layer.vala +++ b/libbirdfont/Layer.vala @@ -24,10 +24,13 @@ public bool is_counter = false; public Gradient? gradient = null; public bool single_path = false; + + public Gee.ArrayList<SvgTransform> transforms; public Layer () { objects = new ObjectGroup (); subgroups = new Gee.ArrayList<Layer> (); + transforms = new Gee.ArrayList<SvgTransform> (); } public int index_of (Layer sublayer) { @@ -64,21 +67,21 @@ } public ObjectGroup get_visible_objects () { - ObjectGroup paths = new ObjectGroup (); + ObjectGroup object_group = new ObjectGroup (); if (visible) { foreach (Object o in objects) { - paths.add (o); + object_group.add (o); } } foreach (Layer sublayer in subgroups) { if (sublayer.visible) { - paths.append (sublayer.get_visible_objects ()); + object_group.append (sublayer.get_visible_objects ()); } } - return paths; + return object_group; } public PathList get_visible_paths () { @@ -211,14 +214,26 @@ } public void print (int indent = 0) { + stdout.printf (@"Layer: $(name)"); + + if (!visible) { + stdout.printf (" hidden"); + } + + stdout.printf (@"\n"); + foreach (Object o in objects) { for (int i = 0; i < indent; i++) { stdout.printf ("\t"); } - stdout.printf (@"Path open: $(o.is_open ())"); + stdout.printf (@"Object $(o.to_string ())"); if (o.color != null) { stdout.printf (" %s", ((!) o.color).to_rgb_hex ()); + } + + if (!o.visible) { + stdout.printf (" hidden"); } stdout.printf ("\n");
--- a/libbirdfont/Object.vala +++ b/libbirdfont/Object.vala @@ -19,6 +19,10 @@ public abstract class Object : GLib.Object { bool open = false; + + public bool visible = true; + public SvgStyle style = new SvgStyle (); + public Gee.ArrayList<SvgTransform> transforms = new Gee.ArrayList<SvgTransform> (); public abstract Color? color { get; set; } public abstract Color? stroke_color { get; set; } @@ -58,7 +62,29 @@ public abstract void rotate (double theta, double xc, double yc); public abstract bool is_empty (); public abstract void resize (double ratio_x, double ratio_y); + + public static void copy_attributes (Object from, Object to) { + to.open = from.open; + + to.color = from.color; + to.stroke_color = from.stroke_color; + to.gradient = from.gradient; + + to.xmax = from.xmax; + to.xmin = from.xmin; + to.ymax = from.ymax; + to.ymin = from.ymin; + + to.rotation = from.rotation; + to.stroke = from.stroke; + to.line_cap = from.line_cap; + to.fill = from.fill; + } + + public virtual string to_string () { + return "Object"; + } } }
--- /dev/null +++ b/libbirdfont/Svg/BezierPoints.vala @@ -1,1 +1,34 @@ + /* + Copyright (C) 2014 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 { + + /** Bezier point container for the SVG parser. */ + public class BezierPoints { + public unichar type = '\0'; + public unichar svg_type = '\0'; + public double x0 = 0; + public double y0 = 0; + public double x1 = 0; + public double y1 = 0; + public double x2 = 0; + public double y2 = 0; + + public string to_string () { + return @"$((!)type.to_string ()) $x0,$y0 $x1,$y1 $x2,$y2 SVG:$((!)svg_type.to_string ())"; + } + } + + }
diff --git libbirdfont/Svg/Points.vala(new)
--- /dev/null +++ b/libbirdfont/Svg/Points.vala @@ -1,1 +1,31 @@ + /* + 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 Cairo; + + namespace BirdFont { + + public class Points : GLib.Object { + public Doubles point_data = new Doubles.for_capacity (100); + public double x = 0; + public double y = 0; + + public void add (double p) { + point_data.add (p); + } + } + + } +
--- a/libbirdfont/Svg/Svg.vala +++ b/libbirdfont/Svg/Svg.vala @@ -15,6 +15,8 @@ using Cairo; namespace BirdFont { + + // FIXME: substrings public class Svg {
--- a/libbirdfont/Svg/SvgFile.vala +++ b/libbirdfont/Svg/SvgFile.vala @@ -11,12 +11,332 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ + + using B; namespace BirdFont { public class SvgFile : GLib.Object { + public SvgFile () { + } + + public Layer 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."); + } + } catch (GLib.Error error) { + warning (error.message); + } + + return new Layer (); + } + + private Layer parse_svg_file (Tag tag) { + Layer layer = new Layer (); + + foreach (Tag t in tag) { + string name = t.get_name (); + + if (name == "g") { + parse_layer (layer, t); + } + + parse_object (layer, t); + } + + return layer; + } + + private void parse_layer (Layer layer, Tag tag) { + bool hidden = false; + + foreach (Attribute attr in tag.get_attributes ()) { + if (attr.get_name () == "display" && attr.get_content () == "none") { + hidden = true; + } + + if (attr.get_name () == "visibility" + && (attr.get_content () == "hidden" + || attr.get_content () == "collapse")) { + hidden = true; + } + } + + if (hidden) { + layer.visible = !hidden; + } + + foreach (Tag t in tag) { + if (t.get_name () == "g") { + Layer sublayer = new Layer (); + parse_layer (layer, t); + layer.subgroups.add (sublayer); + } + + parse_object (layer, t); + } + + foreach (Attribute attr in tag.get_attributes ()) { + if (attr.get_name () == "transform") { + layer.transforms = parse_transform (attr.get_content ()); + } + } + } + + void parse_object (Layer layer, Tag tag) { + string name = tag.get_name (); + + if (name == "path") { + parse_path (layer, tag); + } + + if (name == "polygon") { + parse_polygon (layer, tag); + } + + if (name == "polyline") { + parse_polyline (layer, tag); + } + + if (name == "rect") { + parse_rect (layer, tag); + } + + if (name == "circle") { + parse_circle (layer, tag); + } + + if (name == "ellipse") { + parse_ellipse (layer, tag); + } + + if (name == "line") { + parse_line (layer, tag); + } + } + + private void parse_polygon (Layer layer, Tag tag) { + } + + private void parse_polyline (Layer layer, Tag tag) { + } + + private void parse_rect (Layer layer, Tag tag) { + } + + private void parse_circle (Layer layer, Tag tag) { + } + + private void parse_ellipse (Layer layer, Tag tag) { + } + + private void parse_line (Layer layer, Tag tag) { + } + + // FIXME: reverse order? + public Gee.ArrayList<SvgTransform> parse_transform (string transforms) { + string[] functions; + string transform = transforms; + Gee.ArrayList<SvgTransform> transform_functions; + + transform_functions = new Gee.ArrayList<SvgTransform> (); + + transform = transform.replace ("\t", " "); + transform = transform.replace ("\n", " "); + transform = transform.replace ("\r", " "); + + // use only a single space as separator + while (transform.index_of (" ") > -1) { + transform = transform.replace (" ", " "); + } + + if (unlikely (transform.index_of (")") > -1)) { + warning ("No parenthesis in transform function."); + return transform_functions; + } + + // add separator + transform = transform.replace (") ", "|"); + transform = transform.replace (")", "|"); + functions = transform.split ("|"); + + for (int i = 0; i < functions.length; i++) { + if (functions[i].has_prefix ("translate")) { + transform_functions.add (translate (functions[i])); + } + + if (functions[i].has_prefix ("scale")) { + transform_functions.add (scale (functions[i])); + } + + if (functions[i].has_prefix ("matrix")) { + transform_functions.add (matrix (functions[i])); + } + + // TODO: rotate etc. + } + + return transform_functions; + } + + private SvgTransform matrix (string function) { + string parameters = get_transform_parameters (function); + string[] p = parameters.split (" "); + SvgTransform transform = new SvgTransform (); + transform.type = TransformType.MATRIX; + + if (unlikely (p.length != 6)) { + warning ("Expecting six parameters for matrix transformation."); + return transform; + } + + for (int i = 0; i < 6; i++) { + double argument = SvgParser.parse_double (p[i]); + transform.arguments.add (argument); + } + + return transform; + } + + private SvgTransform scale (string function) { + string parameters = get_transform_parameters (function); + string[] p = parameters.split (" "); + SvgTransform transform = new SvgTransform (); + transform.type = TransformType.SCALE; + + if (p.length > 0) { + transform.arguments.add (SvgParser.parse_double (p[0])); + } + + if (p.length > 1) { + transform.arguments.add (SvgParser.parse_double (p[1])); + } + + return transform; + } + + private SvgTransform translate (string function) { + string parameters = get_transform_parameters (function); + string[] p = parameters.split (" "); + SvgTransform transform = new SvgTransform (); + transform.type = TransformType.TRANSLATE; + + if (p.length > 0) { + transform.arguments.add (SvgParser.parse_double (p[0])); + } + + if (p.length > 1) { + transform.arguments.add (SvgParser.parse_double (p[1])); + } + + return transform; + } + + private string get_transform_parameters (string function) { + int i; + string param = ""; + + i = function.index_of ("("); + return_val_if_fail (i != -1, param); + param = function.substring (i); + + param = param.replace ("(", ""); + param = param.replace ("\n", " "); + param = param.replace ("\t", " "); + param = param.replace (",", " "); + + while (param.index_of (" ") > -1) { + param.replace (" ", " "); + } + + return param.strip(); + } + + private bool is_visible (Tag tag) { + bool hidden = false; + + foreach (Attribute attr in tag.get_attributes ()) { + if (attr.get_name () == "display" && attr.get_content () == "none") { + hidden = true; + } + + if (attr.get_name () == "visibility" + && (attr.get_content () == "hidden" + || attr.get_content () == "collapse")) { + hidden = true; + } + } + + return !hidden; + } + + private void parse_path (Layer layer, Tag tag) { + SvgPath path = new SvgPath (); + + foreach (Attribute attr in tag.get_attributes ()) { + if (attr.get_name () == "d") { + path.points = parse_points (attr.get_content ()); + } + + if (attr.get_name () == "transform") { + path.transforms = parse_transform (attr.get_content ()); + } + } + + path.style = SvgStyle.parse (tag.get_attributes ()); + path.visible = is_visible (tag); + + layer.add_object (path); + } + + public Gee.ArrayList<Points> parse_points (string data) { + Gee.ArrayList<Points> path_data = new Gee.ArrayList<Points> (); + Points points = new Points (); + BezierPoints[] bezier_points; + int points_size; + + SvgParser.get_bezier_points (data, out bezier_points, out points_size, true); + + for (int i = 0; i < points_size; i++) { + if (bezier_points[i].type == 'M') { + points.x = bezier_points[i].x0; + points.y = bezier_points[i].y0; + } else if (bezier_points[i].type == 'C') { + points.add (bezier_points[i].x0); + points.add (bezier_points[i].y0); + points.add (bezier_points[i].x1); + points.add (bezier_points[i].y1); + points.add (bezier_points[i].x2); + points.add (bezier_points[i].y2); + } else if (bezier_points[i].type == 'L') { + points.add (bezier_points[i].x0); + points.add (bezier_points[i].y0); + points.add (bezier_points[i].x0); + points.add (bezier_points[i].y0); + points.add (bezier_points[i].x0); + points.add (bezier_points[i].y0); + } else if (bezier_points[i].type == 'z') { + path_data.add (points); + points = new Points (); + } else { + string type = (!) bezier_points[i].type.to_string (); + warning (@"SVG conversion not implemented for $type"); + } + } + + return path_data; + } } }
--- a/libbirdfont/Svg/SvgParser.vala +++ b/libbirdfont/Svg/SvgParser.vala @@ -63,18 +63,9 @@ } 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); - } + SvgFile svg_file = new SvgFile (); + Layer layer = svg_file.parse (path); + glyph.add_layer (layer); } public static void import_folder (SvgType type) { @@ -1017,7 +1008,7 @@ /** Add space as separator to svg data. * @param d svg data */ - static string add_separators (string d) { + public static string add_separators (string d) { string data = d; data = data.replace (",", " "); @@ -1063,44 +1054,34 @@ g.add_path (path); } } - - /** - * @param d svg data - * @param glyph use lines from this glyph but don't add the generated paths - * @param svg_glyph parse svg glyph with origo in lower left corner - * - * @return the new paths - */ - public PathList parse_svg_data (string d, Glyph glyph, bool svg_glyph = false, double units = 1) { + + public static void get_bezier_points (string point_data, out BezierPoints[] bezier_points, out int points, bool svg_glyph) { double px = 0; double py = 0; double px2 = 0; double py2 = 0; double cx = 0; double cy = 0; - string data; - Font font; - PathList path_list = new PathList (); - BezierPoints[] bezier_points; string[] c; double arc_rx, arc_ry; double arc_rotation; int large_arc; int arc_sweep; double arc_dest_x, arc_dest_y; + + int bi = 0; - font = BirdFont.get_current_font (); - - data = add_separators (d); + string data = add_separators (point_data); c = data.split (" "); - bezier_points = new BezierPoints[8 * c.length + 1]; // the arc instruction can use up to eight points + + // the arc instruction can use up to eight points + int bezier_points_length = 8 * c.length + 1; + bezier_points = new BezierPoints[bezier_points_length]; - for (int i = 0; i < 2 * c.length + 1; i++) { + for (int i = 0; i < bezier_points_length; i++) { bezier_points[i] = new BezierPoints (); } - - int bi = 0; - + // parse path int i = -1; while (++i < c.length && bi < bezier_points.length) { @@ -1358,7 +1339,6 @@ bi++; } } else if (c[i] == "Q") { - while (i + 4 < c.length && is_point (c[i + 1])) { bezier_points[bi].type = 'Q'; bezier_points[bi].svg_type = 'Q'; @@ -1431,7 +1411,7 @@ // the reflection cx = 2 * px - px2; - cy = 2 * py - py2; // if (svg_glyph) ? + cy = 2 * py - py2; bezier_points[bi].x0 = cx; bezier_points[bi].y0 = cy; @@ -1538,7 +1518,7 @@ px = cx; py = cy; - bi++; + bi++; } } else if (c[i] == "a") { while (i + 7 < c.length && is_point (c[i + 1])) { @@ -1564,8 +1544,6 @@ px = cx; py = cy; - - } } else if (i + 7 < c.length && c[i] == "A") { while (is_point (c[i + 1])) { @@ -1612,16 +1590,39 @@ } if (bi == 0) { + warning ("No points in path."); + } + + points = bi; + } + + /** + * @param d svg data + * @param glyph use lines from this glyph but don't add the generated paths + * @param svg_glyph parse svg glyph with origo in lower left corner + * + * @return the new paths + */ + public PathList parse_svg_data (string d, Glyph glyph, bool svg_glyph = false, double units = 1) { + Font font; + PathList path_list = new PathList (); + BezierPoints[] bezier_points; + int points; + + font = BirdFont.get_current_font (); + get_bezier_points (d, out bezier_points, out points, svg_glyph); + + if (points == 0) { warning ("No points in path."); return path_list; } - move_and_resize (bezier_points, bi, svg_glyph, units, glyph); + move_and_resize (bezier_points, points, svg_glyph, units, glyph); if (format == SvgFormat.ILLUSTRATOR) { - path_list = create_paths_illustrator (bezier_points, bi); + path_list = create_paths_illustrator (bezier_points, points); } else { - path_list = create_paths_inkscape (bezier_points, bi); + path_list = create_paths_inkscape (bezier_points, points); } // TODO: Find out if it is possible to tie handles. @@ -2044,13 +2045,13 @@ return int.parse ((!) s); } - static double parse_double (string? s) { - if (is_null (s)) { + public static double parse_double (string? s) { + if (unlikely (is_null (s))) { warning ("Got null instead of expected string."); return 0; } - if (!is_point ((!) s)) { + if (unlikely (!is_point ((!) s))) { warning (@"Expecting a double got: $((!) s)"); return 0; } @@ -2089,7 +2090,7 @@ } bezier_points[bi] = new BezierPoints (); - bezier_points[bi].type == 'L'; + bezier_points[bi].type = 'L'; bezier_points[bi].x0 = parse_double (c[i]); bezier_points[bi].y0 = -parse_double (c[i + 1]); bi++;
--- /dev/null +++ b/libbirdfont/Svg/SvgPath.vala @@ -1,1 +1,128 @@ + /* + 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 Cairo; + + namespace BirdFont { + + public class SvgPath : Object { + public override double stroke { get; set; } + public override double rotation { get; set; } + public override LineCap line_cap { get; set; } + public override bool fill { get; set; } + + public override Color? color { get; set; } + public override Color? stroke_color { get; set; } + public override Gradient? gradient { get; set; } + + public override double xmin { get; set; } + public override double xmax { get; set; } + public override double ymin { get; set; } + public override double ymax { get; set; } + + public Gee.ArrayList<Points> points = new Gee.ArrayList<Points> (); + + public SvgPath () { + } + + public SvgPath.create_copy (SvgPath p) { + Object.copy_attributes (p, this); + } + + public override bool is_over (double x, double y) { + return false; + } + + public override void draw (Context cr, Color? c = null) { + cr.save (); + + foreach (Points p in points) { + cr.new_path (); + cr.move_to (p.x, p.y); + + draw_points (cr, p); + } + + cr.fill (); // FIXME: stroke etc. + cr.restore (); + } + + public void draw_points (Context cr, Points points) { + Doubles p = points.point_data; + + print(@"draw $(p.size)\n"); + + return_if_fail (p.size % 6 != 0); + + for (int i = 0; i < p.size; i += 6) { + cr.curve_to (p.data[i], p.data[i + 1], + p.data[i + 2], p.data[i + 3], + p.data[i + 4], p.data[i + 5]); + + print(@"$(p.data[i])"); + } + + cr.set_source_rgba (0, 0.5, 0, 1); + cr.fill (); + + cr.close_path (); + cr.new_path (); + cr.move_to (points.x, points.y); + cr.set_source_rgba (0, 0, 0.5, 0.5); + + for (int i = 0; i < p.size; i += 2) { + cr.line_to (p.data[i], p.data[i + 1]); + } + + cr.fill (); + + cr.close_path (); + cr.new_path (); + cr.move_to (points.x, points.y); + cr.set_source_rgba (0.5, 0, 0, 0.5); + + for (int i = 0; i < p.size; i += 6) { + cr.line_to (p.data[i + 4], p.data[i + 5]); + } + + cr.fill (); + } + + public override void move (double dx, double dy) { + } + + public override void update_region_boundaries () { + } + + 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) { + } + + public override Object copy () { + return new SvgPath.create_copy (this); + } + + public override string to_string () { + return "SvgPath"; + } + } + + }
--- /dev/null +++ b/libbirdfont/Svg/SvgTransform.vala @@ -1,1 +1,35 @@ + /* + 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 enum TransformType { + NONE, + TRANSLATE, + MATRIX, + SCALE + } + + public class SvgTransform : GLib.Object { + public TransformType type = TransformType.NONE; + public Doubles arguments = new Doubles.for_capacity (10); + + public SvgTransform () { + } + } + + }