Clone in a terminal:
Commit 616fbab
Johan Mattsson - 2016-07-02T09:47:53+00:00
616fbabd957e312219d92ec61a8fad9b08a9cbc1johan.mattsson.m@gmail.com

Preserve aspect ratio in view box

Changed files (3)

Diff

diff --git a/libsvgbird/SvgDrawing.vala b/libsvgbird/SvgDrawing.valaindex af48f32..0aa8bf4 100644--- a/libsvgbird/SvgDrawing.vala+++ b/libsvgbird/SvgDrawing.vala@@ -66,8 +66,47 @@ public class SvgDrawing : Object { 	void apply_view_box (Context cr) { 		if (view_box != null) { 			ViewBox box = (!) view_box;+			double scale_x = 1;+			double scale_y = 1;+			double scale = 1;+			 			cr.translate (box.minx, box.miny);-			cr.scale (width / box.width, height / box.height);+			scale_x = width / box.width;+			scale_y = height / box.height;+			+			bool scale_width = height * box.width > width * box.height;+			+			if (box.alignment == ViewBox.NONE) {	+				cr.scale (scale_x, scale_y);+			} else if (scale_width && box.slice) {+				scale = scale_x;+				cr.scale (scale, scale);+			} else {+				scale = scale_y;+				cr.scale (scale, scale);+			}+			+			if (!box.slice) {+				if ((box.alignment & ViewBox.XMID) > 0) {+					cr.translate ((box.width - width) / 2, 0);+				} else if ((box.alignment & ViewBox.XMAX) > 0) {+					cr.translate (box.width - width, 0);+				}++				if ((box.alignment & ViewBox.YMID) > 0) {+					cr.translate (0, (box.height - height) / 2);+				} else if ((box.alignment & ViewBox.YMAX) > 0) {+					cr.translate (0, box.height - height);+				}+			} else {+				Layer layer = new Layer ();+				Rectangle rectangle = new Rectangle ();+				rectangle.width = box.width;+				rectangle.height = box.height;+				layer.add_object (rectangle);+				ClipPath clip = new ClipPath (layer);+				clip_path = clip;+			} 		} 	} @@ -84,10 +123,7 @@ public class SvgDrawing : Object { 	} 		 	public override void draw_outline (Context cr) {-		cr.save ();-		apply_transform (cr); 		root_layer.draw_outline (cr);-		cr.restore (); 	} 	 	public override Object copy () {diff --git a/libsvgbird/SvgFile.vala b/libsvgbird/SvgFile.valaindex 2a1a856..5f7b752 100644--- a/libsvgbird/SvgFile.vala+++ b/libsvgbird/SvgFile.vala@@ -46,7 +46,7 @@ public class SvgFile : GLib.Object { 			}  			if (attr.get_name () == "viewBox") {-				drawing.view_box = parse_view_box (attr.get_content ());+				drawing.view_box = parse_view_box (attr.get_content (), svg_tag); 			} 		} 				@@ -78,8 +78,26 @@ public class SvgFile : GLib.Object { 		return drawing; 	} -	ViewBox? parse_view_box (string parameters) {+	ViewBox? parse_view_box (string parameters, XmlElement tag) { 		string arguments = parameters.replace (",", " ");+		string aspect_ratio = "";+		bool slice = false;+		+		foreach (Attribute attribute in tag.get_attributes ()) {+			if (attribute.get_name () == "preserveAspectRatio") {+				aspect_ratio = attribute.get_content ();+				+				string[] preserveSettings = aspect_ratio.split (" ");+				+				if (preserveSettings.length >= 1) {+					aspect_ratio = preserveSettings[0];+				}+				+				if (preserveSettings.length >= 2) {+					slice = preserveSettings[1] == "slice";+				}+			}+		} 		 		while (arguments.index_of ("  ") > -1) { 			arguments = arguments.replace ("  ", " ");@@ -97,7 +115,32 @@ public class SvgFile : GLib.Object { 		double width = parse_number (view_box_parameters[2]); 		double height = parse_number (view_box_parameters[3]); 		-		return new ViewBox (minx, miny, width, height);+		uint alignment = ViewBox.XMID_YMID;+		aspect_ratio = aspect_ratio.up ();+		+		if (aspect_ratio == "NONE") {+			alignment = ViewBox.NONE;+		} else if (aspect_ratio == "XMIN_YMIN") {+			alignment = ViewBox.XMIN_YMIN;+		} else if (aspect_ratio == "XMID_YMIN") {+			alignment = ViewBox.XMIN_YMIN;+		} else if (aspect_ratio == "XMAX_YMIN") {+			alignment = ViewBox.XMIN_YMIN;+		} else if (aspect_ratio == "XMIN_YMID") {+			alignment = ViewBox.XMIN_YMIN;+		} else if (aspect_ratio == "XMID_YMID") {+			alignment = ViewBox.XMIN_YMIN;+		} else if (aspect_ratio == "XMAX_YMID") {+			alignment = ViewBox.XMIN_YMIN;+		} else if (aspect_ratio == "XMIN_YMAX") {+			alignment = ViewBox.XMIN_YMIN;+		} else if (aspect_ratio == "XMID_YMAX") {+			alignment = ViewBox.XMIN_YMIN;+		} else if (aspect_ratio == "XMAX_YMAX") {+			alignment = ViewBox.XMIN_YMIN;+		}+		+		return new ViewBox (minx, miny, width, height, alignment, slice); 	}  	private void parse_layer (Layer layer, SvgStyle parent_style, XmlElement tag) {		diff --git a/libsvgbird/ViewBox.vala b/libsvgbird/ViewBox.valaindex 2d1c786..c7c9c95 100644--- a/libsvgbird/ViewBox.vala+++ b/libsvgbird/ViewBox.vala@@ -21,16 +21,42 @@ namespace SvgBird {  public class ViewBox : GLib.Object { +	public const uint NONE = 1;+	public const uint XMIN = 1 << 1;+	public const uint XMID = 1 << 2;+	public const uint XMAX = 1 << 3;+	public const uint YMIN = 1 << 4;+	public const uint YMID = 1 << 5;+	public const uint YMAX = 1 << 6;+	+	public const uint XMIN_YMIN = XMIN | YMIN;+	public const uint XMID_YMIN = XMID | YMIN;+	public const uint XMAX_YMIN = XMAX | YMIN;+	public const uint XMIN_YMID = XMIN | YMID;+	public const uint XMID_YMID = XMID | YMID;+	public const uint XMAX_YMID = XMAX | YMID;+	public const uint XMIN_YMAX = XMIN | YMAX;+	public const uint XMID_YMAX = XMID | YMAX;+	public const uint XMAX_YMAX = XMAX | YMAX;+ 	public double minx = 0; 	public double miny = 0; 	public double width = 0; 	public double height = 0; -	public ViewBox (double minx, double miny, double width, double height) {+	public uint alignment;+	public bool slice;++	public ViewBox (double minx, double miny, double width, double height,+		uint alignment, bool slice) {+			 		this.minx = minx; 		this.miny = miny; 		this.width = width; 		this.height = height;+		+		this.alignment = alignment;+		this.slice = slice; 	} 	 }

Contact

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