The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

StyleSheet.vala in libsvgbird

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git

Revisions

View the latest version of libsvgbird/StyleSheet.vala.
Bounding box for SVG rectangles
1 /* 2 Copyright (C) 2016 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 15 using B; 16 using Math; 17 18 namespace SvgBird { 19 20 21 public class StyleSheet : GLib.Object { 22 23 public Gee.ArrayList<Selector> styles = new Gee.ArrayList<Selector> (); 24 25 public StyleSheet () { 26 } 27 28 /** Copy references to all selectors in this style sheet. */ 29 public StyleSheet shallow_copy () { 30 StyleSheet style_sheet = new StyleSheet (); 31 32 foreach (Selector selector in styles) { 33 style_sheet.styles.add (selector); 34 } 35 36 return style_sheet; 37 } 38 39 public StyleSheet copy () { 40 StyleSheet style_sheet = new StyleSheet (); 41 42 foreach (Selector selector in styles) { 43 style_sheet.styles.add (selector.copy ()); 44 } 45 46 return style_sheet; 47 } 48 49 public void apply_style (XmlElement tag, SvgStyle style) { 50 string? id = null; 51 string? css_class = null; 52 53 foreach (Attribute attribute in tag.get_attributes ()) { 54 string name = attribute.get_name (); 55 56 if (name == "id") { 57 id = attribute.get_content (); 58 } else if (name == "class") { 59 css_class = attribute.get_content (); 60 } 61 } 62 63 foreach (Selector selector in styles) { 64 if (selector.match (tag, id, css_class)) { 65 style.apply (selector.style); 66 } 67 } 68 } 69 70 public void merge (StyleSheet style_sheet) { 71 foreach (Selector selector in style_sheet.styles) { 72 styles.add (selector.copy ()); 73 } 74 } 75 76 public static StyleSheet parse (Defs defs, XmlElement style_tag) { 77 StyleSheet style_sheet = new StyleSheet (); 78 string css = style_tag.get_content (); 79 css = get_cdata (css); 80 css = add_separators (css); 81 css = replace_whitespace (css); 82 83 int index = 0; 84 int start_bracket_length = "{".length; 85 int end_bracket_length = "}".length; 86 int css_length = css.length; 87 88 while (index < css_length) { 89 int style_rules_start = css.index_of ("{", index); 90 int style_rules_end = css.index_of ("}", style_rules_start); 91 92 if (style_rules_start == -1 || style_rules_end == -1) { 93 break; 94 } 95 96 int selector_end = style_rules_start - start_bracket_length; 97 string selectors = css.substring (index, selector_end - index); 98 99 int style_start = style_rules_start + start_bracket_length; 100 int style_end = style_rules_end; 101 string style_rules = css.substring (style_start, style_end - style_start); 102 103 index = style_rules_end + end_bracket_length; 104 SvgStyle style = new SvgStyle.for_properties (defs, style_rules); 105 106 Selector selector = new Selector (selectors, style); 107 style_sheet.styles.add (selector); 108 } 109 110 return style_sheet; 111 } 112 113 public static string get_cdata (string tag_content) { 114 StringBuilder data = new StringBuilder (); 115 116 int index = 0; 117 int cdata_tag_length = "<![CDATA[".length; 118 int cdata_end_tag_length = "]]>".length; 119 int content_length = tag_content.length; 120 121 while (index < content_length) { 122 int cdata_start = tag_content.index_of ("<![CDATA[", index); 123 int cdata_end = tag_content.index_of ("]]>", cdata_start); 124 125 if (cdata_start == -1 || cdata_end == -1) { 126 break; 127 } 128 129 cdata_start += cdata_tag_length; 130 data.append (tag_content.substring (cdata_start, cdata_end - cdata_start)); 131 index = cdata_end + cdata_end_tag_length; 132 } 133 134 if (index < tag_content.length) { 135 data.append (tag_content.substring (index)); 136 } 137 138 return data.str; 139 } 140 141 public static string add_separators (string data) { 142 string style_data = data.replace (">", " > "); 143 style_data = data.replace ("+", " + "); 144 return style_data; 145 } 146 147 public static string replace_whitespace (string data) { 148 string style_data = data.replace ("\n", " "); 149 style_data = style_data.replace ("\r", " "); 150 style_data = style_data.replace ("\t", " "); 151 152 while (style_data.index_of (" ") != -1) { 153 style_data = style_data.replace (" ", " "); 154 } 155 156 return style_data; 157 } 158 } 159 160 } 161