Updated Files
libbirdfont/Glyph.vala |
libbirdfont/Path.vala |
libbirdfont/PathList.vala |
libbirdfont/StrokeTool.vala |
libbirdfont/TabBar.vala |
--- a/libbirdfont/Glyph.vala
+++ b/libbirdfont/Glyph.vala
@@ -834,6 +834,10 @@
double view_zoom_x, view_zoom_y;
double ivz, off;
+
+ if (move_canvas) {
+ return;
+ }
if (Path.distance (x, x + w, y, y + h) < 7) {
zoom_in ();
@@ -1230,6 +1234,10 @@
}
public override void zoom_in () {
+ if (move_canvas) {
+ return;
+ }
+
set_zoom_area (10, 10, allocation.width - 10, allocation.height - 10);
set_zoom_from_area ();
update_view ();
--- a/libbirdfont/Path.vala
+++ b/libbirdfont/Path.vala
@@ -2082,6 +2082,10 @@
}
public static bool is_counter (PathList pl, Path path) {
+ return counters (pl, path) % 2 != 0;
+ }
+
+ public static int counters (PathList pl, Path path) {
int inside_count = 0;
bool inside;
@@ -2100,10 +2104,11 @@
}
}
- return inside_count % 2 != 0;
- }
+ return inside_count;
+ }
- public void remove_points_on_points () {
+ /** @param t smallest distance to other points. */
+ public void remove_points_on_points (double t = 0.00001) {
Gee.ArrayList<EditPoint> remove = new Gee.ArrayList<EditPoint> ();
EditPoint n;
EditPointHandle hr, h;
@@ -2121,7 +2126,7 @@
n = points.get (0);
}
- if (fabs (n.x - ep.x) < 0.00001 && fabs (n.y - ep.y) < 0.00001) {
+ if (fabs (n.x - ep.x) < t && fabs (n.y - ep.y) < t) {
remove.add (ep);
}
}
@@ -2140,8 +2145,8 @@
h.angle = hr.angle;
h.type = hr.type;
- if (h.length < 0.00001) {
- h.length = 0.00001;
+ if (h.length < t) {
+ h.length = t;
h.angle = n.get_right_handle ().angle - PI;
}
--- a/libbirdfont/PathList.vala
+++ b/libbirdfont/PathList.vala
@@ -19,6 +19,12 @@
public PathList () {
paths = new Gee.ArrayList<Path> ();
+ }
+
+ public void add_unique (Path p) {
+ if (paths.index_of (p) == -1) {
+ paths.add (p);
+ }
}
public void add (Path p) {
--- a/libbirdfont/StrokeTool.vala
+++ b/libbirdfont/StrokeTool.vala
@@ -48,11 +48,7 @@
PathList paths = new PathList ();
foreach (Path p in g.active_paths) {
- if (p.stroke == 0) {
- add_self_intersection_points (p);
- } else {
- paths.append (get_stroke (p, p.stroke));
- }
+ paths.append (get_stroke (p, p.stroke));
}
foreach (Path np in paths.paths) {
@@ -63,18 +59,20 @@
public static PathList get_stroke (Path path, double thickness) {
PathList pl = new PathList ();
PathList parts;
+ Path original = path.copy ();
- parts = new PathList ();
- parts.add (path);
+ original.remove_points_on_points ();
// split self intersecting paths before interpolating
- // parts = get_parts (path.copy ());
+ parts = get_parts (original);
foreach (Path p in parts.paths) {
p.get_first_point ().color = new Color (0, 1, 0, 1);
p.get_last_point ().color = new Color (0, 0, 0, 1);
pl.append (get_stroke_outline (p, thickness));
}
+
+ pl = merge (pl);
return pl;
}
@@ -347,10 +345,33 @@
return parts;
}
- static PathList get_parts (Path path, PathList? paths = null) {
- PathList pl;
+ static PathList get_parts (Path path) {
+ PathList intersections;
+ PathList pli;
PathList r;
+ Path np;
+ r = get_parts_self (path);
+ intersections = new PathList ();
+
+ foreach (Path p in r.paths) {
+ intersections.add (p);
+ }
+
+ foreach (Path p1 in r.paths) {
+ foreach (Path p2 in r.paths) {
+ if (merge_path (p1, p2, out np)) {
+ intersections.append (get_parts (np));
+ }
+ }
+ }
+ return intersections;
+ }
+
+ static PathList get_parts_self (Path path, PathList? paths = null) {
+ PathList pl;
+ PathList r;
+
r = paths == null ? new PathList () : (!) paths;
pl = split (path);
@@ -358,14 +379,14 @@
if (!has_self_intersection (part)) {
r.add (part);
} else {
- get_parts (part, r);
+ get_parts_self (part, r);
}
}
if (r.paths.size == 0) {
warning ("No parts in path");
}
-
+
return r;
}
@@ -444,21 +465,9 @@
if (pl.paths.size == 0) {
pl.add (old_path);
- }
-
- if (stroke_selected) {
- foreach (Path pn in pl.paths) {
- ((!) BirdFont.get_current_font ().get_glyph ("a")).add_path (pn);
- }
}
foreach (Path pn in pl.paths) {
-
- // FIXME: DELETE
- if (pn.has_deleted_point ()) {
- warning ("Points left.");
- }
-
pn.close ();
}
@@ -636,6 +645,11 @@
PathList remove = new PathList ();
foreach (Path p in parts.paths) {
+
+ if (stroke_selected) { // FIXME: DELETE
+ ((!) BirdFont.get_current_font ().get_glyph ("a")).add_path (p);
+ }
+
if (is_stroke (original, p, stroke_width)) {
remove.add (p);
}
@@ -654,13 +668,11 @@
original.all_of_path ((cx, cy, ct) => {
foreach (EditPoint p in part.points) {
if (Path.distance (cx, p.x, cy, p.y) < stroke_size - 0.5) {
- if (48 < p.x < 50) print (@"D: $(Path.distance (cx, p.x, cy, p.y)) < $(stroke_size) \n");
-
- // p.color = new Color (1, 0, 1, 1); // FIXME: DELETE
+ p.color = new Color (1, 0, 1, 1); // FIXME: DELETE
stroke = true;
return false;
} else {
- // p.color = new Color (1, 1, 1, 1); // FIXME: DELETE
+ p.color = new Color (1, 1, 1, 1); // FIXME: DELETE
}
}
@@ -668,20 +680,62 @@
}, 12);
return stroke;
+ }
+
+ static Path get_outline (Path path) {
+ PathList pl = get_parts (path);
+ Path outline = new Path ();
+ int inside;
+ int min_inside = int.MAX;
+ int points = 0;
+ int i = 0;
+
+ foreach (Path p in pl.paths) {
+ inside = Path.counters (pl, p);
+
+ if (inside < min_inside) {
+ outline = p;
+ min_inside = inside;
+ }
+
+ if (stroke_selected) { // FIXME: DELETE
+ ((!) BirdFont.get_current_font ().get_glyph ("a")).add_path (p);
+ }
+ i++;
+ }
+
+ if (min_inside == 0) {
+ foreach (Path p in pl.paths) {
+ if (p.points.size > points) {
+ outline = p;
+ points = p.points.size;
+ }
+ }
+ }
+
+ return outline;
}
static PathList merge (PathList pl) {
Path merged;
+ int i, j;
+ i = 0;
foreach (Path p1 in pl.paths) {
+ j = 0;
foreach (Path p2 in pl.paths) {
if (merge_path (p1, p2, out merged)) {
- //pl.paths.remove (p1);
- //pl.paths.remove (p2);
+ pl.paths.remove (p1);
+ pl.paths.remove (p2);
+
+ merged = get_outline (merged);
pl.add (merged);
- return pl;
- }
+
+ return merge (pl);
+ }
+ j++;
}
+ i++;
}
return pl;
@@ -700,7 +754,7 @@
return i;
}
-
+
/** @return true if the two paths can be merged. */
static bool merge_path (Path path1, Path path2, out Path merged) {
PathList pl1, pl2;
@@ -708,6 +762,10 @@
int i;
merged = new Path ();
+
+ if (path1 == path2) {
+ return false;
+ }
if (add_intersection_points (path1, path2)) {
i = mark_intersection_as_deleted (path1);
@@ -752,7 +810,8 @@
return intersection;
}
+
}
}
--- a/libbirdfont/TabBar.vala
+++ b/libbirdfont/TabBar.vala
@@ -678,7 +678,7 @@
if (MainWindow.get_menu ().show_menu) {
Theme.text_color (menu_icon, "Foreground Inverted");
} else {
- Theme.text_color (menu_icon, "Foreground 2");
+ Theme.text_color (menu_icon, "Highlighted 1");
}
menu_icon.set_font_size (40 / scale);