The Birdfont Source Code
Speed optimizations
These changes was commited to the Birdfont repository Fri, 16 Oct 2015 07:12:11 +0000.
Contributing
Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
Speed optimizations
This commit removes old optimizations as well.
--- a/birdfont-test/TestRunner.vala
+++ b/birdfont-test/TestRunner.vala
@@ -89,7 +89,7 @@
Test test_path = new Test.time ("Simple path creation");
for (uint i = 0; i < 3000; i++) {
- for (uint j = 0; j < 3000; j++) {
+ for (uint j = 0; j < 300; j++) {
Path p = new Path ();
}
}
@@ -109,7 +109,7 @@
Test test_cairo = new Test.time ("Simple Cairo");
- for (int i = 0; i < 3000; i++) {
+ for (int i = 0; i < 300; i++) {
ImageSurface s;
Context c;
@@ -129,7 +129,7 @@
Test test_toolbox = new Test.time ("Toolbox");
- for (int i = 0; i < 30; i++) {
+ for (int i = 0; i < 3000; i++) {
ImageSurface s;
Context c;
@@ -142,7 +142,7 @@
Test test_tool_drawing = new Test.time ("Draw Tool");
- for (int i = 0; i < 30; i++) {
+ for (int i = 0; i < 3000; i++) {
ImageSurface s;
Context c;
Tool tool;
@@ -157,7 +157,7 @@
Test test_tool = new Test.time ("Create Tool");
- for (int i = 0; i < 30; i++) {
+ for (int i = 0; i < 3000; i++) {
Tool tool;
tool = new Tool ();
tool.set_tool_visibility (true);
--- a/libbirdfont/Path.vala
+++ b/libbirdfont/Path.vala
@@ -956,11 +956,8 @@
}
public EditPoint add (double x, double y) {
- if (points.size > 0) {
- return add_after (x, y, points.get (points.size - 1));
- }
-
- return add_after (x, y, null);
+ EditPoint ep = new EditPoint (x, y);
+ return add_point (ep);
}
public EditPoint add_point (EditPoint p) {
@@ -980,14 +977,6 @@
last_point = p;
return p;
- }
-
- /** Insert a new point after @param previous_point and return a reference
- * to the new item in list.
- */
- public EditPoint add_after (double x, double y, EditPoint? previous_point) {
- EditPoint p = new EditPoint (x, y, PointType.NONE);
- return add_point_after (p, previous_point);
}
/** @return a list item pointing to the new point */
@@ -2454,9 +2443,16 @@
return;
}
- print(@"Create full stroke for $(points.size) points.\n");
StrokeTask task = new StrokeTask (this);
- MainWindow.native_window.run_non_blocking_background_thread (task);
+
+ // Create idle task in order ignore repeted calls to this method
+ // during one main loop iteration.
+ IdleSource idle = new IdleSource ();
+ idle.set_callback (() => {
+ MainWindow.native_window.run_non_blocking_background_thread (task);
+ return false;
+ });
+ idle.attach (null);
stop_stroke_creator ();
stroke_creator = task;
@@ -2487,9 +2483,7 @@
}
StrokeTool s = new StrokeTool ();
- Test t = new Test.time ("fast stroke");
fast_stroke = s.get_stroke_fast (this, stroke);
- t.print();
return (!) fast_stroke;
}
--- a/libbirdfont/PenTool.vala
+++ b/libbirdfont/PenTool.vala
@@ -149,8 +149,8 @@
release_action.connect ((self, b, ix, iy) => {
double x, y;
- Glyph g;
-
+ Glyph g;
+
g = MainWindow.get_current_glyph ();
x = Glyph.path_coordinate_x (ix);
y = Glyph.path_coordinate_y (iy);
@@ -176,8 +176,7 @@
point_selection_image = false;
BirdFont.get_current_font ().touch ();
- reset_stroke ();
-
+
foreach (Path p in g.get_visible_paths ()) {
if (p.is_open () && p.points.size > 0) {
p.get_first_point ().set_tie_handle (false);
--- a/libbirdfont/StrokeTask.vala
+++ b/libbirdfont/StrokeTask.vala
@@ -37,10 +37,7 @@
w = background_path.stroke;
- Test t = new Test.time ("full stroke");
stroke = tool.get_stroke (background_path, w);
- t.print ();
- print(@"Cancelled: $(is_cancelled ())\n");
IdleSource idle = new IdleSource ();
idle.set_callback (() => {
--- a/libbirdfont/StrokeTool.vala
+++ b/libbirdfont/StrokeTool.vala
@@ -85,7 +85,7 @@
stroke = path.copy ();
stroke.remove_points_on_points (0.1);
- o = s.create_stroke (stroke, thickness, false); // set to true for faster stroke
+ o = s.create_stroke (stroke, thickness);
return o;
}
@@ -93,10 +93,14 @@
public PathList get_stroke (Path path, double thickness) {
PathList o, m;
Path stroke;
+
+ if (task.is_cancelled ()) {
+ return new PathList ();
+ }
stroke = path.copy ();
stroke.remove_points_on_points (0.1);
- o = create_stroke (stroke, thickness, false);
+ o = create_stroke (stroke, thickness);
o = get_all_parts (o);
o = remove_intersection_paths (o);
o = merge (o);
@@ -112,8 +116,7 @@
void reset_flags (PathList o) {
foreach (Path p in o.paths) {
foreach (EditPoint ep in p.points) {
- ep.flags &= uint.MAX ^
- (EditPoint.INTERSECTION
+ ep.flags &= ~(EditPoint.INTERSECTION
| EditPoint.COPIED
| EditPoint.NEW_CORNER
| EditPoint.SELF_INTERSECTION);
@@ -2784,8 +2787,7 @@
return sum > 0;
}
- public PathList create_stroke (Path original_path,
- double thickness, bool fast) {
+ public PathList create_stroke (Path original_path, double thickness) {
PathList pl;
EditPoint p1, p2, p3;
@@ -2834,7 +2836,7 @@
corner1 = new EditPoint ();
corner1_inside = new EditPoint ();
- if (path.is_open () || fast) {
+ if (path.is_open ()) {
p1 = path.points.get (0);
p2 = path.points.get (1 % path.points.size);
@@ -2852,17 +2854,16 @@
}
min_increment = 0.02; // 0.013
-
- Test t1 = new Test.time ("generate");
+
for (i = 0; i < size; i++) {
p1 = path.points.get (i % path.points.size);
p2 = path.points.get ((i + 1) % path.points.size);
p3 = path.points.get ((i + 2) % path.points.size);
- if (task.is_cancelled ()) {
+ if (unlikely (task.is_cancelled ())) {
return new PathList ();
}
-
+
tolerance = 0.01;
step_increment = 1.05;
step_size = 0.039;
@@ -2888,8 +2889,8 @@
step = step_size;
keep = 0;
- step_size = 0.05; // 0.01
-
+ step_size = 0.05;
+
while (step < 1 - 2 * step_size) {
Path.get_point_for_step (p1, p2, step, out x, out y);
Path.get_point_for_step (p1, p2, step + step_size, out x2, out y2);
@@ -2987,87 +2988,28 @@
get_segment (-thickness, 0, 0.00001, p2, p3, out start);
add_corner (side2, previous_inside, start, p2.copy (), thickness);
}
- }
- t1.print();
-
- if (fast) {
- EditPoint s1, s2;
- bool open;
-
- convert_to_curve (side1);
- convert_to_curve (side2);
-
- side2.reverse ();
- s1 = side1.get_last_point ().copy ();
- s2 = side2.get_first_point ().copy ();
-
- s1.flags &= EditPoint.CURVE ^ EditPoint.ALL;
- s2.flags &= EditPoint.CURVE ^ EditPoint.ALL;
-
- s1.convert_to_line ();
- s2.convert_to_line ();
-
- open = path.is_open ();
-
- if (!open) {
- path.reopen ();
- }
-
- pl.append (merge_stroke_parts (path, side1, side2));
-
- if (!open) {
- path.close ();
- }
-
- side1 = new Path ();
- side2 = new Path ();
-
- get_segment (thickness, 0, 0.00001, p2, p3, out start);
- get_segment (-thickness, 0, 0.00001, p2, p3, out start_inside);
-
- previous = start.copy ();
- previous_inside = start_inside.copy ();
-
- previous.flags |= EditPoint.CURVE;
- previous_inside.flags |= EditPoint.CURVE;
-
- side1.add_point (previous);
- side2.add_point (previous_inside);
}
}
- if (!fast) {
- side1.remove_points_on_points ();
- side2.remove_points_on_points ();
+ side1.remove_points_on_points ();
+ side2.remove_points_on_points ();
+
+ convert_to_curve (side1);
+ convert_to_curve (side2);
- convert_to_curve (side1);
- convert_to_curve (side2);
+ side2.reverse ();
+ pl = merge_stroke_parts (path, side1, side2);
- side2.reverse ();
-
- Test t2 = new Test.time ("merge2");
- pl = merge_stroke_parts (path, side1, side2);
- t2.print();
- }
-
- if (fast) {
- foreach (Path p in pl.paths) {
- p.close ();
- convert_to_curve (p);
- }
- }
-
return pl;
}
void convert_to_curve (Path path) {
if (path.is_open ()) {
- path.get_first_point ().flags &= EditPoint.ALL ^ EditPoint.CURVE;
- path.get_last_point ().flags &= EditPoint.ALL ^ EditPoint.CURVE;
+ path.get_first_point ().flags &= ~EditPoint.CURVE;
+ path.get_last_point ().flags &= ~EditPoint.CURVE;
}
path.recalculate_linear_handles ();
- path.remove_points_on_points ();
foreach (EditPoint ep in path.points) {
if ((ep.flags & EditPoint.SEGMENT_END) == 0) {