The Birdfont Source Code


All Repositories / birdfont.git / commit – RSS feed

Fix arc arguments

These changes was commited to the Birdfont repository Sun, 10 Jul 2016 18:31:26 +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>
Sun, 10 Jul 2016 18:31:26 +0000 (20:31 +0200)
committer Johan Mattsson <johan.mattsson.m@gmail.com>
Sun, 10 Jul 2016 18:32:06 +0000 (20:32 +0200)
commit 0663b6789ac16c29e64e5dc3b1feba4142bcc0fa
tree 04691205911efaa8b3b026e619ee8dd9b44ccf19
parent 6650e23a21caebdacaa48c4bdf411e112115ffee
Fix arc arguments

libbirdfont/SvgParser.vala
libsvgbird/BezierPoints.vala
libsvgbird/SvgFile.vala
libsvgbird/SvgPath.vala
--- a/libbirdfont/SvgParser.vala +++ b/libbirdfont/SvgParser.vala @@ -1094,7 +1094,7 @@ add_arc_points (arc_data, ref arc_index, instructions[i].x0, instructions[i].y0, instructions[i].rx, instructions[i].ry, - instructions[i].angle, + instructions[i].rotation, instructions[i].large_arc, instructions[i].sweep, instructions[i].x1, instructions[i].y1);
--- a/libsvgbird/BezierPoints.vala +++ b/libsvgbird/BezierPoints.vala @@ -28,14 +28,14 @@ // arc arguments public double rx = 0; public double ry = 0; - public double angle = 0; + public double rotation = 0; public bool large_arc = false; public bool sweep = false; // the arc instructions begins at x0, y0 and ends at x1, x1 public string to_string () { if (svg_type == 'A' || svg_type == 'a') { - return @"SVG type:$((!) svg_type.to_string ()) $x0,$y0 $x1,$y1 rx=$rx, ry=$ry, angle=$angle, large_arc=$large_arc, sweep=$sweep)"; + return @"SVG type:$((!) svg_type.to_string ()) $x0,$y0 $x1,$y1 rx=$rx, ry=$ry, rotation=$rotation, large_arc=$large_arc, sweep=$sweep)"; } return @"$((!)type.to_string ()) $x0,$y0 $x1,$y1 $x2,$y2 SVG:$((!)svg_type.to_string ())";
--- a/libsvgbird/SvgFile.vala +++ b/libsvgbird/SvgFile.vala @@ -800,6 +800,8 @@ double first_x = 0; double first_y = 0; + double last_x = 0; + double last_y = 0; if (points_size > 0) { first_x = bezier_points[0].x0; @@ -817,6 +819,8 @@ points.add (0); points.add (0); points.add (0); + last_x = bezier_points[i].x0; + last_y = bezier_points[i].y0; } else if (bezier_points[i].type == 'C') { points.add_type (POINT_CUBIC); points.add (bezier_points[i].x0); @@ -826,6 +830,8 @@ points.add (bezier_points[i].x2); points.add (bezier_points[i].y2); points.add (0); + last_x = bezier_points[i].x2; + last_y = bezier_points[i].y2; } else if (bezier_points[i].type == 'L') { points.add_type (POINT_LINE); points.add (bezier_points[i].x0); @@ -835,38 +841,34 @@ points.add (0); points.add (0); points.add (0); + last_x = bezier_points[i].x0; + last_y = bezier_points[i].y0; } else if (bezier_points[i].type == 'A') { BezierPoints b = bezier_points[i]; - double angle_start; - double angle_extent; - double center_x; - double center_y; - double rotation = b.angle; - - get_arc_arguments (b.x0, b.y0, b.rx, b.ry, - b.angle, b.large_arc, b.sweep, b.x1, b.y1, - out angle_start, out angle_extent, - out center_x, out center_y); - points.add_type (POINT_ARC); - points.add (center_x); - points.add (center_y); points.add (b.rx); points.add (b.ry); - points.add (angle_start); - points.add (angle_extent); - points.add (rotation); + points.add (b.rotation); + points.add (b.large_arc ? 1 : 0); + points.add (b.sweep ? 1 : 0); + points.add (b.x1); + points.add (b.y1); + + last_x = bezier_points[i].x1; + last_y = bezier_points[i].y1; } else if (bezier_points[i].type == 'z') { points.closed = true; - points.add_type (POINT_LINE); - points.add (first_x); - points.add (first_y); - points.add (0); - points.add (0); - points.add (0); - points.add (0); - points.add (0); + if (fabs (first_x - last_x) > 0.0001 && fabs (first_y - last_y) > 0.0001) { + points.add_type (POINT_LINE); + points.add (first_x); + points.add (first_y); + points.add (0); + points.add (0); + points.add (0); + points.add (0); + points.add (0); + } path_data.add (points); points = new Points (); @@ -878,7 +880,7 @@ } else { string type = (!) bezier_points[i].type.to_string (); warning (@"SVG conversion not implemented for $type"); - } + } } if (points.size > 0) { @@ -1440,7 +1442,7 @@ bezier_points[bi].y1 = cy; bezier_points[bi].rx = arc_rx; bezier_points[bi].ry = arc_ry; - bezier_points[bi].angle = arc_rotation; + bezier_points[bi].rotation = arc_rotation; bezier_points[bi].large_arc = large_arc == 1; bezier_points[bi].sweep = arc_sweep == 1; bi++; @@ -1476,7 +1478,7 @@ bezier_points[bi].y1 = cy; bezier_points[bi].rx = arc_rx; bezier_points[bi].ry = arc_ry; - bezier_points[bi].angle = arc_rotation; + bezier_points[bi].rotation = arc_rotation; bezier_points[bi].large_arc = large_arc == 1; bezier_points[bi].sweep = arc_sweep == 1; bi++;
--- a/libsvgbird/SvgPath.vala +++ b/libsvgbird/SvgPath.vala @@ -18,6 +18,9 @@ public class SvgPath : Object { public Gee.ArrayList<Points> points = new Gee.ArrayList<Points> (); + + double pen_position_x = 0; + double pen_position_y = 0; public SvgPath () { } @@ -73,7 +76,7 @@ int size = path.point_data.size; return_if_fail (size % 8 == 0); - + for (int i = 0; i < size; i += 8) { switch (points[i].type) { case POINT_ARC: @@ -81,38 +84,56 @@ points[i + 3].value, points[i + 4].value, points[i + 5].value, points[i + 6].value, points[i + 7].value); + + pen_position_x = points[i + 6].value; + pen_position_y = points[i + 7].value; break; case POINT_CUBIC: cr.curve_to (points[i + 1].value, points[i + 2].value, points[i + 3].value, points[i + 4].value, points[i + 5].value, points[i + 6].value); + + pen_position_x = points[i + 5].value; + pen_position_y = points[i + 6].value; break; case POINT_LINE: cr.line_to (points[i + 1].value, points[i + 2].value); + pen_position_x = points[i + 1].value; + pen_position_y = points[i + 2].value; break; } } } + + void draw_arc (Context cr, + double rx, double ry, double rotation, + double large_arc, double sweep, + double x, double y) { + + double angle_start, angle_extent, cx, cy; + + get_arc_arguments (pen_position_x, pen_position_y, rx, ry, + rotation, large_arc > 0, sweep > 0, x, y, + out angle_start, out angle_extent, + out cx, out cy); - static void draw_arc (Context cr, - double x, double y, - double rx, double ry, - double angle_start, double angle_extent, - double rotation) { - cr.save (); - cr.translate (x, y); + + cr.translate (cx, cy); cr.rotate (rotation); cr.scale (rx, ry); - double start_x = Math.cos (-angle_start); - double start_y = Math.sin (-angle_start); + double start_x = Math.cos (angle_start); + double start_y = Math.sin (angle_start); cr.move_to (start_x, start_y); - + + angle_start %= 2 * Math.PI; + angle_extent %= 2 * Math.PI; + if (angle_extent > 0) { - cr.arc_negative (0, 0, 1, -angle_start, -angle_start - angle_extent); + cr.arc_negative (0, 0, 1, angle_start, angle_start + angle_extent); } else { - cr.arc (0, 0, 1, -angle_start, -angle_start - angle_extent); + cr.arc (0, 0, 1, angle_start, angle_start + angle_extent); } cr.restore ();