The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

CircleTool.vala in libbirdfont

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git

Revisions

View the latest version of libbirdfont/CircleTool.vala.
Suppress zoom when canvas is moving
1 /* 2 Copyright (C) 2012 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 15 using Math; 16 using Cairo; 17 18 namespace BirdFont { 19 20 public class CircleTool : Tool { 21 22 Path circle = new Path (); 23 24 double press_x = -1; 25 double press_y = -1; 26 27 double last_x = -1; 28 double last_y = -1; 29 30 double last_radius = 2; 31 32 bool move_circle = false; 33 bool resize_circle = false; 34 35 public CircleTool (string n) { 36 base (n, t_("Circle")); 37 38 press_action.connect((self, b, x, y) => { 39 press (b, x, y); 40 }); 41 42 release_action.connect((self, b, x, y) => { 43 press_x = -1; 44 press_y = -1; 45 circle = new Path (); 46 }); 47 48 move_action.connect ((self, x, y) => { 49 move (x, y); 50 }); 51 } 52 53 void move (double x, double y) { 54 double dx = last_x - x; 55 double dy = last_y - y; 56 double p = PenTool.precision; 57 double ratio, diameter, radius, cx, cy, nx, ny; 58 59 if (move_circle) { 60 circle.move (Glyph.ivz () * -dx * p, Glyph.ivz () * dy * p); 61 } 62 63 if (resize_circle) { 64 circle.update_region_boundaries (); 65 diameter = circle.xmax - circle.xmin; 66 cx = circle.xmin + diameter / 2; 67 cy = circle.ymin + diameter / 2; 68 69 radius = Path.distance_pixels (press_x, press_y, x, y); 70 ratio = 2 * radius / diameter; 71 72 if (diameter * ratio > 0.5) { 73 circle.resize (ratio); 74 } 75 76 diameter = circle.xmax - circle.xmin; 77 nx = circle.xmin + diameter / 2; 78 ny = circle.ymin + diameter / 2; 79 80 circle.update_region_boundaries (); 81 circle.move (cx - nx, cy - ny); 82 83 last_radius = radius; 84 } 85 86 last_x = x; 87 last_y = y; 88 89 GlyphCanvas.redraw (); 90 } 91 92 void press (int button, double x, double y) { 93 Glyph glyph = MainWindow.get_current_glyph (); 94 double radius = 2; 95 double px, py, steps; 96 Path path = new Path (); 97 98 press_x = x; 99 press_y = y; 100 101 move_circle = (button == 3); 102 resize_circle = (button == 1); 103 104 if (!move_circle && !resize_circle) { 105 return; 106 } 107 108 glyph.store_undo_state (); 109 110 steps = (DrawingTools.point_type == PointType.QUADRATIC) ? PI / 8 : PI / 4; 111 112 for (double angle = 0; angle < 2 * PI; angle += steps) { 113 px = radius * cos (angle) + Glyph.path_coordinate_x (x); 114 py = radius * sin (angle) + Glyph.path_coordinate_y (y); 115 path.add (px, py); 116 } 117 118 path.init_point_type (); 119 path.close (); 120 path.recalculate_linear_handles (); 121 122 for (int i = 0; i < 3; i++) { 123 foreach (EditPoint ep in path.points) { 124 ep.set_tie_handle (true); 125 ep.process_tied_handle (); 126 } 127 } 128 129 glyph.add_path (path); 130 131 if (!PenTool.is_counter_path (circle)) { 132 path.reverse (); 133 } 134 135 circle = path; 136 137 GlyphCanvas.redraw (); 138 } 139 140 } 141 142 } 143