The Birdfont Source Code


All Repositories / birdfont.git / commitdiff – RSS feed

Use other types of graphical objects

These changes was commited to the Birdfont repository Mon, 28 Dec 2015 10:29:21 +0000.

Contributing

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

Updated Files

dodo.py
libbirdfont/ClipTool.vala
libbirdfont/DrawingTools.vala
libbirdfont/ExportTool.vala
libbirdfont/FastPath.vala
libbirdfont/Glyph.vala
libbirdfont/Layer.vala
libbirdfont/MenuTab.vala
libbirdfont/MoveTool.vala
libbirdfont/Object.vala
libbirdfont/ObjectGroup.vala
libbirdfont/OpenFontFormat/FontData.vala
libbirdfont/OpenFontFormat/GlyfData.vala
libbirdfont/OpenFontFormat/GlyfTable.vala
libbirdfont/OpenFontFormat/OpenFontFormatReader.vala
libbirdfont/OpenFontFormat/OpenFontFormatWriter.vala
libbirdfont/OpenFontFormat/OtfInputStream.vala
libbirdfont/OpenFontFormat/OtfTable.vala
libbirdfont/OrientationTool.vala
libbirdfont/OtfFeatureTable.vala
libbirdfont/Path.vala
libbirdfont/PenTool.vala
libbirdfont/ResizeTool.vala
libbirdfont/StrokeTool.vala
libbirdfont/SvgFontFormatWriter.vala
libbirdfont/SvgParser.vala
libbirdfont/Test.vala
libbirdfont/TrackTool.vala
diff --git a/dodo.py b/dodo.py
--- a/dodo.py +++ b/dodo.py @@ -301,7 +301,7 @@ -H build/libbirdfont/birdfont.h \ libbirdfont/*.vala \ libbirdfont/OpenFontFormat/*.vala \ - libbirdfont/Renderer/*.vala \ + libbirdfont/TextRendering/*.vala \ --pkg """ + config.GEE + """ \ --pkg gio-2.0 \ --pkg cairo \
--- a/libbirdfont/ClipTool.vala +++ b/libbirdfont/ClipTool.vala @@ -95,7 +95,7 @@ dx = g.motion_x - x - w / 2.0; dy = g.motion_y - y + h / 2.0; - foreach (Path path in g.active_paths) { + foreach (Object path in g.active_paths) { path.move (dx, dy); } } else if (fd is KerningDisplay) { @@ -260,7 +260,7 @@ } } } else if (glyph.get_visible_paths ().size > 0) { - foreach (Path path in glyph.active_paths) { + foreach (Path path in glyph.get_active_paths ()) { // FIXME: other objects s.append ("BF path: "); s.append (BirdFontFile.get_point_data (path)); s.append ("\n"); @@ -447,13 +447,13 @@ if (path.points.size > 0) { PenTool.clear_directions (); glyph.add_path (path); - glyph.active_paths.add (path); + glyph.add_active_path (null, path); path.update_region_boundaries (); } PenTool.remove_all_selected_points (); - foreach (Path p in glyph.active_paths) { + foreach (Path p in glyph.get_active_paths ()) { if (p.is_open ()) { foreach (EditPoint e in p.points) { e.set_selected (true);
--- a/libbirdfont/DrawingTools.vala +++ b/libbirdfont/DrawingTools.vala @@ -292,7 +292,7 @@ glyph.selection_boundaries (out x, out y, out w, out h); delta = x_coordinate.get_value () - x + glyph.left_limit; - foreach (Path path in glyph.active_paths) { + foreach (Object path in glyph.active_paths) { path.move (delta, 0); } @@ -335,7 +335,7 @@ glyph.selection_boundaries (out x, out y, out w, out h); - foreach (Path path in glyph.active_paths) { + foreach (Path path in glyph.get_active_paths ()) { path.move (0, y_coordinate.get_value () - (y - h) - font.base_line); } @@ -375,7 +375,7 @@ double x, y, w, h; Glyph glyph = MainWindow.get_current_glyph (); double angle = (self.get_value () / 360) * 2 * PI; - Path last_path; + Object last_path; glyph.selection_boundaries (out x, out y, out w, out h); x += w / 2; @@ -480,7 +480,7 @@ tie = !p.tie_handles; // don't tie end points - foreach (Path path in MainWindow.get_current_glyph ().active_paths) { + foreach (Path path in MainWindow.get_current_glyph ().get_active_paths ()) { if (path.is_open ()) { if (p == path.get_first_point () || p == path.get_last_point ()) { tie = false; @@ -598,9 +598,9 @@ Glyph g = MainWindow.get_current_glyph (); Layer layer = g.get_current_layer (); - foreach (Path p in g.active_paths) { - layer.paths.remove (p); - layer.paths.paths.insert (0, p); + foreach (Object p in g.active_paths) { + layer.remove (p); + layer.objects.objects.insert (0, p); } GlyphCanvas.redraw (); @@ -798,12 +798,12 @@ g.store_undo_state (); if (StrokeTool.add_stroke) { - foreach (Path p in g.active_paths) { + foreach (Object p in g.active_paths) { p.stroke = StrokeTool.stroke_width; p.line_cap = StrokeTool.line_cap; } } else { - foreach (Path p in g.active_paths) { + foreach (Object p in g.active_paths) { p.stroke = 0; } } @@ -838,9 +838,13 @@ StrokeTool.stroke_width = object_stroke.get_value (); if (tool && StrokeTool.add_stroke) { - foreach (Path p in g.active_paths) { + foreach (Object p in g.active_paths) { p.stroke = StrokeTool.stroke_width; - p.reset_stroke (); + + if (p is FastPath) { + Path path = ((FastPath) p).get_path (); + path.reset_stroke (); + } } } @@ -876,9 +880,12 @@ g = MainWindow.get_current_glyph (); g.store_undo_state (); - foreach (Path p in g.active_paths) { + foreach (Object p in g.active_paths) { p.line_cap = LineCap.BUTT; - p.reset_stroke (); + + if (p is FastPath) { + ((FastPath) p).get_path ().reset_stroke (); + } } StrokeTool.line_cap = LineCap.BUTT; @@ -900,9 +907,12 @@ g = MainWindow.get_current_glyph (); g.store_undo_state (); - foreach (Path p in g.active_paths) { + foreach (Object p in g.active_paths) { p.line_cap = LineCap.ROUND; - p.reset_stroke (); + + if (p is FastPath) { + ((FastPath) p).get_path ().reset_stroke (); + } } StrokeTool.line_cap = LineCap.ROUND; @@ -925,9 +935,12 @@ g = MainWindow.get_current_glyph (); g.store_undo_state (); - foreach (Path p in g.active_paths) { + foreach (Object p in g.active_paths) { p.line_cap = LineCap.SQUARE; - p.reset_stroke (); + + if (p is FastPath) { + ((FastPath) p).get_path ().reset_stroke (); + } } StrokeTool.line_cap = LineCap.SQUARE; @@ -1249,7 +1262,7 @@ bool stroke = false; Glyph g = MainWindow.get_current_glyph (); - foreach (Path p in g.active_paths) { + foreach (Object p in g.active_paths) { if (p.stroke > 0) { stroke = true; }
--- a/libbirdfont/ExportTool.vala +++ b/libbirdfont/ExportTool.vala @@ -95,37 +95,50 @@ name = glyph.get_name (); - Gee.ArrayList<Path> pl; + Gee.ArrayList<Object> pl; s = new StringBuilder (); glyph_svg = ""; - pl = only_selected_paths ? glyph.active_paths : glyph.get_visible_paths (); - foreach (Path p in pl) { - if (p.stroke > 0) { - s.append (@"<path "); - s.append (@"style=\""); - s.append (@"fill:none;"); - s.append (@"stroke:#000000;"); - s.append (@"stroke-width:$(p.stroke)px;"); - - if (p.line_cap == LineCap.ROUND) { - s.append (@"stroke-linecap:round;"); - } else if (p.line_cap == LineCap.SQUARE) { - s.append (@"stroke-linecap:square;"); + pl = only_selected_paths ? glyph.active_paths : glyph.get_visible_objects (); + + foreach (Object o in pl) { + + if (o is FastPath) { + Path p = ((FastPath) o).get_path (); + + if (p.stroke > 0) { + s.append (@"<path "); + s.append (@"style=\""); + s.append (@"fill:none;"); + s.append (@"stroke:#000000;"); + s.append (@"stroke-width:$(p.stroke)px;"); + + if (p.line_cap == LineCap.ROUND) { + s.append (@"stroke-linecap:round;"); + } else if (p.line_cap == LineCap.SQUARE) { + s.append (@"stroke-linecap:square;"); + } + + s.append (@"\" "); + + s.append (@"d=\"$(Svg.to_svg_path (p, glyph))\" id=\"path_$(name)_$(id)\" />\n"); + id++; } - - s.append (@"\" "); - - s.append (@"d=\"$(Svg.to_svg_path (p, glyph))\" id=\"path_$(name)_$(id)\" />\n"); - id++; + } else { + warning ("Copy and paste for other objects not implemented."); } } if (only_selected_paths) { - foreach (Path p in glyph.active_paths) { - if (p.stroke == 0) { - glyph_svg += Svg.to_svg_path (p, glyph); + foreach (Object p in glyph.active_paths) { + if (p is FastPath) { + Path path = ((FastPath) p).get_path (); + if (path.stroke == 0) { + glyph_svg += Svg.to_svg_path (path, glyph); + } + } else { + warning ("Not implemented"); } } } else {
diff --git libbirdfont/FastPath.vala(new)
--- /dev/null +++ b/libbirdfont/FastPath.vala @@ -1,1 +1,82 @@ + /* + 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 FastPath : Object { + + Path path; + + public FastPath () { + path = new Path (); + update_region_boundaries (); + } + + public FastPath.create_copy (FastPath p) { + base.create_copy (p); + path = p.path.copy (); + } + + public FastPath.for_path (Path path) { + this.path = path; + } + + public override bool is_over (double x, double y) { + return path.is_over (x, y); + } + + public override void draw (Context cr) { + } + + public override void move (double dx, double dy) { + path.move (dx, dy); + path.reset_stroke (); + } + + public Path get_path () { + return path; + } + + public override void update_region_boundaries () { + path.update_region_boundaries (); + xmax = path.xmax; + xmin = path.xmin; + ymax = path.ymax; + ymin = path.ymin; + } + + public override void rotate (double theta, double xc, double yc) { + path.rotate (theta, xc, yc); + rotation += theta; + rotation %= 2 * Math.PI; + } + + public override bool is_empty () { + return path.points.size == 0; + } + + public override void resize (double ratio_x, double ratio_y) { + path.resize (ratio_x, ratio_y); + path.reset_stroke (); + } + + public override Object copy () { + return new FastPath.create_copy (this); + } + } + + }
--- a/libbirdfont/Glyph.vala +++ b/libbirdfont/Glyph.vala @@ -132,7 +132,7 @@ public Layer layers = new Layer (); public int current_layer = 0; - public Gee.ArrayList<Path> active_paths = new Gee.ArrayList<Path> (); + public Gee.ArrayList<Object> active_paths = new Gee.ArrayList<Object> (); public Gee.ArrayList<Layer> selected_groups = new Gee.ArrayList<Layer> (); // used if this glyph originates from a fallback font @@ -189,14 +189,14 @@ public Glyph.no_lines (string name, unichar unichar_code = 0) { this.name = name; this.unichar_code = unichar_code; - } - - public Gee.ArrayList<Path> get_active_paths () { - return active_paths; } public Layer get_current_layer () { - return_val_if_fail (0 <= current_layer < layers.subgroups.size, new Layer ()); + if (unlikely (!(0 <= current_layer < layers.subgroups.size))) { + warning ("Layer index out of bounds."); + return new Layer (); + } + return layers.subgroups.get (current_layer); } @@ -211,6 +211,10 @@ } warning ("Layer is not added to glyph."); + } + + public Gee.ArrayList<Object> get_visible_objects () { + return layers.get_visible_objects ().objects; } public Gee.ArrayList<Path> get_visible_paths () { @@ -219,6 +223,10 @@ public PathList get_visible_path_list () { return layers.get_visible_paths (); + } + + public Gee.ArrayList<Object> get_objects_in_current_layer () { + return get_current_layer ().get_all_objects ().objects; } public Gee.ArrayList<Path> get_paths_in_current_layer () { @@ -289,22 +297,35 @@ } public void add_active_path (Layer? group, Path? p) { - Path path; + if (p != null) { + FastPath path = new FastPath.for_path ((!) p); + add_active_object (group, path); + } else { + add_active_object (group, null); + } + } + + public void add_active_object (Layer? group, Object? o) { + Object object; Layer g; - if (p != null) { - path = (!) p; + if (o != null) { + object = (!) o; - if (Toolbox.get_move_tool ().is_selected ()) { - if (path.stroke > 0) { - Toolbox.set_object_stroke (path.stroke); - } + if (!active_paths.contains (object)) { + active_paths.add (object); } - - if (!active_paths.contains (path)) { - active_paths.add (path); + + if (object is FastPath) { + FastPath path = (FastPath) object; + if (Toolbox.get_move_tool ().is_selected ()) { + if (path.get_path ().stroke > 0) { + Toolbox.set_object_stroke (path.get_path ().stroke); + } + } + + PenTool.active_path = path.get_path (); } - PenTool.active_path = path; } if (group != null) { @@ -319,11 +340,6 @@ store_undo_state (); background_image = null; GlyphCanvas.redraw (); - } - - public Path? get_active_path () { - return_val_if_fail (active_paths.size > 0, null); - return active_paths.get (active_paths.size - 1); } public bool boundaries (out double x1, out double y1, out double x2, out double y2) { @@ -375,7 +391,7 @@ px2 = -10000; py2 = -10000; - foreach (Path p in active_paths) { + foreach (Object p in active_paths) { if (p.xmin < px) { px = p.xmin; } @@ -485,6 +501,14 @@ } get_current_layer ().add_path (p); + } + + public void add_object (Object object) { + if (layers.subgroups.size == 0) { + layers.add_layer (new Layer ()); + } + + get_current_layer ().add_object (object); } public override void selected_canvas () { @@ -926,8 +950,9 @@ add_path (path); path.reopen (); path.create_list (); - - add_active_path (null, path); + + FastPath object = new FastPath.for_path (path); + add_active_object (null, object); } if (remaining_points.paths.size > 0) { @@ -1040,7 +1065,7 @@ public void set_active_path (Path p) { p.reopen (); clear_active_paths (); - add_active_path (null, p); + add_active_object (null, new FastPath.for_path (p)); } /** Move view port centrum to this coordinate. */ @@ -1189,8 +1214,8 @@ bool found = false; foreach (Layer layer in get_current_layer ().subgroups) { - foreach (Path pt in layer.paths.paths) { - if (pt.is_over (x, y)) { + foreach (Object o in layer.objects) { + if (o.is_over (x, y)) { found = true; group = layer; } @@ -1233,8 +1258,8 @@ } public bool is_over_selected_path (double x, double y) { - foreach (Path pt in active_paths) { - if (pt.is_over (x, y)) { + foreach (Object p in active_paths) { + if (p.is_over (x, y)) { return true; } } @@ -1349,8 +1374,9 @@ return; } - foreach (Path path in active_paths) { + foreach (Object object in active_paths) { EditPoint p; + Path path = ((FastPath) object).get_path (); EditPoint pl = path.get_last_point (); if (pl.prev != null) { @@ -1364,7 +1390,6 @@ if (px > x) px -= tw + 60; if (py > y) py -= th + 60; - } else { px = x - 60; py = y - 60; @@ -1678,7 +1703,7 @@ p.recalculate_linear_handles (); } - p.draw_path (cr, this, color); + p.draw_path (cr, color); if (open) { p.reopen (); @@ -1718,11 +1743,14 @@ && !(MainWindow.get_toolbox ().get_current_tool () is BezierTool)) { cr.save (); cr.new_path (); - foreach (Path p in active_paths) { - if (p.stroke > 0) { - stroke = p.get_stroke_fast (); - color = Theme.get_color ("Selected Objects"); - draw_path_list (stroke, cr, color); + foreach (Object o in active_paths) { + if (o is FastPath) { + Path p = ((FastPath) o).get_path (); + if (p.stroke > 0) { + stroke = p.get_stroke_fast (); + color = Theme.get_color ("Selected Objects"); + draw_path_list (stroke, cr, color); + } } } cr.fill (); @@ -1735,7 +1763,7 @@ foreach (Path p in get_visible_paths ()) { if (p.stroke == 0) { color = p.color == null ? get_path_fill_color () : (!) p.color; - p.draw_path (cr, this, color); + p.draw_path (cr, color); } } cr.fill (); @@ -1761,22 +1789,25 @@ foreach (Path p in get_visible_paths ()) { if (p.stroke == 0) { color = p.color == null ? Color.black () : (!) p.color; - p.draw_path (cr, this, color); + p.draw_path (cr, color); } } cr.close_path (); cr.fill (); cr.restore (); - foreach (Path p in active_paths) { - cr.save (); - cr.new_path (); - if (p.stroke == 0) { - p.draw_path (cr, this); + foreach (Object o in active_paths) { + if (o is FastPath) { + Path p = ((FastPath) o).get_path (); + cr.save (); + cr.new_path (); + if (p.stroke == 0) { + p.draw_path (cr); + } + cr.close_path (); + cr.fill (); + cr.restore (); } - cr.close_path (); - cr.fill (); - cr.restore (); } } @@ -1800,7 +1831,7 @@ public void draw_path_list (PathList pl, Context cr, Color? c = null) { foreach (Path p in pl.paths) { - p.draw_path (cr, this, c); + p.draw_path (cr, c); } } @@ -1961,8 +1992,8 @@ g.layers = layers.copy (); - foreach (Path p in active_paths) { - g.active_paths.add (p); + foreach (Object o in active_paths) { + g.active_paths.add (o); } if (background_image != null) { @@ -2049,8 +2080,8 @@ } clear_active_paths (); - foreach (Path p in g.active_paths) { - add_active_path (null, p); + foreach (Object p in g.active_paths) { + add_active_object (null, p); } redraw_area (0, 0, allocation.width, allocation.height); @@ -2543,7 +2574,21 @@ return g2; } + + // FIXME: convert everything to the new Object code + public Gee.ArrayList<Path> get_active_paths () { + Gee.ArrayList<Path> paths = new Gee.ArrayList<Path> (); + + foreach (Object object in active_paths) { + if (object is FastPath) { + paths.add (((FastPath) object).get_path ()); + } + } + + return paths; + } + } }
--- a/libbirdfont/Layer.vala +++ b/libbirdfont/Layer.vala @@ -15,7 +15,8 @@ namespace BirdFont { public class Layer : GLib.Object { - public PathList paths; + public ObjectGroup objects; + public Gee.ArrayList<Layer> subgroups; public bool visible = true; public string name = "Layer"; @@ -25,40 +26,80 @@ public bool single_path = false; public Layer () { - paths = new PathList (); + objects = new ObjectGroup (); subgroups = new Gee.ArrayList<Layer> (); } public int index_of (Layer sublayer) { return subgroups.index_of (sublayer); } - + + public ObjectGroup get_all_objects () { + ObjectGroup o = new ObjectGroup (); + + o.append (objects); + + foreach (Layer sublayer in subgroups) { + o.append (sublayer.get_all_objects ()); + } + + return o; + } + public PathList get_all_paths () { - PathList p = new PathList (); + PathList paths = new PathList (); - p.append (paths); + foreach (Object o in objects) { + if (o is FastPath) { + FastPath p = (FastPath) o; + paths.add (p.get_path ()); + } + } foreach (Layer sublayer in subgroups) { - p.append (sublayer.get_all_paths ()); + paths.append (sublayer.get_all_paths ()); } - return p; + return paths; + } + + public ObjectGroup get_visible_objects () { + ObjectGroup paths = new ObjectGroup (); + + if (visible) { + foreach (Object o in objects) { + paths.add (o); + } + } + + foreach (Layer sublayer in subgroups) { + if (sublayer.visible) { + paths.append (sublayer.get_visible_objects ()); + } + } + + return paths; } public PathList get_visible_paths () { - PathList p = new PathList (); + PathList paths = new PathList (); if (visible) { - p.append (paths); + foreach (Object o in objects) { + if (o is FastPath) { + FastPath p = (FastPath) o; + paths.add (p.get_path ()); + } + } } foreach (Layer sublayer in subgroups) { if (sublayer.visible) { - p.append (sublayer.get_all_paths ()); + paths.append (sublayer.get_visible_paths ()); } } - return p; + return paths; } public void add_layer (Layer layer) { @@ -66,18 +107,52 @@ } public void add_path (Path path) { - paths.add (path); + FastPath p = new FastPath.for_path (path); + objects.add (p); } + public void add_object (Object object) { + objects.add (object); + } + + public void append_paths (PathList path_list) { + foreach (Path p in path_list.paths) { + add_path (p); + } + } + + private FastPath? get_fast_path (Path path) { + foreach (Object o in objects) { + if (o is FastPath) { + FastPath p = (FastPath) o; + if (p.get_path () == path) { + return p; + } + } + } + + return null; + } + public void remove_path (Path path) { - paths.remove (path); + FastPath? p = get_fast_path (path); + + if (p != null) { + objects.remove ((!) p); + } + foreach (Layer sublayer in subgroups) { sublayer.remove_path (path); } } + public void remove (Object o) { + objects.remove (o); + } + public void remove_layer (Layer layer) { subgroups.remove (layer); + foreach (Layer sublayer in subgroups) { sublayer.remove_layer (layer); } @@ -87,7 +162,7 @@ Layer layer = new Layer (); layer.name = name; - layer.paths = paths.copy (); + layer.objects = objects.copy (); layer.visible = visible; foreach (Layer l in subgroups) { @@ -111,7 +186,7 @@ px2 = Glyph.CANVAS_MIN; py2 = Glyph.CANVAS_MIN; - foreach (Path p in get_all_paths ().paths) { + foreach (Object p in get_all_objects ().objects) { if (px > p.xmin) { px = p.xmin; } @@ -136,14 +211,14 @@ } public void print (int indent = 0) { - foreach (Path p in paths.paths) { + foreach (Object o in objects) { for (int i = 0; i < indent; i++) { stdout.printf ("\t"); } - stdout.printf (@"Path open: $(p.is_open ())"); + stdout.printf (@"Path open: $(o.is_open ())"); - if (p.color != null) { - stdout.printf (" %s", ((!) p.color).to_rgb_hex ()); + if (o.color != null) { + stdout.printf (" %s", ((!) o.color).to_rgb_hex ()); } stdout.printf ("\n");
--- a/libbirdfont/MenuTab.vala +++ b/libbirdfont/MenuTab.vala @@ -645,28 +645,28 @@ Gee.ArrayList<Path> paths = new Gee.ArrayList<Path> (); // selected objects - foreach (Path p in g.active_paths) { + foreach (Path p in g.get_active_paths ()) { paths.add (PenTool.simplify (p, false, PenTool.simplification_threshold)); } // selected segments if (paths.size == 0) { - foreach (Path p in g.get_all_paths ()) { + foreach (Path p in g.get_active_paths ()) { g.add_active_path (null, p); } - foreach (Path p in g.active_paths) { + foreach (Path p in g.get_active_paths ()) { paths.add (PenTool.simplify (p, true, PenTool.simplification_threshold)); } } g.store_undo_state (); - foreach (Path p in g.active_paths) { - g.layers.remove_path (p); + foreach (Object o in g.active_paths) { + g.layers.remove (o); } - foreach (Path p in g.active_paths) { + foreach (Path p in g.get_active_paths ()) { g.layers.remove_path (p); }
--- a/libbirdfont/MoveTool.vala +++ b/libbirdfont/MoveTool.vala @@ -94,8 +94,8 @@ g.store_undo_state (); } - foreach (Path p in g.active_paths) { - g.layers.remove_path (p); + foreach (Object p in g.active_paths) { + g.layers.remove (p); g.update_view (); } @@ -138,7 +138,7 @@ } } - foreach (Path path in glyph.active_paths) { + foreach (Object path in glyph.active_paths) { path.move (delta_x, delta_y); } } @@ -167,7 +167,7 @@ if (GridTool.is_visible () && moved) { tie_paths_to_grid (glyph); } else if (GridTool.has_ttf_grid ()) { - foreach (Path p in glyph.active_paths) { + foreach (Object p in glyph.active_paths) { tie_path_to_ttf_grid (p); } } @@ -184,8 +184,11 @@ objects_moved (); DrawingTools.resize_tool.signal_objects_rotated (); - foreach (Path p in glyph.active_paths) { - p.create_full_stroke (); + foreach (Object o in glyph.active_paths) { + if (o is FastPath) { + FastPath path = (FastPath) o; + path.get_path ().create_full_stroke (); + } } } else { objects_deselected (); @@ -194,7 +197,7 @@ public void press (int b, int x, int y) { Glyph glyph = MainWindow.get_current_glyph (); - Path p; + Object object; bool selected = false; Layer? group; Layer g; @@ -207,20 +210,20 @@ 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); + 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 (Path lp in g.paths.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_path ((!) group, lp); + glyph.add_active_object ((!) group, lp); } } } else if (!KeyBindings.has_shift ()) { @@ -256,10 +259,10 @@ glyph.clear_active_paths (); - foreach (Path p in glyph.get_paths_in_current_layer ()) { + foreach (Object p in glyph.get_objects_in_current_layer ()) { if (p.xmin > x1 && p.xmax < x2 && p.ymin < y1 && p.ymax > y2) { - if (p.points.size > 0) { - glyph.add_active_path (null, p); + if (!p.is_empty ()) { + glyph.add_active_object (null, p); } } } @@ -280,7 +283,7 @@ get_selection_box_boundaries (out x, out y, out w, out h); - foreach (Path path in glyph.active_paths) { + foreach (Object path in glyph.active_paths) { path.move (glyph.left_limit - x + w / 2, font.base_line - y + h / 2); } @@ -317,23 +320,26 @@ px2 = -10000; py2 = -10000; - foreach (Path p in glyph.active_paths) { - p.update_region_boundaries (); - - if (px > p.xmin) { - px = p.xmin; - } + foreach (Object o in glyph.active_paths) { + if (o is FastPath) { + Path p = ((FastPath) o).get_path (); + p.update_region_boundaries (); + + if (px > p.xmin) { + px = p.xmin; + } - if (py > p.ymin) { - py = p.ymin; - } + if (py > p.ymin) { + py = p.ymin; + } - if (px2 < p.xmax) { - px2 = p.xmax; - } - - if (py2 < p.ymax) { - py2 = p.ymax; + if (px2 < p.xmax) { + px2 = p.xmax; + } + + if (py2 < p.ymax) { + py2 = p.ymax; + } } } @@ -367,7 +373,7 @@ break; } - foreach (Path path in glyph.active_paths) { + foreach (Object path in glyph.active_paths) { path.move (x * Glyph.ivz (), y * Glyph.ivz ()); } @@ -378,7 +384,7 @@ glyph.redraw_area (0, 0, glyph.allocation.width, glyph.allocation.height); } - static void tie_path_to_ttf_grid (Path p) { + static void tie_path_to_ttf_grid (Object p) { double sx, sy, qx, qy; sx = p.xmax; @@ -428,7 +434,7 @@ dx_min = Math.fabs (qx - minx); dx_max = Math.fabs (sx - maxx); - foreach (Path p in g.active_paths) { + foreach (Object p in g.active_paths) { if (dy_min < dy_max) { p.move (0, qy - miny); } else { @@ -447,8 +453,10 @@ public static void update_boundaries_for_selection () { Glyph glyph = MainWindow.get_current_glyph (); - foreach (Path p in glyph.active_paths) { - p.update_region_boundaries (); + foreach (Object o in glyph.active_paths) { + if (o is FastPath) { + ((FastPath)o).get_path ().update_region_boundaries (); + } } } @@ -470,14 +478,19 @@ xc = selection_box_center_x; yc = selection_box_center_y; - foreach (Path p in glyph.active_paths) { - if (vertical) { - p.flip_vertical (); - } else { - p.flip_horizontal (); + foreach (Object p in glyph.active_paths) { + if (p is FastPath) { + Path path = ((FastPath) p).get_path (); + + // FIXME: move to object + if (vertical) { + path.flip_vertical (); + } else { + path.flip_horizontal (); + } + + path.reverse (); } - - p.reverse (); } get_selection_box_boundaries (out xc2, out yc2, out w, out h); @@ -485,7 +498,7 @@ dx = -(xc2 - xc); dy = -(yc2 - yc); - foreach (Path p in glyph.active_paths) { + foreach (Object p in glyph.active_paths) { p.move (dx, dy); } @@ -499,9 +512,9 @@ Glyph g = MainWindow.get_current_glyph (); g.clear_active_paths (); - foreach (Path p in g.get_paths_in_current_layer ()) { - if (p.points.size > 0) { - g.add_active_path (null, p); + foreach (Object p in g.get_objects_in_current_layer ()) { + if (!p.is_empty ()) { + g.add_active_object (null, p); } }
diff --git libbirdfont/Object.vala(new)
--- /dev/null +++ b/libbirdfont/Object.vala @@ -1,1 +1,89 @@ + /* + 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; + using Math; + + namespace BirdFont { + + public abstract class Object : GLib.Object { + bool open = false; + + public Color? color = null; + public Color? stroke_color = null; + public Gradient? gradient = null; + + /** Path boundaries */ + public double xmax = Glyph.CANVAS_MIN; + public double xmin = Glyph.CANVAS_MAX; + public double ymax = Glyph.CANVAS_MIN; + public double ymin = Glyph.CANVAS_MAX; + + public double rotation = 0; + public double stroke = 0; + public LineCap line_cap = LineCap.BUTT; + + public Object () { + } + + public Object.create_copy (Object o) { + open = o.open; + + if (color != null) { + color = ((!) color).copy (); + } else { + color = null; + } + + if (stroke_color != null) { + stroke_color = ((!) stroke_color).copy (); + } else { + stroke_color = null; + } + + if (gradient != null) { + gradient = ((!) gradient).copy (); + } else { + gradient = null; + } + + xmax = o.xmax; + xmin = o.xmin; + ymax = o.ymax; + ymin = o.ymin; + + rotation = o.rotation; + stroke = o.stroke; + } + + public void set_open (bool open) { + this.open = open; + } + + public bool is_open () { + return open; + } + + public abstract void update_region_boundaries (); + public abstract bool is_over (double x, double y); + 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); + public abstract bool is_empty (); + public abstract void resize (double ratio_x, double ratio_y); + } + + }
--- /dev/null +++ b/libbirdfont/ObjectGroup.vala @@ -1,1 +1,58 @@ + /* + 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 ObjectGroup : GLib.Object { + public Gee.ArrayList<Object> objects; + + public ObjectGroup () { + objects = new Gee.ArrayList<Object> (); + } + + public Gee.Iterator<Object> iterator () { + return objects.iterator (); + } + + public void remove (Object p) { + objects.remove (p); + } + + public void add (Object p) { + objects.add (p); + } + + public void clear () { + objects.clear (); + } + + public void append (ObjectGroup group) { + foreach (Object o in group.objects) { + objects.add (o); + } + } + + public ObjectGroup copy () { + ObjectGroup objects_copy = new ObjectGroup (); + + foreach (Object o in objects) { + objects_copy.add (o.copy ()); + } + + return objects_copy; + } + } + + }
--- a/libbirdfont/OpenFontFormat/FontData.vala +++ b/libbirdfont/OpenFontFormat/FontData.vala @@ -14,7 +14,7 @@ namespace BirdFont { - public class FontData : Object { + public class FontData : GLib.Object { // Read pointer uint rp = 0;
--- a/libbirdfont/OpenFontFormat/GlyfData.vala +++ b/libbirdfont/OpenFontFormat/GlyfData.vala @@ -16,7 +16,7 @@ namespace BirdFont { - public class CoordinateFlags { + public class CoordinateFlags : GLib.Object { /** TTF coordinate flags. */ public static const uint8 NONE = 0;
--- a/libbirdfont/OpenFontFormat/GlyfTable.vala +++ b/libbirdfont/OpenFontFormat/GlyfTable.vala @@ -1,5 +1,5 @@ /* - Copyright (C) 2012, 2013, 2014 Johan Mattsson + Copyright (C) 2012 2013 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 @@ -478,7 +478,7 @@ end_points = new uint16[ncontours + 1]; for (int i = 0; i < ncontours; i++) { - end_points[i] = dis.read_ushort (); // FIXA: mind shot vector is negative + end_points[i] = dis.read_ushort (); // FIXME: mind shot vector is negative if (i > 0 && end_points[i] < end_points[i -1]) { warning (@"Next endpoint has bad value in $(name.str). (end_points[i] > end_points[i -1]) ($(end_points[i]) > $(end_points[i -1])) i: $i ncontours: $ncontours");
--- a/libbirdfont/OpenFontFormat/OpenFontFormatReader.vala +++ b/libbirdfont/OpenFontFormat/OpenFontFormatReader.vala @@ -58,7 +58,7 @@ PARSE } - public class OpenFontFormatReader : Object { + public class OpenFontFormatReader : GLib.Object { public DirectoryTable directory_table; public FontData font_data = new FontData ();
--- a/libbirdfont/OpenFontFormat/OpenFontFormatWriter.vala +++ b/libbirdfont/OpenFontFormat/OpenFontFormatWriter.vala @@ -14,7 +14,7 @@ namespace BirdFont { - public class OpenFontFormatWriter : Object { + public class OpenFontFormatWriter : GLib.Object { DataOutputStream os; DataOutputStream os_mac;
--- a/libbirdfont/OpenFontFormat/OtfInputStream.vala +++ b/libbirdfont/OpenFontFormat/OtfInputStream.vala @@ -15,7 +15,7 @@ namespace BirdFont { /** Reader for otf data types. */ - public class OtfInputStream : Object { + public class OtfInputStream : GLib.Object { public FileInputStream fin; public DataInputStream din;
--- a/libbirdfont/OpenFontFormat/OtfTable.vala +++ b/libbirdfont/OpenFontFormat/OtfTable.vala @@ -14,7 +14,7 @@ namespace BirdFont { - public class OtfTable : Object { + public class OtfTable : GLib.Object { public string id = "NO_ID";
--- a/libbirdfont/OrientationTool.vala +++ b/libbirdfont/OrientationTool.vala @@ -30,8 +30,11 @@ select_action.connect ((self) => { Glyph g = MainWindow.get_current_glyph (); - foreach (Path p in g.active_paths) { - p.reverse (); + foreach (Object o in g.active_paths) { + if (o is FastPath) { + FastPath p = (FastPath) o; + p.get_path ().reverse (); + } } count_down = true; @@ -54,13 +57,17 @@ bool has_clockwise_paths = false; bool has_counter_clockwise_paths = false; - foreach (Path p in glyph.active_paths) { - if (p.is_clockwise ()) { - has_clockwise_paths = true; - } - - if (!p.is_clockwise ()) { - has_counter_clockwise_paths = true; + foreach (Object o in glyph.active_paths) { + if (o is FastPath) { + Path p = ((FastPath) o).get_path (); + + if (p.is_clockwise ()) { + has_clockwise_paths = true; + } + + if (!p.is_clockwise ()) { + has_counter_clockwise_paths = true; + } } }
--- a/libbirdfont/OtfFeatureTable.vala +++ b/libbirdfont/OtfFeatureTable.vala @@ -45,7 +45,7 @@ public override void selected_row (Row row, int column, bool delete_button) { int row_index = row.get_index (); - Object o; + GLib.Object o; String s; AlternateItem a;
--- a/libbirdfont/Path.vala +++ b/libbirdfont/Path.vala @@ -99,13 +99,12 @@ public bool highlight_last_segment = false; public string point_data = ""; + + private static Text? arrow = null; public Color? color = null; public Color? stroke_color = null; - public Gradient? gradient = null; - - private static Text? arrow = null; public Path () { string width; @@ -262,7 +261,7 @@ * Call Context.new_path (); before this method and Context.fill () * to show the path. */ - public void draw_path (Context cr, Glyph glyph, Color? color = null) { + public void draw_path (Context cr, Color? color = null) { unowned EditPoint? n = null; unowned EditPoint en; unowned EditPoint em; @@ -274,8 +273,8 @@ return; } - center_x = glyph.allocation.width / 2.0; - center_y = glyph.allocation.height / 2.0; + center_x = Glyph.xc (); + center_y = Glyph.yc (); ex = center_x + points.get (0).x; ey = center_y - points.get (0).y; @@ -2265,12 +2264,6 @@ PathList lines = new PathList (); lines = pl; - - /** // FIXME: Check automatic orientation. - foreach (Path p in pl.paths) { - lines.add (SvgParser.get_lines (p)); - } - */ foreach (Path p in lines.paths) { if (p.points.size > 1 && p != path
--- a/libbirdfont/PenTool.vala +++ b/libbirdfont/PenTool.vala @@ -765,8 +765,11 @@ p.path.reset_stroke (); } - foreach (Path path in g.active_paths) { - path.reset_stroke (); + foreach (Object path in g.active_paths) { + if (path is FastPath) { + FastPath p = (FastPath) path; + p.get_path ().reset_stroke (); + } } } @@ -1055,10 +1058,11 @@ // don't use set point to reflective to on open ends reflective = true; - foreach (Path path in MainWindow.get_current_glyph ().active_paths) { - if (path.is_open () && path.points.size > 0) { - if (selected_handle.parent == path.get_first_point () - || selected_handle.parent == path.get_last_point ()) { + foreach (Object path in MainWindow.get_current_glyph ().active_paths) { + if (path.is_open () && !path.is_empty () && path is FastPath) { + Path p = ((FastPath) path).get_path (); + if (selected_handle.parent == p.get_first_point () + || selected_handle.parent == p.get_last_point ()) { reflective = false; } } @@ -1229,7 +1233,10 @@ if (active_edit_point != null) { glyph.clear_active_paths (); - glyph.add_active_path (null, active_path); + + FastPath path = new FastPath.for_path (active_path); + glyph.add_active_object (null, path); + DrawingTools.update_stroke_settings (); if (KeyBindings.modifier != SHIFT) { @@ -1408,8 +1415,10 @@ foreach (Path merge in paths) { if (merge.points.size > 0) { - if (is_close_to_point (merge.points.get (merge.points.size - 1), px, py)) { - glyph.add_active_path (null, merge); + FastPath merged_path = new FastPath.for_path (merge); + + if (is_close_to_point (merge.points.get (merge.points.size - 1), px, py)) { + glyph.add_active_object (null, merged_path); active_path = merge; merge.reopen (); glyph.open_path (); @@ -1417,7 +1426,7 @@ } if (is_close_to_point (merge.points.get (0), px, py)) { - glyph.add_active_path (null, merge); + glyph.add_active_object (null, merged_path); active_path = merge; clear_directions (); merge.reopen (); @@ -1453,7 +1462,9 @@ force_direction (); glyph.clear_active_paths (); - glyph.add_active_path (null, path); + + FastPath closed_path = new FastPath.for_path (path); + glyph.add_active_object (null, closed_path); if (direction_changed) { path.reverse (); @@ -1492,11 +1503,12 @@ } else { union = merge_open_paths (path, merge); + FastPath union_path = new FastPath.for_path (union); glyph.add_path (union); glyph.delete_path (path); glyph.delete_path (merge); glyph.clear_active_paths (); - glyph.add_active_path (null, union); + glyph.add_active_object (null, union_path); union.reopen (); union.create_list (); @@ -1777,13 +1789,19 @@ active_edit_point = new_point.point; return_val_if_fail (glyph.active_paths.size > 0, new PointSelection.empty ()); - add_selected_point (selected_point, glyph.active_paths.get (glyph.active_paths.size - 1)); + Object object = glyph.active_paths.get (glyph.active_paths.size - 1); + + if (object is FastPath) { + Path path = ((FastPath) object).get_path (); + + add_selected_point (selected_point, path); - active_path = new_point.path; - glyph.clear_active_paths (); - glyph.add_active_path (null, new_point.path); - - move_selected = true; + active_path = new_point.path; + glyph.clear_active_paths (); + glyph.add_active_object (null, object); + + move_selected = true; + } return new_point; } @@ -1819,6 +1837,7 @@ EditPoint inserted; bool stroke = StrokeTool.add_stroke; Glyph g = MainWindow.get_current_glyph (); + FastPath path; if (g.active_paths.size == 0) { np = new Path (); @@ -1826,7 +1845,8 @@ np.stroke = stroke ? StrokeTool.stroke_width : 0; np.line_cap = StrokeTool.line_cap; - g.add_active_path (null, np); + path = new FastPath.for_path (np); + g.add_active_object (null, path); active_path = np; selected_path = np; @@ -1852,7 +1872,8 @@ } g.clear_active_paths (); - g.add_active_path (null, np); + path = new FastPath.for_path (np); + g.add_active_object (null, path); active_path = np; selected_path = np; @@ -2062,7 +2083,8 @@ selected_handle.selected = true; active_path = p.path; - g.add_active_path (null, active_path); + FastPath path = new FastPath.for_path (active_path); + g.add_active_object (null, path); } public static void add_selected_point (EditPoint p, Path path) {
--- a/libbirdfont/ResizeTool.vala +++ b/libbirdfont/ResizeTool.vala @@ -21,7 +21,7 @@ bool resize_path_proportional = false; bool resize_width = false; - Path? resized_path = null; + Object? resized_path = null; double last_resize_y; double last_resize_x; @@ -63,13 +63,13 @@ }); press_action.connect((self, b, x, y) => { - Path last_path; + Object last_path; Glyph glyph; glyph = MainWindow.get_current_glyph (); glyph.store_undo_state (); - foreach (Path p in glyph.active_paths) { + foreach (Object p in glyph.active_paths) { if (is_over_resize_handle (p, x, y)) { resize_path_proportional = true; resized_path = p; @@ -87,7 +87,7 @@ } } - foreach (Path p in glyph.active_paths) { + foreach (Object p in glyph.active_paths) { if (is_over_rotate_handle (p, x, y)) { rotate_path = true; return; @@ -121,8 +121,11 @@ update_selection_box (); GlyphCanvas.redraw (); - foreach (Path p in MainWindow.get_current_glyph ().active_paths) { - p.create_full_stroke (); + foreach (Object p in MainWindow.get_current_glyph ().active_paths) { + if (p is FastPath) { + FastPath path = (FastPath) p; + path.get_path ().create_full_stroke (); + } } }); @@ -150,10 +153,6 @@ || resize_width) { glyph = MainWindow.get_current_glyph (); - - foreach (Path selected_path in glyph.active_paths) { - selected_path.reset_stroke (); - } GlyphCanvas.redraw (); } @@ -234,9 +233,9 @@ public void rotate_selected_paths (double angle, double cx, double cy) { Glyph glyph = MainWindow.get_current_glyph (); double dx, dy, xc2, yc2, w, h; - Path last_path; + Object last_path; - foreach (Path p in glyph.active_paths) { + foreach (Object p in glyph.active_paths) { p.rotate (angle, cx, cy); } @@ -245,7 +244,7 @@ dx = -(xc2 - cx); dy = -(yc2 - cy); - foreach (Path p in glyph.active_paths) { + foreach (Object p in glyph.active_paths) { p.move (dx, dy); } @@ -287,7 +286,7 @@ rotate_selected_paths (rotation - last_rotate, selection_box_center_x, selection_box_center_y); } - static bool is_over_rotate_handle (Path p, double x, double y) { + static bool is_over_rotate_handle (Object p, double x, double y) { double cx, cy, hx, hy; double size = 10; bool inx, iny; @@ -364,17 +363,16 @@ if (!selected) { glyph.clear_active_paths (); - foreach (Path path in glyph.get_visible_paths ()) { - glyph.add_active_path (null, path); + foreach (Object path in glyph.get_visible_objects ()) { + glyph.add_active_object (null, path); } } get_selection_min (out resize_pos_x, out resize_pos_y); // resize paths - foreach (Path selected_path in glyph.active_paths) { + foreach (Object selected_path in glyph.active_paths) { selected_path.resize (ratio_x, ratio_y); - selected_path.reset_stroke (); } // move paths relative to the updated xmin and xmax @@ -382,7 +380,7 @@ dx = resize_pos_x - selection_minx; dy = resize_pos_y - selection_miny; - foreach (Path selected_path in glyph.active_paths) { + foreach (Object selected_path in glyph.active_paths) { selected_path.move (dx, dy); } @@ -470,7 +468,7 @@ DrawingTools.move_tool.move_to_baseline (); - foreach (Path path in glyph.active_paths) { + foreach (Object path in glyph.active_paths) { path.move (0, -descender * scale); } @@ -481,7 +479,7 @@ Glyph glyph = MainWindow.get_current_glyph (); x = double.MAX; y = double.MAX; - foreach (Path p in glyph.active_paths) { + foreach (Object p in glyph.active_paths) { if (p.xmin < x) { x = p.xmin; } @@ -497,11 +495,11 @@ double h, w; double ratio = get_resize_ratio (x, y); - foreach (Path selected_path in glyph.active_paths) { + foreach (Object selected_path in glyph.active_paths) { h = selected_path.ymax - selected_path.ymin; w = selected_path.xmax - selected_path.xmin; - if (selected_path.points.size <= 1) { + if (selected_path.is_empty ()) { // FIXME: test with one point continue; } @@ -513,13 +511,13 @@ return true; } - bool is_over_resize_handle (Path p, double x, double y) { + bool is_over_resize_handle (Object p, double x, double y) { double handle_x, handle_y; get_resize_handle_position (out handle_x, out handle_y); return Path.distance (handle_x, x, handle_y, y) < 12 * MainWindow.units; } - bool is_over_horizontal_resize_handle (Path p, double x, double y) { + bool is_over_horizontal_resize_handle (Object p, double x, double y) { double handle_x, handle_y; get_horizontal_reseize_handle_position (out handle_x, out handle_y); return Path.distance (handle_x, x, handle_y, y) < 12 * MainWindow.units; @@ -540,26 +538,28 @@ if (!selected_paths) { glyph.clear_active_paths (); - foreach (Path path in glyph.get_visible_paths ()) { - glyph.add_active_path (null, path); + foreach (Object path in glyph.get_visible_objects ()) { + glyph.add_active_object (null, path); } } glyph.selection_boundaries (out x, out y, out w, out h); - foreach (Path path in glyph.active_paths) { - SvgParser.apply_matrix (path, 1, 0, s, 1, 0, 0); - path.skew = skew; - path.update_region_boundaries (); + foreach (Object path in glyph.active_paths) { + if (path is FastPath) { // FIXME: other objects + Path p = ((FastPath) path).get_path (); + SvgParser.apply_matrix (p, 1, 0, s, 1, 0, 0); + p.skew = skew; + path.update_region_boundaries (); + } } glyph.selection_boundaries (out nx, out y, out nw, out h); dx = -(nx - x); - foreach (Path p in glyph.active_paths) { + foreach (Object p in glyph.active_paths) { p.move (dx, 0); - p.reset_stroke (); } dw = (nw - w);
--- a/libbirdfont/StrokeTool.vala +++ b/libbirdfont/StrokeTool.vala @@ -51,22 +51,27 @@ convert_stroke = true; g.store_undo_state (); - foreach (Path p in g.active_paths) { - if (p.stroke > 0) { - paths.append (p.get_completed_stroke ()); + foreach (Object o in g.active_paths) { + if (o is FastPath) { + FastPath path = (FastPath) o; + Path p = path.get_path (); + + if (p.stroke > 0) { + paths.append (p.get_completed_stroke ()); + } } } if (paths.paths.size > 0) { - foreach (Path p in g.active_paths) { - g.layers.remove_path (p); + foreach (Object o in g.active_paths) { + g.layers.remove (o); } g.active_paths.clear (); foreach (Path np in paths.paths) { g.add_path (np); - g.active_paths.add (np); + g.active_paths.add (new FastPath.for_path (np)); } PenTool.update_orientation (); @@ -134,11 +139,15 @@ g.store_undo_state (); - foreach (Path p in g.active_paths) { - if (p.stroke == 0) { - o.add (p); - } else { - o.append (p.get_completed_stroke ()); + foreach (Object object in g.active_paths) { + if (object is FastPath) { + Path p = ((FastPath) object).get_path (); + + if (p.stroke == 0) { + o.add (p); + } else { + o.append (p.get_completed_stroke ()); + } } } @@ -217,8 +226,8 @@ return; } - foreach (Path p in g.active_paths) { - g.delete_path (p); + foreach (Object object in g.active_paths) { + g.layers.remove (object); } g.clear_active_paths (); @@ -226,8 +235,9 @@ remove_merged_curve_parts (new_paths); foreach (Path p in new_paths.paths) { - g.add_path (p); - g.add_active_path (null, p); + FastPath path = new FastPath.for_path (p); + g.add_object (path); + g.add_active_object (null, path); } PenTool.update_orientation ();
--- a/libbirdfont/SvgFontFormatWriter.vala +++ b/libbirdfont/SvgFontFormatWriter.vala @@ -14,7 +14,7 @@ namespace BirdFont { - class SvgFontFormatWriter : Object { + class SvgFontFormatWriter : GLib.Object { DataOutputStream os;
--- a/libbirdfont/SvgParser.vala +++ b/libbirdfont/SvgParser.vala @@ -160,12 +160,10 @@ glyph = MainWindow.get_current_glyph (); foreach (Path p in path_list.paths) { - glyph.add_path (p); - } - - foreach (Path p in path_list.paths) { - glyph.add_active_path (null, p); // FIXME: groups - p.update_region_boundaries (); + FastPath path = new FastPath.for_path (p); + glyph.add_object (path); + glyph.add_active_object (null, path); // FIXME: groups + path.update_region_boundaries (); } glyph.close_path (); @@ -302,7 +300,15 @@ } private void transform (string transform_functions, Layer layer) { - transform_paths (transform_functions, layer.paths); + PathList path_list = new PathList (); + + foreach (Object o in layer.objects) { + if (o is FastPath) { + path_list.add (((FastPath) o).get_path ()); + } + } + + transform_paths (transform_functions, path_list); transform_subgroups (transform_functions, layer); } @@ -315,7 +321,7 @@ private void transform_paths (string transform_functions, PathList pl) { string data = transform_functions.dup (); string[] functions; - + // use only a single space as separator while (data.index_of (" ") > -1) { data = data.replace (" ", " "); @@ -538,7 +544,7 @@ } style.apply (npl); - pl.paths.append (npl); + pl.append_paths (npl); } private void parse_ellipse (Tag tag, Layer pl) { @@ -606,7 +612,7 @@ } style.apply (npl); - pl.paths.append (npl); + pl.append_paths (npl); } private void parse_line (Tag tag, Layer pl) { @@ -683,10 +689,10 @@ } style.apply (npl); - pl.paths.append (npl); + pl.append_paths (npl); } - private void parse_rect (Tag tag, Layer pl) { + private void parse_rect (Tag tag, Layer layer) { Path p; double x, y, x2, y2; BezierPoints[] bezier_points; @@ -784,22 +790,22 @@ } style.apply (npl); - pl.paths.append (npl); + layer.append_paths (npl); } - private void parse_polygon (Tag tag, Layer pl) { + private void parse_polygon (Tag tag, Layer layer) { PathList path_list = get_polyline (tag); foreach (Path p in path_list.paths) { p.close (); } - pl.paths.append (path_list); + layer.append_paths (path_list); } - private void parse_polyline (Tag tag, Layer pl) { - pl.paths.append (get_polyline (tag)); + private void parse_polyline (Tag tag, Layer layer) { + layer.append_paths (get_polyline (tag)); } private PathList get_polyline (Tag tag) { @@ -836,7 +842,7 @@ return path_list; } - private void parse_path (Tag tag, Layer pl) { + private void parse_path (Tag tag, Layer layer) { Glyph glyph = MainWindow.get_current_glyph (); PathList path_list = new PathList (); SvgStyle style = new SvgStyle (); @@ -863,37 +869,47 @@ if (hidden) { return; } - - pl.paths.append (path_list); + + foreach (Path path in path_list.paths) { + layer.add_path (path); + } + style.apply (path_list); // assume the even odd rule is applied and convert the path // to a path using the non-zero rule int inside_count; bool inside; - foreach (Path p1 in pl.paths.paths) { - inside_count = 0; - - foreach (Path p2 in pl.paths.paths) { - if (p1 != p2) { - inside = true; + foreach (Object o1 in layer.objects) { + if (o1 is FastPath) { + Path p1 = ((FastPath) o1).get_path (); + inside_count = 0; + + foreach (Object o2 in layer.objects) { + if (o2 is FastPath) { + Path p2 = ((FastPath) o2).get_path (); - foreach (EditPoint ep in p1.points) { - if (!is_inside (ep, p2)) { - inside = false; + if (p1 != p2) { + inside = true; + + foreach (EditPoint ep in p1.points) { + if (!is_inside (ep, p2)) { + inside = false; + } + } + + if (inside) { + inside_count++; + } } - } - - if (inside) { - inside_count++; } } - } - - if (inside_count % 2 == 0) { - p1.force_direction (Direction.CLOCKWISE); - } else { - p1.force_direction (Direction.COUNTER_CLOCKWISE); + + if (inside_count % 2 == 0) { + p1.force_direction (Direction.CLOCKWISE); + } else { + p1.force_direction (Direction.COUNTER_CLOCKWISE); + } } }
--- a/libbirdfont/Test.vala +++ b/libbirdfont/Test.vala @@ -14,7 +14,7 @@ namespace BirdFont { - public class Test : Object { + public class Test : GLib.Object { public Callback callback; public string name; double time_stamp;
--- a/libbirdfont/TrackTool.vala +++ b/libbirdfont/TrackTool.vala @@ -121,8 +121,11 @@ start_update_timer (); drawing = true; - foreach (Path path in glyph.active_paths) { - path.create_full_stroke (); // cache merged stroke parts + foreach (Object path in glyph.active_paths) { + if (path is FastPath) { + // cache merged stroke parts + ((FastPath) path).get_path ().create_full_stroke (); + } } } }); @@ -146,8 +149,9 @@ g = MainWindow.get_current_glyph (); if (g.active_paths.size > 0) { // set type for last point - p = g.active_paths.get (g.active_paths.size - 1); - + Object o = g.active_paths.get (g.active_paths.size - 1); + p = ((FastPath) o).get_path (); + if (p.points.size > 1) { previous = p.points.get (p.points.size - 1); previous.type = DrawingTools.point_type; @@ -164,8 +168,10 @@ add_endpoint_and_merge (x, y); } - foreach (Path path in g.active_paths) { - convert_hidden_points (path); + foreach (Object path in g.active_paths) { + if (path is FastPath) { + convert_hidden_points (((FastPath) path).get_path ()); + } } g.clear_active_paths (); @@ -403,7 +409,14 @@ return; } - p = glyph.active_paths.get (glyph.active_paths.size - 1); + Object o = glyph.active_paths.get (glyph.active_paths.size - 1); + + if (o is FastPath) { + warning ("Object is not a path"); + return; + } + + p = ((FastPath) o).get_path (); p.reopen (); px = Glyph.path_coordinate_x (x); py = Glyph.path_coordinate_y (y); @@ -488,7 +501,15 @@ return new Path (); } - return glyph.active_paths.get (glyph.active_paths.size - 1); + Object o = glyph.active_paths.get (glyph.active_paths.size - 1); + + if (likely (o is FastPath)) { + return ((FastPath) o).get_path (); + } + + warning ("Active object is a path."); + + return new Path (); } /** Delete all points close to the pixel at x,y. */