]> gitweb.michael.orlitzky.com - libsvgtiny.git/blob - src/svgtiny_css.c
src/svgtiny_css.c: implement node_id() select handler
[libsvgtiny.git] / src / svgtiny_css.c
1 #include <libcss/libcss.h>
2
3 #include "svgtiny.h"
4 #include "svgtiny_internal.h"
5
6 static css_error node_name(void *pw, void *node, css_qname *qname);
7 static css_error node_classes(void *pw, void *node,
8 lwc_string ***classes, uint32_t *n_classes);
9 static css_error node_id(void *pw, void *node, lwc_string **id);
10
11
12 /**
13 * Resolve a relative URL to an absolute one by doing nothing. This is
14 * the simplest possible implementation of a URL resolver, needed for
15 * parsing CSS.
16 */
17 css_error svgtiny_resolve_url(void *pw,
18 const char *base, lwc_string *rel, lwc_string **abs)
19 {
20 UNUSED(pw);
21 UNUSED(base);
22
23 /* Copy the relative URL to the absolute one (the return
24 value) */
25 *abs = lwc_string_ref(rel);
26 return CSS_OK;
27 }
28
29 /**
30 * Create a stylesheet with the default set of params.
31 *
32 * \param sheet A stylesheet pointer, passed in by reference, that
33 * we use to store the newly-created stylesheet.
34 * \param inline_style True if this stylesheet represents an inline
35 * style, and false otherwise.
36 *
37 * \return The return value from css_stylesheet_create() is returned.
38 */
39 css_error svgtiny_create_stylesheet(css_stylesheet **sheet,
40 bool inline_style)
41 {
42 css_stylesheet_params params;
43
44 params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
45 params.level = CSS_LEVEL_DEFAULT;
46 params.charset = NULL;
47 params.url = "";
48 params.title = NULL;
49 params.allow_quirks = false;
50 params.inline_style = inline_style;
51 params.resolve = svgtiny_resolve_url;
52 params.resolve_pw = NULL;
53 params.import = NULL;
54 params.import_pw = NULL;
55 params.color = NULL;
56 params.color_pw = NULL;
57 params.font = NULL;
58 params.font_pw = NULL;
59
60 return css_stylesheet_create(&params, sheet);
61 }
62
63
64 /**************************/
65 /* libcss select handlers */
66 /**************************/
67 /*
68 * From here on we implement the "select handler "API defined in
69 * libcss's include/libcss/select.h and discussed briefly in its
70 * docs/API document.
71 */
72
73
74 /**
75 * Retrieve the given node's name
76 *
77 * \param pw Pointer to the current SVG parser state
78 * \param node Libdom SVG node
79 * \param qname Address at which to store the node name
80 *
81 * \return CSS_OK on success, or CSS_NOMEM if anything goes wrong
82 */
83 css_error node_name(void *pw, void *node, css_qname *qname)
84 {
85 dom_string *name;
86 dom_exception err;
87 struct svgtiny_parse_state *state;
88
89 err = dom_node_get_node_name((dom_node *)node, &name);
90 if (err != DOM_NO_ERR) {
91 return CSS_NOMEM;
92 }
93
94 state = (struct svgtiny_parse_state *)pw;
95 qname->ns = lwc_string_ref(state->interned_svg_xmlns);
96
97 err = dom_string_intern(name, &qname->name);
98 if (err != DOM_NO_ERR) {
99 dom_string_unref(name);
100 return CSS_NOMEM;
101 }
102
103 dom_string_unref(name);
104
105 return CSS_OK;
106 }
107
108
109 /**
110 * Retrieve the given node's classes
111 *
112 * \param pw Pointer to the current SVG parser state
113 * \param node Libdom SVG node
114 * \param classes Address at which to store the class name array
115 * \param n_classes Address at which to store the length of the class
116 * name array
117 *
118 * \return CSS_OK on success, or CSS_NOMEM if anything goes wrong
119 *
120 * \note CSS_NOMEM is not possible in practice as of libdom-0.4.1,
121 * because the underlying libdom function never fails
122 */
123 css_error node_classes(void *pw, void *node,
124 lwc_string ***classes, uint32_t *n_classes)
125 {
126 UNUSED(pw);
127 dom_exception err;
128
129 err = dom_element_get_classes((dom_node *)node, classes, n_classes);
130
131 /* The implementation does not do it, but the documentation
132 for dom_element_get_classes() says that a DOM_NO_MEM_ERR is
133 possible here, so we handle it to be on the safe side. */
134 if (err != DOM_NO_ERR) {
135 return CSS_NOMEM;
136 }
137
138 return CSS_OK;
139 }
140
141
142 /**
143 * Retrieve the given node's id
144 *
145 * \param pw Pointer to the current SVG parser state
146 * \param node Libdom SVG node
147 * \param id Address at which to store the id
148 *
149 * \return CSS_OK on success, or CSS_NOMEM if anything goes wrong
150 */
151 css_error node_id(void *pw, void *node, lwc_string **id)
152 {
153 dom_string *attr;
154 dom_exception err;
155 struct svgtiny_parse_state *state;
156
157 /* Begin with the assumption that this node has no id */
158 *id = NULL;
159
160 state = (struct svgtiny_parse_state *)pw;
161 err = dom_element_get_attribute((dom_node *)node,
162 state->interned_id, &attr);
163 if (err != DOM_NO_ERR) {
164 return CSS_NOMEM;
165 }
166 else if (attr == NULL) {
167 /* The node has no id attribute and our return value
168 is already set to NULL so we're done */
169 return CSS_OK;
170 }
171
172 /* If we found an id attribute (a dom_string), intern it into
173 an lwc_string that we can return, and then cleanup the
174 dom_string. */
175 err = dom_string_intern(attr, id);
176 if (err != DOM_NO_ERR) {
177 dom_string_unref(attr);
178 return CSS_NOMEM;
179 }
180 dom_string_unref(attr);
181 return CSS_OK;
182 }