Clone in a terminal:
Commit d051bd2
Johan Mattsson - 2016-01-13T22:51:16+00:00
d051bd2a86e93559a017767a1a5777eabb1f4cbfjohan.mattsson.m@gmail.com

Parse arc instructions in SVG paths

Changed files (14)

Diff

diff --git a/libbirdfont/EmbeddedSvg.vala b/libbirdfont/EmbeddedSvg.valaindex 4992d5c..e797b20 100644--- a/libbirdfont/EmbeddedSvg.vala+++ b/libbirdfont/EmbeddedSvg.vala@@ -71,11 +71,7 @@ public class EmbeddedSvg : SvgBird.Object { 		drawing.update_region_boundaries (); 	} -	// FIXME: handle this in SVG library instead 	public override bool is_over (double x, double y) {-		print (@" $(this.x) <= $(x) <= $(this.x) + $(drawing.width)");-		print (@" $(this.y) <= $(y) <= $(this.y) + $(drawing.height)");-			 		return (this.x <= x <= this.x + drawing.width)  			&& (this.y - drawing.height <= y <= this.y); 	}diff --git a/libbirdfont/MoveTool.vala b/libbirdfont/MoveTool.valaindex 76c5f00..9da3b2d 100644--- a/libbirdfont/MoveTool.vala+++ b/libbirdfont/MoveTool.vala@@ -493,8 +493,6 @@ public class MoveTool : Tool { 		double w = Math.fabs (selection_x - last_x); 		double h = Math.fabs (selection_y - last_y); 		-		Glyph glyph = MainWindow.get_current_glyph ();-		 		cr.save ();			 		Theme.color (cr, "Foreground 1"); 		cr.set_line_width (2);diff --git a/libbirdfont/OverViewItem.vala b/libbirdfont/OverViewItem.valaindex 350718d..66c30f3 100644--- a/libbirdfont/OverViewItem.vala+++ b/libbirdfont/OverViewItem.vala@@ -99,7 +99,6 @@ public class OverViewItem : GLib.Object { 		} 		 		Glyph g;-		Font font; 		double gx, gy; 		double x1, x2, y1, y2; 		double scale_box;diff --git a/libbirdfont/SvgParser.vala b/libbirdfont/SvgParser.valaindex 322cd20..487198c 100644--- a/libbirdfont/SvgParser.vala+++ b/libbirdfont/SvgParser.vala@@ -1016,6 +1016,36 @@ public class SvgParser { 		} 	} 	+	public void get_bezier_points (string svg_data, out BezierPoints[] instructions, out int points, bool svg_glyph) {+		SvgFile.get_bezier_points (svg_data, out instructions, out points, svg_glyph);+		Gee.ArrayList<BezierPoints> bezier_points = new Gee.ArrayList<BezierPoints> ();+		BezierPoints[] arc_data = new BezierPoints[8];+		+		for (int i = 0; i < points; i++) {+			if (instructions[i].type == 'A') {+				int arc_index = 0;+				+				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].large_arc,+					instructions[i].sweep,+					instructions[i].x1, instructions[i].y1);+					+				for (int j = 0; j < arc_index; j++) {+					bezier_points.add (instructions[j]);+				}+			}+			+			bezier_points.add (instructions[i]);+		}+	+		instructions = new BezierPoints[bezier_points.size];+		for (int i = 0; i < bezier_points.size; i++) {+			instructions[i] = bezier_points.get (i);+		}+	} 	/**  	 * @param d svg data 	 * @param glyph use lines from this glyph but don't add the generated paths@@ -1517,7 +1547,6 @@ public class SvgParser {  	public static EmbeddedSvg parse_embedded_svg_file (string path) { 		string xml_data;-		SvgFile svg_file = new SvgFile ();  		 		try { 			FileUtils.get_contents (path, out xml_data);@@ -1532,7 +1561,6 @@ public class SvgParser {  	public static EmbeddedSvg parse_embedded_svg_data (string xml_data) { 		XmlTree tree = new XmlTree (xml_data);-		XmlElement tag = tree.get_root (); 		SvgDrawing drawing = new SvgDrawing ();	 		SvgFile svg_file = new SvgFile ();  @@ -1543,6 +1571,55 @@ public class SvgParser { 		return svg; 	} +	/** Convert an SVG arc instruction to a Beziér path. */+	public static void add_arc_points (BezierPoints[] bezier_points, ref int bi, +		double x0, double y0, double rx, double ry, double angle,+		bool largeArcFlag, bool sweepFlag, double x, double y) {+		+		double angleStart, angleExtent;+		double s, step, theta;+		double cx, cy;+		+		cx = 0;+		cy = 0;+		+		// Approximate the path with Beziér points+		SvgBird.get_arc_arguments (x0, y0, rx, ry, angle, largeArcFlag, sweepFlag, x, y,+			out angleStart, out angleExtent, out cx, out cx);+		+		s = (angleExtent > 0) ? 1 : -1;+		step = fabs (angleExtent) / (2 * fabs (angleExtent));++		theta = PI - angleStart - angleExtent;+		+		bezier_points[bi].type = 'C';+		bezier_points[bi].svg_type = 'a';++		bezier_points[bi].x0 = cx + rx * cos (theta);+		bezier_points[bi].y0 = cy + ry * sin (theta);+		+		bi++;+						+		for (double a = 0; a < fabs (angleExtent); a += step) {+			theta = PI - angleStart - angleExtent + s * a;++			return_if_fail (0 <= bi < bezier_points.length);++			bezier_points[bi].type = 'S';+			bezier_points[bi].svg_type = 'a';++			bezier_points[bi].x0 = cx + rx * cos (theta);+			bezier_points[bi].y0 = cy + ry * sin (theta);++			bezier_points[bi].x1 = cx + rx * cos (theta + 1 * step / 4);+			bezier_points[bi].y1 = cy + ry * sin (theta + 1 * step / 4);+			+			bezier_points[bi].x2 = cx + rx * cos (theta + 2 * step / 4);+			bezier_points[bi].y2 = cy + ry * sin (theta + 2 * step / 4);+							+			bi++;+		}+	} }  }diff --git a/libsvgbird/BezierPoints.vala b/libsvgbird/BezierPoints.valaindex 5d5256d..d9c015a 100644--- a/libsvgbird/BezierPoints.vala+++ b/libsvgbird/BezierPoints.vala@@ -1,5 +1,5 @@ /*-	Copyright (C) 2014 Johan Mattsson+	Copyright (C) 2014 2016 Johan Mattsson  	This library is free software; you can redistribute it and/or modify  	it under the terms of the GNU Lesser General Public License as @@ -24,8 +24,20 @@ public class BezierPoints { 	public double y1 = 0; 	public double x2 = 0; 	public double y2 = 0;-	++	// arc arguments+	public double rx = 0; +	public double ry = 0;+	public double angle = 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 @"$((!)type.to_string ()) $x0,$y0 $x1,$y1 $x2,$y2 SVG:$((!)svg_type.to_string ())"; 	} }diff --git a/libsvgbird/Doubles.vala b/libsvgbird/Doubles.valaindex a4b1c35..ad6133f 100644--- a/libsvgbird/Doubles.vala+++ b/libsvgbird/Doubles.vala@@ -17,12 +17,12 @@ using Cairo; namespace SvgBird {  public class Doubles : GLib.Object {-	public double* data;+	public PointValue* data; 	public int size = 0; 	int capacity = 10; 	 	public Doubles () {-		data = new double[capacity];+		data = new PointValue[capacity]; 	}  	~Doubles () {@@ -31,21 +31,34 @@ public class Doubles : GLib.Object { 	} 	 	public Doubles.for_capacity (int capacity) {-		data = new double[capacity];+		data = new PointValue[capacity]; 		this.capacity = capacity; 	}-		-	public void add(double d) {+	+	void increase_capacity () {+		int new_capacity = 2 * capacity;+		PointValue* new_data = new PointValue[new_capacity];+		Posix.memcpy (new_data, data, sizeof (PointValue) * size);+		delete data;+		data = new_data;+		capacity = new_capacity;		+	}++	public void add_type (uchar type) {+		if (size >= capacity) {+			increase_capacity ();+		}++		data[size].type = type;+		size++;+	}++	public void add (double d) { 		if (size >= capacity) {-			int new_capacity = 2 * capacity;-			double* new_data = new double[new_capacity];-			Posix.memcpy (new_data, data, sizeof (double) * size);-			delete data;-			data = new_data;-			capacity = new_capacity;+			increase_capacity (); 		} 		-		data[size] = d;+		data[size].value = d; 		size++; 	} 	@@ -55,7 +68,7 @@ public class Doubles : GLib.Object { 		d.data = new double[capacity]; 		d.capacity = capacity; 		d.size = size;-		Posix.memcpy (d.data, data, sizeof (double) * size);+		Posix.memcpy (d.data, data, sizeof (PointValue) * size); 		return d; 	} 	@@ -70,7 +83,7 @@ public class Doubles : GLib.Object { 			return 0; 		} 		-		return data[index];+		return data[index].value; 	} } diff --git a/libsvgbird/Ellipse.vala b/libsvgbird/Ellipse.valaindex 86e4be6..38efe1c 100644--- a/libsvgbird/Ellipse.vala+++ b/libsvgbird/Ellipse.vala@@ -13,6 +13,7 @@ */  using Cairo;+using Math;  namespace SvgBird { @@ -40,10 +41,10 @@ public class Ellipse : Object { 			 	public override void draw (Context cr) { 		cr.save ();-		cr.translate (cx + rx, cy + ry);+		cr.translate (cx, cy); 		cr.scale (rx, ry);-		cr.arc (0, 0, 1, 0, 2 * Math.PI);-		cr.restore ();+		cr.arc (0, 0, 1, 0, 2 * PI);+		cr.restore ();	 		 		cr.save (); 		apply_transform (cr);		diff --git a/libsvgbird/Points.vala b/libsvgbird/Points.valaindex f6bbea5..890cd90 100644--- a/libsvgbird/Points.vala+++ b/libsvgbird/Points.vala@@ -25,6 +25,10 @@ public class Points : GLib.Object { 	public void add (double p) { 		point_data.add (p); 	}+	+	public void add_type (uchar type) {+		point_data.add_type (type);+	} }  }diff --git a/libsvgbird/Polygon.vala b/libsvgbird/Polygon.valaindex dd82120..b0c283a 100644--- a/libsvgbird/Polygon.vala+++ b/libsvgbird/Polygon.vala@@ -33,10 +33,10 @@ public class Polygon : Object { 		apply_transform (cr); 		 		if (points.size > 2) {-			cr.move_to (points.data[0], points.data[1]);+			cr.move_to (points.data[0].value, points.data[1].value); 			 			for (int i = 2; i < points.size - 1; i += 2) {-				cr.line_to (points.data[i], points.data[i + 1]);+				cr.line_to (points.data[i].value, points.data[i + 1].value); 			} 			 			cr.close_path ();diff --git a/libsvgbird/Polyline.vala b/libsvgbird/Polyline.valaindex 89a2e86..4c47e54 100644--- a/libsvgbird/Polyline.vala+++ b/libsvgbird/Polyline.vala@@ -33,10 +33,10 @@ public class Polyline : Object { 		apply_transform (cr); 		 		if (points.size > 2) {-			cr.move_to (points.data[0], points.data[1]);+			cr.move_to (points.data[0].value, points.data[1].value); 			 			for (int i = 2; i < points.size - 1; i += 2) {-				cr.line_to (points.data[i], points.data[i + 1]);+				cr.line_to (points.data[i].value, points.data[i + 1].value); 			} 		} 		diff --git a/libsvgbird/SvgArc.vala b/libsvgbird/SvgArc.valaindex 9569e12..d083b90 100644--- a/libsvgbird/SvgArc.vala+++ b/libsvgbird/SvgArc.vala@@ -41,27 +41,30 @@ using Math;  namespace SvgBird { -/** Convert an SVG arc instruction to a Beziér path. */-static void add_arc_points (BezierPoints[] bezier_points, ref int bi, double x0, double y0, double rx, double ry, double angle, bool largeArcFlag, bool sweepFlag, double x, double y) {+public static void get_arc_arguments (double x0, double y0,+	double rx, double ry, double angle, bool largeArcFlag,+	bool sweepFlag, double x, double y,+	out double angle_start, out double angle_extent,+	out double center_x, out double center_y) {  	// 	// Elliptical arc implementation based on the SVG specification notes 	// +	double cx, cy; 	double dx2, dy2, cosAngle, sinAngle; 	double x1, y1, Prx, Pry, Px1, Py1, radiiCheck; 	double sign, sq, coef, cx1, cy1;-	double sx2, sy2, cx, cy;+	double sx2, sy2; 	double ux, uy, vx, vy, p, n; 	double angleStart, angleExtent;-	double s, step, theta; 	 	// Compute the half distance between the current and the final point 	dx2 = (x0 - x) / 2.0; 	dy2 = (y0 - y) / 2.0; 	 	// Convert angle from degrees to radians-	angle = 2 * PI * ((angle % 360.0) / 360.0);+	angle = angle % (2 * Math.PI); 	 	cosAngle = cos (angle); 	sinAngle = sin (angle);@@ -71,7 +74,7 @@ static void add_arc_points (BezierPoints[] bezier_points, ref int bi, double x0, 	// 	x1 = cosAngle * dx2 + sinAngle * dy2; 	y1 = -sinAngle * dx2 + cosAngle * dy2;-	+ 	// Ensure radii are large enough 	rx = fabs(rx); 	ry = fabs(ry);@@ -80,7 +83,6 @@ static void add_arc_points (BezierPoints[] bezier_points, ref int bi, double x0, 	Px1 = x1 * x1; 	Py1 = y1 * y1; -	 	// Check that radii are large enough 	radiiCheck = Px1 / Prx + Py1 / Pry; 	@@ -107,13 +109,13 @@ static void add_arc_points (BezierPoints[] bezier_points, ref int bi, double x0, 	 	sx2 = (x0 + x) / 2.0; 	sy2 = (y0 + y) / 2.0;-	cx = sx2 - (cosAngle * cx1 - sinAngle * cy1);-	cy = sy2 - (sinAngle * cx1 + cosAngle * cy1);+	cx = sx2 + (cosAngle * cx1 - sinAngle * cy1); // FIXME: + delete this+	cy = sy2 + (sinAngle * cx1 + cosAngle * cy1);  	// 	// Step 4 : Compute the angleStart (angle1) and the angleExtent (dangle) 	//-	+ 	ux = (x1 - cx1) / rx; 	uy = (y1 - cy1) / ry; 	vx = (-x1 - cx1) / rx;@@ -132,50 +134,26 @@ static void add_arc_points (BezierPoints[] bezier_points, ref int bi, double x0, 	angleExtent = sign * Math.acos(p / n); 	 	if(!sweepFlag && angleExtent > 0) {-		angleExtent -= 2 *PI;+		angleExtent -= 2 * PI; 	} else if (sweepFlag && angleExtent < 0) {-		angleExtent += 2 *PI;+		angleExtent += 2 * PI; 	}-	angleExtent %= 2 * PI;-	angleStart %= 2 * PI;--	angleExtent *= -1;-	angleStart *= -1;-	-	// Approximate the path with Beziér points-	s = (angleExtent > 0) ? 1 : -1;-	step = fabs (angleExtent) / (2 * fabs (angleExtent));--	theta = PI - angleStart - angleExtent;-	-	bezier_points[bi].type = 'L';-	bezier_points[bi].svg_type = 'a';+		+	//center_x = cx - rx;+	//center_y = cy - ry; -	bezier_points[bi].x0 = cx + rx * cos (theta);-	bezier_points[bi].y0 = cy + ry * sin (theta);-									-	bi++;-					-	for (double a = 0; a < fabs (angleExtent); a += step) {-		theta = PI - angleStart - angleExtent + s * a;+	center_x = cx;+	center_y = cy;+		+	angleExtent = -angleExtent;+	angleStart = -angleStart; -		return_if_fail (0 <= bi < bezier_points.length);+	angle_start = angleStart;+	angle_extent = angleExtent; -		bezier_points[bi].type = 'S';-		bezier_points[bi].svg_type = 'a';+	print (@"angleStart: $angle_start  angleExtent $angle_extent\n");+} -		bezier_points[bi].x0 = cx + rx * cos (theta);-		bezier_points[bi].y0 = cy + ry * sin (theta); -		bezier_points[bi].x1 = cx + rx * cos (theta + 1 * step / 4);-		bezier_points[bi].y1 = cy + ry * sin (theta + 1 * step / 4);-		-		bezier_points[bi].x2 = cx + rx * cos (theta + 2 * step / 4);-		bezier_points[bi].y2 = cy + ry * sin (theta + 2 * step / 4);-						-		bi++;-	} } -}-	diff --git a/libsvgbird/SvgFile.vala b/libsvgbird/SvgFile.valaindex b00eb30..d95400d 100644--- a/libsvgbird/SvgFile.vala+++ b/libsvgbird/SvgFile.vala@@ -14,6 +14,7 @@  using B; using Cairo;+using Math;  namespace SvgBird { @@ -636,25 +637,53 @@ public class SvgFile : GLib.Object { 	 		get_bezier_points (data, out bezier_points, out points_size, true); +		// instructions are padded+ 		for (int i = 0; i < points_size; i++) { 			// FIXME: add more types 			if (bezier_points[i].type == 'M') { 				points.x = bezier_points[i].x0; 				points.y = bezier_points[i].y0; 			} else if (bezier_points[i].type == 'C') {+				points.add_type (CUBIC); 				points.add (bezier_points[i].x0); 				points.add (bezier_points[i].y0); 				points.add (bezier_points[i].x1); 				points.add (bezier_points[i].y1); 				points.add (bezier_points[i].x2); 				points.add (bezier_points[i].y2);+				points.add (0); 			} else if (bezier_points[i].type == 'L') {+				points.add_type (CUBIC); // FIXME: use cairo line 				points.add (bezier_points[i].x0); 				points.add (bezier_points[i].y0); 				points.add (bezier_points[i].x0); 				points.add (bezier_points[i].y0); 				points.add (bezier_points[i].x0); 				points.add (bezier_points[i].y0);+				points.add (0);+			} 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 = Math.PI * (b.angle / 180.0);+				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 (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); 			} else if (bezier_points[i].type == 'z') { 				points.closed = true; 				path_data.add (points);@@ -686,7 +715,7 @@ public class SvgFile : GLib.Object { 		return double.parse ((!) s); 	} 	-+	// FIXME: rename to instructions 	public static void get_bezier_points (string point_data, out BezierPoints[] bezier_points, out int points, bool svg_glyph) { 		double px = 0; 		double py = 0;@@ -1157,7 +1186,7 @@ public class SvgFile : GLib.Object { 					arc_rx = parse_double (c[++i]); 					arc_ry = parse_double (c[++i]); 					-					arc_rotation = parse_double (c[++i]);+					arc_rotation = PI * (parse_double (c[++i]) / 180.0); 					large_arc = parse_int (c[++i]); 					arc_sweep = parse_int (c[++i]); 							@@ -1172,7 +1201,20 @@ public class SvgFile : GLib.Object { 					arc_dest_x = cx; 					arc_dest_y = cy; 					-					add_arc_points (bezier_points, ref bi, px, py, arc_rx, arc_ry, arc_rotation, large_arc == 1, arc_sweep == 1, cx, cy);+					bezier_points[bi].type = 'A';+					bezier_points[bi].svg_type = 'a';+					bezier_points[bi].x0 = px;+					bezier_points[bi].y0 = py;+					bezier_points[bi].x1 = cx;+					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].large_arc = large_arc == 1;+					bezier_points[bi].sweep = arc_sweep == 1;+					bi++;+					+					// FIXME: Delete add_arc_points (bezier_points, ref bi, px, py, arc_rx, arc_ry, arc_rotation, large_arc == 1, arc_sweep == 1, cx, cy); 					 					px = cx; 					py = cy;@@ -1182,7 +1224,7 @@ public class SvgFile : GLib.Object { 					arc_rx = parse_double (c[++i]); 					arc_ry = parse_double (c[++i]); 					-					arc_rotation = parse_double (c[++i]);+					arc_rotation = PI * (parse_double (c[++i]) / 180.0); 					large_arc = parse_int (c[++i]); 					arc_sweep = parse_int (c[++i]); 							@@ -1197,12 +1239,21 @@ public class SvgFile : GLib.Object { 					arc_dest_x = cx; 					arc_dest_y = cy; 					-					add_arc_points (bezier_points, ref bi, px, py, arc_rx, arc_ry, arc_rotation, large_arc == 1, arc_sweep == 1, cx, cy);-+					bezier_points[bi].type = 'A';+					bezier_points[bi].svg_type = 'A';+					bezier_points[bi].x0 = px;+					bezier_points[bi].y0 = py;+					bezier_points[bi].x1 = cx;+					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].large_arc = large_arc == 1;+					bezier_points[bi].sweep = arc_sweep == 1;+					bi++;+					 					px = cx; 					py = cy;-					-					 				} 			} else if (c[i] == "z") { 				bezier_points[bi].type = 'z';diff --git a/libsvgbird/SvgPath.vala b/libsvgbird/SvgPath.valaindex a6bf077..e66c152 100644--- a/libsvgbird/SvgPath.vala+++ b/libsvgbird/SvgPath.vala@@ -48,18 +48,49 @@ public class SvgPath : Object { 		cr.restore (); 	} -	public void draw_points (Context cr, Points points) {-		Doubles p = points.point_data;+	public void draw_points (Context cr, Points path) {+		PointValue* points = path.point_data.data;+		int size = path.point_data.size; 		-		return_if_fail (p.size % 6 == 0);+		return_if_fail (size % 8 == 0); 		-		for (int i = 0; i < p.size; i += 6) {-			cr.curve_to (p.data[i], p.data[i + 1], -				p.data[i + 2], p.data[i + 3],-				p.data[i + 4], p.data[i + 5]);+		for (int i = 0; i < size; i += 8) {+			switch (points[i].type) {+			case ARC:		+				draw_arc (cr, points[i + 1].value, points[i + 2].value,+					points[i + 3].value, points[i + 4].value,+					points[i + 5].value, points[i + 6].value,+					points[i + 7].value);+				break;+			case 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);+				break;+			} 		}		 	} +	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.rotate (rotation);+		cr.scale (rx, ry);++		if (angle_extent > 0) {+			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.restore ();+	}+ 	public override void move (double dx, double dy) { 	} 	diff --git a/libsvgbird/SvgStyle.vala b/libsvgbird/SvgStyle.valaindex 116b79e..a9807b8 100644--- a/libsvgbird/SvgStyle.vala+++ b/libsvgbird/SvgStyle.vala@@ -1,5 +1,5 @@ /*-	Copyright (C) 2015 Johan Mattsson+	Copyright (C) 2015 2016 Johan Mattsson  	This library is free software; you can redistribute it and/or modify  	it under the terms of the GNU Lesser General Public License as @@ -70,7 +70,6 @@ public class SvgStyle : GLib.Object { 	 	public void inherit (SvgStyle inherited) { 		foreach (string key in inherited.style.keys) {-			print (@"inherit $key: " + inherited.style.get (key) + "\n"); 			style.set (key, inherited.style.get (key)); 		} 	}

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112