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.
Fix Clang compile error
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 double xmin, xmax, ymin; 59 60 if (move_circle) { 61 circle.move (Glyph.ivz () * -dx * p, Glyph.ivz () * dy * p); 62 circle.reset_stroke (); 63 } 64 65 if (resize_circle) { 66 get_boundaries (out xmin, out xmax, out ymin); 67 68 diameter = xmax - xmin; 69 cx = xmin + diameter / 2; 70 cy = ymin + diameter / 2; 71 72 radius = Path.distance_pixels (press_x, press_y, x, y); 73 ratio = 2 * radius / diameter; 74 75 if (diameter * ratio > 0.5) { 76 circle.resize (ratio); 77 } 78 79 get_boundaries (out xmin, out xmax, out ymin); 80 81 diameter = xmax - xmin; 82 nx = xmin + diameter / 2; 83 ny = ymin + diameter / 2; 84 85 circle.move (cx - nx, cy - ny); 86 87 last_radius = radius; 88 circle.reset_stroke (); 89 circle.update_region_boundaries (); 90 } 91 92 last_x = x; 93 last_y = y; 94 95 GlyphCanvas.redraw (); 96 } 97 98 void get_boundaries (out double xmin, out double xmax, out double ymin) { 99 xmin = Glyph.CANVAS_MAX; 100 xmax = Glyph.CANVAS_MIN; 101 ymin = Glyph.CANVAS_MAX; 102 foreach (EditPoint p in circle.points) { 103 if (p.x < xmin) { 104 xmin = p.x; 105 } 106 107 if (p.x > xmax) { 108 xmax = p.x; 109 } 110 111 if (p.y < ymin) { 112 ymin = p.y; 113 } 114 } 115 } 116 117 void press (int button, double x, double y) { 118 Glyph glyph = MainWindow.get_current_glyph (); 119 double radius = 2; 120 double px, py, steps; 121 Path path = new Path (); 122 123 press_x = x; 124 press_y = y; 125 126 move_circle = (button == 3); 127 resize_circle = (button == 1); 128 129 if (!move_circle && !resize_circle) { 130 return; 131 } 132 133 glyph.store_undo_state (); 134 135 steps = (DrawingTools.point_type == PointType.QUADRATIC) ? PI / 8 : PI / 4; 136 137 for (double angle = 0; angle < 2 * PI; angle += steps) { 138 px = radius * cos (angle) + Glyph.path_coordinate_x (x); 139 py = radius * sin (angle) + Glyph.path_coordinate_y (y); 140 path.add (px, py); 141 } 142 143 path.init_point_type (); 144 path.close (); 145 path.recalculate_linear_handles (); 146 147 if (StrokeTool.add_stroke) { 148 path.stroke = StrokeTool.stroke_width; 149 path.line_cap = StrokeTool.line_cap; 150 } 151 152 for (int i = 0; i < 3; i++) { 153 foreach (EditPoint ep in path.points) { 154 ep.set_tie_handle (true); 155 ep.process_tied_handle (); 156 } 157 } 158 159 glyph.add_path (path); 160 161 if (!PenTool.is_counter_path (circle)) { 162 path.reverse (); 163 } 164 165 circle = path; 166 167 GlyphCanvas.redraw (); 168 } 169 170 } 171 172 } 173