Commit 23685fe
resize all selected paths
Changed files (6)
modifiedlibbirdfont/MoveTool.valamodifiedlibbirdfont/OpenFontFormatWriter.valamodifiedlibbirdfont/Path.valadeletedlibbirdfont/ResizeTool.valamodifiedlibbirdfont/TooltipArea.valamodifiedlibbirdfont/ZoomTool.vala
Diff
@@ -97,8 +97,6 @@ class MoveTool : Tool { double dx = last_x - x; double dy = last_y - y; double p = PenTool.precision;- Path rp;- double h, ratio; if (move_path) { foreach (Path path in glyph.active_paths) {@@ -106,16 +104,8 @@ class MoveTool : Tool { } } - if (resize_path) {- return_if_fail (!is_null (resized_path));- rp = (!) resized_path;- h = rp.xmax - rp.xmin;- - ratio = 1;- ratio -= 0.7 * p * (Glyph.path_coordinate_y (last_resize_y) - Glyph.path_coordinate_y (y)) / h;- - rp.resize (ratio);- last_resize_y = y;+ if (resize_path && can_resize (x, y)) {+ resize (x, y); } last_x = x;@@ -156,6 +146,70 @@ class MoveTool : Tool { }); } + double get_resize_ratio (double x, double y) {+ double ratio;+ double h;+ Path rp;+ + return_if_fail (!is_null (resized_path));+ rp = (!) resized_path;+ h = rp.xmax - rp.xmin;++ ratio = 1;+ ratio -= 0.7 * PenTool.precision * (Glyph.path_coordinate_y (last_resize_y) - Glyph.path_coordinate_y (y)) / h; ++ return ratio;+ }++ /** Move resize handle to pixel x,y. */+ void resize (double x, double y) {+ Path rp;+ double ratio;+ double resize_pos_x = 0;+ double resize_pos_y = 0;+ Glyph glyph = MainWindow.get_current_glyph ();++ ratio = get_resize_ratio (x, y);++ return_if_fail (!is_null (resized_path));+ rp = (!) resized_path;+ resize_pos_x = rp.xmin;+ resize_pos_y = rp.ymin; + + foreach (Path selected_path in glyph.active_paths) {+ selected_path.resize (ratio);+ }+ + // resize paths+ foreach (Path selected_path in glyph.active_paths) {+ selected_path.resize (ratio);+ }+ + // move paths relative to the updated xmin and xmax+ foreach (Path selected_path in glyph.active_paths) {+ selected_path.move (resize_pos_x - rp.xmin, resize_pos_y - rp.ymin);+ }+ + last_resize_y = y;+ }++ bool can_resize (double x, double y) {+ Glyph glyph = MainWindow.get_current_glyph ();+ double h, w;+ double ratio = get_resize_ratio (x, y);+ + foreach (Path selected_path in glyph.active_paths) {+ h = selected_path.ymax - selected_path.ymin;+ w = selected_path.xmax - selected_path.xmin;+ + if (h * ratio < 1 || w * ratio < 1) {+ return false;+ }+ }+ + return true;+ }+ bool is_over_resize_handle (Path p, double x, double y) { double handle_x = Math.fabs (Glyph.reverse_path_coordinate_x (p.xmax)); double handle_y = Math.fabs (Glyph.reverse_path_coordinate_y (p.ymax));@@ -699,7 +699,7 @@ class GlyfTable : Table { public HeadTable head_table; public HmtxTable hmtx_table; public LocaTable loca_table; - public CmapTable cmap_table; // hack, hack, hack. cmap and post is null when inistialized and set in parse method + public CmapTable cmap_table; // cmap and post is null when inistialized and set in parse method public PostTable post_table; public KernTable kern_table; @@ -708,7 +708,7 @@ class GlyfTable : Table { // list of glyphs sorted in the order we expect to find them in a // ttf font. notdef is the firs glyph followed by null and nonmarkingreturn. // after that will all assigned glyphs appear in sorted order, all - // remaining unassigned glyphs live in the last part of the file. + // remaining unassigned glyphs is in the last part of the file. public List<Glyph> glyphs; uint16 max_points = 0; @@ -544,16 +544,16 @@ public class Path { i = i.next; } }- ++ /** Resize path relative to bottom left coordinates.+ * @param cx xmin position during resize+ * @param cy ymin position during resize+ */ public void resize (double ratio) { double h = ymax - ymin;- double px, py, nx, ny; - px = xmin;- py = ymin;- - if (ratio < 1 && h < 2) {- return;+ if (unlikely (ratio < 1 && h < 2)) {+ warning ("Minimum size"); } foreach (var p in points) {@@ -567,11 +567,6 @@ public class Path { xmax *= ratio; ymin *= ratio; ymax *= ratio;-- nx = xmin;- ny = ymin;- - move (px - nx, py - ny); } public Path copy () {deleted file mode 100644@@ -1,248 +0,0 @@-/*- Copyright (C) 2012 Johan Mattsson-- This program is free software: you can redistribute it and/or modify- it under the terms of the GNU General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- This program 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 General Public License for more details.-- You should have received a copy of the GNU General Public License- along with this program. If not, see <http://www.gnu.org/licenses/>.-*/--using Cairo;--namespace Supplement {--class ResizeTool : Tool {-- ImageSurface move_icon;- ImageSurface move_icon_active;-- ImageSurface rotate_icon;- ImageSurface rotate_icon_active;- - int active_handle = -1;- - Path selected_path = new Path ();- - bool resize = false;- double resize_begin_x = 0;- double resize_begin_y = 0;- Path? original_path = null;- - public ResizeTool (string n) {- base (n, "resize paths");-- select_action.connect((self) => {- active_handle = -1;- redraw_handle ();- });- - deselect_action.connect((self) => {- active_handle = -1;- redraw_handle ();- });- - press_action.connect((self, b, x, y) => {- if (get_handle_at (x, y) > -1) {- resize_begin_x = x;- resize_begin_y = y;- resize = true;- original_path = null;- }- });-- release_action.connect((self, b, x, y) => {- resize = false;- original_path = null;- });- - move_action.connect ((self, x, y) => {- high_light (x, y);- - if (resize) {- resize_process (x, y);- }- });- - draw_action.connect ((self, cairo_context, glyph) => {- draw_handle (cairo_context, glyph);- });- - move_icon = (!) Icons.get_icon ("move_handle.png");- move_icon_active = (!) Icons.get_icon ("move_handle_active.png");-- rotate_icon = (!) Icons.get_icon ("rotate_icon.png");- rotate_icon_active = (!) Icons.get_icon ("rotate_icon_active.png"); - - }-- private void resize_process (double x, double y) {- double a, b, c, nc, tx, ty;- - Path p;- - // TODO: this function resizes only one path not a group of paths- Path po = selected_path;- - if (po.empty ()) return;- - if (original_path == null) original_path = po.copy ();- - p = ((!)original_path).copy ();- - a = p.xmax - p.xmin;- b = p.ymax - p.ymin;- - tx = x - resize_begin_x;- ty = y - resize_begin_y;- - c = Math.sqrt (Math.pow (a, 2) + Math.pow (b, 2));- nc = Math.sqrt (Math.pow (a + tx, 2) + Math.pow (b + ty, 2));-- p.resize (nc / c);- po.replace_path (p);-- MainWindow.get_current_glyph ().queue_redraw_path (po);- MainWindow.get_current_glyph ().queue_redraw_path (p);- }-- private void high_light (double x, double y) {- int i = get_handle_at (x, y);-- if (active_handle != i) {- redraw_handle ();- active_handle = i;- }- }-- private int get_handle_at (double x, double y) {- Glyph g = MainWindow.get_current_glyph ();- int hx, hy;- double ivz = 1/g.view_zoom;- - int i = 0;- foreach (var p in g.path_list) {- hx = (int) (p.xmax * ivz + g.view_offset_x + (g.allocation.width / 2) * ivz);- hy = (int) (p.ymax * ivz + g.view_offset_y + (g.allocation.height / 2) * ivz);- - if (p.points.length () > 0 && hx <= x <= hx + move_icon.get_width () && hy <= y <= hy + move_icon.get_height ()) {- selected_path = p;- return i;- }- - i++;- }- - selected_path = new Path ();- return -1;- }-- private void draw_handle (Context cr, Glyph g) {- double x, y;- int i = 0; - double ivz = 1/g.view_zoom;-- if (resize) return;- - foreach (var p in g.path_list) {- x = p.xmax * ivz + g.view_offset_x + (g.allocation.width / 2) * ivz;- y = p.ymax * ivz + g.view_offset_y + (g.allocation.height / 2) * ivz;- - if (p.points.length () > 0) {- ImageSurface s = (i == active_handle) ? move_icon_active : move_icon;- cr.set_source_surface (s, x, y);- cr.paint ();-- ImageSurface r = (i == active_handle) ? rotate_icon_active : rotate_icon;- cr.set_source_surface (r, x, y - 20);- cr.paint ();- }- - i++;- }- }-- private void redraw_handle () {- Glyph g = MainWindow.get_current_glyph ();- int x, y;- double ivz = 1/g.view_zoom;- - foreach (var p in g.path_list) {- x = (int) (p.xmax * ivz + g.view_offset_x + (g.allocation.width / 2) * ivz);- y = (int) (p.ymax * ivz + g.view_offset_y + (g.allocation.height / 2) * ivz);-- g.redraw_area (x, y, (int) move_icon.get_width (), (int) move_icon.get_height ());- g.redraw_area (0, 0, g.allocation.width, g.allocation.height);- }- }-- public override bool test () {- // draw and resize glyphs - - draw_test_glyph (0, 100); // 1:1-- draw_test_glyph (0, 89); - resize_test_glyph (0.99); // 99%- - for (int i = 2; i < 10; i++) {- draw_test_glyph (10 * (i - 1), 100);- resize_test_glyph (1.0 / i);- }-- int m = 100;- for (int i = 2; i < 6; i++) {- m += ((i - 1) * 30) + 5;- draw_test_glyph (0, m);- resize_test_glyph (i);- }-- Tool.yield ();- - return true;- }-- private void resize_test_glyph (double ratio_percent) {- test_select_action ();- - Tool.yield ();- - Glyph g = MainWindow.get_current_glyph ();- Path? pn = g.get_last_path ();- return_if_fail (pn != null);-- Path p = (!) pn; - p.resize (ratio_percent);-- }- - private void draw_test_glyph (int x_offset, int y_offset) {- // open a new glyph- Tool pen_tool = MainWindow.get_toolbox ().get_tool ("pen_tool");- Tool.yield ();- MainWindow.get_tab_bar ().select_overview ();-- Tool.yield ();- MainWindow.get_overview ().open_current_glyph ();- - pen_tool.test_select_action ();- - // paint- pen_tool.test_click_action (1, 10 + x_offset, 10 + y_offset); - pen_tool.test_click_action (1, 20 + x_offset, 10 + y_offset);- pen_tool.test_click_action (1, 20 + x_offset, 20 + y_offset);- pen_tool.test_click_action (1, 10 + x_offset, 20 + y_offset);- - // close- pen_tool.test_click_action (3, 0, 0);- }- -}--}@@ -17,7 +17,6 @@ using Cairo; using Gdk;-using Gtk; namespace Supplement { @@ -15,8 +15,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -using Gtk;- namespace Supplement { class ZoomTool : Tool {