Commit ed8f47a
default value for tied control point
Changed files (8)
modifiedsrc/EditPoint.valamodifiedsrc/EditPointHandle.valamodifiedsrc/Font.valamodifiedsrc/Glyph.valamodifiedsrc/Path.valamodifiedsrc/PenTool.valamodifiedsrc/Svg.valamodifiedsrc/Toolbox.vala
Diff
@@ -102,20 +102,29 @@ class EditPoint { /** Set bezier points for linear paths. */ public void recalculate_linear_handles () { EditPointHandle h;- unowned EditPoint n;+ EditPoint n; double nx, ny; - return_if_fail (type == PointType.LINE);- // left handle if (prev != null) { n = get_prev ().data; h = get_left_handle (); - nx = x + ((n.x - x) / 3);- ny = y + ((n.y - y) / 3);+ if (h.type == PointType.LINE) {+ nx = x + ((n.x - x) / 3);+ ny = y + ((n.y - y) / 3);+ + h.move_to_coordinate (nx, ny);+ }+ + h = n.get_right_handle (); - h.move_to_coordinate (nx, ny); + if (h.type == PointType.LINE) { + nx = n.x + ((x - n.x) / 3);+ ny = n.y + ((y - n.y) / 3);+ + h.move_to_coordinate (nx, ny); + } } // right handle@@ -123,10 +132,21 @@ class EditPoint { n = get_next ().data; h = get_right_handle (); - nx = x + ((n.x - x) / 3);- ny = y + ((n.y - y) / 3);+ if (h.type == PointType.LINE) {+ nx = x + ((n.x - x) / 3);+ ny = y + ((n.y - y) / 3);+ + h.move_to_coordinate (nx, ny);+ }+ + h = n.get_left_handle (); - h.move_to_coordinate (nx, ny);+ if (h.type == PointType.LINE) {+ nx = n.x + ((x - n.x) / 3);+ ny = n.y + ((y - n.y) / 3);+ + h.move_to_coordinate (nx, ny); + } } } @@ -151,9 +171,11 @@ class EditPoint { new_point.right_handle.angle = right_handle.angle; new_point.right_handle.length = right_handle.length;+ new_point.right_handle.type = right_handle.type; new_point.left_handle.angle = left_handle.angle; new_point.left_handle.length = left_handle.length; + new_point.left_handle.type = left_handle.type; return new_point; }@@ -194,11 +216,11 @@ class EditPoint { return double.MAX; } - public EditPointHandle get_left_handle () {+ public unowned EditPointHandle get_left_handle () { return left_handle; } - public EditPointHandle get_right_handle () {+ public unowned EditPointHandle get_right_handle () { return right_handle; } @@ -27,7 +27,9 @@ class EditPointHandle { public double angle; public double length; - public unowned EditPoint parent;+ public PointType type;+ + public EditPoint parent; EditPoint? visual_handle = null; @@ -37,12 +39,18 @@ class EditPointHandle { this.parent = none; this.angle = 0; this.length = 10;+ this.type = PointType.LINE; } public EditPointHandle (EditPoint parent, double angle, double length) { this.parent = parent; this.angle = angle; this.length = length;+ this.type = PointType.LINE;+ }++ public void set_point_type (PointType point_type) {+ type = point_type; } public double x () {@@ -479,11 +479,17 @@ class Font : GLib.Object { foreach (var ep in p.points) { os.put_string (@"<point x=\"$(ep.x)\" y=\"$(ep.y)\" "); - if (ep.type == PointType.CURVE) {+ if (ep.right_handle.type == PointType.CURVE) { os.put_string (@"right_angle=\"$(ep.right_handle.angle)\" "); os.put_string (@"right_length=\"$(ep.right_handle.length)\" ");+ }+ + if (ep.left_handle.type == PointType.CURVE) { os.put_string (@"left_angle=\"$(ep.left_handle.angle)\" "); os.put_string (@"left_length=\"$(ep.left_handle.length)\" "); + }+ + if (ep.right_handle.type == PointType.CURVE || ep.left_handle.type == PointType.CURVE) { os.put_string (@"tie_handles=\"$(ep.tie_handles)\" "); } @@ -832,6 +838,9 @@ class Font : GLib.Object { double length_right = 0; double length_left = 0; + PointType type_right = PointType.LINE;+ PointType type_left = PointType.LINE;+ bool tie_handles = false; EditPoint ep;@@ -844,9 +853,17 @@ class Font : GLib.Object { if (attr_name == "y") y = double.parse (attr_content); if (attr_name == "right_angle") {- type = PointType.CURVE;+ type = PointType.CURVE; // FIXA: delete, maybe } + if (attr_name == "right_angle") {+ type_right = PointType.CURVE;+ } ++ if (attr_name == "left_angle") {+ type_left = PointType.CURVE;+ }+ if (attr_name == "right_angle") angle_right = double.parse (attr_content); if (attr_name == "right_length") length_right = double.parse (attr_content); if (attr_name == "left_angle") angle_left = double.parse (attr_content);@@ -861,9 +878,11 @@ class Font : GLib.Object { ep.right_handle.angle = angle_right; ep.right_handle.length = length_right;+ ep.right_handle.type = type_right; ep.left_handle.angle = angle_left; ep.left_handle.length = length_left;+ ep.left_handle.type = type_left; ep.tie_handles = tie_handles; @@ -816,6 +816,9 @@ class Glyph : FontDisplay { p.add_point (e); e.type = PointType.CURVE; + e.right_handle.type = PointType.CURVE;+ e.left_handle.type = PointType.CURVE;+ paths.append (p); active_path = p; flipping_point_on_path = new_point_on_path;@@ -128,29 +128,26 @@ class Path { cr.stroke (); - // control points for curvature- foreach (EditPoint e in ep) {- if (e.get_active_handle () || e.selected_handle > 0)- draw_edit_point_handles (e, cr);- }- - // control points- foreach (EditPoint e in ep) {- draw_edit_point (e, cr);+ if (is_editable ()) {+ // control points for curvature+ foreach (EditPoint e in ep) {+ if (e.get_active_handle () || e.selected_handle > 0)+ draw_edit_point_handles (e, cr);+ }+ + // control points+ foreach (EditPoint e in ep) {+ draw_edit_point (e, cr);+ } }- } private void draw_next (EditPoint e, EditPoint en, Context cr) {-- if (en.type == PointType.CURVE || e.type == PointType.CURVE) {- draw_curve (e, en, cr);- } else if (en.type == PointType.LINE && e.type == PointType.LINE) {+ if (en.right_handle.type == PointType.LINE && e.right_handle.type == PointType.LINE) { draw_line (e, en, cr);- } else if (unlikely (en.type != PointType.CURVE)) {- warning (@"PointType is $(en.type)");+ } else {+ draw_curve (e, en, cr); }- } private static void draw_curve (EditPoint e, EditPoint en, Context cr, double alpha = 1) {@@ -859,7 +856,7 @@ class Path { ymin = 0; } - // inside and outside in vala lambda functions is a tricky matter+ // inside and outside in vala lambda functions reveals a tricky problem // (look at c code). that's the reason for the !new_val expression xmax = -10000;@@ -103,10 +103,13 @@ class PenTool : Tool { GridTool.tie (ref x, ref y); } - selected_handle.parent.set_point_type (PointType.CURVE);+ selected_handle.parent.set_point_type (PointType.CURVE); // FIXA: find a way to remove+ selected_handle.set_point_type (PointType.CURVE); selected_handle.move_to (x, y); - selected_handle.parent.get_prev ().data.set_point_type (PointType.CURVE);+ selected_handle.parent.recalculate_linear_handles ();+ + selected_handle.parent.get_prev ().data.set_point_type (PointType.CURVE); // FIXA: find a way to remove // Fixa: redraw line only glyph.redraw_area (0, 0, glyph.allocation.width, glyph.allocation.height);@@ -133,9 +136,7 @@ class PenTool : Tool { active_corner.set_active_handle (true); } - if (ep.type == PointType.LINE) {- ep.recalculate_linear_handles ();- }+ ep.recalculate_linear_handles (); } } @@ -347,6 +348,9 @@ class PenTool : Tool { glyph = MainWindow.get_current_glyph (); glyph.open_path (); glyph.add_new_edit_point (x, y);+ + ((!)glyph.active_path).points.last ().data.right_handle.parent.recalculate_linear_handles ();+ move_selected = true; } @@ -369,9 +373,7 @@ class PenTool : Tool { // as default handle position for LINE points. foreach (EditPoint e in path.points) {- if (e.type == PointType.LINE) {- e.recalculate_linear_handles ();- }+ e.recalculate_linear_handles (); } } @@ -83,18 +83,10 @@ class Svg { } private static void add_abs_next (EditPoint m, EditPoint e, StringBuilder svg, Glyph g, bool do_glyph, double scale = 1) {- switch (m.type) {- case PointType.LINE: - add_abs_line_to (e, m, svg, g, do_glyph, scale);- break;- - case PointType.CURVE:- add_abs_path (e, m, svg, g, do_glyph, scale);- break;- - default:- warning (@"PointType is $(e.type)");- break;+ if (e.right_handle.type == PointType.LINE && m.left_handle.type == PointType.LINE) {+ add_abs_line_to (e, m, svg, g, do_glyph, scale);+ } else {+ add_abs_path (e, m, svg, g, do_glyph, scale); } } @@ -18,6 +18,7 @@ using Gtk; using Gdk; using Cairo;+using Math; namespace Supplement { @@ -152,23 +153,46 @@ class Toolbox : DrawingArea { tie_editpoint_tool.select_action.connect((self) => { EditPoint ep; EditPointHandle eh;- + EditPointHandle el;+ double a, b, c, length, angle, al, ar;+ bool tie;+ select_draw_tool (); ep = pen_tool.selected_corner;+ tie = !ep.tie_handles;++ eh = ep.right_handle; - ep.tie_handles = !ep.tie_handles;- - eh = (ep.left_handle.length > ep.right_handle.length) ? ep.left_handle : ep.right_handle;- - if (ep.next != null) {- eh.move_to_coordinate (eh.x (), eh.y ());- ep.type = PointType.CURVE;+ if (tie) {+ a = ep.left_handle.x () - ep.right_handle.x ();+ b = ep.left_handle.y () - ep.right_handle.y ();+ c = a * a + b * b;+ + if (c == 0) {+ return;+ }+ + length = sqrt (fabs (c)); - ep.get_next ().data.set_point_type (PointType.CURVE); // Fixa: add curve left, right and both- ep.get_next ().data.set_point_type (PointType.CURVE);+ if (ep.right_handle.y () < ep.left_handle.y ()) {+ angle = acos (a / length) + PI;+ } else {+ angle = -acos (a / length) + PI;+ }+ + ep.left_handle.type = PointType.CURVE;+ ep.right_handle.type = PointType.CURVE;+ + ep.right_handle.angle = angle;+ ep.left_handle.angle = angle;++ ep.set_tie_handle (true);+ eh.move_to_coordinate (ep.right_handle.x (), ep.right_handle.y ()); }- + + ep.set_tie_handle (tie);+ TimeoutSource anim = new TimeoutSource (300); anim.set_callback(() => { select_tool (corner_tool);