Clone in a terminal:
Commit df5ae9c
Johan Mattsson - 2016-07-04T18:49:09+00:00
df5ae9cb468cf1261901dd918c6d00b96294c631johan.mattsson.m@gmail.com

CSS pseudo classes in SVG files

Changed files (7)

Diff

diff --git a/libbirdfont/SvgParser.vala b/libbirdfont/SvgParser.valaindex e2ace23..205c6ee 100644--- a/libbirdfont/SvgParser.vala+++ b/libbirdfont/SvgParser.vala@@ -557,7 +557,7 @@ public class SvgParser { 			} 		} 		-		style = SvgStyle.parse (null, style, tag);+		style = SvgStyle.parse (null, style, tag, null); 		 		if (hidden) { 			return;@@ -625,7 +625,7 @@ public class SvgParser { 			} 		} 		-		style = SvgStyle.parse (null, style, tag);+		style = SvgStyle.parse (null, style, tag, null); 		 		if (hidden) { 			return;@@ -691,7 +691,7 @@ public class SvgParser { 			} 		} 		-		style = SvgStyle.parse (null, style, tag);+		style = SvgStyle.parse (null, style, tag, null); 		 		if (hidden) { 			return;@@ -769,7 +769,7 @@ public class SvgParser { 			} 		} 		-		style = SvgStyle.parse (null, style, tag);+		style = SvgStyle.parse (null, style, tag, null); 		 		if (hidden) { 			return;@@ -867,7 +867,7 @@ public class SvgParser { 			} 		} -		style = SvgStyle.parse (null, style, tag);+		style = SvgStyle.parse (null, style, tag, null); 		 		if (hidden) { 			return path_list;@@ -907,7 +907,7 @@ public class SvgParser { 			} 		} 		-		style = SvgStyle.parse (null, style, tag);+		style = SvgStyle.parse (null, style, tag, null); 		 		if (hidden) { 			return;diff --git a/libsvgbird/Selector.vala b/libsvgbird/Selector.valaindex 6f9ec0e..7436323 100644--- a/libsvgbird/Selector.vala+++ b/libsvgbird/Selector.vala@@ -21,6 +21,7 @@ public class Selector : GLib.Object { 	 	Gee.ArrayList<SelectorPattern> tag_patterns = new Gee.ArrayList<SelectorPattern> (); 	Gee.ArrayList<SelectorPattern> class_patterns = new Gee.ArrayList<SelectorPattern> ();+	Gee.ArrayList<SelectorPattern> pseudo_class_patterns = new Gee.ArrayList<SelectorPattern> (); 	Gee.ArrayList<SelectorPattern> id_patterns = new Gee.ArrayList<SelectorPattern> (); 	 	public SvgStyle style { get; set; }@@ -32,13 +33,20 @@ public class Selector : GLib.Object { 			SelectorPattern p = new SelectorPattern (selector_patterns[i]); 			 			if (p.has_id ()) {-				id_patterns.add (p);+				SelectorPattern id = p.get_id_patterns ();+				id_patterns.add (id); 			} 			 			if (p.has_class ()) {-				class_patterns.add (p);+				SelectorPattern css_class = p.get_class_patterns ();+				class_patterns.add (css_class); 			} +			if (p.has_pseudo_class ()) {+				SelectorPattern pseudo_class = p.get_pseudo_class_patterns ();+				pseudo_class_patterns.add (pseudo_class);+			}+			 			tag_patterns.add (p); 		} @@ -59,6 +67,10 @@ public class Selector : GLib.Object { 		foreach (SelectorPattern pattern in selector.id_patterns) { 			id_patterns.add (pattern.copy ()); 		}+		+		foreach (SelectorPattern pattern in selector.pseudo_class_patterns) {+			pseudo_class_patterns.add (pattern.copy ());+		} 	} 	 	public string to_string () {@@ -79,9 +91,9 @@ public class Selector : GLib.Object { 		return new Selector.copy_constructor (this); 	} 	-	public bool match_tag (XmlElement tag, string? id, string? css_class) {+	public bool match_tag (XmlElement tag, string? id, string? css_class, string? psedo_class) { 		foreach (SelectorPattern pattern in tag_patterns) {-			if (pattern.match (tag, id, css_class)) {+			if (pattern.match (tag, id, css_class, psedo_class)) { 				return true; 			} 		}@@ -89,9 +101,9 @@ public class Selector : GLib.Object { 		return false; 	} 	-	public bool match_id (XmlElement tag, string? id, string? css_class) {+	public bool match_id (XmlElement tag, string? id, string? css_class, string? psedo_class) { 		foreach (SelectorPattern pattern in id_patterns) {-			if (pattern.match (tag, id, css_class)) {+			if (pattern.match (tag, id, css_class, psedo_class)) { 				return true; 			} 		}@@ -99,9 +111,19 @@ public class Selector : GLib.Object { 		return false; 	} 	-	public bool match_class (XmlElement tag, string? id, string? css_class) {+	public bool match_class (XmlElement tag, string? id, string? css_class, string? psedo_class) { 		foreach (SelectorPattern pattern in class_patterns) {-			if (pattern.match (tag, id, css_class)) {+			if (pattern.match (tag, id, css_class, psedo_class)) {+				return true;+			}+		}+		+		return false;+	}+	+	public bool match_pseudo_class (XmlElement tag, string? id, string? css_class, string? psedo_class) {+		foreach (SelectorPattern pattern in pseudo_class_patterns) {+			if (pattern.match (tag, id, css_class, psedo_class)) { 				return true; 			} 		}diff --git a/libsvgbird/SelectorPattern.vala b/libsvgbird/SelectorPattern.valaindex a67865f..8b9d806 100644--- a/libsvgbird/SelectorPattern.vala+++ b/libsvgbird/SelectorPattern.vala@@ -23,7 +23,7 @@ public class SelectorPattern : GLib.Object {  	public SelectorPattern.empty () { 	}-+	 	public SelectorPattern (string pattern) { 		string p = pattern.strip (); 		string[] elements = p.split (" ");@@ -35,6 +35,36 @@ public class SelectorPattern : GLib.Object { 		} 	} +	public SelectorPattern get_id_patterns () {+		SelectorPattern pattern = new SelectorPattern.empty ();+		foreach (SelectorTag tag in tags) {+			if (tag.id != null) {+				pattern.tags.add (tag);+			}+		}+		return pattern;+	}++	public SelectorPattern get_class_patterns () {+		SelectorPattern pattern = new SelectorPattern.empty ();+		foreach (SelectorTag tag in tags) {+			if (tag.css_class != null) {+				pattern.tags.add (tag);+			}+		}+		return pattern;+	}++	public SelectorPattern get_pseudo_class_patterns () {+		SelectorPattern pattern = new SelectorPattern.empty ();+		foreach (SelectorTag tag in tags) {+			if (tag.pseudo_class != null) {+				pattern.tags.add (tag);+			}+		}+		return pattern;+	}+ 	public bool has_id () { 		foreach (SelectorTag tag in tags) { 			if (tag.id != null) {@@ -55,6 +85,16 @@ public class SelectorPattern : GLib.Object { 		return false; 	} +	public bool has_pseudo_class () {+		foreach (SelectorTag tag in tags) {+			if (tag.pseudo_class != null) {+				return true;+			}+		}+		+		return false;+	}+	 	public string to_string () { 		StringBuilder s = new StringBuilder (); 		@@ -78,7 +118,11 @@ public class SelectorPattern : GLib.Object { 		return pattern; 	} 	-	public bool match (XmlElement tag, string? id, string? css_class) {+	public bool match (XmlElement tag, string? id, string? css_class, string? pseudo_class) {+		if (tag.get_name () == "") {+			return false;+		}+		 		for (int i = tags.size - 1; i >= 0; i--) { 			SelectorTag pattern = tags.get (i); 						@@ -104,7 +148,7 @@ public class SelectorPattern : GLib.Object { 				} 			}  			-			if (!pattern.match (tag, id, css_class)) {+			if (!pattern.match (tag, id, css_class, pseudo_class)) { 				return false; 			} 		}diff --git a/libsvgbird/SelectorTag.vala b/libsvgbird/SelectorTag.valaindex 7c1de2b..9cc6dac 100644--- a/libsvgbird/SelectorTag.vala+++ b/libsvgbird/SelectorTag.vala@@ -22,6 +22,7 @@ public class SelectorTag : GLib.Object { 	public string name; 	public string? id = null; 	public string? css_class = null;+	public string? pseudo_class = null; 	Gee.ArrayList<AttributePattern>? attribute_patterns = null;  	public SelectorTag.empty () {@@ -29,39 +30,38 @@ public class SelectorTag : GLib.Object { 	 	public SelectorTag (string pattern) { 		string tag_pattern = pattern.strip ();-		int id_separator = tag_pattern.index_of ("#");-		int class_separator = tag_pattern.index_of ("."); 		int attribute_separator = tag_pattern.index_of ("[");  		if (attribute_separator != -1) { 			parse_attributes (tag_pattern.substring (attribute_separator));+			tag_pattern = tag_pattern.substring (0, attribute_separator - "[".length); 		}-				-		if (id_separator != -1) {-			name = tag_pattern.substring (0, id_separator);-			-			id_separator += "#".length;-			if (attribute_separator == -1) {-				id = tag_pattern.substring (id_separator);-			} else {-				id = tag_pattern.substring (id_separator, attribute_separator - id_separator);-			}-		} else if (class_separator != -1) {-			name = tag_pattern.substring (0, class_separator);-			-			class_separator += ".".length;-			if (attribute_separator == -1) {-				css_class = tag_pattern.substring (class_separator);-			} else {-				css_class = tag_pattern.substring (class_separator, attribute_separator - class_separator);-			}-		} else {-			if (attribute_separator == -1) {-				name = tag_pattern;-			} else {-				css_class = tag_pattern.substring (0, attribute_separator);-			}++		tag_pattern = create_part (tag_pattern, ":", out pseudo_class);+		tag_pattern = create_part (tag_pattern, ".", out css_class);+		tag_pattern = create_part (tag_pattern, "#", out id);+		name = tag_pattern;+	}+	+	string create_part (string tag_pattern, string separator, out string? part) {+		int separator_index = tag_pattern.index_of (separator);+		int separator_length = separator.length;+	+		part = null;+		+		if (separator_index == -1) {+			return tag_pattern;+		}+		+		if (separator_index > -1 && separator_index + separator_length < tag_pattern.length) {+			part = tag_pattern.substring (separator_index + separator_length); 		}+		+		if (separator_index > separator_length) {+			return tag_pattern.substring (0, separator_index);+		} +		+		return ""; 	} 	 	public SelectorTag copy () {@@ -70,6 +70,7 @@ public class SelectorTag : GLib.Object { 		tag.name = name; 		tag.id = id; 		tag.css_class = css_class;+		tag.pseudo_class = pseudo_class; 		 		if (attribute_patterns != null) {  			foreach (AttributePattern p in (!) attribute_patterns) {@@ -133,7 +134,7 @@ public class SelectorTag : GLib.Object { 		return pattern; 	} -	public bool match (XmlElement tag, string? id, string? css_class) {+	public bool match (XmlElement tag, string? id, string? css_class, string? pseudo_class) { 		string tag_name = tag.get_name (); 		 		if (this.name != "*" && this.name != "" && tag_name != "") {@@ -162,6 +163,16 @@ public class SelectorTag : GLib.Object { 			} 		} 		+		if (this.pseudo_class != null) {+			if (pseudo_class == null) {+				return false;+			} +			+			if (((!) this.pseudo_class) != ((!) pseudo_class)) {+				return false;+			}+		}+		 		if (attribute_patterns != null) { 			foreach (AttributePattern pattern in (!) attribute_patterns) { 				if (!pattern.match (tag.get_attributes ())) {@@ -186,6 +197,11 @@ public class SelectorTag : GLib.Object { 			s.append ("."); 			s.append ((!) css_class); 		}++		if (pseudo_class != null) {+			s.append (":");+			s.append ((!) pseudo_class);+		} 		 		if (attribute_patterns != null) { 			foreach (AttributePattern a in (!) attribute_patterns) {diff --git a/libsvgbird/StyleSheet.vala b/libsvgbird/StyleSheet.valaindex 12dd14d..fdac481 100644--- a/libsvgbird/StyleSheet.vala+++ b/libsvgbird/StyleSheet.vala@@ -47,7 +47,7 @@ public class StyleSheet : GLib.Object { 		return style_sheet; 	} 	-	public void apply_style (XmlElement tag, SvgStyle style) {+	public void apply_style (XmlElement tag, SvgStyle style, string? pseudo_class) { 		string? id = null; 		string? css_class = null; 		@@ -62,20 +62,32 @@ public class StyleSheet : GLib.Object { 		}  		foreach (Selector selector in styles) {-			if (selector.match_tag (tag, id, css_class)) {+			if (selector.match_tag (tag, id, css_class, pseudo_class)) { 				style.apply (selector.style); 			} 		}+		+		if (css_class != null) {+			foreach (Selector selector in styles) {+				if (selector.match_class (tag, id, css_class, pseudo_class)) {+					style.apply (selector.style);+				}+			}+		} -		foreach (Selector selector in styles) {-			if (selector.match_class (tag, id, css_class)) {-				style.apply (selector.style);+		if (id != null) {+			foreach (Selector selector in styles) {+				if (selector.match_id (tag, id, css_class, pseudo_class)) {+					style.apply (selector.style);+				} 			} 		}-		-		foreach (Selector selector in styles) {-			if (selector.match_id (tag, id, css_class)) {-				style.apply (selector.style);++		if (pseudo_class != null) {+			foreach (Selector selector in styles) {+				if (selector.match_pseudo_class (tag, id, css_class, pseudo_class)) {+					style.apply (selector.style);+				} 			} 		} 		diff --git a/libsvgbird/SvgFile.vala b/libsvgbird/SvgFile.valaindex cf9db0a..b246b73 100644--- a/libsvgbird/SvgFile.vala+++ b/libsvgbird/SvgFile.vala@@ -34,7 +34,7 @@ public class SvgFile : GLib.Object { 		drawing = new SvgDrawing ();  		SvgStyle style = new SvgStyle ();-		SvgStyle.parse (drawing.defs, style, svg_tag);+		SvgStyle.parse (drawing.defs, style, svg_tag, null);  		foreach (Attribute attr in svg_tag.get_attributes ()) {	 			if (attr.get_name () == "width") {@@ -315,7 +315,7 @@ public class SvgFile : GLib.Object {  	void parse_stop (Gradient gradient, XmlElement tag) { 		SvgStyle parent_style = new SvgStyle (); // not inherited-		SvgStyle style = SvgStyle.parse (drawing.defs, parent_style, tag);+		SvgStyle style = SvgStyle.parse (drawing.defs, parent_style, tag, null); 		Stop stop = new Stop (); 		 		gradient.stops.add (stop);@@ -428,7 +428,7 @@ public class SvgFile : GLib.Object { 		 		object.clip_path = get_clip_path (attributes); 		object.transforms = get_transform (attributes);-		object.style = SvgStyle.parse (drawing.defs, parent_style, tag);+		object.style = SvgStyle.parse (drawing.defs, parent_style, tag, null); 		object.visible = is_visible (tag); // FIXME: add style fill none 	} 		diff --git a/libsvgbird/SvgStyle.vala b/libsvgbird/SvgStyle.valaindex 85b8754..fef2d0d 100644--- a/libsvgbird/SvgStyle.vala+++ b/libsvgbird/SvgStyle.vala@@ -236,7 +236,7 @@ public class SvgStyle : GLib.Object { 		} 	} 	-	public static SvgStyle parse (Defs? d, SvgStyle inherited, XmlElement tag) {+	public static SvgStyle parse (Defs? d, SvgStyle inherited, XmlElement tag, string? psedo_class) { 		SvgStyle s = new SvgStyle (); 		Attributes attributes = tag.get_attributes (); @@ -245,7 +245,7 @@ public class SvgStyle : GLib.Object { 		 		if (d != null) { 			StyleSheet style_sheet = ((!) d).style_sheet;-			style_sheet.apply_style (tag, s);+			style_sheet.apply_style (tag, s, psedo_class); 		}  		foreach (Attribute a in attributes) {

Contact

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