The Birdfont Source Code
Select paths
These changes was commited to the Birdfont repository Fri, 01 May 2015 07:23:00 +0000.
Contributing
Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
Select paths
--- a/libbirdfont/ClickMap.vala
+++ /dev/null
@@ -1,119 +1,1 @@
- /*
- Copyright (C) 2014 2015 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 Cairo;
-
- namespace BirdFont {
-
- public class ClickMap : GLib.Object {
- public ImageSurface map;
- public int width;
-
- public double xmax;
- public double ymax;
- public double xmin;
- public double ymin;
-
- public ClickMap (int width) {
- this.width = width;
- map = new Cairo.ImageSurface (Cairo.Format.ARGB32, width, width);
- xmax = 0;
- ymax = 0;
- xmin = 0;
- ymin = 0;
- }
-
- public bool get_value (int x, int y) {
- unowned uchar[] d = map.get_data ();
- bool transparent;
-
- Context c;
-
- c = new Context (map);
- c.set_fill_rule (Cairo.FillRule.WINDING);
-
- if (unlikely (!(0 <= x < width && 0 <= y < width))) {
- warning (@"Array index out of bounds. x: $x y: $y size: $width");
- return true;
- }
-
- transparent = d[y * map.get_stride () + 4 * x + 3] == 0;
-
- return !transparent;
- }
-
- bool add_point (Context c, double cx, double cy) {
- int px = (int) (width * ((cx - xmin) / (xmax - xmin)));
- int py = (int) (width * ((cy - ymin) / (ymax - ymin)));
- c.line_to (px, py);
- return true;
- }
-
- public void create_click_map (Path path, Path? counter = null) { // FIXME: clean up
- Path p;
- Context c;
-
- c = new Context (map);
-
- if (counter == null) {
- xmax = path.xmax;
- ymax = path.ymax;
- xmin = path.xmin;
- ymin = path.ymin;
- } else {
- p = (!) counter;
-
- xmax = fmax (p.xmax, path.xmax);
- ymax = fmax (p.ymax, path.ymax);
- xmin = fmin (p.xmin, path.xmin);
- ymin = fmin (p.ymin, path.ymin);
- }
-
- c.save ();
- c.set_fill_rule (FillRule.EVEN_ODD);
- c.set_source_rgba (0, 0, 0, 1);
- c.new_path ();
- path.all_of_path ((cx, cy) => {
- add_point (c, cx, cy);
- return true;
- }, 2 * width);
- c.close_path ();
-
- if (counter != null) {
- c.new_path ();
-
- p = (!) counter;
- p.all_of_path ((cx, cy) => {
- add_point (c, cx, cy);
- return true;
- }, 2 * width);
-
- c.close_path ();
- }
-
- c.fill ();
- c.restore ();
- }
- }
-
- static double fmin (double a, double b) {
- return a < b ? a : b;
- }
-
- static double fmax (double a, double b) {
- return a > b ? a : b;
- }
-
- }
--- a/libbirdfont/Path.vala
+++ b/libbirdfont/Path.vala
@@ -817,44 +817,23 @@
/** Variable precision */
public bool is_over_coordinate_var (double x, double y) {
- PathList pathlist;
- int width;
- ClickMap click_map;
- int px, py;
- int click_x, click_y;
+ int insides = 0;
- if (points.size < 2) {
- return false;
- }
-
if (stroke > 0) {
- pathlist = get_stroke_fast (); // FIXME: add to clickmap instead
-
- if (pathlist.paths.size > 1) {
- if (pathlist.paths.get (1).is_over_coordinate_var (x, y)) {
- return false;
+ foreach (Path p in get_stroke_fast ().paths) {
+ if (StrokeTool.is_inside (new EditPoint (x, y), p)) {
+ insides++;
}
}
- return pathlist.get_first_path ().is_over_coordinate_var (x, y);
- }
-
- if (!is_over_boundry (x, y)) {
- return false;
+ if (insides % 2 == 1) {
+ return true;
+ }
+ } else if (is_over_boundry (x, y)) {
+ return StrokeTool.is_inside (new EditPoint (x, y), this);
}
-
- // generate a rasterized image of the object
- width = 160;
- click_map = new ClickMap (width);
- px = 0;
- py = 0;
- click_map.create_click_map (this);
-
- click_x = (int) (width * ((x - xmin) / (xmax - xmin)));
- click_y = (int) (width * ((y - ymin) / (ymax - ymin)));
-
- return click_map.get_value (click_x, click_y);
+ return false;
}
public bool is_over_boundry (double x, double y) {