Commit a3ad8bf
Self interpolation
Changed files (5)
modifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/GlyphCollection.valamodifiedlibbirdfont/OverviewTools.valamodifiedlibbirdfont/Path.valamodifiedlibbirdfont/StrokeTool.vala
Diff
@@ -2432,17 +2432,23 @@ public class Glyph : FontDisplay { } } - public override void magnify (double magnification) {- double x_center = path_coordinate_x (xc ());- double y_center = path_coordinate_y (yc ());+ public override void magnify (double magnification) {+ double x_center = path_coordinate_x (xc ());+ double y_center = path_coordinate_y (yc ()); - view_zoom *= 1 + magnification;+ view_zoom *= 1 + magnification; - view_offset_x -= path_coordinate_x (xc ()) - x_center;- view_offset_y += path_coordinate_y (yc ()) - y_center;+ view_offset_x -= path_coordinate_x (xc ()) - x_center;+ view_offset_y += path_coordinate_y (yc ()) - y_center; - GlyphCanvas.redraw ();- }+ GlyphCanvas.redraw ();+ }+ + public void self_interpolate (double weight) {+ foreach (Path p in get_visible_paths ()) {+ p.self_interpolate (weight);+ }+ } } }@@ -58,9 +58,15 @@ public class GlyphCollection : GLib.Object { /** This method returns the current master, it has global state. */ public GlyphMaster get_current_master () { int i = current_master;+ GlyphMaster m; - if (i >= glyph_masters.size) {+ if (unlikely (glyph_masters.size == 0)) { warning("No master is set for glyph.");+ m = new GlyphMaster ();+ add_master (m);+ return m;+ } else if (unlikely (i >= glyph_masters.size)) {+ warning(@"No master at index $i."); i = glyph_masters.size - 1; } @@ -114,6 +120,15 @@ public class GlyphCollection : GLib.Object { glyph_masters.add (master); } + public void set_selected_master (GlyphMaster m) {+ current_master = glyph_masters.index_of (m);+ + if (current_master == -1) {+ warning ("Master does not exits");+ current_master = 0;+ }+ }+ public Glyph get_current () { Glyph? g = get_current_master ().get_current (); @@ -126,6 +141,18 @@ public class GlyphCollection : GLib.Object { } public Glyph get_interpolated (double weight) {+ if (weight == 0) { // FIXME: compare to master weight+ return get_current (); + }+ + if (glyph_masters.size == 1) {+ Glyph master1 = get_current ().copy ();+ master1.self_interpolate (weight);+ return master1;+ } else {+ warning("Not implemented.");+ }+ return get_current (); } @@ -152,20 +152,26 @@ public class OverviewTools : ToolCollection { glyph_expander.add_tool (curve_orientation); SpinButton master_size;- current_master_size = 1- master_size = new SpinButton ("master_size", t_("Master Size")); /// master refers to a master in a multi-master font+ current_master_size = 0;+ master_size = new SpinButton ("master_size", t_("Master Size")); /// Master refers to a glyph master in a multi-master font. master_size.set_big_number (false);- master_size.set_int_value ("1.000");+ master_size.set_int_value ("0.000"); master_size.set_int_step (1);- master_size.set_min (0.001);- master_size.set_max (9);+ master_size.set_min (-2);+ master_size.set_max (2); master_size.show_icon (true); master_size.set_persistent (false); master_size.new_value_action.connect ((self) => { current_master_size = self.get_value ();+ MainWindow.get_overview ().update_item_list ();+ GlyphCanvas.redraw (); }); multi_master.add_tool (master_size);- ++ Tool create_new_master = new Tool ("new_master", t_("Create new master font")); /// Master is a master in a multi-master font.+ create_new_master.select_action.connect (create_master);+ multi_master.add_tool (create_new_master);+ expanders.add (font_name); expanders.add (zoom_expander); expanders.add (character_sets);@@ -177,6 +183,32 @@ public class OverviewTools : ToolCollection { } } + void create_master () {+ Font font = BirdFont.get_current_font ();+ int i = 0;+ GlyphCollection glyph_collection;+ GlyphCollection? gc = font.get_glyph_collection_indice (i);+ Glyph g;+ + while (gc != null) {+ glyph_collection = (!) gc;+ + // FIXME: MASTER NAME+ GlyphMaster master = new GlyphMaster.for_id("Master 2"); + g = glyph_collection.get_interpolated (current_master_size);+ master.add_glyph(g);+ glyph_collection.add_master (master);+ glyph_collection.set_selected_master (master);+ print(@"$(glyph_collection.get_name ())\n");+ + i++;+ gc = font.get_glyph_collection_indice (i);+ }++ MainWindow.get_overview ().update_item_list ();+ GlyphCanvas.redraw ();+ }+ void fix_curve_orientation () { OverView o; Glyph g;@@ -2633,6 +2633,88 @@ public class Path : GLib.Object { h.move_to_coordinate (nx, ny); } }+ + public EditPoint get_closest_point (double x, double y) {+ double min = Glyph.CANVAS_MAX;+ double d; + EditPoint p = new EditPoint (Glyph.CANVAS_MAX, Glyph.CANVAS_MAX);+ + foreach (EditPoint ep in points) {+ d = distance (x, ep.x, y, ep.y);+ + if (d < min) {+ min = d;+ p = ep;+ }+ }+ + return p;+ }+ + public void self_interpolate (double weight) {+ Path master;+ + if (stroke > 0) {+ stroke += 5 * weight * 2;+ + if (stroke < 0.002) {+ stroke = 0.002;+ }+ } else {+ remove_points_on_points ();+ master = get_self_interpolated_master ();+ interpolate_path (master, weight);+ recalculate_linear_handles ();+ } + }+ + Path get_self_interpolated_master () {+ Path master = new Path ();+ EditPoint ep1, ep2, none;+ + none = new EditPoint ();+ for (int i = 0; i < points.size; i++) {+ ep1 = points.get (i).copy ();+ ep2 = ep1.copy ();+ + StrokeTool.move_segment (ep1, none, 5);+ StrokeTool.move_segment (none, ep2, 5);+ + ep1.x = (ep2.x + ep1.x) / 2;+ ep1.y = (ep2.y + ep1.y) / 2;+ + master.add_point (ep1.copy ());+ }+ + return master; + }+ + void interpolate_path (Path master, double weight) {+ EditPoint ep, master_point;+ EditPointHandle h;+ double length;+ + if (unlikely (points.size != master.points.size)) {+ warning ("Master and path must have the same number of points.");+ return;+ }+ + for (int i = 0; i < points.size; i++) {+ ep = points.get (i);+ master_point = master.points.get (i);+ + ep.x += (master_point.x - ep.x) * weight;+ ep.y += (master_point.y - ep.y) * weight;++ h = ep.get_right_handle ();+ length = master_point.get_right_handle ().length;+ h.length = length * weight + h.length * (1 - weight);+ + h = ep.get_left_handle ();+ length = master_point.get_left_handle ().length;+ h.length = length * weight + h.length * (1 - weight) ;+ }+ } } }@@ -1309,7 +1309,7 @@ public class StrokeTool : GLib.Object { return merged; } - void move_segment (EditPoint stroke_start, EditPoint stroke_stop, double thickness) {+ public static void move_segment (EditPoint stroke_start, EditPoint stroke_stop, double thickness) { EditPointHandle r, l; double m, n; double qx, qy;