Clone in a terminal:
Commit 45c9c30
Johan Mattsson - 2016-06-21T14:14:50+00:00
45c9c3049b7344f2dd7637b452317591363f0641johan.mattsson.m@gmail.com

Add birdfont paths to Svg table in OTF fonts

Changed files (4)

Diff

diff --git a/libbirdfont/BezierTool.vala b/libbirdfont/BezierTool.valaindex fd3b379..352ddee 100644--- a/libbirdfont/BezierTool.vala+++ b/libbirdfont/BezierTool.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 diff --git a/libbirdfont/OpenFontFormat/SvgTable.vala b/libbirdfont/OpenFontFormat/SvgTable.valaindex a6c4069..2b026a2 100644--- a/libbirdfont/OpenFontFormat/SvgTable.vala+++ b/libbirdfont/OpenFontFormat/SvgTable.vala@@ -13,6 +13,7 @@ */  using B;+using SvgBird;  namespace BirdFont { @@ -49,16 +50,18 @@ public class SvgTable : OtfTable { 					 					StringBuilder svg = new StringBuilder (); 					svg.append ("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");++					svg.append ("""<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">""");+					svg.append ("\n\n");+					+					svg.append ("<g id=");+					svg.append ("\"");+					svg.append ("glyph");+					svg.append (@"$gid");+					svg.append ("\" >"); 		 					foreach (EmbeddedSvg embedded in embedded_svg) {-						svg.append ("""<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">""");-						svg.append ("\n\n");-						-						svg.append ("<g id=");-						svg.append ("\"");-						svg.append ("glyph");-						svg.append (@"$gid");-						svg.append ("\" ");+						svg.append ("<g "); 						 						// scale the internal coordinates from 100 units per em to the  						// number of units per em in this font and move the glyph@@ -74,10 +77,12 @@ public class SvgTable : OtfTable {  						append_svg_glyph (svg, embedded.svg_data, glyphs); -						svg.append ("\n\n"); 						svg.append ("</g>\n");-						svg.append ("</svg>");+						svg.append ("\n\n"); 					}++					svg.append ("</g>\n");+					svg.append ("</svg>"); 					 					SvgTableEntry entry; 					entry = new SvgTableEntry ((uint16) gid, svg.str);@@ -93,16 +98,30 @@ public class SvgTable : OtfTable { 	 	Gee.ArrayList<EmbeddedSvg> get_embedded_svg (GlyphCollection glyphs) { 		Gee.ArrayList<EmbeddedSvg> svg = new Gee.ArrayList<EmbeddedSvg> ();+		PathList path_list = new PathList (); 		-		foreach (Object object in glyphs.get_current ().get_visible_objects ()) {+		foreach (SvgBird.Object object in glyphs.get_current ().get_visible_objects ()) { 			if (object is EmbeddedSvg) { 				svg.add ((EmbeddedSvg) object);+			} else if (object is PathObject) {+				Path path = ((PathObject) object).get_path ();+				+				if (path.stroke > 0) {+					path_list.append (path.get_completed_stroke ());+				} else {+					path_list.add (path);+				} 			} 		}++		if (path_list.paths.size > 0) {+			EmbeddedSvg svg_data = generate_svg (path_list, glyphs);+			svg.add (svg_data);+		} 		 		return svg; 	}-	+		 	void append_svg_glyph (StringBuilder svg, string svg_data, GlyphCollection glyphs) { 		Gee.ArrayList<Tag> layer_content; 		Gee.ArrayList<Tag> svg_tags;@@ -238,6 +257,140 @@ public class SvgTable : OtfTable { 		 		this.font_data = fd; 	}++	public EmbeddedSvg generate_svg (PathList paths, GlyphCollection glyphs) {+		StringBuilder svg = new StringBuilder ();+		+		svg.append ("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");+		svg.append ("""<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">""");+		+		Glyph g = glyphs.get_current ();+		Font font = OpenFontFormatWriter.get_current_font ();+		svg.append (@"<g transform=\"translate(0, $(font.get_height ()))\">\n");+		svg.append (@"<g transform=\"translate($(-g.left_limit), $(-font.base_line))\">\n");++		svg.append ("""<path style="fill:#000000;fill-opacity:1;" """);+		svg.append ("d=\"");++		foreach (Path p in paths.paths) {+			p.add_hidden_double_points ();+			+			+			int i = 0;+			EditPoint? n = null;+			EditPoint m;+			+			if (p.points.size < 2) {+				return new EmbeddedSvg (new SvgDrawing ());+			}++			p.create_list ();+				+			foreach (var e in p.points) {+				if (i == 0) {+					add_abs_start (e, svg);+					i++;+					n = e;+					continue;+				}+				+				m = (!) n;++				add_abs_next (m, e, svg);+				+				n = e;+				i++;+			}++			if (!p.is_open ()) {+				m = p.get_first_point ();	+				add_abs_next ((!) n, m, svg);+				close_path (svg);+			}+		}+		svg.append ("\" />\n");+		+		svg.append ("</g>\n");+		svg.append ("</g>\n");+		svg.append ("</svg>\n");++		EmbeddedSvg embedded = new EmbeddedSvg (new SvgDrawing ());+		embedded.x = g.left_limit;+		embedded.y = font.get_height ();+		embedded.svg_data = svg.str;++		return embedded;+	}++	public static void add_abs_next (EditPoint start, EditPoint end, StringBuilder svg) {+		if (start.right_handle.type == PointType.LINE_QUADRATIC) {+			add_abs_line_to (start, end, svg);+		} else if (start.right_handle.type == PointType.LINE_CUBIC && end.left_handle.type == PointType.LINE_CUBIC) {+			add_abs_line_to (start, end, svg);+		} else if (end.left_handle.type == PointType.QUADRATIC || start.right_handle.type == PointType.QUADRATIC) {+			add_quadratic_abs_path (start, end, svg);+		} else if (end.left_handle.type == PointType.DOUBLE_CURVE || start.right_handle.type == PointType.DOUBLE_CURVE) {+			add_double_quadratic_abs_path (start, end, svg);+		} else {+			add_cubic_abs_path (start, end, svg);+		}+	}++	private static void add_abs_start (EditPoint ep, StringBuilder svg) {		+		svg.append_printf ("M");		+		svg.append_printf ("%s ",  round (ep.x));+		svg.append_printf ("%s ",  round (-ep.y));+	}++	public static void close_path (StringBuilder svg) {+		svg.append ("z");+	}	+	+	private static void add_abs_line_to (EditPoint start, EditPoint stop, StringBuilder svg) {+		svg.append ("L");	+		svg.append_printf ("%s ", round (stop.x));+		svg.append_printf ("%s ", round (-stop.y));	+	}+	+	private static void add_double_quadratic_abs_path (EditPoint start, EditPoint end, StringBuilder svg) {+		EditPoint middle;+		double x, y;+		+		x = start.get_right_handle ().x + (end.get_left_handle ().x - start.get_right_handle ().x) / 2;+		y = start.get_right_handle ().y + (end.get_left_handle ().y - start.get_right_handle ().y) / 2;+		+		middle = new EditPoint (x, y, PointType.QUADRATIC);+		middle.right_handle = end.get_left_handle ().copy ();+		+		add_quadratic_abs_path (start, middle, svg);+		add_quadratic_abs_path (middle, end, svg);+	}+		+	private static void add_quadratic_abs_path (EditPoint start, EditPoint stop, StringBuilder svg) {+		// cubic path+		svg.append_printf ("Q");++		svg.append_printf ("%s ", round (start.get_right_handle ().x));+		svg.append_printf ("%s ", round (-start.get_right_handle ().y));+		+		svg.append_printf ("%s ", round (stop.x));+		svg.append_printf ("%s ", round (-stop.y));+	}+			+	private static void add_cubic_abs_path (EditPoint start, EditPoint stop, StringBuilder svg) {+		// cubic path+		svg.append_printf ("C");++		svg.append_printf ("%s ", round (start.get_right_handle ().x));+		svg.append_printf ("%s ", round (-start.get_right_handle ().y));++		svg.append_printf ("%s ", round (stop.get_left_handle ().x));+		svg.append_printf ("%s ", round (-stop.get_left_handle ().y));+		+		svg.append_printf ("%s ", round (stop.x));+		svg.append_printf ("%s ", round (-stop.y));+	}+ }  }diff --git a/libbirdfont/Svg.vala b/libbirdfont/Svg.valaindex 82eaf9a..14a1915 100644--- a/libbirdfont/Svg.vala+++ b/libbirdfont/Svg.vala@@ -83,13 +83,13 @@ public class Svg { 		}  		if (!p.is_open ()) {-			m = p.points.get (0);	+			m = p.get_first_point ();	 			add_abs_next ((!) n, m, svg, g, do_glyph); 			close_path (svg); 		} 	} -	private static void add_abs_next (EditPoint start, EditPoint end, StringBuilder svg, Glyph g, bool do_glyph) {+	public static void add_abs_next (EditPoint start, EditPoint end, StringBuilder svg, Glyph g, bool do_glyph) { 		if (start.right_handle.type == PointType.LINE_QUADRATIC) { 			add_abs_line_to (start, end, svg, g, do_glyph); 		} else if (start.right_handle.type == PointType.LINE_CUBIC && end.left_handle.type == PointType.LINE_CUBIC) {@@ -119,7 +119,7 @@ public class Svg { 		} 	} 		-	private static void close_path (StringBuilder svg) {+	public static void close_path (StringBuilder svg) { 		svg.append ("z"); 	}	 	diff --git a/libsvgbird/SvgFile.vala b/libsvgbird/SvgFile.valaindex fcf030c..e41408a 100644--- a/libsvgbird/SvgFile.vala+++ b/libsvgbird/SvgFile.vala@@ -636,7 +636,7 @@ public class SvgFile : GLib.Object { 		param = param.replace (",", " "); 		 		while (param.index_of ("  ") > -1) {-			param.replace ("  ", " ");+			param = param.replace ("  ", " "); 		} 			 		return param.strip();			

Contact

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