Commit ef7ff70
quadratic handle for lines in TTF format
Changed files (8)
modifiedlibbirdfont/EditPoint.valamodifiedlibbirdfont/Font.valamodifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/ImportSvg.valamodifiedlibbirdfont/Path.valamodifiedlibbirdfont/PenTool.valamodifiedlibbirdfont/Svg.valamodifiedlibbirdfont/Toolbox.vala
Diff
@@ -22,6 +22,7 @@ namespace BirdFont { public enum PointType { NONE, NORMAL,+ LINE_QUADRATIC, LINE_CUBIC, CUBIC, QUADRATIC,@@ -54,7 +55,7 @@ public class EditPoint { public bool tie_handles = false; - public EditPoint (double nx = 0, double ny = 0, PointType nt = PointType.LINE_CUBIC) {+ public EditPoint (double nx = 0, double ny = 0, PointType nt = PointType.NONE) { x = nx; y = ny; type = nt;@@ -126,9 +127,7 @@ public class EditPoint { h.move_to_coordinate (nx, ny); }-- h = n.get_right_handle ();- + // on the other side h = n.get_right_handle (); @@ -152,6 +151,13 @@ public class EditPoint { h.move_to_coordinate (nx, ny); } + if (h.type == PointType.LINE_QUADRATIC) {+ nx = x + ((n.x - x) / 2);+ ny = y + ((n.y - y) / 2);+ + h.move_to_coordinate (nx, ny);+ }+ h = n.get_left_handle (); if (h.type == PointType.LINE_CUBIC) {@@ -824,23 +824,33 @@ public class Font : GLib.Object { ligature.remove_all (); if (path.has_suffix (".svg")) {+ Toolbox.select_tool_by_name ("cubic_points"); font_file = path; loaded = parse_svg_file (path); format = FontFormat.SVG; } if (path.has_suffix (".ffi")) {+ Toolbox.select_tool_by_name ("cubic_points"); font_file = path; loaded = parse_file (path); format = FontFormat.FFI; } - if (path.has_suffix (".ttf") || path.has_suffix (".otf")) {+ if (path.has_suffix (".ttf")) {+ Toolbox.select_tool_by_name ("quadratic_points"); font_file = path; loaded = parse_freetype_file (path); format = FontFormat.FREETYPE; } - ++ if (path.has_suffix (".otf")) {+ Toolbox.select_tool_by_name ("cubic_points");+ font_file = path;+ loaded = parse_freetype_file (path);+ format = FontFormat.FREETYPE;+ } + /* // TODO: Remove the old way of loading ttfs when testing of the OTF writer is complete. if (BirdFont.experimental) { if (path.has_suffix (".ttf")) {@@ -861,6 +861,7 @@ public class Glyph : FontDisplay { added = false; + // FIXME: what about removeing this feature if (new_point_on_path != null) { return_if_fail (active_paths.length () > 0); @@ -703,6 +703,8 @@ public class ImportSvg { if (command[i] == "L") { path.add (p[ic++], p[ic++]);+ ep1 = path.points.last ().data;+ ep1.recalculate_linear_handles (); } if (command[i] == "Q") {@@ -781,11 +783,12 @@ public class ImportSvg { } glyph.add_path (path);- path.close ();+ glyph.close_path ();+ path = new Path (); } }- + // TODO: Find out if it is possible to tie handles. } @@ -202,6 +202,7 @@ public class Path { private static void draw_curve (EditPoint e, EditPoint en, Context cr, double alpha = 1) { Glyph g = MainWindow.get_current_glyph (); double xa, ya, xb, yb, xc, yc, xd, yd;+ PointType t = en.get_right_handle ().type; get_bezier_points (e, en, out xa, out ya, out xb, out yb, out xc, out yc, out xd, out yd); @@ -210,7 +211,7 @@ public class Path { cr.line_to (xa, ya); // this point makes sense only if it is the first or last position, the other points are meaningless don't export them - if (en.get_right_handle ().type == PointType.QUADRATIC) {+ if (t == PointType.QUADRATIC || t == PointType.LINE_QUADRATIC) { cr.curve_to ((xa + 2 * xb) / 3, (ya + 2 * yb) / 3, (xd + 2 * xb) / 3, (yd + 2 * yb) / 3, xd, yd); } else { cr.curve_to (xb, yb, xc, yc, xd, yd);@@ -293,6 +294,8 @@ public class Path { EditPoint handle_right = e.get_right_handle ().get_point (); EditPoint handle_left = e.get_left_handle ().get_point (); + PointType type = e.get_left_handle ().type;+ cr.stroke (); img_right = (e.get_right_handle ().active) ? (!) active_edit_point_handle_image : (!) edit_point_handle_image;@@ -303,7 +306,7 @@ public class Path { draw_img_center (cr, img_right, e.get_right_handle ().x (), e.get_right_handle ().y ()); } - if (!(is_open () && e == points.first ().data) && e.get_left_handle ().type != PointType.QUADRATIC) {+ if (!(is_open () && e == points.first ().data) && type != PointType.QUADRATIC && type != PointType.LINE_QUADRATIC) { draw_line (handle_left, e, cr, 0.15); draw_img_center (cr, img_left, e.get_left_handle ().x (), e.get_left_handle ().y ()); }@@ -742,7 +745,7 @@ public class Path { * to the new item in list. */ public unowned List<EditPoint> add_after (double x, double y, List<EditPoint>? previous_point) {- EditPoint p = new EditPoint (x, y, PointType.LINE_CUBIC); + EditPoint p = new EditPoint (x, y); return add_point_after (p, previous_point); } @@ -776,10 +779,13 @@ public class Path { PenTool.set_default_handle_positions (); - if (p.prev != null) {- if (p.get_prev ().data.right_handle.type == PointType.QUADRATIC) {- p.left_handle.type = PointType.QUADRATIC;- }+ if (p.prev != null && p.get_prev ().data.right_handle.type == PointType.QUADRATIC) {+ p.left_handle.type = PointType.QUADRATIC;+ p.right_handle.type = PointType.LINE_QUADRATIC;+ } else if (Toolbox.use_quadratic_points ()) {+ p.left_handle.type = PointType.LINE_QUADRATIC;+ p.right_handle.type = PointType.LINE_QUADRATIC;+ p.type = PointType.LINE_QUADRATIC; } return np;@@ -1137,7 +1143,12 @@ public class Path { }); // this is a point on a line- if (start.get_right_handle ().type == PointType.LINE_CUBIC && stop.get_left_handle ().type == PointType.LINE_CUBIC) {+ + if (start.get_right_handle ().type == PointType.LINE_QUADRATIC && stop.get_left_handle ().type == PointType.LINE_QUADRATIC) {+ ep.get_right_handle ().set_point_type (PointType.LINE_QUADRATIC);+ ep.get_left_handle ().set_point_type (PointType.LINE_QUADRATIC);+ ep.recalculate_linear_handles ();+ } else if (start.get_right_handle ().type == PointType.LINE_CUBIC && stop.get_left_handle ().type == PointType.LINE_CUBIC) { ep.get_right_handle ().set_point_type (PointType.LINE_CUBIC); ep.get_left_handle ().set_point_type (PointType.LINE_CUBIC); ep.recalculate_linear_handles ();@@ -172,7 +172,11 @@ public class PenTool : Tool { // move curve handles if (move_selected_handle) { if (selected_handle.type == PointType.LINE_CUBIC) {- selected_handle.set_point_type (PointType.CUBIC); // TODO: quadratic+ selected_handle.set_point_type (PointType.CUBIC);+ }++ if (selected_handle.type == PointType.LINE_QUADRATIC) {+ selected_handle.set_point_type (PointType.QUADRATIC); } if (GridTool.is_visible ()) {@@ -78,10 +78,12 @@ class Svg { } private static void add_abs_next (EditPoint start, EditPoint end, StringBuilder svg, Glyph g, bool do_glyph) {- if (end.get_left_handle ().type == PointType.QUADRATIC) {- add_quadratic_abs_path (end, start, svg, g, do_glyph);+ if (start.right_handle.type == PointType.LINE_QUADRATIC) {+ add_abs_line_to (end, start, svg, g, do_glyph); } else if (start.right_handle.type == PointType.LINE_CUBIC && end.left_handle.type == PointType.LINE_CUBIC) { add_abs_line_to (end, start, svg, g, do_glyph);+ } else if (end.left_handle.type == PointType.QUADRATIC || start.right_handle.type == PointType.QUADRATIC) {+ add_quadratic_abs_path (end, start, svg, g, do_glyph); } else { add_cubic_abs_path (end, start, svg, g, do_glyph); }@@ -47,6 +47,8 @@ public class Toolbox : GLib.Object { ImageSurface? toolbox_background = null; + public static bool use_quadratic_bezierpoints = false;+ public Toolbox (GlyphCanvas main_glyph_canvas) { glyph_canvas = main_glyph_canvas; @@ -129,6 +131,20 @@ public class Toolbox : GLib.Object { draw_tool_modifiers.add_tool (precision); + // quadratic Bézier points+ Tool quadratic_points = new Tool ("quadratic_points", _("Create quadratic Bézier curves"));+ quadratic_points.select_action.connect ((self) => {+ Toolbox.use_quadratic_bezierpoints = true;+ });+ draw_tool_modifiers.add_tool (quadratic_points); + + // cubic Bézier points+ Tool cubic_points = new Tool ("cubic_points", _("Create cubic Bézier curves"));+ cubic_points.select_action.connect ((self) => {+ Toolbox.use_quadratic_bezierpoints = false;+ });+ draw_tool_modifiers.add_tool (cubic_points);+ // path tools Tool union_paths_tool = new MergeTool ("union_paths"); path_tool_modifiers.add_tool (union_paths_tool);@@ -562,6 +578,8 @@ public class Toolbox : GLib.Object { var idle = new IdleSource(); idle.set_callback (() => { pen_tool.set_selected (true);+ select_tool (cubic_points);+ select_draw_tool (); if (GlyphCanvas.get_current_glyph ().get_show_help_lines ()) {@@ -579,6 +597,13 @@ public class Toolbox : GLib.Object { idle.attach (null); }++ /**+ * @return true if new points should be quadratic instead of cubic.+ */+ public static bool use_quadratic_points () {+ return use_quadratic_bezierpoints;+ } public void key_press (uint keyval) { foreach (var exp in MainWindow.get_toolbox ().expanders) {