Commit 0663b67
Fix arc arguments
Changed files (4)
modifiedlibbirdfont/SvgParser.valamodifiedlibsvgbird/BezierPoints.valamodifiedlibsvgbird/SvgFile.valamodifiedlibsvgbird/SvgPath.vala
Diff
@@ -1094,7 +1094,7 @@ public class SvgParser { 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);@@ -28,14 +28,14 @@ public class BezierPoints { // 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 ())";@@ -800,6 +800,8 @@ public class SvgFile : GLib.Object { 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 @@ public class SvgFile : GLib.Object { 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 @@ public class SvgFile : GLib.Object { 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 @@ public class SvgFile : GLib.Object { 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 @@ public class SvgFile : GLib.Object { } else { string type = (!) bezier_points[i].type.to_string (); warning (@"SVG conversion not implemented for $type");- }+ } } if (points.size > 0) {@@ -1440,7 +1442,7 @@ public class SvgFile : GLib.Object { 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 @@ public class SvgFile : GLib.Object { 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++;@@ -19,6 +19,9 @@ namespace SvgBird { 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 @@ public class SvgPath : Object { 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 @@ public class SvgPath : Object { 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 ();