| 39dd0cf by Thomas Thurman at 2009-07-28 |
1 |
#include <string.h> |
| d71b5ce by Thomas Thurman at 2009-07-12 |
2 |
#include <stdlib.h> |
|
3 |
#include <cairo.h> |
|
4 |
#include <ccss-cairo/ccss-cairo.h> |
|
5 |
#include <gtk/gtk.h> |
|
6 |
|
| e33cc03 by Thomas Thurman at 2009-07-13 |
7 |
/* ================================================================ */ |
|
8 |
/* Our little hierarchy */ |
|
9 |
typedef enum _CopperClasses { |
| ccf35e1 by Thomas Thurman at 2009-07-23 |
10 |
CC_FRAME, |
|
11 |
CC_CONTENT, CC_TITLEBAR, |
|
12 |
CC_MENU, CC_TITLE, CC_MINIMIZE, CC_MAXIMIZE, CC_CLOSE, |
| 39dd0cf by Thomas Thurman at 2009-07-28 |
13 |
CC_FILLER, |
| e33cc03 by Thomas Thurman at 2009-07-13 |
14 |
CC_LAST |
|
15 |
} CopperClasses; |
|
16 |
|
|
17 |
char *names[] = |
|
18 |
{ |
| ccf35e1 by Thomas Thurman at 2009-07-23 |
19 |
"frame", |
| 2a0a456 by Thomas Thurman at 2009-07-23 |
20 |
"area", "area", |
|
21 |
"button", "title", "button", "button", "button", |
| 39dd0cf by Thomas Thurman at 2009-07-28 |
22 |
"area", |
| e33cc03 by Thomas Thurman at 2009-07-13 |
23 |
"last" |
|
24 |
}; |
|
25 |
|
|
26 |
CopperClasses parents[] = |
|
27 |
{ |
|
28 |
CC_LAST, |
| ccf35e1 by Thomas Thurman at 2009-07-23 |
29 |
CC_FRAME, CC_FRAME, |
|
30 |
CC_TITLEBAR, CC_TITLEBAR, CC_TITLEBAR, CC_TITLEBAR, CC_TITLEBAR, |
| 39dd0cf by Thomas Thurman at 2009-07-28 |
31 |
CC_TITLEBAR, |
| e33cc03 by Thomas Thurman at 2009-07-13 |
32 |
CC_LAST |
|
33 |
}; |
|
34 |
|
| 377ad01 by Thomas Thurman at 2009-07-23 |
35 |
char *copper_classnames[] = |
|
36 |
{ |
|
37 |
NULL, |
|
38 |
"content", "titlebar", |
| 46ca9d2 by Thomas Thurman at 2009-07-23 |
39 |
"menu", NULL, "minimize", "maximize", "close", |
| 39dd0cf by Thomas Thurman at 2009-07-28 |
40 |
"filler", |
| 377ad01 by Thomas Thurman at 2009-07-23 |
41 |
NULL |
|
42 |
}; |
|
43 |
|
| da232ca by Thomas Thurman at 2009-07-13 |
44 |
typedef struct |
|
45 |
{ |
|
46 |
ccss_node_t basic; |
|
47 |
CopperClasses copper_class; |
|
48 |
} CopperNode; |
|
49 |
|
|
50 |
CopperNode copper_nodes[CC_LAST]; |
| 1cc33d7 by Thomas Thurman at 2009-07-13 |
51 |
|
| 7a06d4b by Thomas Thurman at 2009-07-13 |
52 |
static char const* |
|
53 |
get_type (ccss_node_t const *self) |
| 67ffe71 by Thomas Thurman at 2009-07-13 |
54 |
{ |
| da232ca by Thomas Thurman at 2009-07-13 |
55 |
g_warning ("It's %s", self->type_name); |
|
56 |
return self->type_name; |
| 7a06d4b by Thomas Thurman at 2009-07-13 |
57 |
} |
|
58 |
|
|
59 |
static ptrdiff_t |
|
60 |
get_instance (ccss_node_t const *self) |
|
61 |
{ |
| da232ca by Thomas Thurman at 2009-07-13 |
62 |
return self->instance; |
| 7a06d4b by Thomas Thurman at 2009-07-13 |
63 |
} |
|
64 |
|
|
65 |
static char const* |
|
66 |
get_style (ccss_node_t const *self) { |
| da232ca by Thomas Thurman at 2009-07-13 |
67 |
return self->inline_style; |
| 7a06d4b by Thomas Thurman at 2009-07-13 |
68 |
} |
|
69 |
|
|
70 |
static ccss_node_t* |
|
71 |
get_container (ccss_node_t const *self) |
|
72 |
{ |
| e7e5579 by Thomas Thurman at 2009-07-13 |
73 |
CopperClasses candidate = parents[((CopperNode*)self)->copper_class]; |
|
74 |
|
|
75 |
if (candidate==CC_LAST) |
|
76 |
return NULL; |
|
77 |
else |
|
78 |
/* or should we allocate a new one? */ |
|
79 |
return (ccss_node_t*) &(copper_nodes[candidate]); |
| 1cc33d7 by Thomas Thurman at 2009-07-13 |
80 |
} |
| 67ffe71 by Thomas Thurman at 2009-07-13 |
81 |
|
| 377ad01 by Thomas Thurman at 2009-07-23 |
82 |
static const char* |
|
83 |
get_class (ccss_node_t const *self) |
|
84 |
{ |
|
85 |
return copper_classnames[((CopperNode*)self)->copper_class]; |
|
86 |
} |
|
87 |
|
| 1cc33d7 by Thomas Thurman at 2009-07-13 |
88 |
static ccss_node_class_t copper_node_class = { |
| 7a06d4b by Thomas Thurman at 2009-07-13 |
89 |
.get_type = (ccss_node_get_type_f) get_type, |
|
90 |
.get_instance = (ccss_node_get_instance_f) get_instance, |
| 1cc33d7 by Thomas Thurman at 2009-07-13 |
91 |
.get_style = (ccss_node_get_style_f) get_style, |
| 377ad01 by Thomas Thurman at 2009-07-23 |
92 |
.get_container = (ccss_node_get_container_f) get_container, |
|
93 |
.get_class = (ccss_node_get_class_f) get_class |
| 1cc33d7 by Thomas Thurman at 2009-07-13 |
94 |
}; |
| a4a4468 by Thomas Thurman at 2009-07-13 |
95 |
|
| e33cc03 by Thomas Thurman at 2009-07-13 |
96 |
static void |
|
97 |
initialise_classes (void) |
|
98 |
{ |
| a4a4468 by Thomas Thurman at 2009-07-13 |
99 |
int i; |
| 67ffe71 by Thomas Thurman at 2009-07-13 |
100 |
|
| a4a4468 by Thomas Thurman at 2009-07-13 |
101 |
for (i=0; i<CC_LAST; i++) |
|
102 |
{ |
| da232ca by Thomas Thurman at 2009-07-13 |
103 |
ccss_node_init ((ccss_node_t*) &copper_nodes[i], &copper_node_class); |
|
104 |
copper_nodes[i].basic.type_name = names[i]; |
|
105 |
copper_nodes[i].basic.instance = 0; |
|
106 |
copper_nodes[i].basic.inline_style = NULL; |
|
107 |
copper_nodes[i].copper_class = i; |
| a4a4468 by Thomas Thurman at 2009-07-13 |
108 |
} |
| e33cc03 by Thomas Thurman at 2009-07-13 |
109 |
} |
|
110 |
|
|
111 |
/* ================================================================ */ |
| 4b90664 by Thomas Thurman at 2009-07-12 |
112 |
|
| 46ca9d2 by Thomas Thurman at 2009-07-23 |
113 |
static gboolean |
| 4b90664 by Thomas Thurman at 2009-07-12 |
114 |
get_number_from_style (ccss_style_t *style, |
|
115 |
char *element, |
| 46ca9d2 by Thomas Thurman at 2009-07-23 |
116 |
int *dummy, |
| 560d85e by Thomas Thurman at 2009-07-12 |
117 |
int *original_value) |
| 4b90664 by Thomas Thurman at 2009-07-12 |
118 |
{ |
| 4e9beba by Thomas Thurman at 2009-07-13 |
119 |
double d = 0.0; |
| 46ca9d2 by Thomas Thurman at 2009-07-23 |
120 |
gboolean result; |
| 4b90664 by Thomas Thurman at 2009-07-12 |
121 |
|
| 46ca9d2 by Thomas Thurman at 2009-07-23 |
122 |
result = ccss_style_get_double (style, element, &d); |
| 4b90664 by Thomas Thurman at 2009-07-12 |
123 |
|
| 46ca9d2 by Thomas Thurman at 2009-07-23 |
124 |
if (original_value) |
|
125 |
*original_value = d; |
| 3b69cfe by Thomas Thurman at 2009-07-12 |
126 |
|
| 46ca9d2 by Thomas Thurman at 2009-07-23 |
127 |
return result; |
| 4b90664 by Thomas Thurman at 2009-07-12 |
128 |
} |
|
129 |
|
| 7d15ba1 by Thomas Thurman at 2009-07-25 |
130 |
static void |
|
131 |
reduce_by_padding_borders_and_margins (ccss_stylesheet_t *stylesheet, |
|
132 |
CopperClasses style_id, |
|
133 |
int *x, int *y, int *w, int *h, |
|
134 |
gboolean honour_margins, |
|
135 |
gboolean reverse) |
|
136 |
{ |
|
137 |
ccss_style_t *style = ccss_stylesheet_query (stylesheet, |
|
138 |
(ccss_node_t*) &copper_nodes[style_id]); |
|
139 |
int bt=0, br=0, bb=0, bl=0, pt=0, pr=0, pb=0, pl=0; |
|
140 |
|
|
141 |
if (!style) return; |
|
142 |
|
|
143 |
/* FIXME this is silly; libccss should do this for us */ |
|
144 |
/* FIXME maybe it does if we get the property rather than the number */ |
|
145 |
if (get_number_from_style (style, "border-width", NULL, &bl)) |
|
146 |
{ |
|
147 |
bt = br = bb = bl; |
|
148 |
} |
|
149 |
else |
|
150 |
{ |
|
151 |
get_number_from_style (style, "border-top-width", NULL, &bt); |
|
152 |
get_number_from_style (style, "border-right-width", NULL, &br); |
|
153 |
get_number_from_style (style, "border-bottom-width", NULL, &bb); |
|
154 |
get_number_from_style (style, "border-left-width", NULL, &bl); |
|
155 |
} |
|
156 |
|
|
157 |
if (get_number_from_style (style, "padding", NULL, &pl)) |
|
158 |
{ |
|
159 |
pt = pr = pb = pl; |
|
160 |
} |
|
161 |
else |
|
162 |
{ |
|
163 |
get_number_from_style (style, "padding-top", NULL, &pt); |
|
164 |
get_number_from_style (style, "padding-right", NULL, &pr); |
|
165 |
get_number_from_style (style, "padding-bottom", NULL, &pb); |
|
166 |
get_number_from_style (style, "padding-left", NULL, &pl); |
|
167 |
} |
|
168 |
|
|
169 |
/* FIXME honour honour_margins */ |
|
170 |
|
|
171 |
bt += pt; |
|
172 |
br += pr; |
|
173 |
bb += pb; |
|
174 |
bl += pl; |
|
175 |
|
|
176 |
if (reverse) |
|
177 |
{ |
|
178 |
if (x) *x -= bl; |
|
179 |
if (y) *y -= bt; |
|
180 |
if (w) *w += (bl+br); |
|
181 |
if (h) *h += (bt+bb); |
|
182 |
} |
|
183 |
else |
|
184 |
{ |
|
185 |
if (x) *x += bl; |
|
186 |
if (y) *y += bt; |
|
187 |
if (w) *w -= (bl+br); |
|
188 |
if (h) *h -= (bt+bb); |
|
189 |
} |
|
190 |
|
|
191 |
ccss_style_destroy (style); |
|
192 |
} |
|
193 |
|
| e1bd3aa by Thomas Thurman at 2009-07-24 |
194 |
static gint |
| d71b5ce by Thomas Thurman at 2009-07-12 |
195 |
draw_rectangle (ccss_stylesheet_t *stylesheet, |
|
196 |
cairo_t *cr, |
| c02398e by Thomas Thurman at 2009-07-13 |
197 |
CopperClasses style_id, |
| 7d1907a by Thomas Thurman at 2009-07-12 |
198 |
int x, int y, int w, int h, |
| ecd7c71 by Thomas Thurman at 2009-07-24 |
199 |
gboolean honour_margins, |
| 4c5428f by Thomas Thurman at 2009-07-25 |
200 |
gboolean from_the_right, |
|
201 |
PangoLayout *layout) |
| d71b5ce by Thomas Thurman at 2009-07-12 |
202 |
{ |
| c02398e by Thomas Thurman at 2009-07-13 |
203 |
ccss_style_t *style = ccss_stylesheet_query (stylesheet, |
|
204 |
(ccss_node_t*) &copper_nodes[style_id]); |
| ecd7c71 by Thomas Thurman at 2009-07-24 |
205 |
int full_width; |
| 7fbd556 by Thomas Thurman at 2009-07-25 |
206 |
int horizontal_margin = 0; |
| c600456 by Thomas Thurman at 2009-07-23 |
207 |
|
| e1bd3aa by Thomas Thurman at 2009-07-24 |
208 |
if (!style) return 0; |
| 3b69cfe by Thomas Thurman at 2009-07-12 |
209 |
|
| 7fbd556 by Thomas Thurman at 2009-07-25 |
210 |
if (honour_margins) |
|
211 |
{ |
| 58bf938 by Thomas Thurman at 2009-07-28 |
212 |
int mn, mt, mr, mb, ml; |
| 7fbd556 by Thomas Thurman at 2009-07-25 |
213 |
/* FIXME: Setting just "margin" doesn't work |
|
214 |
* because libccss doesn't know about margins. |
|
215 |
*/ |
| 58bf938 by Thomas Thurman at 2009-07-28 |
216 |
get_number_from_style (style, "margin", NULL, &mn); |
|
217 |
if (mn) |
|
218 |
{ |
|
219 |
/* FIXME this is broken; "margin" may have multiple values */ |
|
220 |
mt = mr = mb = ml = mn; |
|
221 |
} |
|
222 |
else |
|
223 |
{ |
|
224 |
get_number_from_style (style, "margin-top", NULL, &mt); |
|
225 |
get_number_from_style (style, "margin-right", NULL, &mr); |
|
226 |
get_number_from_style (style, "margin-bottom", NULL, &mb); |
|
227 |
get_number_from_style (style, "margin-left", NULL, &ml); |
|
228 |
} |
| 7fbd556 by Thomas Thurman at 2009-07-25 |
229 |
|
| 58bf938 by Thomas Thurman at 2009-07-28 |
230 |
x += ml; |
| 7fbd556 by Thomas Thurman at 2009-07-25 |
231 |
y += mt; |
|
232 |
horizontal_margin = ml+mr; |
|
233 |
h -= (mt+mb); |
|
234 |
} |
|
235 |
|
| ecd7c71 by Thomas Thurman at 2009-07-24 |
236 |
if (w==0) |
|
237 |
{ |
|
238 |
int height, width; |
|
239 |
|
|
240 |
get_number_from_style (style, "height", NULL, &height); |
|
241 |
get_number_from_style (style, "width", NULL, &width); |
|
242 |
|
|
243 |
if (height!=0 && width!=0) |
|
244 |
{ |
|
245 |
int min_w, max_w; |
|
246 |
double scale = ((double)h/(double)height); |
|
247 |
|
|
248 |
w = (int) ((double)width) * scale; |
|
249 |
|
|
250 |
get_number_from_style (style, "min-width", NULL, &min_w); |
|
251 |
get_number_from_style (style, "max-width", NULL, &max_w); |
|
252 |
|
|
253 |
if (max_w && w>max_w && max_w>min_w) w = max_w; |
|
254 |
if (w<min_w) w = min_w; |
|
255 |
} |
|
256 |
} |
|
257 |
|
| 7fbd556 by Thomas Thurman at 2009-07-25 |
258 |
full_width = w+ horizontal_margin; |
| 4e9beba by Thomas Thurman at 2009-07-13 |
259 |
|
| 58b60a3 by Thomas Thurman at 2009-07-25 |
260 |
if (from_the_right) |
|
261 |
x -= full_width; |
|
262 |
|
| d71b5ce by Thomas Thurman at 2009-07-12 |
263 |
ccss_cairo_style_draw_rectangle (style, cr, x, y, w, h); |
|
264 |
|
| 4c5428f by Thomas Thurman at 2009-07-25 |
265 |
if (layout) |
|
266 |
{ |
| cd86241 by Thomas Thurman at 2009-07-25 |
267 |
reduce_by_padding_borders_and_margins (stylesheet, CC_TITLE, |
|
268 |
&x, &y, &w, &h, |
|
269 |
TRUE, FALSE); |
| 4c5428f by Thomas Thurman at 2009-07-25 |
270 |
/* |
|
271 |
* we should maybe undo the translate later, but |
|
272 |
* we're always the last one to use this context anyway |
|
273 |
*/ |
|
274 |
cairo_translate (cr, x, y); |
|
275 |
|
|
276 |
pango_cairo_show_layout (cr, layout); |
|
277 |
} |
|
278 |
|
| d71b5ce by Thomas Thurman at 2009-07-12 |
279 |
ccss_style_destroy (style); |
| e1bd3aa by Thomas Thurman at 2009-07-24 |
280 |
|
| ecd7c71 by Thomas Thurman at 2009-07-24 |
281 |
return full_width; |
| d71b5ce by Thomas Thurman at 2009-07-12 |
282 |
} |
|
283 |
|
| ee4f678 by Thomas Thurman at 2009-07-25 |
284 |
static char* |
|
285 |
handle_data_url(char *data) |
|
286 |
{ |
|
287 |
const char* base64 = "base64"; |
|
288 |
char *cursor = data; |
|
289 |
const char *base64_cursor = base64; |
|
290 |
gchar *result; |
| 39dd0cf by Thomas Thurman at 2009-07-28 |
291 |
gsize result_length; |
| ee4f678 by Thomas Thurman at 2009-07-25 |
292 |
gchar *md5, *filename, *uri; |
|
293 |
|
|
294 |
md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, cursor, -1); |
|
295 |
|
|
296 |
/* FIXME: here we should check whether it already exists in /tmp |
|
297 |
* and return that if so |
|
298 |
*/ |
|
299 |
|
|
300 |
while (*cursor && *cursor!=',') |
|
301 |
{ |
|
302 |
if (*base64_cursor) |
|
303 |
{ |
|
304 |
if (*cursor==*base64_cursor) |
|
305 |
base64_cursor++; |
|
306 |
else |
|
307 |
base64_cursor = base64; |
|
308 |
} |
|
309 |
cursor++; |
|
310 |
} |
|
311 |
|
|
312 |
if (*base64_cursor) |
|
313 |
{ |
|
314 |
/* we didn't see "base64" */ |
|
315 |
g_warning ("data: URLs must be base64 encoded in this system!"); |
|
316 |
g_free (md5); |
|
317 |
return NULL; |
|
318 |
} |
|
319 |
|
|
320 |
result = g_base64_decode (cursor+1, &result_length); |
|
321 |
|
|
322 |
/* unfortunately we can't just return the data; libccss requires it |
|
323 |
* to be in a file. |
|
324 |
*/ |
|
325 |
filename = g_build_filename ("/tmp", md5, NULL); |
|
326 |
g_file_set_contents (filename, result, result_length, NULL); |
|
327 |
|
|
328 |
uri = g_strdup_printf ("file://%s", filename); |
|
329 |
g_free (filename); |
|
330 |
g_free (result); |
|
331 |
g_free (md5); |
|
332 |
|
|
333 |
return uri; |
|
334 |
} |
|
335 |
|
| d71b5ce by Thomas Thurman at 2009-07-12 |
336 |
static char * |
|
337 |
url (GSList const *args, |
|
338 |
void *user_data) |
|
339 |
{ |
| 1cc33d7 by Thomas Thurman at 2009-07-13 |
340 |
char *cwd; |
|
341 |
char *path; |
|
342 |
char *uri; |
|
343 |
char *filename = NULL; |
|
344 |
|
|
345 |
g_return_val_if_fail (args && args->data, NULL); |
|
346 |
filename = (char*) args->data; |
|
347 |
|
| 9d10179 by Thomas Thurman at 2009-07-23 |
348 |
if (strcmp (filename, "wm:icon")==0) |
| 1cc33d7 by Thomas Thurman at 2009-07-13 |
349 |
{ |
|
350 |
/* this is magic */ |
| 39dd0cf by Thomas Thurman at 2009-07-28 |
351 |
return g_strdup ("file:///service/website/themecreator.marnanel.org/htdocs/gtk-edit.png"); |
| 1cc33d7 by Thomas Thurman at 2009-07-13 |
352 |
} |
| 39dd0cf by Thomas Thurman at 2009-07-28 |
353 |
#if 0 |
| ee4f678 by Thomas Thurman at 2009-07-25 |
354 |
else if (strncmp (filename, "data:", 5)==0) |
|
355 |
{ |
|
356 |
return handle_data_url (filename+5); |
|
357 |
} |
| 39dd0cf by Thomas Thurman at 2009-07-28 |
358 |
#endif |
|
359 |
else if (index (filename, '/') == NULL) |
|
360 |
{ |
|
361 |
char *md5, *result; |
|
362 |
md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, filename, -1); |
|
363 |
result = g_strdup_printf ("file:///service/website/themecreator.marnanel.org/htdocs/w/images/%c/%c%c/%s", |
|
364 |
md5[0], md5[0], md5[1], |
|
365 |
filename); |
|
366 |
g_free (md5); |
|
367 |
return result; |
|
368 |
} |
|
369 |
else |
|
370 |
{ |
|
371 |
return g_strdup ("file:///service/website/themecreator.marnanel.org/htdocs/gtk-error.png"); |
|
372 |
} |
| d71b5ce by Thomas Thurman at 2009-07-12 |
373 |
} |
|
374 |
|
| b3922b5 by Thomas Thurman at 2009-07-17 |
375 |
static char * |
|
376 |
named (GSList const *args, void *user_data) |
|
377 |
{ |
|
378 |
char *name = NULL; |
|
379 |
|
|
380 |
if (!name) |
|
381 |
/* fall back to black */ |
|
382 |
return g_strdup("#00000000"); |
|
383 |
|
|
384 |
name = args->data; |
|
385 |
g_warning ("Looking up named colour %s", name); |
|
386 |
|
|
387 |
/* stub: magenta for everything */ |
|
388 |
return g_strdup("#FF00FFFF"); |
|
389 |
} |
|
390 |
|
| d71b5ce by Thomas Thurman at 2009-07-12 |
391 |
static ccss_function_t const _functions[] = |
|
392 |
{ |
|
393 |
{ "url", url, NULL }, |
| b3922b5 by Thomas Thurman at 2009-07-17 |
394 |
{ "named", named, NULL }, |
| d71b5ce by Thomas Thurman at 2009-07-12 |
395 |
{ NULL } |
|
396 |
}; |
|
397 |
|
| c89db0f by Thomas Thurman at 2009-07-25 |
398 |
static PangoLayout* |
|
399 |
title_text (ccss_stylesheet_t *stylesheet, |
|
400 |
cairo_t *cr, |
|
401 |
char *text) |
| d71b5ce by Thomas Thurman at 2009-07-12 |
402 |
{ |
|
403 |
PangoLayout *layout; |
| d99f405 by Thomas Thurman at 2009-07-25 |
404 |
PangoAttrList *attrs = NULL; |
| da232ca by Thomas Thurman at 2009-07-13 |
405 |
ccss_style_t *style = ccss_stylesheet_query (stylesheet, |
|
406 |
(ccss_node_t*) &copper_nodes[CC_TITLE]); |
| c89db0f by Thomas Thurman at 2009-07-25 |
407 |
char *align; |
| d99f405 by Thomas Thurman at 2009-07-25 |
408 |
ccss_color_t const *colour; |
| 9414d5a by Thomas Thurman at 2009-07-19 |
409 |
|
| 5994402 by Thomas Thurman at 2009-07-25 |
410 |
layout = pango_cairo_create_layout (cr); |
|
411 |
|
| d99f405 by Thomas Thurman at 2009-07-25 |
412 |
attrs = pango_attr_list_new (); |
|
413 |
|
| c89db0f by Thomas Thurman at 2009-07-25 |
414 |
/* We have to handle CSS text properties ourselves here because |
|
415 |
* libccss doesn't know how to render them yet. We don't try |
|
416 |
* to do all the funky effects like shadows and so on, |
|
417 |
* unfortunately. |
|
418 |
*/ |
| d99f405 by Thomas Thurman at 2009-07-25 |
419 |
|
|
420 |
if (ccss_style_get_property (style, "color", |
|
421 |
(const ccss_property_base_t**) &colour)) |
|
422 |
{ |
|
423 |
pango_attr_list_insert (attrs, |
|
424 |
pango_attr_foreground_new |
|
425 |
((int)65535.0*colour->red, |
|
426 |
(int)65535.0*colour->green, |
|
427 |
(int)65535.0*colour->blue)); |
|
428 |
} |
| c89db0f by Thomas Thurman at 2009-07-25 |
429 |
|
| 37677a3 by Thomas Thurman at 2009-07-12 |
430 |
/* Alignment */ |
| 1e50d92 by Thomas Thurman at 2009-07-25 |
431 |
|
|
432 |
if (ccss_style_get_string (style, "text-align", &align)) |
| 37677a3 by Thomas Thurman at 2009-07-12 |
433 |
{ |
| 3197c3a by Thomas Thurman at 2009-07-25 |
434 |
if (strcmp (align, "left")==0) |
|
435 |
{ |
|
436 |
pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT); |
|
437 |
} |
|
438 |
else if (strcmp (align, "center")==0) |
| 7a06d4b by Thomas Thurman at 2009-07-13 |
439 |
{ |
|
440 |
pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); |
|
441 |
} |
|
442 |
else if (strcmp (align, "right")==0) |
|
443 |
{ |
|
444 |
pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); |
|
445 |
} |
| 3197c3a by Thomas Thurman at 2009-07-25 |
446 |
else |
|
447 |
/* FIXME: "align" contains garbage if it's undefined; |
|
448 |
* is there an easy way of checking? |
|
449 |
*/ |
|
450 |
g_warning ("Unknown alignment: %s", align); |
| 37677a3 by Thomas Thurman at 2009-07-12 |
451 |
} |
|
452 |
|
| d99f405 by Thomas Thurman at 2009-07-25 |
453 |
pango_layout_set_attributes (layout, attrs); |
|
454 |
|
| c89db0f by Thomas Thurman at 2009-07-25 |
455 |
/* The actual text */ |
|
456 |
pango_layout_set_text (layout, text, -1); |
|
457 |
|
|
458 |
ccss_style_destroy (style); |
|
459 |
|
|
460 |
return layout; |
|
461 |
} |
|
462 |
|
|
463 |
static void |
| 28f0a80 by Thomas Thurman at 2009-07-24 |
464 |
render_copper (cairo_surface_t *surface, |
|
465 |
ccss_stylesheet_t *stylesheet) |
| d71b5ce by Thomas Thurman at 2009-07-12 |
466 |
{ |
| 28f0a80 by Thomas Thurman at 2009-07-24 |
467 |
cairo_t *cr = cairo_create (surface); |
| ccf35e1 by Thomas Thurman at 2009-07-23 |
468 |
|
| 28f0a80 by Thomas Thurman at 2009-07-24 |
469 |
int x = 0; |
|
470 |
int y = 0; |
|
471 |
int w = cairo_image_surface_get_width (surface); |
|
472 |
int h = cairo_image_surface_get_height (surface); |
| ccf35e1 by Thomas Thurman at 2009-07-23 |
473 |
|
| 5572806 by Thomas Thurman at 2009-07-25 |
474 |
PangoRectangle text_extents; |
|
475 |
|
|
476 |
int titlebar_height; |
| ccf35e1 by Thomas Thurman at 2009-07-23 |
477 |
|
| e1bd3aa by Thomas Thurman at 2009-07-24 |
478 |
CopperClasses left_buttons[] = {CC_MENU, CC_LAST}; |
|
479 |
CopperClasses right_buttons[] = {CC_CLOSE, CC_MAXIMIZE, CC_MINIMIZE, CC_LAST}; |
|
480 |
CopperClasses *cursor; |
|
481 |
int leftpos, rightpos; |
|
482 |
|
| 7d15ba1 by Thomas Thurman at 2009-07-25 |
483 |
PangoLayout *layout = title_text (stylesheet, cr, "Badgers"); |
| c89db0f by Thomas Thurman at 2009-07-25 |
484 |
|
| 5572806 by Thomas Thurman at 2009-07-25 |
485 |
pango_layout_get_pixel_extents (layout, NULL, &text_extents); |
| 7d15ba1 by Thomas Thurman at 2009-07-25 |
486 |
reduce_by_padding_borders_and_margins (stylesheet, CC_TITLE, |
|
487 |
&text_extents.x, &text_extents.y, |
|
488 |
&text_extents.width, |
|
489 |
&text_extents.height, |
|
490 |
TRUE, TRUE); |
| 5572806 by Thomas Thurman at 2009-07-25 |
491 |
|
|
492 |
titlebar_height = text_extents.height; |
|
493 |
|
| 39dd0cf by Thomas Thurman at 2009-07-28 |
494 |
reduce_by_padding_borders_and_margins (stylesheet, CC_TITLEBAR, |
|
495 |
NULL, NULL, NULL, |
|
496 |
&titlebar_height, |
|
497 |
TRUE, TRUE); |
|
498 |
|
| 4c5428f by Thomas Thurman at 2009-07-25 |
499 |
draw_rectangle (stylesheet, cr, CC_FRAME, x, y, w, h, FALSE, FALSE, NULL); |
| ccf35e1 by Thomas Thurman at 2009-07-23 |
500 |
|
| 7d15ba1 by Thomas Thurman at 2009-07-25 |
501 |
reduce_by_padding_borders_and_margins (stylesheet, CC_FRAME, &x, &y, &w, &h, FALSE, FALSE); |
| ccf35e1 by Thomas Thurman at 2009-07-23 |
502 |
|
| 4c5428f by Thomas Thurman at 2009-07-25 |
503 |
draw_rectangle (stylesheet, cr, CC_TITLEBAR, x, y, w, titlebar_height, TRUE, FALSE, NULL); |
| c600456 by Thomas Thurman at 2009-07-23 |
504 |
|
| 4c5428f by Thomas Thurman at 2009-07-25 |
505 |
draw_rectangle (stylesheet, cr, CC_CONTENT, x, y+titlebar_height, w, h-titlebar_height, TRUE, FALSE, NULL); |
| ccf35e1 by Thomas Thurman at 2009-07-23 |
506 |
|
| 9c9a6bf by Thomas Thurman at 2009-07-23 |
507 |
h = titlebar_height; |
|
508 |
|
| 7d15ba1 by Thomas Thurman at 2009-07-25 |
509 |
reduce_by_padding_borders_and_margins (stylesheet, CC_TITLEBAR, &x, &y, &w, &h, TRUE, FALSE); |
| 9c9a6bf by Thomas Thurman at 2009-07-23 |
510 |
|
| e1bd3aa by Thomas Thurman at 2009-07-24 |
511 |
cursor = left_buttons; |
|
512 |
leftpos = x; |
|
513 |
while (*cursor != CC_LAST) |
|
514 |
{ |
| 4c5428f by Thomas Thurman at 2009-07-25 |
515 |
leftpos += draw_rectangle (stylesheet, cr, *cursor, leftpos, y, 0, h, TRUE, FALSE, NULL); |
| e1bd3aa by Thomas Thurman at 2009-07-24 |
516 |
cursor++; |
|
517 |
} |
|
518 |
|
|
519 |
cursor = right_buttons; |
|
520 |
rightpos = x+w; |
|
521 |
while (*cursor != CC_LAST) |
|
522 |
{ |
| 4c5428f by Thomas Thurman at 2009-07-25 |
523 |
rightpos -= draw_rectangle (stylesheet, cr, *cursor, rightpos, y, 0, h, TRUE, TRUE, NULL); |
| e1bd3aa by Thomas Thurman at 2009-07-24 |
524 |
cursor++; |
|
525 |
} |
| 9c9a6bf by Thomas Thurman at 2009-07-23 |
526 |
|
| 3197c3a by Thomas Thurman at 2009-07-25 |
527 |
switch (pango_layout_get_alignment (layout)) |
|
528 |
{ |
|
529 |
case PANGO_ALIGN_LEFT: |
|
530 |
x = leftpos; |
| 39dd0cf by Thomas Thurman at 2009-07-28 |
531 |
draw_rectangle (stylesheet, cr, CC_FILLER, leftpos+text_extents.width, y, |
|
532 |
(rightpos-leftpos)-text_extents.width, h, TRUE, FALSE, NULL); |
| 3197c3a by Thomas Thurman at 2009-07-25 |
533 |
break; |
|
534 |
case PANGO_ALIGN_CENTER: |
|
535 |
x = leftpos + ((rightpos-leftpos)/2 - text_extents.width); |
| 39dd0cf by Thomas Thurman at 2009-07-28 |
536 |
draw_rectangle (stylesheet, cr, CC_FILLER, leftpos, y, |
|
537 |
x-leftpos, h, TRUE, FALSE, NULL); |
|
538 |
draw_rectangle (stylesheet, cr, CC_FILLER, x+text_extents.width, y, |
|
539 |
rightpos-(x+text_extents.width), h, TRUE, FALSE, NULL); |
| 3197c3a by Thomas Thurman at 2009-07-25 |
540 |
break; |
|
541 |
case PANGO_ALIGN_RIGHT: |
|
542 |
x = rightpos - text_extents.width; |
| 8ea489d by Thomas Thurman at 2009-07-28 |
543 |
draw_rectangle (stylesheet, cr, CC_FILLER, leftpos, y, |
|
544 |
rightpos-(leftpos-text_extents.width), h, TRUE, FALSE, NULL); |
| 3197c3a by Thomas Thurman at 2009-07-25 |
545 |
break; |
|
546 |
default: |
|
547 |
g_error ("Unknown alignment"); |
|
548 |
} |
|
549 |
|
|
550 |
draw_rectangle (stylesheet, cr, CC_TITLE, x, y, text_extents.width, h, TRUE, FALSE, layout); |
| 9d10179 by Thomas Thurman at 2009-07-23 |
551 |
|
| c89db0f by Thomas Thurman at 2009-07-25 |
552 |
g_object_unref (G_OBJECT (layout)); |
| 7a71be1 by Thomas Thurman at 2009-07-12 |
553 |
cairo_destroy (cr); |
| d71b5ce by Thomas Thurman at 2009-07-12 |
554 |
} |
|
555 |
|
|
556 |
int |
|
557 |
main (int argc, |
|
558 |
char **argv) |
|
559 |
{ |
|
560 |
ccss_grammar_t *grammar; |
|
561 |
ccss_stylesheet_t *stylesheet; |
|
562 |
ccss_style_t *style; |
| 28f0a80 by Thomas Thurman at 2009-07-24 |
563 |
|
|
564 |
cairo_surface_t *surface; |
|
565 |
|
|
566 |
int image_width = 800; |
|
567 |
int image_height = 250; |
| d71b5ce by Thomas Thurman at 2009-07-12 |
568 |
|
| e33cc03 by Thomas Thurman at 2009-07-13 |
569 |
initialise_classes (); |
|
570 |
|
| 28f0a80 by Thomas Thurman at 2009-07-24 |
571 |
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, |
|
572 |
image_width, |
|
573 |
image_height); |
|
574 |
|
| d71b5ce by Thomas Thurman at 2009-07-12 |
575 |
grammar = ccss_cairo_grammar_create (); |
|
576 |
ccss_grammar_add_functions (grammar, _functions); |
|
577 |
stylesheet = ccss_grammar_create_stylesheet_from_file (grammar, |
| 39dd0cf by Thomas Thurman at 2009-07-28 |
578 |
argv[1], |
| d71b5ce by Thomas Thurman at 2009-07-12 |
579 |
NULL); |
|
580 |
|
| 28f0a80 by Thomas Thurman at 2009-07-24 |
581 |
render_copper (surface, stylesheet); |
| d71b5ce by Thomas Thurman at 2009-07-12 |
582 |
|
|
583 |
ccss_stylesheet_destroy (stylesheet); |
|
584 |
ccss_grammar_destroy (grammar); |
|
585 |
|
| 39dd0cf by Thomas Thurman at 2009-07-28 |
586 |
cairo_surface_write_to_png (surface, argv[2]); |
| 28f0a80 by Thomas Thurman at 2009-07-24 |
587 |
cairo_surface_destroy (surface); |
|
588 |
|
| d71b5ce by Thomas Thurman at 2009-07-12 |
589 |
return EXIT_SUCCESS; |
|
590 |
} |
|
591 |
|