The Birdfont Source Code


All Repositories / birdfont.git / commit – RSS feed

Smooth stroke

These changes was commited to the Birdfont repository Sat, 02 May 2015 20:54:57 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
author Johan Mattsson <johan.mattsson.m@gmail.com>
Sat, 02 May 2015 20:54:57 +0000 (22:54 +0200)
committer Johan Mattsson <johan.mattsson.m@gmail.com>
Sat, 02 May 2015 20:54:57 +0000 (22:54 +0200)
commit cd5d48d9b4db72cde65d554ea88bd35d04b3c0a3
tree bddbfa1b6265a74b84e9e25c7b6f03d036a35430
parent 8a0a1ff64adfea0ba55c84b09b20a567300d91ea
Smooth stroke

libbirdfont/EditPoint.vala
libbirdfont/Path.vala
libbirdfont/StrokeTool.vala
--- a/libbirdfont/EditPoint.vala +++ b/libbirdfont/EditPoint.vala @@ -52,6 +52,8 @@ public static uint COPIED = 1 << 9; public static uint REMOVE_PART = 1 << 10; public static uint OVERLAY = 1 << 11; + public static uint CURVE = 1 << 12; + public static uint ALL = 0xFFFFFF; public uint flags = NONE;
--- a/libbirdfont/Path.vala +++ b/libbirdfont/Path.vala @@ -1134,7 +1134,7 @@ foreach (EditPoint next in points) { left = first.get_right_handle ().type; right = next.get_left_handle ().type; - + if (next != first && (right == PointType.DOUBLE_CURVE || left == PointType.DOUBLE_CURVE)) { first.get_right_handle ().type = PointType.QUADRATIC; @@ -1151,7 +1151,6 @@ hidden.right_handle.move_to_coordinate_internal (next.get_left_handle ().x, next.get_left_handle ().y); first.get_right_handle ().type = PointType.QUADRATIC; - first.type = PointType.QUADRATIC; next.get_left_handle ().type = PointType.QUADRATIC; @@ -1162,7 +1161,7 @@ } first = next; } - + for (int i = 0; i < middle_points.size; i++) { hidden = middle_points.get (i); add_point_after (middle_points.get (i), first_points.get (i)); @@ -1456,6 +1455,7 @@ PointType left = PenTool.to_curve (stop.type); if (right == PointType.DOUBLE_CURVE || left == PointType.DOUBLE_CURVE) { + warning ("FIX the double curve in stroke."); x = double_bezier_path (step, start.x, start.get_right_handle ().x, stop.get_left_handle ().x, stop.x); y = double_bezier_path (step, start.y, start.get_right_handle ().y, stop.get_left_handle ().y, stop.y); } else if (right == PointType.QUADRATIC && left == PointType.QUADRATIC) { @@ -1683,8 +1683,8 @@ PointType left = PenTool.to_curve (stop.type); if (right == PointType.DOUBLE_CURVE || left == PointType.DOUBLE_CURVE) { - double_bezier_vector (step, start.x, start.get_right_handle ().x, stop.get_left_handle ().x, stop.x, out x2, out x1); // FIXME: swap parameter - double_bezier_vector (step, start.y, start.get_right_handle ().y, stop.get_left_handle ().y, stop.y, out y2, out y1); + double_bezier_vector (step, start.x, start.get_right_handle ().x, stop.get_left_handle ().x, stop.x, out x1, out x2); // FIXME: swap parameter? + double_bezier_vector (step, start.y, start.get_right_handle ().y, stop.get_left_handle ().y, stop.y, out y1, out y2); } else if (right == PointType.QUADRATIC && left == PointType.QUADRATIC) { x1 = quadratic_bezier_vector (step, start.x, start.get_right_handle ().x, stop.x); y1 = quadratic_bezier_vector (step, start.y, start.get_right_handle ().y, stop.y);
--- a/libbirdfont/StrokeTool.vala +++ b/libbirdfont/StrokeTool.vala @@ -92,7 +92,11 @@ stroke = path.copy (); stroke.remove_points_on_points (0.3); o = create_stroke (stroke, thickness); - + + // FIXME: remove + //o = get_all_parts (o); + //o = merge (o); + return o; } @@ -100,7 +104,7 @@ PathList o; o = get_stroke_fast (path, thickness); - o = get_all_parts (o); + o = get_all_parts (o); // FIXME: keep. o = merge (o); return o; @@ -1021,12 +1025,12 @@ c = counters (r, p); if (has_zero_area_segment (p)) { - remove.add (p); + //FIXME: remove.add (p); } if (c % 2 == 0) { - if (!is_clockwise (p)) { + if (!p.is_clockwise ()) { remove.add (p); } @@ -1037,7 +1041,7 @@ if (stroke_selected) ((!) BirdFont.get_current_font ().get_glyph ("n")).add_path (p); - if (is_clockwise (p)) { + if (p.is_clockwise ()) { remove.add (p); } } @@ -1619,7 +1623,7 @@ EditPointHandle l, r; p.recalculate_linear_handles (); - + if (p.points.size < 3) { return true; } @@ -1638,10 +1642,10 @@ return sum > 0; } - public static PathList create_stroke (Path path, double thickness) { + public static PathList create_stroke (Path original_path, double thickness) { PathList pl; EditPoint p1, p2, p3; - EditPoint previous, previous_inside, start; + EditPoint previous, previous_inside, start, start_inside; Path side1, side2; @@ -1658,7 +1662,14 @@ EditPointHandle l, r; - //path.add_hidden_double_points (); + Path path = original_path.copy (); + + path.add_hidden_double_points (); // FIXME: + foreach (EditPoint ep in path.points) { + if (ep.type == PointType.DOUBLE_CURVE || ep.type == PointType.LINE_DOUBLE_CURVE) { + PenTool.convert_point_type (ep, PointType.QUADRATIC); + } + } pl = new PathList (); size = path.is_open () ? path.points.size - 1 : path.points.size; @@ -1680,11 +1691,14 @@ p2 = path.points.get (1 % path.points.size); get_segment (thickness, 0, 0.00001, p1, p2, out start); - get_segment (-thickness, 0, 0.00001, p1, p2, out start); + get_segment (-thickness, 0, 0.00001, p1, p2, out start_inside); previous = start.copy (); - previous_inside = 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); } @@ -1694,8 +1708,8 @@ p2 = path.points.get ((i + 1) % path.points.size); p3 = path.points.get ((i + 2) % path.points.size); - // tolerance = 0.13 / sqrt (stroke_width); - tolerance = 2 / sqrt (stroke_width); + tolerance = 0.13 / sqrt (stroke_width); + // tolerance = 2 / sqrt (stroke_width); step_increment = 1.05; step_size = 0.039 / stroke_width; @@ -1735,7 +1749,7 @@ step_size *= step_increment; continue; } - + get_segment (thickness, step, step_size, p1, p2, out corner1); get_segment (-thickness, step, step_size, p1, p2, out corner1_inside); @@ -1749,19 +1763,28 @@ previous = corner1.copy (); previous_inside = corner1_inside.copy (); - + + previous.flags |= EditPoint.CURVE; + previous_inside.flags |= EditPoint.CURVE; + side1.add_point (previous); side2.add_point (previous_inside); - adjust_left_handle (x2, y2, x3, y3, previous); - adjust_left_handle (x2, y2, x3, y3, previous_inside); + // FIXME: DELETE + //adjust_left_handle (x2, y2, x3, y3, previous); + //adjust_left_handle (x2, y2, x3, y3, previous_inside); step += step_size; } + + previous.get_right_handle ().length *= step_size; + corner1.get_left_handle ().length *= step_size; + previous_inside.get_right_handle ().length *= step_size; + corner1_inside.get_left_handle ().length *= step_size; get_segment (thickness, 1 - 0.00001, 0.00001, p1, p2, out corner1); get_segment (-thickness, 1 - 0.00001, 0.00001, p1, p2, out corner1_inside); - + previous = corner1.copy (); previous_inside = corner1_inside.copy (); @@ -1770,13 +1793,16 @@ previous_inside.get_right_handle ().length *= step_size; previous_inside.get_left_handle ().length *= step_size; + previous.flags |= EditPoint.CURVE; + previous_inside.flags |= EditPoint.CURVE; + side1.add_point (previous); side2.add_point (previous_inside); - + l = p2.get_left_handle (); r = p2.get_right_handle (); - if (fabs (l.angle + r.angle - PI) % 2 * PI > 0.01) { + if (fabs ((l.angle + r.angle + PI) % (2 * PI) - PI) > 0.005) { // FIXME: 0.01 if (!path.is_open () || i < size - 1) { get_segment (thickness, 0, 0.00001, p2, p3, out start); add_corner (side1, previous, start, p2.copy (), thickness); @@ -1784,17 +1810,51 @@ get_segment (-thickness, 0, 0.00001, p2, p3, out start); add_corner (side2, previous_inside, start, p2.copy (), thickness); } + } else { + print (@"l.angle + r.angle $(l.angle) + $(r.angle) $(fabs (l.angle + r.angle % (2 * PI) - PI) )\n"); + + //previous.flags |= EditPoint.CURVE; + //previous_inside.flags |= EditPoint.CURVE; } } - side1.recalculate_linear_handles (); - side2.recalculate_linear_handles (); + convert_to_curve (side1); + convert_to_curve (side2); side2.reverse (); pl = merge_stroke_parts (path, side1, side2); return pl; + } + + static 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.recalculate_linear_handles (); + path.remove_points_on_points (); + + foreach (EditPoint ep in path.points) { + if ((ep.flags & EditPoint.CURVE) > 0) { + ep.convert_to_curve (); + } + } + + foreach (EditPoint ep in path.points) { + if ((ep.flags & EditPoint.CURVE) > 0) { + ep.set_tie_handle (true); + } + } + + foreach (EditPoint ep in path.points) { + if ((ep.flags & EditPoint.CURVE) > 0) { + ep.process_tied_handle (); + } + } } public static void adjust_left_handle (double x0, double y0, double x1, double y1, EditPoint ep) { @@ -1805,8 +1865,8 @@ double rp = dp / op; EditPointHandle l = ep.get_left_handle (); - if (l.type == PointType.CUBIC) { - l.length *= 2 * rp; + if (l.type == PointType.CUBIC && dp > 0 && op > 0) { + //l.length *= rp * rp; } } @@ -1818,9 +1878,19 @@ double rp = dp / op; EditPointHandle r = ep.get_right_handle (); - if (r.type == PointType.CUBIC) { - r.length *= 2 * rp; - } + if (r.type == PointType.CUBIC && dp > 0 && op > 0) { + //r.length *= rp * rp; + } + + // FIXME: DELETE + /* + ep.convert_to_line (); + ep.recalculate_linear_handles (); + ep.convert_to_curve (); + ep.set_tie_handle (true); + ep.process_tied_handle (); + ep.set_tie_handle (false); + */ } public static void get_segment (double stroke_thickness, double step, double step_size, @@ -1843,6 +1913,9 @@ corner1 = new EditPoint (x, y, type); corner2 = new EditPoint (x2, y2, type); corner3 = new EditPoint (x3, y3, type); + + //corner2.convert_to_curve (); + corner2.convert_to_line (); // FIXME: delete overlay.add_point (corner1); overlay.add_point (corner2); @@ -1851,13 +1924,14 @@ overlay.close (); overlay.recalculate_linear_handles (); + // FIXME: DELETE + /* Path.get_handles_for_step (p1, p2, step + step_size, out handle1_x, out handle1_y, out handle2_x, out handle2_y); - + corner2.get_left_handle ().move_to_coordinate (handle1_x, handle1_y); corner2.get_right_handle ().move_to_coordinate (handle2_x, handle2_y); - - corner2.convert_to_curve (); + */ move_segment (corner1, corner2, thickness);