Commit d3aa7fe
circles
Changed files (4)
addedicons/circle.pngaddedlibbirdfont/CircleTool.valamodifiedlibbirdfont/Path.valamodifiedlibbirdfont/Toolbox.vala
Diff
new file mode 100644Binary files /dev/null and b/icons/circle.png differnew file mode 100644@@ -0,0 +1,171 @@+/*+ Copyright (C) 2012 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 Math;+using Cairo;++namespace BirdFont {++public class CircleTool : Tool {++ Path circle = new Path ();++ double press_x = -1;+ double press_y = -1;+ + double last_x = -1;+ double last_y = -1;+ + double last_radius = 2;+ + bool move_circle = false;+ bool resize_circle = false;+ + public CircleTool (string n) {+ base (n, _("Circle"));+ + select_action.connect((self) => {+ });++ deselect_action.connect((self) => {+ Glyph glyph = MainWindow.get_current_glyph ();+ });+ + press_action.connect((self, b, x, y) => {+ press (b, x, y);+ });++ release_action.connect((self, b, x, y) => {+ press_x = -1;+ press_y = -1;+ circle = new Path ();+ });+ + move_action.connect ((self, x, y) => {+ move (x, y);+ });+ }+ + void move (double x, double y) {+ double dx = last_x - x;+ double dy = last_y - y; + double p = PenTool.precision;+ double ratio, diameter, radius, cx, cy, nx, ny;+ + if (move_circle) {+ circle.move (Glyph.ivz () * -dx * p, Glyph.ivz () * dy * p);+ }+ + if (resize_circle) {+ circle.update_region_boundries ();+ diameter = circle.xmax - circle.xmin;+ cx = circle.xmin + diameter / 2;+ cy = circle.ymin + diameter / 2;+ + radius = Path.distance_pixels (press_x, press_y, x, y);+ ratio = 2 * radius / diameter;+ + if (diameter * ratio > 0.5) {+ circle.resize (ratio);+ }+ + diameter = circle.xmax - circle.xmin;+ nx = circle.xmin + diameter / 2;+ ny = circle.ymin + diameter / 2;+ + circle.update_region_boundries ();+ circle.move (cx - nx, cy - ny);+ + last_radius = radius;+ }+ + last_x = x;+ last_y = y;++ MainWindow.get_glyph_canvas ().redraw ();+ }+ + void press (int button, double x, double y) {+ Glyph glyph = MainWindow.get_current_glyph ();+ double radius = 2;+ double px, py, steps;+ Path path = new Path ();+ PointType type;+ + press_x = x;+ press_y = y;+ + move_circle = (button == 1);+ resize_circle = (button == 3);+ + if (!move_circle && !resize_circle) {+ return;+ }+ + glyph.store_undo_state ();+ + steps = (Toolbox.point_type == PointType.QUADRATIC) ? PI / 8 : PI / 4; + + for (double angle = 0; angle < 2 * PI; angle += steps) {+ px = radius * cos (angle) + Glyph.path_coordinate_x (x);+ py = radius * sin (angle) + Glyph.path_coordinate_y (y);+ path.add (px, py);+ }+ + switch (Toolbox.point_type) {+ case PointType.QUADRATIC:+ type = PointType.LINE_QUADRATIC;+ break;+ case PointType.DOUBLE_CURVE:+ type = PointType.LINE_DOUBLE_CURVE;+ break;+ case PointType.CUBIC:+ type = PointType.LINE_CUBIC;+ break;+ default:+ warning ("No type is set");+ type = PointType.LINE_CUBIC;+ break;+ }+ + foreach (EditPoint ep in path.points) {+ ep.type = type;+ ep.get_right_handle ().type = type;+ ep.get_left_handle ().type = type;+ }+ + path.close ();+ path.recalculate_linear_handles ();++ for (int i = 0; i < 3; i++) {+ foreach (EditPoint ep in path.points) {+ ep.set_tie_handle (true);+ ep.process_tied_handle ();+ }+ }+ + glyph.add_path (path);+ + if (!PenTool.is_counter_path (circle)) {+ path.reverse ();+ }++ circle = path;+ + MainWindow.get_glyph_canvas ().redraw ();+ }++}++}@@ -639,6 +639,13 @@ public class Path { return Math.fabs (Math.sqrt (Math.pow (ax - bx, 2) + Math.pow (ay - by, 2))); } + public static double distance_pixels (double x1, double y1, double x2, double y2) {+ return distance (Glyph.path_coordinate_x (x1),+ Glyph.path_coordinate_x (x2),+ Glyph.path_coordinate_x (y1),+ Glyph.path_coordinate_x (y2));+ }+ private static double get_length_from (EditPoint a, EditPoint b) { double x, y; @@ -28,7 +28,8 @@ public class Toolbox : GLib.Object { Expander draw_tools; Expander grid_expander;- + Expander shape_tools;+ BackgroundTool move_background; CutBackgroundTool cut_background; @@ -56,6 +57,7 @@ public class Toolbox : GLib.Object { add_expander (toolbox_expander); draw_tools = new Expander ();+ shape_tools = new Expander (); Expander path_tool_modifiers = new Expander (); Expander draw_tool_modifiers = new Expander ();@@ -65,6 +67,7 @@ public class Toolbox : GLib.Object { Expander guideline_tools = new Expander (); Expander view_tools = new Expander (); Expander grid = new Expander ();+ Expander background_tools = new Expander (); Expander style_tools = new Expander (); @@ -431,7 +434,11 @@ public class Toolbox : GLib.Object { zoom_tool.next_view (); }); view_tools.add_tool (zoom_next);- + + // shape tools + Tool circle = new CircleTool ("circle");+ shape_tools.add_tool (circle);+ // background tools background_scale = new SpinButton ("scale_background", _("Set size for background image")); background_scale.set_int_value ("1.000");@@ -583,6 +590,7 @@ public class Toolbox : GLib.Object { characterset_tools.set_open (true); test_tools.set_open (true); guideline_tools.set_open (true);+ shape_tools.set_open (true); background_tools.set_open (true); style_tools.set_open (true); @@ -595,6 +603,7 @@ public class Toolbox : GLib.Object { add_expander (guideline_tools); add_expander (grid); add_expander (view_tools);+ add_expander (shape_tools); add_expander (background_tools); add_expander (style_tools); @@ -626,6 +635,9 @@ public class Toolbox : GLib.Object { grid.set_unique (true); grid.set_open (false); + shape_tools.set_persistent (true);+ shape_tools.set_unique (true);+ background_tools.set_persistent (true); background_tools.set_unique (true); @@ -891,7 +903,8 @@ public class Toolbox : GLib.Object { redraw ((int) exp.x - 10, (int) exp.y - 10, allocation_width, (int) (allocation_height - exp.y + 10)); } - if (exp == draw_tools || t == move_background || t == cut_background) {+ if (exp == draw_tools || t == move_background || t == cut_background+ || exp == shape_tools) { current_tool = tool; } }