1 #ifndef test_dump_h_
2 #define test_dump_h_
3 
4 #include <string.h>
5 
6 #include <libcss/types.h>
7 
8 #include "stylesheet.h"
9 #include "bytecode/bytecode.h"
10 #include "bytecode/opcodes.h"
11 #include "select/font_face.h"
12 
13 #include "testutils.h"
14 
15 static void dump_sheet(css_stylesheet *sheet, char *buf, size_t *len);
16 static void dump_rule_selector(css_rule_selector *s, char **buf,
17 		size_t *buflen, uint32_t depth);
18 static void dump_rule_charset(css_rule_charset *s, char **buf, size_t *buflen);
19 static void dump_rule_import(css_rule_import *s, char **buf, size_t *buflen);
20 static void dump_rule_media(css_rule_media *s, char **buf, size_t *buflen);
21 static void dump_rule_page(css_rule_page *s, char **buf, size_t *buflen);
22 static void dump_rule_font_face(css_rule_font_face *s,
23 		char **buf, size_t *buflen);
24 static void dump_selector_list(css_selector *list, char **ptr);
25 static void dump_selector(css_selector *selector, char **ptr);
26 static void dump_selector_detail(css_selector_detail *detail, char **ptr);
27 static void dump_bytecode(css_style *style, char **ptr, uint32_t depth);
28 static void dump_string(lwc_string *string, char **ptr);
29 static void dump_font_face(css_font_face *font_face, char**ptr);
30 
dump_sheet(css_stylesheet * sheet,char * buf,size_t * buflen)31 void dump_sheet(css_stylesheet *sheet, char *buf, size_t *buflen)
32 {
33 	css_rule *rule;
34 
35 	for (rule = sheet->rule_list; rule != NULL; rule = rule->next) {
36 		switch (rule->type) {
37 		case CSS_RULE_SELECTOR:
38 			dump_rule_selector((css_rule_selector *) rule,
39 				&buf, buflen, 1);
40 			break;
41 		case CSS_RULE_CHARSET:
42 			dump_rule_charset((css_rule_charset *) rule,
43 				&buf, buflen);
44 			break;
45 		case CSS_RULE_IMPORT:
46 			dump_rule_import((css_rule_import *) rule,
47 				&buf, buflen);
48 			break;
49 		case CSS_RULE_MEDIA:
50 			dump_rule_media((css_rule_media *) rule,
51 				&buf, buflen);
52 			break;
53 		case CSS_RULE_PAGE:
54 			dump_rule_page((css_rule_page *) rule,
55 				&buf, buflen);
56 			break;
57 		case CSS_RULE_FONT_FACE:
58 			dump_rule_font_face((css_rule_font_face *) rule,
59 				&buf, buflen);
60 			break;
61 		default:
62 		{
63 			int written = sprintf(buf, "Unhandled rule type %d\n",
64 				rule->type);
65 
66 			*buflen -= written;
67 			buf += written;
68 		}
69 			break;
70 		}
71 	}
72 }
73 
dump_rule_selector(css_rule_selector * s,char ** buf,size_t * buflen,uint32_t depth)74 void dump_rule_selector(css_rule_selector *s, char **buf, size_t *buflen,
75 		uint32_t depth)
76 {
77 	uint32_t i;
78 	char *ptr = *buf;
79 
80 	*ptr++ = '|';
81 	for (i = 0; i < depth; i++)
82 		*ptr++ = ' ';
83 
84 	/* Build selector string */
85 	for (i = 0; i < s->base.items; i++) {
86 		dump_selector_list(s->selectors[i], &ptr);
87 		if (i != (uint32_t) (s->base.items - 1)) {
88 			memcpy(ptr, ", ", 2);
89 			ptr += 2;
90 		}
91 	}
92 	*ptr++ = '\n';
93 
94 	if (s->style != NULL)
95 		dump_bytecode(s->style, &ptr, depth + 1);
96 
97 	*buflen -= ptr - *buf;
98 	*buf = ptr;
99 }
100 
dump_rule_charset(css_rule_charset * s,char ** buf,size_t * buflen)101 void dump_rule_charset(css_rule_charset *s, char **buf, size_t *buflen)
102 {
103 	char *ptr = *buf;
104 
105 	ptr += sprintf(ptr, "| @charset(");
106 	dump_string(s->encoding, &ptr);
107 	*ptr++ = ')';
108 	*ptr++ = '\n';
109 
110 	*buflen -= ptr - *buf;
111 	*buf = ptr;
112 }
113 
dump_rule_import(css_rule_import * s,char ** buf,size_t * buflen)114 void dump_rule_import(css_rule_import *s, char **buf, size_t *buflen)
115 {
116 	char *ptr = *buf;
117 
118 	ptr += sprintf(ptr, "| @import url(\"%.*s\")",
119                        (int) lwc_string_length(s->url), lwc_string_data(s->url));
120 
121 	/** \todo media list */
122 
123 	*ptr++ = '\n';
124 
125 	*buflen -= ptr - *buf;
126 	*buf = ptr;
127 }
128 
dump_rule_media(css_rule_media * s,char ** buf,size_t * buflen)129 void dump_rule_media(css_rule_media *s, char **buf, size_t *buflen)
130 {
131 	char *ptr = *buf;
132 	css_rule *rule;
133 
134 	ptr += sprintf(ptr, "| @media ");
135 
136 	/* \todo media list */
137 
138 	*ptr++ = '\n';
139 
140 	for (rule = s->first_child; rule != NULL; rule = rule->next) {
141 		size_t len = *buflen - (ptr - *buf);
142 
143 		dump_rule_selector((css_rule_selector *) rule, &ptr, &len, 2);
144 	}
145 
146 	*buflen -= ptr - *buf;
147 	*buf = ptr;
148 }
149 
dump_rule_page(css_rule_page * s,char ** buf,size_t * buflen)150 void dump_rule_page(css_rule_page *s, char **buf, size_t *buflen)
151 {
152 	char *ptr = *buf;
153 
154 	ptr += sprintf(ptr, "| @page ");
155 
156 	if (s->selector != NULL)
157 		dump_selector_list(s->selector, &ptr);
158 
159 	*ptr++ = '\n';
160 
161 	if (s->style != NULL)
162 		dump_bytecode(s->style, &ptr, 2);
163 
164 	*buflen -= ptr - *buf;
165 	*buf = ptr;
166 }
167 
dump_rule_font_face(css_rule_font_face * s,char ** buf,size_t * buflen)168 void dump_rule_font_face(css_rule_font_face *s, char **buf, size_t *buflen)
169 {
170 	char *ptr = *buf;
171 
172 	ptr += sprintf(ptr, "| @font-face ");
173 
174 	if (s->font_face != NULL) {
175 		dump_font_face(s->font_face, &ptr);
176 	}
177 
178 	*ptr++ = '\n';
179 
180 	*buflen -= ptr - *buf;
181 	*buf = ptr;
182 }
183 
dump_selector_list(css_selector * list,char ** ptr)184 void dump_selector_list(css_selector *list, char **ptr)
185 {
186 	if (list->combinator != NULL) {
187 		dump_selector_list(list->combinator, ptr);
188 	}
189 
190 	switch (list->data.comb) {
191 	case CSS_COMBINATOR_NONE:
192 		break;
193 	case CSS_COMBINATOR_ANCESTOR:
194 		(*ptr)[0] = ' ';
195 		*ptr += 1;
196 		break;
197 	case CSS_COMBINATOR_PARENT:
198 		memcpy(*ptr, " > ", 3);
199 		*ptr += 3;
200 		break;
201 	case CSS_COMBINATOR_SIBLING:
202 		memcpy(*ptr, " + ", 3);
203 		*ptr += 3;
204 		break;
205 	case CSS_COMBINATOR_GENERIC_SIBLING:
206 		memcpy(*ptr, " + ", 3);
207 		*ptr += 3;
208 		break;
209 	}
210 
211 	dump_selector(list, ptr);
212 }
213 
214 
dump_selector(css_selector * selector,char ** ptr)215 void dump_selector(css_selector *selector, char **ptr)
216 {
217 	css_selector_detail *d = &selector->data;
218 
219 	while (true) {
220 		dump_selector_detail(d, ptr);
221 
222 		if (d->next == 0)
223 			break;
224 
225 		d++;
226 	}
227 }
228 
dump_selector_detail(css_selector_detail * detail,char ** ptr)229 void dump_selector_detail(css_selector_detail *detail, char **ptr)
230 {
231 	if (detail->negate)
232 		*ptr += sprintf(*ptr, ":not(");
233 
234 	switch (detail->type) {
235 	case CSS_SELECTOR_ELEMENT:
236                 if (lwc_string_length(detail->qname.name) == 1 &&
237                     lwc_string_data(detail->qname.name)[0] == '*' &&
238 				detail->next == 0) {
239 			dump_string(detail->qname.name, ptr);
240 		} else if (lwc_string_length(detail->qname.name) != 1 ||
241                            lwc_string_data(detail->qname.name)[0] != '*') {
242 			dump_string(detail->qname.name, ptr);
243 		}
244 		break;
245 	case CSS_SELECTOR_CLASS:
246 		**ptr = '.';
247 		*ptr += 1;
248 		dump_string(detail->qname.name, ptr);
249 		break;
250 	case CSS_SELECTOR_ID:
251 		**ptr = '#';
252 		*ptr += 1;
253 		dump_string(detail->qname.name, ptr);
254 		break;
255 	case CSS_SELECTOR_PSEUDO_CLASS:
256 	case CSS_SELECTOR_PSEUDO_ELEMENT:
257 		**ptr = ':';
258 		*ptr += 1;
259 		dump_string(detail->qname.name, ptr);
260 		if (detail->value_type == CSS_SELECTOR_DETAIL_VALUE_STRING) {
261 			if (detail->value.string != NULL) {
262 				**ptr = '(';
263 				*ptr += 1;
264 				dump_string(detail->value.string, ptr);
265 				**ptr = ')';
266 				*ptr += 1;
267 			}
268 		} else {
269 			*ptr += sprintf(*ptr, "(%dn+%d)",
270 					detail->value.nth.a,
271 					detail->value.nth.b);
272 		}
273 		break;
274 	case CSS_SELECTOR_ATTRIBUTE:
275 		**ptr = '[';
276 		*ptr += 1;
277 		dump_string(detail->qname.name, ptr);
278 		**ptr = ']';
279 		*ptr += 1;
280 		break;
281 	case CSS_SELECTOR_ATTRIBUTE_EQUAL:
282 		**ptr = '[';
283 		*ptr += 1;
284 		dump_string(detail->qname.name, ptr);
285 		(*ptr)[0] = '=';
286 		(*ptr)[1] = '"';
287 		*ptr += 2;
288 		dump_string(detail->value.string, ptr);
289 		(*ptr)[0] = '"';
290 		(*ptr)[1] = ']';
291 		*ptr += 2;
292 		break;
293 	case CSS_SELECTOR_ATTRIBUTE_DASHMATCH:
294 		**ptr = '[';
295 		*ptr += 1;
296 		dump_string(detail->qname.name, ptr);
297 		(*ptr)[0] = '|';
298 		(*ptr)[1] = '=';
299 		(*ptr)[2] = '"';
300 		*ptr += 3;
301 		dump_string(detail->value.string, ptr);
302 		(*ptr)[0] = '"';
303 		(*ptr)[1] = ']';
304 		*ptr += 2;
305 		break;
306 	case CSS_SELECTOR_ATTRIBUTE_INCLUDES:
307 		**ptr = '[';
308 		*ptr += 1;
309 		dump_string(detail->qname.name, ptr);
310 		(*ptr)[0] = '~';
311 		(*ptr)[1] = '=';
312 		(*ptr)[2] = '"';
313 		*ptr += 3;
314 		dump_string(detail->value.string, ptr);
315 		(*ptr)[0] = '"';
316 		(*ptr)[1] = ']';
317 		*ptr += 2;
318 		break;
319 	case CSS_SELECTOR_ATTRIBUTE_PREFIX:
320 		**ptr = '[';
321 		*ptr += 1;
322 		dump_string(detail->qname.name, ptr);
323 		(*ptr)[0] = '^';
324 		(*ptr)[1] = '=';
325 		(*ptr)[2] = '"';
326 		*ptr += 3;
327 		dump_string(detail->value.string, ptr);
328 		(*ptr)[0] = '"';
329 		(*ptr)[1] = ']';
330 		*ptr += 2;
331 		break;
332 	case CSS_SELECTOR_ATTRIBUTE_SUFFIX:
333 		**ptr = '[';
334 		*ptr += 1;
335 		dump_string(detail->qname.name, ptr);
336 		(*ptr)[0] = '$';
337 		(*ptr)[1] = '=';
338 		(*ptr)[2] = '"';
339 		*ptr += 3;
340 		dump_string(detail->value.string, ptr);
341 		(*ptr)[0] = '"';
342 		(*ptr)[1] = ']';
343 		*ptr += 2;
344 		break;
345 	case CSS_SELECTOR_ATTRIBUTE_SUBSTRING:
346 		**ptr = '[';
347 		*ptr += 1;
348 		dump_string(detail->qname.name, ptr);
349 		(*ptr)[0] = '*';
350 		(*ptr)[1] = '=';
351 		(*ptr)[2] = '"';
352 		*ptr += 3;
353 		dump_string(detail->value.string, ptr);
354 		(*ptr)[0] = '"';
355 		(*ptr)[1] = ']';
356 		*ptr += 2;
357 		break;
358 	}
359 
360 	if (detail->negate)
361 		*ptr += sprintf(*ptr, ")");
362 }
363 
364 /**
365  * Opcode names, indexed by opcode
366  */
367 static const char *opcode_names[] = {
368 	"azimuth",
369 	"background-attachment",
370 	"background-color",
371 	"background-image",
372 	"background-position",
373 	"background-repeat",
374 	"border-collapse",
375 	"border-spacing",
376 	"border-top-color",
377 	"border-right-color",
378 	"border-bottom-color",
379 	"border-left-color",
380 	"border-top-style",
381 	"border-right-style",
382 	"border-bottom-style",
383 	"border-left-style",
384 	"border-top-width",
385 	"border-right-width",
386 	"border-bottom-width",
387 	"border-left-width",
388 	"bottom",
389 	"caption-side",
390 	"clear",
391 	"clip",
392 	"color",
393 	"content",
394 	"counter-increment",
395 	"counter-reset",
396 	"cue-after",
397 	"cue-before",
398 	"cursor",
399 	"direction",
400 	"display",
401 	"elevation",
402 	"empty-cells",
403 	"float",
404 	"font-family",
405 	"font-size",
406 	"font-style",
407 	"font-variant",
408 	"font-weight",
409 	"height",
410 	"left",
411 	"letter-spacing",
412 	"line-height",
413 	"list-style-image",
414 	"list-style-position",
415 	"list-style-type",
416 	"margin-top",
417 	"margin-right",
418 	"margin-bottom",
419 	"margin-left",
420 	"max-height",
421 	"max-width",
422 	"min-height",
423 	"min-width",
424 	"orphans",
425 	"outline-color",
426 	"outline-style",
427 	"outline-width",
428 	"overflow-x",
429 	"padding-top",
430 	"padding-right",
431 	"padding-bottom",
432 	"padding-left",
433 	"page-break-after",
434 	"page-break-before",
435 	"page-break-inside",
436 	"pause-after",
437 	"pause-before",
438 	"pitch-range",
439 	"pitch",
440 	"play-during",
441 	"position",
442 	"quotes",
443 	"richness",
444 	"right",
445 	"speak-header",
446 	"speak-numeral",
447 	"speak-punctuation",
448 	"speak",
449 	"speech-rate",
450 	"stress",
451 	"table-layout",
452 	"text-align",
453 	"text-decoration",
454 	"text-indent",
455 	"text-transform",
456 	"top",
457 	"unicode-bidi",
458 	"vertical-align",
459 	"visibility",
460 	"voice-family",
461 	"volume",
462 	"white-space",
463 	"widows",
464 	"width",
465 	"word-spacing",
466 	"z-index",
467 	"opacity",
468 	"break-after",
469 	"break-before",
470 	"break-inside",
471 	"column-count",
472 	"column-fill",
473 	"column-gap",
474 	"column-rule-color",
475 	"column-rule-style",
476 	"column-rule-width",
477 	"column-span",
478 	"column-width",
479 	"writing-mode",
480 	"overflow-y",
481 	"box-sizing",
482 	"align-content",
483 	"align-items",
484 	"align-self",
485 	"flex-basis",
486 	"flex-direction",
487 	"flex-grow",
488 	"flex-shrink",
489 	"flex-wrap",
490 	"justify-content",
491 	"order",
492 };
493 
dump_css_fixed(css_fixed f,char ** ptr)494 static void dump_css_fixed(css_fixed f, char **ptr)
495 {
496 #define ABS(x) (uint32_t)((x) < 0 ? -(x) : (x))
497 	uint32_t uintpart = FIXTOINT(ABS(f));
498 	/* + 500 to ensure round to nearest (division will truncate) */
499 	uint32_t fracpart = ((ABS(f) & 0x3ff) * 1000 + 500) / (1 << 10);
500 #undef ABS
501 	size_t flen = 0;
502 	char tmp[20];
503 	size_t tlen = 0;
504 	char *buf = *ptr;
505 
506 	if (f < 0) {
507 		buf[0] = '-';
508 		buf++;
509 	}
510 
511 	do {
512 		tmp[tlen] = "0123456789"[uintpart % 10];
513 		tlen++;
514 
515 		uintpart /= 10;
516 	} while (tlen < 20 && uintpart != 0);
517 
518 	while (tlen > 0) {
519 		buf[0] = tmp[--tlen];
520 		buf++;
521 	}
522 
523 	buf[0] = '.';
524 	buf++;
525 
526 	do {
527 		tmp[tlen] = "0123456789"[fracpart % 10];
528 		tlen++;
529 
530 		fracpart /= 10;
531 	} while (tlen < 20 && fracpart != 0);
532 
533 	while (tlen > 0) {
534 		buf[0] = tmp[--tlen];
535 		buf++;
536 		flen++;
537 	}
538 
539 	while (flen < 3) {
540 		buf[0] = '0';
541 		buf++;
542 		flen++;
543 	}
544 
545 	buf[0] = '\0';
546 
547 	*ptr = buf;
548 }
549 
dump_number(css_fixed val,char ** ptr)550 static void dump_number(css_fixed val, char **ptr)
551 {
552 	if (INTTOFIX(FIXTOINT(val)) == val)
553 		*ptr += sprintf(*ptr, "%d", FIXTOINT(val));
554 	else
555 		dump_css_fixed(val, ptr);
556 }
557 
dump_unit(css_fixed val,uint32_t unit,char ** ptr)558 static void dump_unit(css_fixed val, uint32_t unit, char **ptr)
559 {
560 	dump_number(val, ptr);
561 
562 	switch (unit) {
563 	case UNIT_PX:
564 		*ptr += sprintf(*ptr, "px");
565 		break;
566 	case UNIT_EX:
567 		*ptr += sprintf(*ptr, "ex");
568 		break;
569 	case UNIT_EM:
570 		*ptr += sprintf(*ptr, "em");
571 		break;
572 	case UNIT_IN:
573 		*ptr += sprintf(*ptr, "in");
574 		break;
575 	case UNIT_CM:
576 		*ptr += sprintf(*ptr, "cm");
577 		break;
578 	case UNIT_MM:
579 		*ptr += sprintf(*ptr, "mm");
580 		break;
581 	case UNIT_PT:
582 		*ptr += sprintf(*ptr, "pt");
583 		break;
584 	case UNIT_PC:
585 		*ptr += sprintf(*ptr, "pc");
586 		break;
587 	case UNIT_CAP:
588 		*ptr += sprintf(*ptr, "cap");
589 		break;
590 	case UNIT_CH:
591 		*ptr += sprintf(*ptr, "ch");
592 		break;
593 	case UNIT_IC:
594 		*ptr += sprintf(*ptr, "ic");
595 		break;
596 	case UNIT_REM:
597 		*ptr += sprintf(*ptr, "rem");
598 		break;
599 	case UNIT_LH:
600 		*ptr += sprintf(*ptr, "lh");
601 		break;
602 	case UNIT_RLH:
603 		*ptr += sprintf(*ptr, "rlh");
604 		break;
605 	case UNIT_VH:
606 		*ptr += sprintf(*ptr, "vh");
607 		break;
608 	case UNIT_VW:
609 		*ptr += sprintf(*ptr, "vw");
610 		break;
611 	case UNIT_VI:
612 		*ptr += sprintf(*ptr, "vi");
613 		break;
614 	case UNIT_VB:
615 		*ptr += sprintf(*ptr, "vb");
616 		break;
617 	case UNIT_VMIN:
618 		*ptr += sprintf(*ptr, "vmin");
619 		break;
620 	case UNIT_VMAX:
621 		*ptr += sprintf(*ptr, "vmax");
622 		break;
623 	case UNIT_Q:
624 		*ptr += sprintf(*ptr, "q");
625 		break;
626 	case UNIT_PCT:
627 		*ptr += sprintf(*ptr, "%%");
628 		break;
629 	case UNIT_DEG:
630 		*ptr += sprintf(*ptr, "deg");
631 		break;
632 	case UNIT_GRAD:
633 		*ptr += sprintf(*ptr, "grad");
634 		break;
635 	case UNIT_RAD:
636 		*ptr += sprintf(*ptr, "rad");
637 		break;
638 	case UNIT_MS:
639 		*ptr += sprintf(*ptr, "ms");
640 		break;
641 	case UNIT_S:
642 		*ptr += sprintf(*ptr, "s");
643 		break;
644 	case UNIT_HZ:
645 		*ptr += sprintf(*ptr, "Hz");
646 		break;
647 	case UNIT_KHZ:
648 		*ptr += sprintf(*ptr, "kHz");
649 		break;
650 	}
651 }
652 
dump_counter(lwc_string * name,uint32_t value,char ** ptr)653 static void dump_counter(lwc_string *name, uint32_t value,
654 		char **ptr)
655 {
656 	*ptr += sprintf(*ptr, "counter(%.*s",
657                         (int) lwc_string_length(name), lwc_string_data(name));
658 
659 	value >>= CONTENT_COUNTER_STYLE_SHIFT;
660 
661 	switch (value) {
662 	case LIST_STYLE_TYPE_DISC:
663 		*ptr += sprintf(*ptr, ", disc");
664 		break;
665 	case LIST_STYLE_TYPE_CIRCLE:
666 		*ptr += sprintf(*ptr, ", circle");
667 		break;
668 	case LIST_STYLE_TYPE_SQUARE:
669 		*ptr += sprintf(*ptr, ", square");
670 		break;
671 	case LIST_STYLE_TYPE_DECIMAL:
672 		break;
673 	case LIST_STYLE_TYPE_DECIMAL_LEADING_ZERO:
674 		*ptr += sprintf(*ptr, ", decimal-leading-zero");
675 		break;
676 	case LIST_STYLE_TYPE_LOWER_ROMAN:
677 		*ptr += sprintf(*ptr, ", lower-roman");
678 		break;
679 	case LIST_STYLE_TYPE_UPPER_ROMAN:
680 		*ptr += sprintf(*ptr, ", upper-roman");
681 		break;
682 	case LIST_STYLE_TYPE_LOWER_GREEK:
683 		*ptr += sprintf(*ptr, ", lower-greek");
684 		break;
685 	case LIST_STYLE_TYPE_LOWER_LATIN:
686 		*ptr += sprintf(*ptr, ", lower-latin");
687 		break;
688 	case LIST_STYLE_TYPE_UPPER_LATIN:
689 		*ptr += sprintf(*ptr, ", upper-latin");
690 		break;
691 	case LIST_STYLE_TYPE_ARMENIAN:
692 		*ptr += sprintf(*ptr, ", armenian");
693 		break;
694 	case LIST_STYLE_TYPE_GEORGIAN:
695 		*ptr += sprintf(*ptr, ", georgian");
696 		break;
697 	case LIST_STYLE_TYPE_LOWER_ALPHA:
698 		*ptr += sprintf(*ptr, ", lower-alpha");
699 		break;
700 	case LIST_STYLE_TYPE_UPPER_ALPHA:
701 		*ptr += sprintf(*ptr, ", upper-alpha");
702 		break;
703 	case LIST_STYLE_TYPE_NONE:
704 		*ptr += sprintf(*ptr, ", none");
705 		break;
706 	}
707 
708 	*ptr += sprintf(*ptr, ")");
709 }
710 
dump_counters(lwc_string * name,lwc_string * separator,uint32_t value,char ** ptr)711 static void dump_counters(lwc_string *name, lwc_string *separator,
712 		uint32_t value, char **ptr)
713 {
714 	*ptr += sprintf(*ptr, "counter(%.*s, %.*s",
715 			(int) lwc_string_length(name),
716                         lwc_string_data(name),
717 			(int) lwc_string_length(separator),
718                         lwc_string_data(separator));
719 
720 	value >>= CONTENT_COUNTER_STYLE_SHIFT;
721 
722 	switch (value) {
723 	case LIST_STYLE_TYPE_DISC:
724 		*ptr += sprintf(*ptr, ", disc");
725 		break;
726 	case LIST_STYLE_TYPE_CIRCLE:
727 		*ptr += sprintf(*ptr, ", circle");
728 		break;
729 	case LIST_STYLE_TYPE_SQUARE:
730 		*ptr += sprintf(*ptr, ", square");
731 		break;
732 	case LIST_STYLE_TYPE_DECIMAL:
733 		break;
734 	case LIST_STYLE_TYPE_DECIMAL_LEADING_ZERO:
735 		*ptr += sprintf(*ptr, ", decimal-leading-zero");
736 		break;
737 	case LIST_STYLE_TYPE_LOWER_ROMAN:
738 		*ptr += sprintf(*ptr, ", lower-roman");
739 		break;
740 	case LIST_STYLE_TYPE_UPPER_ROMAN:
741 		*ptr += sprintf(*ptr, ", upper-roman");
742 		break;
743 	case LIST_STYLE_TYPE_LOWER_GREEK:
744 		*ptr += sprintf(*ptr, ", lower-greek");
745 		break;
746 	case LIST_STYLE_TYPE_LOWER_LATIN:
747 		*ptr += sprintf(*ptr, ", lower-latin");
748 		break;
749 	case LIST_STYLE_TYPE_UPPER_LATIN:
750 		*ptr += sprintf(*ptr, ", upper-latin");
751 		break;
752 	case LIST_STYLE_TYPE_ARMENIAN:
753 		*ptr += sprintf(*ptr, ", armenian");
754 		break;
755 	case LIST_STYLE_TYPE_GEORGIAN:
756 		*ptr += sprintf(*ptr, ", georgian");
757 		break;
758 	case LIST_STYLE_TYPE_LOWER_ALPHA:
759 		*ptr += sprintf(*ptr, ", lower-alpha");
760 		break;
761 	case LIST_STYLE_TYPE_UPPER_ALPHA:
762 		*ptr += sprintf(*ptr, ", upper-alpha");
763 		break;
764 	case LIST_STYLE_TYPE_NONE:
765 		*ptr += sprintf(*ptr, ", none");
766 		break;
767 	}
768 
769 	*ptr += sprintf(*ptr, ")");
770 }
771 
dump_bytecode(css_style * style,char ** ptr,uint32_t depth)772 void dump_bytecode(css_style *style, char **ptr, uint32_t depth)
773 {
774 	void *bytecode = style->bytecode;
775 	size_t length = (style->used * sizeof(css_code_t));
776 	uint32_t offset = 0;
777 
778 #define ADVANCE(n) do {					\
779 	offset += (n);					\
780 	bytecode = ((uint8_t *) bytecode) + (n);	\
781 } while(0)
782 
783 	while (offset < length) {
784 		opcode_t op;
785 		uint32_t value;
786 		uint32_t opv = *((uint32_t *) bytecode);
787 		uint32_t i;
788 
789 		ADVANCE(sizeof(opv));
790 
791 		op = getOpcode(opv);
792 
793 		*((*ptr)++) = '|';
794 		for (i = 0; i < depth; i++)
795 			*((*ptr)++) = ' ';
796 		*ptr += sprintf(*ptr, "%s: ", opcode_names[op]);
797 
798 		if (isInherit(opv)) {
799 			*ptr += sprintf(*ptr, "inherit");
800 		} else {
801 			value = getValue(opv);
802 
803 			switch (op) {
804 			case CSS_PROP_ALIGN_CONTENT:
805 				switch (value) {
806 				case ALIGN_CONTENT_STRETCH:
807 					*ptr += sprintf(*ptr, "stretch");
808 					break;
809 				case ALIGN_CONTENT_FLEX_START:
810 					*ptr += sprintf(*ptr, "flex-start");
811 					break;
812 				case ALIGN_CONTENT_FLEX_END:
813 					*ptr += sprintf(*ptr, "flex-end");
814 					break;
815 				case ALIGN_CONTENT_CENTER:
816 					*ptr += sprintf(*ptr, "center");
817 					break;
818 				case ALIGN_CONTENT_SPACE_BETWEEN:
819 					*ptr += sprintf(*ptr, "space-between");
820 					break;
821 				case ALIGN_CONTENT_SPACE_AROUND:
822 					*ptr += sprintf(*ptr, "space-around");
823 					break;
824 				case ALIGN_CONTENT_SPACE_EVENLY:
825 					*ptr += sprintf(*ptr, "space-evenly");
826 					break;
827 				}
828 				break;
829 			case CSS_PROP_ALIGN_ITEMS:
830 				switch (value) {
831 				case ALIGN_ITEMS_STRETCH:
832 					*ptr += sprintf(*ptr, "stretch");
833 					break;
834 				case ALIGN_ITEMS_FLEX_START:
835 					*ptr += sprintf(*ptr, "flex-start");
836 					break;
837 				case ALIGN_ITEMS_FLEX_END:
838 					*ptr += sprintf(*ptr, "flex-end");
839 					break;
840 				case ALIGN_ITEMS_CENTER:
841 					*ptr += sprintf(*ptr, "center");
842 					break;
843 				case ALIGN_ITEMS_BASELINE:
844 					*ptr += sprintf(*ptr, "baseline");
845 					break;
846 				}
847 				break;
848 			case CSS_PROP_ALIGN_SELF:
849 				switch (value) {
850 				case ALIGN_SELF_STRETCH:
851 					*ptr += sprintf(*ptr, "stretch");
852 					break;
853 				case ALIGN_SELF_FLEX_START:
854 					*ptr += sprintf(*ptr, "flex-start");
855 					break;
856 				case ALIGN_SELF_FLEX_END:
857 					*ptr += sprintf(*ptr, "flex-end");
858 					break;
859 				case ALIGN_SELF_CENTER:
860 					*ptr += sprintf(*ptr, "center");
861 					break;
862 				case ALIGN_SELF_BASELINE:
863 					*ptr += sprintf(*ptr, "baseline");
864 					break;
865 				case ALIGN_SELF_AUTO:
866 					*ptr += sprintf(*ptr, "auto");
867 					break;
868 				}
869 				break;
870 			case CSS_PROP_AZIMUTH:
871 				switch (value & ~AZIMUTH_BEHIND) {
872 				case AZIMUTH_ANGLE:
873 				{
874 					uint32_t unit;
875 					css_fixed val = *((css_fixed *) bytecode);
876 					ADVANCE(sizeof(val));
877 					unit = *((uint32_t *) bytecode);
878 					ADVANCE(sizeof(unit));
879 					dump_unit(val, unit, ptr);
880 				}
881 					break;
882 				case AZIMUTH_LEFTWARDS:
883 					*ptr += sprintf(*ptr, "leftwards");
884 					break;
885 				case AZIMUTH_RIGHTWARDS:
886 					*ptr += sprintf(*ptr, "rightwards");
887 					break;
888 				case AZIMUTH_LEFT_SIDE:
889 					*ptr += sprintf(*ptr, "left-side");
890 					break;
891 				case AZIMUTH_FAR_LEFT:
892 					*ptr += sprintf(*ptr, "far-left");
893 					break;
894 				case AZIMUTH_LEFT:
895 					*ptr += sprintf(*ptr, "left");
896 					break;
897 				case AZIMUTH_CENTER_LEFT:
898 					*ptr += sprintf(*ptr, "center-left");
899 					break;
900 				case AZIMUTH_CENTER:
901 					*ptr += sprintf(*ptr, "center");
902 					break;
903 				case AZIMUTH_CENTER_RIGHT:
904 					*ptr += sprintf(*ptr, "center-right");
905 					break;
906 				case AZIMUTH_RIGHT:
907 					*ptr += sprintf(*ptr, "right");
908 					break;
909 				case AZIMUTH_FAR_RIGHT:
910 					*ptr += sprintf(*ptr, "far-right");
911 					break;
912 				case AZIMUTH_RIGHT_SIDE:
913 					*ptr += sprintf(*ptr, "right-side");
914 					break;
915 				}
916 				if (value & AZIMUTH_BEHIND)
917 					*ptr += sprintf(*ptr, " behind");
918 				break;
919 			case CSS_PROP_BACKGROUND_ATTACHMENT:
920 				switch (value) {
921 				case BACKGROUND_ATTACHMENT_FIXED:
922 					*ptr += sprintf(*ptr, "fixed");
923 					break;
924 				case BACKGROUND_ATTACHMENT_SCROLL:
925 					*ptr += sprintf(*ptr, "scroll");
926 					break;
927 				}
928 				break;
929 			case CSS_PROP_BORDER_TOP_COLOR:
930 			case CSS_PROP_BORDER_RIGHT_COLOR:
931 			case CSS_PROP_BORDER_BOTTOM_COLOR:
932 			case CSS_PROP_BORDER_LEFT_COLOR:
933 			case CSS_PROP_BACKGROUND_COLOR:
934 			case CSS_PROP_COLUMN_RULE_COLOR:
935 				assert(BACKGROUND_COLOR_TRANSPARENT ==
936 						(enum op_background_color)
937 						BORDER_COLOR_TRANSPARENT);
938 				assert(BACKGROUND_COLOR_CURRENT_COLOR ==
939 						(enum op_background_color)
940 						BORDER_COLOR_CURRENT_COLOR);
941 				assert(BACKGROUND_COLOR_SET ==
942 						(enum op_background_color)
943 						BORDER_COLOR_SET);
944 
945 				switch (value) {
946 				case BACKGROUND_COLOR_TRANSPARENT:
947 					*ptr += sprintf(*ptr, "transparent");
948 					break;
949 				case BACKGROUND_COLOR_CURRENT_COLOR:
950 					*ptr += sprintf(*ptr, "currentColor");
951 					break;
952 				case BACKGROUND_COLOR_SET:
953 				{
954 					uint32_t colour =
955 						*((uint32_t *) bytecode);
956 					ADVANCE(sizeof(colour));
957 					*ptr += sprintf(*ptr, "#%08x", colour);
958 				}
959 					break;
960 				}
961 				break;
962 			case CSS_PROP_BACKGROUND_IMAGE:
963 			case CSS_PROP_CUE_AFTER:
964 			case CSS_PROP_CUE_BEFORE:
965 			case CSS_PROP_LIST_STYLE_IMAGE:
966 				assert(BACKGROUND_IMAGE_NONE ==
967 						(enum op_background_image)
968 						CUE_AFTER_NONE);
969 				assert(BACKGROUND_IMAGE_URI ==
970 						(enum op_background_image)
971 						CUE_AFTER_URI);
972 				assert(BACKGROUND_IMAGE_NONE ==
973 						(enum op_background_image)
974 						CUE_BEFORE_NONE);
975 				assert(BACKGROUND_IMAGE_URI ==
976 						(enum op_background_image)
977 						CUE_BEFORE_URI);
978 				assert(BACKGROUND_IMAGE_NONE ==
979 						(enum op_background_image)
980 						LIST_STYLE_IMAGE_NONE);
981 				assert(BACKGROUND_IMAGE_URI ==
982 						(enum op_background_image)
983 						LIST_STYLE_IMAGE_URI);
984 
985 				switch (value) {
986 				case BACKGROUND_IMAGE_NONE:
987 					*ptr += sprintf(*ptr, "none");
988 					break;
989 				case BACKGROUND_IMAGE_URI:
990 				{
991 					uint32_t snum = *((uint32_t *) bytecode);
992 					lwc_string *he;
993 					css__stylesheet_string_get(style->sheet,
994 								  snum,
995 								  &he);
996 					ADVANCE(sizeof(snum));
997 					*ptr += sprintf(*ptr, "url('%.*s')",
998 							(int) lwc_string_length(he),
999 							lwc_string_data(he));
1000 				}
1001 					break;
1002 				}
1003 				break;
1004 			case CSS_PROP_BACKGROUND_POSITION:
1005 				switch (value & 0xf0) {
1006 				case BACKGROUND_POSITION_HORZ_SET:
1007 				{
1008 					uint32_t unit;
1009 					css_fixed val = *((css_fixed *) bytecode);
1010 					ADVANCE(sizeof(val));
1011 					unit = *((uint32_t *) bytecode);
1012 					ADVANCE(sizeof(unit));
1013 					dump_unit(val, unit, ptr);
1014 				}
1015 					break;
1016 				case BACKGROUND_POSITION_HORZ_CENTER:
1017 					*ptr += sprintf(*ptr, "center");
1018 					break;
1019 				case BACKGROUND_POSITION_HORZ_RIGHT:
1020 					*ptr += sprintf(*ptr, "right");
1021 					break;
1022 				case BACKGROUND_POSITION_HORZ_LEFT:
1023 					*ptr += sprintf(*ptr, "left");
1024 					break;
1025 				}
1026 				*ptr += sprintf(*ptr, " ");
1027 				switch (value & 0x0f) {
1028 				case BACKGROUND_POSITION_VERT_SET:
1029 				{
1030 					uint32_t unit;
1031 					css_fixed val = *((css_fixed *) bytecode);
1032 					ADVANCE(sizeof(val));
1033 					unit = *((uint32_t *) bytecode);
1034 					ADVANCE(sizeof(unit));
1035 					dump_unit(val, unit, ptr);
1036 				}
1037 					break;
1038 				case BACKGROUND_POSITION_VERT_CENTER:
1039 					*ptr += sprintf(*ptr, "center");
1040 					break;
1041 				case BACKGROUND_POSITION_VERT_BOTTOM:
1042 					*ptr += sprintf(*ptr, "bottom");
1043 					break;
1044 				case BACKGROUND_POSITION_VERT_TOP:
1045 					*ptr += sprintf(*ptr, "top");
1046 					break;
1047 				}
1048 				break;
1049 			case CSS_PROP_BACKGROUND_REPEAT:
1050 				switch (value) {
1051 				case BACKGROUND_REPEAT_NO_REPEAT:
1052 					*ptr += sprintf(*ptr, "no-repeat");
1053 					break;
1054 				case BACKGROUND_REPEAT_REPEAT_X:
1055 					*ptr += sprintf(*ptr, "repeat-x");
1056 					break;
1057 				case BACKGROUND_REPEAT_REPEAT_Y:
1058 					*ptr += sprintf(*ptr, "repeat-y");
1059 					break;
1060 				case BACKGROUND_REPEAT_REPEAT:
1061 					*ptr += sprintf(*ptr, "repeat");
1062 					break;
1063 				}
1064 				break;
1065 			case CSS_PROP_BORDER_COLLAPSE:
1066 				switch (value) {
1067 				case BORDER_COLLAPSE_SEPARATE:
1068 					*ptr += sprintf(*ptr, "separate");
1069 					break;
1070 				case BORDER_COLLAPSE_COLLAPSE:
1071 					*ptr += sprintf(*ptr, "collapse");
1072 					break;
1073 				}
1074 				break;
1075 			case CSS_PROP_BORDER_SPACING:
1076 				switch (value) {
1077 				case BORDER_SPACING_SET:
1078 				{
1079 					uint32_t unit;
1080 					css_fixed val = *((css_fixed *) bytecode);
1081 					ADVANCE(sizeof(val));
1082 					unit = *((uint32_t *) bytecode);
1083 					ADVANCE(sizeof(unit));
1084 					dump_unit(val, unit, ptr);
1085 
1086 					val = *((css_fixed *) bytecode);
1087 					ADVANCE(sizeof(val));
1088 					unit = *((uint32_t *) bytecode);
1089 					ADVANCE(sizeof(unit));
1090 					dump_unit(val, unit, ptr);
1091 				}
1092 					break;
1093 				}
1094 				break;
1095 			case CSS_PROP_BOX_SIZING:
1096 				switch (value) {
1097 				case BOX_SIZING_CONTENT_BOX:
1098 					*ptr += sprintf(*ptr, "content-box");
1099 					break;
1100 				case BOX_SIZING_BORDER_BOX:
1101 					*ptr += sprintf(*ptr, "border-box");
1102 					break;
1103 				}
1104 				break;
1105 			case CSS_PROP_BORDER_TOP_STYLE:
1106 			case CSS_PROP_BORDER_RIGHT_STYLE:
1107 			case CSS_PROP_BORDER_BOTTOM_STYLE:
1108 			case CSS_PROP_BORDER_LEFT_STYLE:
1109 			case CSS_PROP_COLUMN_RULE_STYLE:
1110 			case CSS_PROP_OUTLINE_STYLE:
1111 				assert(BORDER_STYLE_NONE ==
1112 						(enum op_border_style)
1113 						OUTLINE_STYLE_NONE);
1114 				assert(BORDER_STYLE_NONE ==
1115 						(enum op_border_style)
1116 						COLUMN_RULE_STYLE_NONE);
1117 				assert(BORDER_STYLE_HIDDEN ==
1118 						(enum op_border_style)
1119 						OUTLINE_STYLE_HIDDEN);
1120 				assert(BORDER_STYLE_HIDDEN ==
1121 						(enum op_border_style)
1122 						COLUMN_RULE_STYLE_HIDDEN);
1123 				assert(BORDER_STYLE_DOTTED ==
1124 						(enum op_border_style)
1125 						OUTLINE_STYLE_DOTTED);
1126 				assert(BORDER_STYLE_DOTTED ==
1127 						(enum op_border_style)
1128 						COLUMN_RULE_STYLE_DOTTED);
1129 				assert(BORDER_STYLE_DASHED ==
1130 						(enum op_border_style)
1131 						OUTLINE_STYLE_DASHED);
1132 				assert(BORDER_STYLE_DASHED ==
1133 						(enum op_border_style)
1134 						COLUMN_RULE_STYLE_DASHED);
1135 				assert(BORDER_STYLE_SOLID ==
1136 						(enum op_border_style)
1137 						OUTLINE_STYLE_SOLID);
1138 				assert(BORDER_STYLE_SOLID ==
1139 						(enum op_border_style)
1140 						COLUMN_RULE_STYLE_SOLID);
1141 				assert(BORDER_STYLE_DOUBLE ==
1142 						(enum op_border_style)
1143 						OUTLINE_STYLE_DOUBLE);
1144 				assert(BORDER_STYLE_DOUBLE ==
1145 						(enum op_border_style)
1146 						COLUMN_RULE_STYLE_DOUBLE);
1147 				assert(BORDER_STYLE_GROOVE ==
1148 						(enum op_border_style)
1149 						OUTLINE_STYLE_GROOVE);
1150 				assert(BORDER_STYLE_GROOVE ==
1151 						(enum op_border_style)
1152 						COLUMN_RULE_STYLE_GROOVE);
1153 				assert(BORDER_STYLE_RIDGE ==
1154 						(enum op_border_style)
1155 						OUTLINE_STYLE_RIDGE);
1156 				assert(BORDER_STYLE_RIDGE ==
1157 						(enum op_border_style)
1158 						COLUMN_RULE_STYLE_RIDGE);
1159 				assert(BORDER_STYLE_INSET ==
1160 						(enum op_border_style)
1161 						OUTLINE_STYLE_INSET);
1162 				assert(BORDER_STYLE_INSET ==
1163 						(enum op_border_style)
1164 						COLUMN_RULE_STYLE_INSET);
1165 				assert(BORDER_STYLE_OUTSET ==
1166 						(enum op_border_style)
1167 						OUTLINE_STYLE_OUTSET);
1168 				assert(BORDER_STYLE_OUTSET ==
1169 						(enum op_border_style)
1170 						COLUMN_RULE_STYLE_OUTSET);
1171 
1172 				switch (value) {
1173 				case BORDER_STYLE_NONE:
1174 					*ptr += sprintf(*ptr, "none");
1175 					break;
1176 				case BORDER_STYLE_HIDDEN:
1177 					*ptr += sprintf(*ptr, "hidden");
1178 					break;
1179 				case BORDER_STYLE_DOTTED:
1180 					*ptr += sprintf(*ptr, "dotted");
1181 					break;
1182 				case BORDER_STYLE_DASHED:
1183 					*ptr += sprintf(*ptr, "dashed");
1184 					break;
1185 				case BORDER_STYLE_SOLID:
1186 					*ptr += sprintf(*ptr, "solid");
1187 					break;
1188 				case BORDER_STYLE_DOUBLE:
1189 					*ptr += sprintf(*ptr, "double");
1190 					break;
1191 				case BORDER_STYLE_GROOVE:
1192 					*ptr += sprintf(*ptr, "groove");
1193 					break;
1194 				case BORDER_STYLE_RIDGE:
1195 					*ptr += sprintf(*ptr, "ridge");
1196 					break;
1197 				case BORDER_STYLE_INSET:
1198 					*ptr += sprintf(*ptr, "inset");
1199 					break;
1200 				case BORDER_STYLE_OUTSET:
1201 					*ptr += sprintf(*ptr, "outset");
1202 					break;
1203 				}
1204 				break;
1205 			case CSS_PROP_BORDER_TOP_WIDTH:
1206 			case CSS_PROP_BORDER_RIGHT_WIDTH:
1207 			case CSS_PROP_BORDER_BOTTOM_WIDTH:
1208 			case CSS_PROP_BORDER_LEFT_WIDTH:
1209 			case CSS_PROP_COLUMN_RULE_WIDTH:
1210 			case CSS_PROP_OUTLINE_WIDTH:
1211 				assert(BORDER_WIDTH_SET ==
1212 						(enum op_border_width)
1213 						OUTLINE_WIDTH_SET);
1214 				assert(BORDER_WIDTH_THIN ==
1215 						(enum op_border_width)
1216 						OUTLINE_WIDTH_THIN);
1217 				assert(BORDER_WIDTH_MEDIUM ==
1218 						(enum op_border_width)
1219 						OUTLINE_WIDTH_MEDIUM);
1220 				assert(BORDER_WIDTH_THICK ==
1221 						(enum op_border_width)
1222 						OUTLINE_WIDTH_THICK);
1223 
1224 				switch (value) {
1225 				case BORDER_WIDTH_SET:
1226 				{
1227 					uint32_t unit;
1228 					css_fixed val = *((css_fixed *) bytecode);
1229 					ADVANCE(sizeof(val));
1230 					unit = *((uint32_t *) bytecode);
1231 					ADVANCE(sizeof(unit));
1232 					dump_unit(val, unit, ptr);
1233 				}
1234 					break;
1235 				case BORDER_WIDTH_THIN:
1236 					*ptr += sprintf(*ptr, "thin");
1237 					break;
1238 				case BORDER_WIDTH_MEDIUM:
1239 					*ptr += sprintf(*ptr, "medium");
1240 					break;
1241 				case BORDER_WIDTH_THICK:
1242 					*ptr += sprintf(*ptr, "thick");
1243 					break;
1244 				}
1245 				break;
1246 			case CSS_PROP_MARGIN_TOP:
1247 			case CSS_PROP_MARGIN_RIGHT:
1248 			case CSS_PROP_MARGIN_BOTTOM:
1249 			case CSS_PROP_MARGIN_LEFT:
1250 			case CSS_PROP_BOTTOM:
1251 			case CSS_PROP_LEFT:
1252 			case CSS_PROP_RIGHT:
1253 			case CSS_PROP_TOP:
1254 			case CSS_PROP_HEIGHT:
1255 			case CSS_PROP_WIDTH:
1256 			case CSS_PROP_COLUMN_WIDTH:
1257 				assert(BOTTOM_SET ==
1258 						(enum op_bottom) LEFT_SET);
1259 				assert(BOTTOM_AUTO ==
1260 						(enum op_bottom) LEFT_AUTO);
1261 				assert(BOTTOM_SET ==
1262 						(enum op_bottom) RIGHT_SET);
1263 				assert(BOTTOM_AUTO ==
1264 						(enum op_bottom) RIGHT_AUTO);
1265 				assert(BOTTOM_SET ==
1266 						(enum op_bottom) TOP_SET);
1267 				assert(BOTTOM_AUTO ==
1268 						(enum op_bottom) TOP_AUTO);
1269 				assert(BOTTOM_SET ==
1270 						(enum op_bottom) HEIGHT_SET);
1271 				assert(BOTTOM_AUTO ==
1272 						(enum op_bottom) HEIGHT_AUTO);
1273 				assert(BOTTOM_SET ==
1274 						(enum op_bottom) MARGIN_SET);
1275 				assert(BOTTOM_AUTO ==
1276 						(enum op_bottom) MARGIN_AUTO);
1277 				assert(BOTTOM_SET ==
1278 						(enum op_bottom) WIDTH_SET);
1279 				assert(BOTTOM_AUTO ==
1280 						(enum op_bottom) WIDTH_AUTO);
1281 				assert(BOTTOM_SET ==
1282 						(enum op_bottom)
1283 							COLUMN_WIDTH_SET);
1284 				assert(BOTTOM_AUTO ==
1285 						(enum op_bottom)
1286 							COLUMN_WIDTH_AUTO);
1287 
1288 				switch (value) {
1289 				case BOTTOM_SET:
1290 				{
1291 					uint32_t unit;
1292 					css_fixed val = *((css_fixed *) bytecode);
1293 					ADVANCE(sizeof(val));
1294 					unit = *((uint32_t *) bytecode);
1295 					ADVANCE(sizeof(unit));
1296 					dump_unit(val, unit, ptr);
1297 				}
1298 					break;
1299 				case BOTTOM_AUTO:
1300 					*ptr += sprintf(*ptr, "auto");
1301 					break;
1302 				}
1303 				break;
1304 			case CSS_PROP_BREAK_AFTER:
1305 			case CSS_PROP_BREAK_BEFORE:
1306 				assert(BREAK_AFTER_AUTO ==
1307 						(enum op_break_after)
1308 						BREAK_BEFORE_AUTO);
1309 				assert(BREAK_AFTER_ALWAYS ==
1310 						(enum op_break_after)
1311 						BREAK_BEFORE_ALWAYS);
1312 				assert(BREAK_AFTER_AVOID ==
1313 						(enum op_break_after)
1314 						BREAK_BEFORE_AVOID);
1315 				assert(BREAK_AFTER_LEFT ==
1316 						(enum op_break_after)
1317 						BREAK_BEFORE_LEFT);
1318 				assert(BREAK_AFTER_RIGHT ==
1319 						(enum op_break_after)
1320 						BREAK_BEFORE_RIGHT);
1321 				assert(BREAK_AFTER_PAGE ==
1322 						(enum op_break_after)
1323 						BREAK_BEFORE_PAGE);
1324 				assert(BREAK_AFTER_COLUMN ==
1325 						(enum op_break_after)
1326 						BREAK_BEFORE_COLUMN);
1327 				assert(BREAK_AFTER_AVOID_PAGE ==
1328 						(enum op_break_after)
1329 						BREAK_BEFORE_AVOID_PAGE);
1330 				assert(BREAK_AFTER_AVOID_COLUMN ==
1331 						(enum op_break_after)
1332 						BREAK_BEFORE_AVOID_COLUMN);
1333 
1334 				switch (value) {
1335 				case BREAK_AFTER_AUTO:
1336 					*ptr += sprintf(*ptr, "auto");
1337 					break;
1338 				case BREAK_AFTER_ALWAYS:
1339 					*ptr += sprintf(*ptr, "always");
1340 					break;
1341 				case BREAK_AFTER_AVOID:
1342 					*ptr += sprintf(*ptr, "avoid");
1343 					break;
1344 				case BREAK_AFTER_LEFT:
1345 					*ptr += sprintf(*ptr, "left");
1346 					break;
1347 				case BREAK_AFTER_RIGHT:
1348 					*ptr += sprintf(*ptr, "right");
1349 					break;
1350 				case BREAK_AFTER_PAGE:
1351 					*ptr += sprintf(*ptr, "page");
1352 					break;
1353 				case BREAK_AFTER_COLUMN:
1354 					*ptr += sprintf(*ptr, "column");
1355 					break;
1356 				case BREAK_AFTER_AVOID_PAGE:
1357 					*ptr += sprintf(*ptr, "avoid-page");
1358 					break;
1359 				case BREAK_AFTER_AVOID_COLUMN:
1360 					*ptr += sprintf(*ptr, "avoid-column");
1361 					break;
1362 				}
1363 				break;
1364 			case CSS_PROP_BREAK_INSIDE:
1365 				switch (value) {
1366 				case BREAK_INSIDE_AUTO:
1367 					*ptr += sprintf(*ptr, "auto");
1368 					break;
1369 				case BREAK_INSIDE_AVOID:
1370 					*ptr += sprintf(*ptr, "avoid");
1371 					break;
1372 				case BREAK_INSIDE_AVOID_PAGE:
1373 					*ptr += sprintf(*ptr, "avoid-page");
1374 					break;
1375 				case BREAK_INSIDE_AVOID_COLUMN:
1376 					*ptr += sprintf(*ptr, "avoid-column");
1377 					break;
1378 				}
1379 				break;
1380 			case CSS_PROP_CAPTION_SIDE:
1381 				switch (value) {
1382 				case CAPTION_SIDE_TOP:
1383 					*ptr += sprintf(*ptr, "top");
1384 					break;
1385 				case CAPTION_SIDE_BOTTOM:
1386 					*ptr += sprintf(*ptr, "bottom");
1387 					break;
1388 				}
1389 				break;
1390 			case CSS_PROP_CLEAR:
1391 				switch (value) {
1392 				case CLEAR_NONE:
1393 					*ptr += sprintf(*ptr, "none");
1394 					break;
1395 				case CLEAR_LEFT:
1396 					*ptr += sprintf(*ptr, "left");
1397 					break;
1398 				case CLEAR_RIGHT:
1399 					*ptr += sprintf(*ptr, "right");
1400 					break;
1401 				case CLEAR_BOTH:
1402 					*ptr += sprintf(*ptr, "both");
1403 					break;
1404 				}
1405 				break;
1406 			case CSS_PROP_CLIP:
1407 				if ((value & CLIP_SHAPE_MASK) ==
1408 						CLIP_SHAPE_RECT) {
1409 					*ptr += sprintf(*ptr, "rect(");
1410 					if (value & CLIP_RECT_TOP_AUTO) {
1411 						*ptr += sprintf(*ptr, "auto");
1412 					} else {
1413 						uint32_t unit;
1414 						css_fixed val =
1415 							*((css_fixed *) bytecode);
1416 						ADVANCE(sizeof(val));
1417 						unit = *((uint32_t *) bytecode);
1418 						ADVANCE(sizeof(unit));
1419 						dump_unit(val, unit, ptr);
1420 					}
1421 					*ptr += sprintf(*ptr, ", ");
1422 					if (value & CLIP_RECT_RIGHT_AUTO) {
1423 						*ptr += sprintf(*ptr, "auto");
1424 					} else {
1425 						uint32_t unit;
1426 						css_fixed val =
1427 							*((css_fixed *) bytecode);
1428 						ADVANCE(sizeof(val));
1429 						unit = *((uint32_t *) bytecode);
1430 						ADVANCE(sizeof(unit));
1431 						dump_unit(val, unit, ptr);
1432 					}
1433 					*ptr += sprintf(*ptr, ", ");
1434 					if (value & CLIP_RECT_BOTTOM_AUTO) {
1435 						*ptr += sprintf(*ptr, "auto");
1436 					} else {
1437 						uint32_t unit;
1438 						css_fixed val =
1439 							*((css_fixed *) bytecode);
1440 						ADVANCE(sizeof(val));
1441 						unit = *((uint32_t *) bytecode);
1442 						ADVANCE(sizeof(unit));
1443 						dump_unit(val, unit, ptr);
1444 					}
1445 					*ptr += sprintf(*ptr, ", ");
1446 					if (value & CLIP_RECT_LEFT_AUTO) {
1447 						*ptr += sprintf(*ptr, "auto");
1448 					} else {
1449 						uint32_t unit;
1450 						css_fixed val =
1451 							*((css_fixed *) bytecode);
1452 						ADVANCE(sizeof(val));
1453 						unit = *((uint32_t *) bytecode);
1454 						ADVANCE(sizeof(unit));
1455 						dump_unit(val, unit, ptr);
1456 					}
1457 					*ptr += sprintf(*ptr, ")");
1458 				} else
1459 					*ptr += sprintf(*ptr, "auto");
1460 				break;
1461 			case CSS_PROP_COLOR:
1462 				switch (value) {
1463 				case COLOR_TRANSPARENT:
1464 					*ptr += sprintf(*ptr, "transparent");
1465 					break;
1466 				case COLOR_CURRENT_COLOR:
1467 					*ptr += sprintf(*ptr, "currentColor");
1468 					break;
1469 				case COLOR_SET:
1470 				{
1471 					uint32_t colour =
1472 						*((uint32_t *) bytecode);
1473 					ADVANCE(sizeof(colour));
1474 					*ptr += sprintf(*ptr, "#%08x", colour);
1475 				}
1476 					break;
1477 				}
1478 				break;
1479 			case CSS_PROP_COLUMN_COUNT:
1480 				switch (value) {
1481 				case COLUMN_COUNT_SET:
1482 				{
1483 					css_fixed val = *((css_fixed *) bytecode);
1484 					ADVANCE(sizeof(val));
1485 					dump_number(val, ptr);
1486 				}
1487 					break;
1488 				case COLUMN_COUNT_AUTO:
1489 					*ptr += sprintf(*ptr, "auto");
1490 					break;
1491 				}
1492 				break;
1493 			case CSS_PROP_COLUMN_FILL:
1494 				switch (value) {
1495 				case COLUMN_FILL_BALANCE:
1496 					*ptr += sprintf(*ptr, "balance");
1497 					break;
1498 				case COLUMN_FILL_AUTO:
1499 					*ptr += sprintf(*ptr, "auto");
1500 					break;
1501 				}
1502 				break;
1503 			case CSS_PROP_COLUMN_GAP:
1504 				switch (value) {
1505 				case COLUMN_GAP_SET:
1506 				{
1507 					uint32_t unit;
1508 					css_fixed val = *((css_fixed *) bytecode);
1509 					ADVANCE(sizeof(val));
1510 					unit = *((uint32_t *) bytecode);
1511 					ADVANCE(sizeof(unit));
1512 					dump_unit(val, unit, ptr);
1513 				}
1514 					break;
1515 				case COLUMN_GAP_NORMAL:
1516 					*ptr += sprintf(*ptr, "normal");
1517 					break;
1518 				}
1519 				break;
1520 			case CSS_PROP_COLUMN_SPAN:
1521 				switch (value) {
1522 				case COLUMN_SPAN_NONE:
1523 					*ptr += sprintf(*ptr, "none");
1524 					break;
1525 				case COLUMN_SPAN_ALL:
1526 					*ptr += sprintf(*ptr, "all");
1527 					break;
1528 				}
1529 				break;
1530 			case CSS_PROP_CONTENT:
1531 				if (value == CONTENT_NORMAL) {
1532 					*ptr += sprintf(*ptr, "normal");
1533 					break;
1534 				} else if (value == CONTENT_NONE) {
1535 					*ptr += sprintf(*ptr, "none");
1536 					break;
1537 				}
1538 
1539 				while (value != CONTENT_NORMAL) {
1540 					uint32_t snum = *((uint32_t *) bytecode);
1541 					lwc_string *he;
1542 					const char *end = "";
1543 
1544 					switch (value & 0xff) {
1545 					case CONTENT_COUNTER:
1546 						css__stylesheet_string_get(style->sheet, snum, &he);
1547 						ADVANCE(sizeof(snum));
1548 						dump_counter(he, value, ptr);
1549 						break;
1550 
1551 					case CONTENT_COUNTERS:
1552 					{
1553 						lwc_string *sep;
1554 						css__stylesheet_string_get(style->sheet, snum, &he);
1555 						ADVANCE(sizeof(snum));
1556 
1557 						sep = *((lwc_string **) bytecode);
1558 						ADVANCE(sizeof(sep));
1559 
1560 						dump_counters(he, sep, value,
1561 							ptr);
1562 					}
1563 						break;
1564 
1565 					case CONTENT_URI:
1566 					case CONTENT_ATTR:
1567 					case CONTENT_STRING:
1568 						css__stylesheet_string_get(style->sheet, snum, &he);
1569 						if (value == CONTENT_URI)
1570 							*ptr += sprintf(*ptr, "url(");
1571 						if (value == CONTENT_ATTR)
1572 							*ptr += sprintf(*ptr, "attr(");
1573 						if (value != CONTENT_STRING)
1574 							end = ")";
1575 
1576 						ADVANCE(sizeof(snum));
1577 
1578 						*ptr += sprintf(*ptr, "'%.*s'%s",
1579                                                                 (int) lwc_string_length(he),
1580                                                                 lwc_string_data(he),
1581 							end);
1582 						break;
1583 
1584 					case CONTENT_OPEN_QUOTE:
1585 						*ptr += sprintf(*ptr, "open-quote");
1586 						break;
1587 
1588 					case CONTENT_CLOSE_QUOTE:
1589 						*ptr += sprintf(*ptr, "close-quote");
1590 						break;
1591 
1592 					case CONTENT_NO_OPEN_QUOTE:
1593 						*ptr += sprintf(*ptr, "no-open-quote");
1594 						break;
1595 
1596 					case CONTENT_NO_CLOSE_QUOTE:
1597 						*ptr += sprintf(*ptr, "no-close-quote");
1598 						break;
1599 					}
1600 
1601 					value = *((uint32_t *) bytecode);
1602 					ADVANCE(sizeof(value));
1603 
1604 					if (value != CONTENT_NORMAL)
1605 						*ptr += sprintf(*ptr, " ");
1606 				}
1607 				break;
1608 			case CSS_PROP_COUNTER_INCREMENT:
1609 			case CSS_PROP_COUNTER_RESET:
1610 				assert(COUNTER_INCREMENT_NONE ==
1611 						(enum op_counter_increment)
1612 						COUNTER_RESET_NONE);
1613 				assert(COUNTER_INCREMENT_NAMED ==
1614 						(enum op_counter_increment)
1615 						COUNTER_RESET_NAMED);
1616 
1617 				switch (value) {
1618 				case COUNTER_INCREMENT_NAMED:
1619 					while (value != COUNTER_INCREMENT_NONE) {
1620 						css_fixed val;
1621 					uint32_t snum = *((uint32_t *) bytecode);					lwc_string *he;
1622 					css__stylesheet_string_get(style->sheet,
1623 								  snum,
1624 								  &he);
1625 						ADVANCE(sizeof(snum));
1626 						*ptr += sprintf(*ptr, "%.*s ",
1627                                                                 (int)lwc_string_length(he),
1628                                                                 lwc_string_data(he));
1629 						val = *((css_fixed *) bytecode);
1630 						ADVANCE(sizeof(val));
1631 						dump_number(val, ptr);
1632 
1633 						value = *((uint32_t *) bytecode);
1634 						ADVANCE(sizeof(value));
1635 
1636 						if (value !=
1637 							COUNTER_INCREMENT_NONE)
1638 							*ptr += sprintf(*ptr,
1639 									" ");
1640 					}
1641 					break;
1642 				case COUNTER_INCREMENT_NONE:
1643 					*ptr += sprintf(*ptr, "none");
1644 					break;
1645 				}
1646 				break;
1647 			case CSS_PROP_CURSOR:
1648 				while (value == CURSOR_URI) {
1649 					uint32_t snum = *((uint32_t *) bytecode);					lwc_string *he;
1650 					css__stylesheet_string_get(style->sheet,
1651 								  snum,
1652 								  &he);
1653 					ADVANCE(sizeof(snum));
1654 					*ptr += sprintf(*ptr, "url('%.*s'), ",
1655 							(int) lwc_string_length(he),
1656 							lwc_string_data(he));
1657 
1658 					value = *((uint32_t *) bytecode);
1659 					ADVANCE(sizeof(value));
1660 				}
1661 
1662 				switch (value) {
1663 				case CURSOR_AUTO:
1664 					*ptr += sprintf(*ptr, "auto");
1665 					break;
1666 				case CURSOR_CROSSHAIR:
1667 					*ptr += sprintf(*ptr, "crosshair");
1668 					break;
1669 				case CURSOR_DEFAULT:
1670 					*ptr += sprintf(*ptr, "default");
1671 					break;
1672 				case CURSOR_POINTER:
1673 					*ptr += sprintf(*ptr, "pointer");
1674 					break;
1675 				case CURSOR_MOVE:
1676 					*ptr += sprintf(*ptr, "move");
1677 					break;
1678 				case CURSOR_E_RESIZE:
1679 					*ptr += sprintf(*ptr, "e-resize");
1680 					break;
1681 				case CURSOR_NE_RESIZE:
1682 					*ptr += sprintf(*ptr, "ne-resize");
1683 					break;
1684 				case CURSOR_NW_RESIZE:
1685 					*ptr += sprintf(*ptr, "nw-resize");
1686 					break;
1687 				case CURSOR_N_RESIZE:
1688 					*ptr += sprintf(*ptr, "n-resize");
1689 					break;
1690 				case CURSOR_SE_RESIZE:
1691 					*ptr += sprintf(*ptr, "se-resize");
1692 					break;
1693 				case CURSOR_SW_RESIZE:
1694 					*ptr += sprintf(*ptr, "sw-resize");
1695 					break;
1696 				case CURSOR_S_RESIZE:
1697 					*ptr += sprintf(*ptr, "s-resize");
1698 					break;
1699 				case CURSOR_W_RESIZE:
1700 					*ptr += sprintf(*ptr, "w-resize");
1701 					break;
1702 				case CURSOR_TEXT:
1703 					*ptr += sprintf(*ptr, "text");
1704 					break;
1705 				case CURSOR_WAIT:
1706 					*ptr += sprintf(*ptr, "wait");
1707 					break;
1708 				case CURSOR_HELP:
1709 					*ptr += sprintf(*ptr, "help");
1710 					break;
1711 				case CURSOR_PROGRESS:
1712 					*ptr += sprintf(*ptr, "progress");
1713 					break;
1714 				}
1715 				break;
1716 			case CSS_PROP_DIRECTION:
1717 				switch (value) {
1718 				case DIRECTION_LTR:
1719 					*ptr += sprintf(*ptr, "ltr");
1720 					break;
1721 				case DIRECTION_RTL:
1722 					*ptr += sprintf(*ptr, "rtl");
1723 					break;
1724 				}
1725 				break;
1726 			case CSS_PROP_DISPLAY:
1727 				switch (value) {
1728 				case DISPLAY_INLINE:
1729 					*ptr += sprintf(*ptr, "inline");
1730 					break;
1731 				case DISPLAY_BLOCK:
1732 					*ptr += sprintf(*ptr, "block");
1733 					break;
1734 				case DISPLAY_LIST_ITEM:
1735 					*ptr += sprintf(*ptr, "list-item");
1736 					break;
1737 				case DISPLAY_RUN_IN:
1738 					*ptr += sprintf(*ptr, "run-in");
1739 					break;
1740 				case DISPLAY_INLINE_BLOCK:
1741 					*ptr += sprintf(*ptr, "inline-block");
1742 					break;
1743 				case DISPLAY_TABLE:
1744 					*ptr += sprintf(*ptr, "table");
1745 					break;
1746 				case DISPLAY_INLINE_TABLE:
1747 					*ptr += sprintf(*ptr, "inline-table");
1748 					break;
1749 				case DISPLAY_TABLE_ROW_GROUP:
1750 					*ptr += sprintf(*ptr, "table-row-group");
1751 					break;
1752 				case DISPLAY_TABLE_HEADER_GROUP:
1753 					*ptr += sprintf(*ptr, "table-header-group");
1754 					break;
1755 				case DISPLAY_TABLE_FOOTER_GROUP:
1756 					*ptr += sprintf(*ptr, "table-footer-group");
1757 					break;
1758 				case DISPLAY_TABLE_ROW:
1759 					*ptr += sprintf(*ptr, "table-row");
1760 					break;
1761 				case DISPLAY_TABLE_COLUMN_GROUP:
1762 					*ptr += sprintf(*ptr, "table-column-group");
1763 					break;
1764 				case DISPLAY_TABLE_COLUMN:
1765 					*ptr += sprintf(*ptr, "table-column");
1766 					break;
1767 				case DISPLAY_TABLE_CELL:
1768 					*ptr += sprintf(*ptr, "table-cell");
1769 					break;
1770 				case DISPLAY_TABLE_CAPTION:
1771 					*ptr += sprintf(*ptr, "table-caption");
1772 					break;
1773 				case DISPLAY_NONE:
1774 					*ptr += sprintf(*ptr, "none");
1775 					break;
1776 				case DISPLAY_FLEX:
1777 					*ptr += sprintf(*ptr, "flex");
1778 					break;
1779 				case DISPLAY_INLINE_FLEX:
1780 					*ptr += sprintf(*ptr, "inline-flex");
1781 					break;
1782 				}
1783 				break;
1784 			case CSS_PROP_ELEVATION:
1785 				switch (value) {
1786 				case ELEVATION_ANGLE:
1787 				{
1788 					uint32_t unit;
1789 					css_fixed val = *((css_fixed *) bytecode);
1790 					ADVANCE(sizeof(val));
1791 					unit = *((uint32_t *) bytecode);
1792 					ADVANCE(sizeof(unit));
1793 					dump_unit(val, unit, ptr);
1794 				}
1795 					break;
1796 				case ELEVATION_BELOW:
1797 					*ptr += sprintf(*ptr, "below");
1798 					break;
1799 				case ELEVATION_LEVEL:
1800 					*ptr += sprintf(*ptr, "level");
1801 					break;
1802 				case ELEVATION_ABOVE:
1803 					*ptr += sprintf(*ptr, "above");
1804 					break;
1805 				case ELEVATION_HIGHER:
1806 					*ptr += sprintf(*ptr, "higher");
1807 					break;
1808 				case ELEVATION_LOWER:
1809 					*ptr += sprintf(*ptr, "lower");
1810 					break;
1811 				}
1812 				break;
1813 			case CSS_PROP_EMPTY_CELLS:
1814 				switch (value) {
1815 				case EMPTY_CELLS_SHOW:
1816 					*ptr += sprintf(*ptr, "show");
1817 					break;
1818 				case EMPTY_CELLS_HIDE:
1819 					*ptr += sprintf(*ptr, "hide");
1820 					break;
1821 				}
1822 				break;
1823 			case CSS_PROP_FLEX_BASIS:
1824 				switch (value) {
1825 				case FLEX_BASIS_AUTO:
1826 					*ptr += sprintf(*ptr, "auto");
1827 					break;
1828 				case FLEX_BASIS_CONTENT:
1829 					*ptr += sprintf(*ptr, "content");
1830 					break;
1831 				case FLEX_BASIS_SET:
1832 				{
1833 					uint32_t unit;
1834 					css_fixed val = *((css_fixed *) bytecode);
1835 					ADVANCE(sizeof(val));
1836 					unit = *((uint32_t *) bytecode);
1837 					ADVANCE(sizeof(unit));
1838 					dump_unit(val, unit, ptr);
1839 				}
1840 					break;
1841 				}
1842 				break;
1843 			case CSS_PROP_FLEX_DIRECTION:
1844 				switch (value) {
1845 				case FLEX_DIRECTION_ROW:
1846 					*ptr += sprintf(*ptr, "row");
1847 					break;
1848 				case FLEX_DIRECTION_COLUMN:
1849 					*ptr += sprintf(*ptr, "column");
1850 					break;
1851 				case FLEX_DIRECTION_ROW_REVERSE:
1852 					*ptr += sprintf(*ptr, "row-reverse");
1853 					break;
1854 				case FLEX_DIRECTION_COLUMN_REVERSE:
1855 					*ptr += sprintf(*ptr, "column-reverse");
1856 					break;
1857 				}
1858 				break;
1859 			case CSS_PROP_FLEX_GROW:
1860 				switch (value) {
1861 				case FLEX_GROW_SET:
1862 				{
1863 					css_fixed val = *((css_fixed *) bytecode);
1864 					ADVANCE(sizeof(val));
1865 					dump_number(val, ptr);
1866 				}
1867 					break;
1868 				}
1869 				break;
1870 			case CSS_PROP_FLEX_SHRINK:
1871 				switch (value) {
1872 				case FLEX_SHRINK_SET:
1873 				{
1874 					css_fixed val = *((css_fixed *) bytecode);
1875 					ADVANCE(sizeof(val));
1876 					dump_number(val, ptr);
1877 				}
1878 					break;
1879 				}
1880 				break;
1881 			case CSS_PROP_FLEX_WRAP:
1882 				switch (value) {
1883 				case FLEX_WRAP_NOWRAP:
1884 					*ptr += sprintf(*ptr, "nowrap");
1885 					break;
1886 				case FLEX_WRAP_WRAP:
1887 					*ptr += sprintf(*ptr, "wrap");
1888 					break;
1889 				case FLEX_WRAP_WRAP_REVERSE:
1890 					*ptr += sprintf(*ptr, "wrap-reverse");
1891 					break;
1892 				}
1893 				break;
1894 			case CSS_PROP_FLOAT:
1895 				switch (value) {
1896 				case FLOAT_LEFT:
1897 					*ptr += sprintf(*ptr, "left");
1898 					break;
1899 				case FLOAT_RIGHT:
1900 					*ptr += sprintf(*ptr, "right");
1901 					break;
1902 				case FLOAT_NONE:
1903 					*ptr += sprintf(*ptr, "none");
1904 					break;
1905 				}
1906 				break;
1907 			case CSS_PROP_FONT_FAMILY:
1908 				while (value != FONT_FAMILY_END) {
1909 					switch (value) {
1910 					case FONT_FAMILY_STRING:
1911 					case FONT_FAMILY_IDENT_LIST:
1912 					{
1913 						uint32_t snum = *((uint32_t *) bytecode);
1914 						lwc_string *he;
1915 						css__stylesheet_string_get(style->sheet, snum, &he);
1916 						ADVANCE(sizeof(snum));
1917 						*ptr += sprintf(*ptr, "'%.*s'",
1918                                                                 (int) lwc_string_length(he),
1919                                                                 lwc_string_data(he));
1920 					}
1921 						break;
1922 					case FONT_FAMILY_SERIF:
1923 						*ptr += sprintf(*ptr, "serif");
1924 						break;
1925 					case FONT_FAMILY_SANS_SERIF:
1926 						*ptr += sprintf(*ptr, "sans-serif");
1927 						break;
1928 					case FONT_FAMILY_CURSIVE:
1929 						*ptr += sprintf(*ptr, "cursive");
1930 						break;
1931 					case FONT_FAMILY_FANTASY:
1932 						*ptr += sprintf(*ptr, "fantasy");
1933 						break;
1934 					case FONT_FAMILY_MONOSPACE:
1935 						*ptr += sprintf(*ptr, "monospace");
1936 						break;
1937 					}
1938 
1939 					value = *((uint32_t *) bytecode);
1940 					ADVANCE(sizeof(value));
1941 
1942 					if (value != FONT_FAMILY_END)
1943 						*ptr += sprintf(*ptr, ", ");
1944 				}
1945 				break;
1946 			case CSS_PROP_FONT_SIZE:
1947 				switch (value) {
1948 				case FONT_SIZE_DIMENSION:
1949 				{
1950 					uint32_t unit;
1951 					css_fixed val = *((css_fixed *) bytecode);
1952 					ADVANCE(sizeof(val));
1953 					unit = *((uint32_t *) bytecode);
1954 					ADVANCE(sizeof(unit));
1955 					dump_unit(val, unit, ptr);
1956 				}
1957 					break;
1958 				case FONT_SIZE_XX_SMALL:
1959 					*ptr += sprintf(*ptr, "xx-small");
1960 					break;
1961 				case FONT_SIZE_X_SMALL:
1962 					*ptr += sprintf(*ptr, "x-small");
1963 					break;
1964 				case FONT_SIZE_SMALL:
1965 					*ptr += sprintf(*ptr, "small");
1966 					break;
1967 				case FONT_SIZE_MEDIUM:
1968 					*ptr += sprintf(*ptr, "medium");
1969 					break;
1970 				case FONT_SIZE_LARGE:
1971 					*ptr += sprintf(*ptr, "large");
1972 					break;
1973 				case FONT_SIZE_X_LARGE:
1974 					*ptr += sprintf(*ptr, "x-large");
1975 					break;
1976 				case FONT_SIZE_XX_LARGE:
1977 					*ptr += sprintf(*ptr, "xx-large");
1978 					break;
1979 				case FONT_SIZE_LARGER:
1980 					*ptr += sprintf(*ptr, "larger");
1981 					break;
1982 				case FONT_SIZE_SMALLER:
1983 					*ptr += sprintf(*ptr, "smaller");
1984 					break;
1985 				}
1986 				break;
1987 			case CSS_PROP_FONT_STYLE:
1988 				switch (value) {
1989 				case FONT_STYLE_NORMAL:
1990 					*ptr += sprintf(*ptr, "normal");
1991 					break;
1992 				case FONT_STYLE_ITALIC:
1993 					*ptr += sprintf(*ptr, "italic");
1994 					break;
1995 				case FONT_STYLE_OBLIQUE:
1996 					*ptr += sprintf(*ptr, "oblique");
1997 					break;
1998 				}
1999 				break;
2000 			case CSS_PROP_FONT_VARIANT:
2001 				switch (value) {
2002 				case FONT_VARIANT_NORMAL:
2003 					*ptr += sprintf(*ptr, "normal");
2004 					break;
2005 				case FONT_VARIANT_SMALL_CAPS:
2006 					*ptr += sprintf(*ptr, "small-caps");
2007 					break;
2008 				}
2009 				break;
2010 			case CSS_PROP_FONT_WEIGHT:
2011 				switch (value) {
2012 				case FONT_WEIGHT_NORMAL:
2013 					*ptr += sprintf(*ptr, "normal");
2014 					break;
2015 				case FONT_WEIGHT_BOLD:
2016 					*ptr += sprintf(*ptr, "bold");
2017 					break;
2018 				case FONT_WEIGHT_BOLDER:
2019 					*ptr += sprintf(*ptr, "bolder");
2020 					break;
2021 				case FONT_WEIGHT_LIGHTER:
2022 					*ptr += sprintf(*ptr, "lighter");
2023 					break;
2024 				case FONT_WEIGHT_100:
2025 					*ptr += sprintf(*ptr, "100");
2026 					break;
2027 				case FONT_WEIGHT_200:
2028 					*ptr += sprintf(*ptr, "200");
2029 					break;
2030 				case FONT_WEIGHT_300:
2031 					*ptr += sprintf(*ptr, "300");
2032 					break;
2033 				case FONT_WEIGHT_400:
2034 					*ptr += sprintf(*ptr, "400");
2035 					break;
2036 				case FONT_WEIGHT_500:
2037 					*ptr += sprintf(*ptr, "500");
2038 					break;
2039 				case FONT_WEIGHT_600:
2040 					*ptr += sprintf(*ptr, "600");
2041 					break;
2042 				case FONT_WEIGHT_700:
2043 					*ptr += sprintf(*ptr, "700");
2044 					break;
2045 				case FONT_WEIGHT_800:
2046 					*ptr += sprintf(*ptr, "800");
2047 					break;
2048 				case FONT_WEIGHT_900:
2049 					*ptr += sprintf(*ptr, "900");
2050 					break;
2051 				}
2052 				break;
2053 			case CSS_PROP_JUSTIFY_CONTENT:
2054 				switch (value) {
2055 				case JUSTIFY_CONTENT_FLEX_START:
2056 					*ptr += sprintf(*ptr, "flex-start");
2057 					break;
2058 				case JUSTIFY_CONTENT_FLEX_END:
2059 					*ptr += sprintf(*ptr, "flex-end");
2060 					break;
2061 				case JUSTIFY_CONTENT_CENTER:
2062 					*ptr += sprintf(*ptr, "center");
2063 					break;
2064 				case JUSTIFY_CONTENT_SPACE_BETWEEN:
2065 					*ptr += sprintf(*ptr, "space-between");
2066 					break;
2067 				case JUSTIFY_CONTENT_SPACE_AROUND:
2068 					*ptr += sprintf(*ptr, "space-around");
2069 					break;
2070 				case JUSTIFY_CONTENT_SPACE_EVENLY:
2071 					*ptr += sprintf(*ptr, "space-evenly");
2072 					break;
2073 				}
2074 				break;
2075 
2076 			case CSS_PROP_LETTER_SPACING:
2077 			case CSS_PROP_WORD_SPACING:
2078 				assert(LETTER_SPACING_SET ==
2079 						(enum op_letter_spacing)
2080 						WORD_SPACING_SET);
2081 				assert(LETTER_SPACING_NORMAL ==
2082 						(enum op_letter_spacing)
2083 						WORD_SPACING_NORMAL);
2084 
2085 				switch (value) {
2086 				case LETTER_SPACING_SET:
2087 				{
2088 					uint32_t unit;
2089 					css_fixed val = *((css_fixed *) bytecode);
2090 					ADVANCE(sizeof(val));
2091 					unit = *((uint32_t *) bytecode);
2092 					ADVANCE(sizeof(unit));
2093 					dump_unit(val, unit, ptr);
2094 				}
2095 					break;
2096 				case LETTER_SPACING_NORMAL:
2097 					*ptr += sprintf(*ptr, "normal");
2098 					break;
2099 				}
2100 				break;
2101 			case CSS_PROP_LINE_HEIGHT:
2102 				switch (value) {
2103 				case LINE_HEIGHT_NUMBER:
2104 				{
2105 					css_fixed val = *((css_fixed *) bytecode);
2106 					ADVANCE(sizeof(val));
2107 					dump_number(val, ptr);
2108 				}
2109 					break;
2110 				case LINE_HEIGHT_DIMENSION:
2111 				{
2112 					uint32_t unit;
2113 					css_fixed val = *((css_fixed *) bytecode);
2114 					ADVANCE(sizeof(val));
2115 					unit = *((uint32_t *) bytecode);
2116 					ADVANCE(sizeof(unit));
2117 					dump_unit(val, unit, ptr);
2118 				}
2119 					break;
2120 				case LINE_HEIGHT_NORMAL:
2121 					*ptr += sprintf(*ptr, "normal");
2122 					break;
2123 				}
2124 				break;
2125 			case CSS_PROP_LIST_STYLE_POSITION:
2126 				switch (value) {
2127 				case LIST_STYLE_POSITION_INSIDE:
2128 					*ptr += sprintf(*ptr, "inside");
2129 					break;
2130 				case LIST_STYLE_POSITION_OUTSIDE:
2131 					*ptr += sprintf(*ptr, "outside");
2132 					break;
2133 				}
2134 				break;
2135 			case CSS_PROP_LIST_STYLE_TYPE:
2136 				switch (value) {
2137 				case LIST_STYLE_TYPE_DISC:
2138 					*ptr += sprintf(*ptr, "disc");
2139 					break;
2140 				case LIST_STYLE_TYPE_CIRCLE:
2141 					*ptr += sprintf(*ptr, "circle");
2142 					break;
2143 				case LIST_STYLE_TYPE_SQUARE:
2144 					*ptr += sprintf(*ptr, "square");
2145 					break;
2146 				case LIST_STYLE_TYPE_DECIMAL:
2147 					*ptr += sprintf(*ptr, "decimal");
2148 					break;
2149 				case LIST_STYLE_TYPE_DECIMAL_LEADING_ZERO:
2150 					*ptr += sprintf(*ptr, "decimal-leading-zero");
2151 					break;
2152 				case LIST_STYLE_TYPE_LOWER_ROMAN:
2153 					*ptr += sprintf(*ptr, "lower-roman");
2154 					break;
2155 				case LIST_STYLE_TYPE_UPPER_ROMAN:
2156 					*ptr += sprintf(*ptr, "upper-roman");
2157 					break;
2158 				case LIST_STYLE_TYPE_LOWER_GREEK:
2159 					*ptr += sprintf(*ptr, "lower-greek");
2160 					break;
2161 				case LIST_STYLE_TYPE_LOWER_LATIN:
2162 					*ptr += sprintf(*ptr, "lower-latin");
2163 					break;
2164 				case LIST_STYLE_TYPE_UPPER_LATIN:
2165 					*ptr += sprintf(*ptr, "upper-latin");
2166 					break;
2167 				case LIST_STYLE_TYPE_ARMENIAN:
2168 					*ptr += sprintf(*ptr, "armenian");
2169 					break;
2170 				case LIST_STYLE_TYPE_GEORGIAN:
2171 					*ptr += sprintf(*ptr, "georgian");
2172 					break;
2173 				case LIST_STYLE_TYPE_LOWER_ALPHA:
2174 					*ptr += sprintf(*ptr, "lower-alpha");
2175 					break;
2176 				case LIST_STYLE_TYPE_UPPER_ALPHA:
2177 					*ptr += sprintf(*ptr, "upper-alpha");
2178 					break;
2179 				case LIST_STYLE_TYPE_NONE:
2180 					*ptr += sprintf(*ptr, "none");
2181 					break;
2182 				}
2183 				break;
2184 			case CSS_PROP_MAX_HEIGHT:
2185 			case CSS_PROP_MAX_WIDTH:
2186 				assert(MAX_HEIGHT_SET ==
2187 						(enum op_max_height)
2188 						MAX_WIDTH_SET);
2189 				assert(MAX_HEIGHT_NONE ==
2190 						(enum op_max_height)
2191 						MAX_WIDTH_NONE);
2192 
2193 				switch (value) {
2194 				case MAX_HEIGHT_SET:
2195 				{
2196 					uint32_t unit;
2197 					css_fixed val = *((css_fixed *) bytecode);
2198 					ADVANCE(sizeof(val));
2199 					unit = *((uint32_t *) bytecode);
2200 					ADVANCE(sizeof(unit));
2201 					dump_unit(val, unit, ptr);
2202 				}
2203 					break;
2204 				case MAX_HEIGHT_NONE:
2205 					*ptr += sprintf(*ptr, "none");
2206 					break;
2207 				}
2208 				break;
2209 			case CSS_PROP_MIN_HEIGHT:
2210 			case CSS_PROP_MIN_WIDTH:
2211 				assert(MIN_HEIGHT_SET ==
2212 						(enum op_min_height)
2213 						MIN_WIDTH_SET);
2214 				assert(MIN_HEIGHT_AUTO ==
2215 						(enum op_min_height)
2216 						MIN_WIDTH_AUTO);
2217 
2218 				switch (value) {
2219 				case MIN_HEIGHT_SET:
2220 				{
2221 					uint32_t unit;
2222 					css_fixed val = *((css_fixed *) bytecode);
2223 					ADVANCE(sizeof(val));
2224 					unit = *((uint32_t *) bytecode);
2225 					ADVANCE(sizeof(unit));
2226 					dump_unit(val, unit, ptr);
2227 				}
2228 					break;
2229 				case MIN_HEIGHT_AUTO:
2230 					*ptr += sprintf(*ptr, "auto");
2231 					break;
2232 				}
2233 				break;
2234 			case CSS_PROP_OPACITY:
2235 				switch (value) {
2236 				case OPACITY_SET:
2237 				{
2238 					css_fixed val = *((css_fixed *) bytecode);
2239 					ADVANCE(sizeof(val));
2240 					dump_number(val, ptr);
2241 				}
2242 					break;
2243 				}
2244 				break;
2245 			case CSS_PROP_ORDER:
2246 				switch (value) {
2247 				case ORDER_SET:
2248 				{
2249 					css_fixed val = *((css_fixed *) bytecode);
2250 					ADVANCE(sizeof(val));
2251 					dump_number(val, ptr);
2252 				}
2253 					break;
2254 				}
2255 				break;
2256 			case CSS_PROP_PADDING_TOP:
2257 			case CSS_PROP_PADDING_RIGHT:
2258 			case CSS_PROP_PADDING_BOTTOM:
2259 			case CSS_PROP_PADDING_LEFT:
2260 			case CSS_PROP_PAUSE_AFTER:
2261 			case CSS_PROP_PAUSE_BEFORE:
2262 			case CSS_PROP_TEXT_INDENT:
2263 				assert(TEXT_INDENT_SET ==
2264 						(enum op_text_indent)
2265 						PADDING_SET);
2266 				assert(TEXT_INDENT_SET ==
2267 						(enum op_text_indent)
2268 						PAUSE_AFTER_SET);
2269 				assert(TEXT_INDENT_SET ==
2270 						(enum op_text_indent)
2271 						PAUSE_BEFORE_SET);
2272 
2273 				switch (value) {
2274 				case TEXT_INDENT_SET:
2275 				{
2276 					uint32_t unit;
2277 					css_fixed val = *((css_fixed *) bytecode);
2278 					ADVANCE(sizeof(val));
2279 					unit = *((uint32_t *) bytecode);
2280 					ADVANCE(sizeof(unit));
2281 					dump_unit(val, unit, ptr);
2282 				}
2283 					break;
2284 				}
2285 				break;
2286 			case CSS_PROP_ORPHANS:
2287 			case CSS_PROP_PITCH_RANGE:
2288 			case CSS_PROP_RICHNESS:
2289 			case CSS_PROP_STRESS:
2290 			case CSS_PROP_WIDOWS:
2291 				assert(ORPHANS_SET ==
2292 						(enum op_orphans)
2293 						PITCH_RANGE_SET);
2294 				assert(ORPHANS_SET ==
2295 						(enum op_orphans)
2296 						RICHNESS_SET);
2297 				assert(ORPHANS_SET ==
2298 						(enum op_orphans)
2299 						STRESS_SET);
2300 				assert(ORPHANS_SET ==
2301 						(enum op_orphans)
2302 						WIDOWS_SET);
2303 
2304 				switch (value) {
2305 				case ORPHANS_SET:
2306 				{
2307 					css_fixed val = *((css_fixed *) bytecode);
2308 					ADVANCE(sizeof(val));
2309 					dump_number(val, ptr);
2310 				}
2311 					break;
2312 				}
2313 				break;
2314 			case CSS_PROP_OUTLINE_COLOR:
2315 				switch (value) {
2316 				case OUTLINE_COLOR_TRANSPARENT:
2317 					*ptr += sprintf(*ptr, "transparent");
2318 					break;
2319 				case OUTLINE_COLOR_CURRENT_COLOR:
2320 					*ptr += sprintf(*ptr, "currentColor");
2321 					break;
2322 				case OUTLINE_COLOR_SET:
2323 				{
2324 					uint32_t colour =
2325 						*((uint32_t *) bytecode);
2326 					ADVANCE(sizeof(colour));
2327 					*ptr += sprintf(*ptr, "#%08x", colour);
2328 				}
2329 					break;
2330 				case OUTLINE_COLOR_INVERT:
2331 					*ptr += sprintf(*ptr, "invert");
2332 					break;
2333 				}
2334 				break;
2335 			case CSS_PROP_OVERFLOW_X:
2336 			case CSS_PROP_OVERFLOW_Y:
2337 				switch (value) {
2338 				case OVERFLOW_VISIBLE:
2339 					*ptr += sprintf(*ptr, "visible");
2340 					break;
2341 				case OVERFLOW_HIDDEN:
2342 					*ptr += sprintf(*ptr, "hidden");
2343 					break;
2344 				case OVERFLOW_SCROLL:
2345 					*ptr += sprintf(*ptr, "scroll");
2346 					break;
2347 				case OVERFLOW_AUTO:
2348 					*ptr += sprintf(*ptr, "auto");
2349 					break;
2350 				}
2351 				break;
2352 			case CSS_PROP_PAGE_BREAK_AFTER:
2353 			case CSS_PROP_PAGE_BREAK_BEFORE:
2354 				assert(PAGE_BREAK_AFTER_AUTO ==
2355 						(enum op_page_break_after)
2356 						PAGE_BREAK_BEFORE_AUTO);
2357 				assert(PAGE_BREAK_AFTER_ALWAYS ==
2358 						(enum op_page_break_after)
2359 						PAGE_BREAK_BEFORE_ALWAYS);
2360 				assert(PAGE_BREAK_AFTER_AVOID ==
2361 						(enum op_page_break_after)
2362 						PAGE_BREAK_BEFORE_AVOID);
2363 				assert(PAGE_BREAK_AFTER_LEFT ==
2364 						(enum op_page_break_after)
2365 						PAGE_BREAK_BEFORE_LEFT);
2366 				assert(PAGE_BREAK_AFTER_RIGHT ==
2367 						(enum op_page_break_after)
2368 						PAGE_BREAK_BEFORE_RIGHT);
2369 
2370 				switch (value) {
2371 				case PAGE_BREAK_AFTER_AUTO:
2372 					*ptr += sprintf(*ptr, "auto");
2373 					break;
2374 				case PAGE_BREAK_AFTER_ALWAYS:
2375 					*ptr += sprintf(*ptr, "always");
2376 					break;
2377 				case PAGE_BREAK_AFTER_AVOID:
2378 					*ptr += sprintf(*ptr, "avoid");
2379 					break;
2380 				case PAGE_BREAK_AFTER_LEFT:
2381 					*ptr += sprintf(*ptr, "left");
2382 					break;
2383 				case PAGE_BREAK_AFTER_RIGHT:
2384 					*ptr += sprintf(*ptr, "right");
2385 					break;
2386 				}
2387 				break;
2388 			case CSS_PROP_PAGE_BREAK_INSIDE:
2389 				switch (value) {
2390 				case PAGE_BREAK_INSIDE_AUTO:
2391 					*ptr += sprintf(*ptr, "auto");
2392 					break;
2393 				case PAGE_BREAK_INSIDE_AVOID:
2394 					*ptr += sprintf(*ptr, "avoid");
2395 					break;
2396 				}
2397 				break;
2398 			case CSS_PROP_PITCH:
2399 				switch (value) {
2400 				case PITCH_FREQUENCY:
2401 				{
2402 					uint32_t unit;
2403 					css_fixed val = *((css_fixed *) bytecode);
2404 					ADVANCE(sizeof(val));
2405 					unit = *((uint32_t *) bytecode);
2406 					ADVANCE(sizeof(unit));
2407 					dump_unit(val, unit, ptr);
2408 				}
2409 					break;
2410 				case PITCH_X_LOW:
2411 					*ptr += sprintf(*ptr, "x-low");
2412 					break;
2413 				case PITCH_LOW:
2414 					*ptr += sprintf(*ptr, "low");
2415 					break;
2416 				case PITCH_MEDIUM:
2417 					*ptr += sprintf(*ptr, "medium");
2418 					break;
2419 				case PITCH_HIGH:
2420 					*ptr += sprintf(*ptr, "high");
2421 					break;
2422 				case PITCH_X_HIGH:
2423 					*ptr += sprintf(*ptr, "x-high");
2424 					break;
2425 				}
2426 				break;
2427 			case CSS_PROP_PLAY_DURING:
2428 				switch (value) {
2429 				case PLAY_DURING_URI:
2430 				{
2431 					uint32_t snum = *((uint32_t *) bytecode);
2432 					lwc_string *he;
2433 					css__stylesheet_string_get(style->sheet, snum, &he);
2434 					ADVANCE(sizeof(snum));
2435 					*ptr += sprintf(*ptr, "'%.*s'",
2436                                                         (int) lwc_string_length(he),
2437                                                         lwc_string_data(he));
2438 				}
2439 					break;
2440 				case PLAY_DURING_AUTO:
2441 					*ptr += sprintf(*ptr, "auto");
2442 					break;
2443 				case PLAY_DURING_NONE:
2444 					*ptr += sprintf(*ptr, "none");
2445 					break;
2446 				}
2447 
2448 				if (value & PLAY_DURING_MIX)
2449 					*ptr += sprintf(*ptr, " mix");
2450 				if (value & PLAY_DURING_REPEAT)
2451 					*ptr += sprintf(*ptr, " repeat");
2452 				break;
2453 			case CSS_PROP_POSITION:
2454 				switch (value) {
2455 				case POSITION_STATIC:
2456 					*ptr += sprintf(*ptr, "static");
2457 					break;
2458 				case POSITION_RELATIVE:
2459 					*ptr += sprintf(*ptr, "relative");
2460 					break;
2461 				case POSITION_ABSOLUTE:
2462 					*ptr += sprintf(*ptr, "absolute");
2463 					break;
2464 				case POSITION_FIXED:
2465 					*ptr += sprintf(*ptr, "fixed");
2466 					break;
2467 				}
2468 				break;
2469 			case CSS_PROP_QUOTES:
2470 				switch (value) {
2471 				case QUOTES_STRING:
2472 					while (value != QUOTES_NONE) {
2473 						uint32_t snum = *((uint32_t *) bytecode);
2474 						lwc_string *he;
2475 						css__stylesheet_string_get(style->sheet, snum, &he);
2476 						ADVANCE(sizeof(snum));
2477 						*ptr += sprintf(*ptr, " '%.*s' ",
2478                                                                 (int) lwc_string_length(he),
2479                                                                 lwc_string_data(he));
2480 
2481 						css__stylesheet_string_get(style->sheet, snum, &he);
2482 						ADVANCE(sizeof(he));
2483 						*ptr += sprintf(*ptr, " '%.*s' ",
2484                                                                 (int) lwc_string_length(he),
2485                                                                 lwc_string_data(he));
2486 
2487 						value = *((uint32_t *) bytecode);
2488 						ADVANCE(sizeof(value));
2489 					}
2490 					break;
2491 				case QUOTES_NONE:
2492 					*ptr += sprintf(*ptr, "none");
2493 					break;
2494 				}
2495 				break;
2496 			case CSS_PROP_SPEAK_HEADER:
2497 				switch (value) {
2498 				case SPEAK_HEADER_ONCE:
2499 					*ptr += sprintf(*ptr, "once");
2500 					break;
2501 				case SPEAK_HEADER_ALWAYS:
2502 					*ptr += sprintf(*ptr, "always");
2503 					break;
2504 				}
2505 				break;
2506 			case CSS_PROP_SPEAK_NUMERAL:
2507 				switch (value) {
2508 				case SPEAK_NUMERAL_DIGITS:
2509 					*ptr += sprintf(*ptr, "digits");
2510 					break;
2511 				case SPEAK_NUMERAL_CONTINUOUS:
2512 					*ptr += sprintf(*ptr, "continuous");
2513 					break;
2514 				}
2515 				break;
2516 			case CSS_PROP_SPEAK_PUNCTUATION:
2517 				switch (value) {
2518 				case SPEAK_PUNCTUATION_CODE:
2519 					*ptr += sprintf(*ptr, "code");
2520 					break;
2521 				case SPEAK_PUNCTUATION_NONE:
2522 					*ptr += sprintf(*ptr, "none");
2523 					break;
2524 				}
2525 				break;
2526 			case CSS_PROP_SPEAK:
2527 				switch (value) {
2528 				case SPEAK_NORMAL:
2529 					*ptr += sprintf(*ptr, "normal");
2530 					break;
2531 				case SPEAK_NONE:
2532 					*ptr += sprintf(*ptr, "none");
2533 					break;
2534 				case SPEAK_SPELL_OUT:
2535 					*ptr += sprintf(*ptr, "spell-out");
2536 					break;
2537 				}
2538 				break;
2539 			case CSS_PROP_SPEECH_RATE:
2540 				switch (value) {
2541 				case SPEECH_RATE_SET:
2542 				{
2543 					css_fixed val = *((css_fixed *) bytecode);
2544 					ADVANCE(sizeof(val));
2545 					dump_number(val, ptr);
2546 				}
2547 					break;
2548 				case SPEECH_RATE_X_SLOW:
2549 					*ptr += sprintf(*ptr, "x-slow");
2550 					break;
2551 				case SPEECH_RATE_SLOW:
2552 					*ptr += sprintf(*ptr, "slow");
2553 					break;
2554 				case SPEECH_RATE_MEDIUM:
2555 					*ptr += sprintf(*ptr, "medium");
2556 					break;
2557 				case SPEECH_RATE_FAST:
2558 					*ptr += sprintf(*ptr, "fast");
2559 					break;
2560 				case SPEECH_RATE_X_FAST:
2561 					*ptr += sprintf(*ptr, "x-fast");
2562 					break;
2563 				case SPEECH_RATE_FASTER:
2564 					*ptr += sprintf(*ptr, "faster");
2565 					break;
2566 				case SPEECH_RATE_SLOWER:
2567 					*ptr += sprintf(*ptr, "slower");
2568 					break;
2569 				}
2570 				break;
2571 			case CSS_PROP_TABLE_LAYOUT:
2572 				switch (value) {
2573 				case TABLE_LAYOUT_AUTO:
2574 					*ptr += sprintf(*ptr, "auto");
2575 					break;
2576 				case TABLE_LAYOUT_FIXED:
2577 					*ptr += sprintf(*ptr, "fixed");
2578 					break;
2579 				}
2580 				break;
2581 			case CSS_PROP_TEXT_ALIGN:
2582 				switch (value) {
2583 				case TEXT_ALIGN_LEFT:
2584 					*ptr += sprintf(*ptr, "left");
2585 					break;
2586 				case TEXT_ALIGN_RIGHT:
2587 					*ptr += sprintf(*ptr, "right");
2588 					break;
2589 				case TEXT_ALIGN_CENTER:
2590 					*ptr += sprintf(*ptr, "center");
2591 					break;
2592 				case TEXT_ALIGN_JUSTIFY:
2593 					*ptr += sprintf(*ptr, "justify");
2594 					break;
2595 				case TEXT_ALIGN_LIBCSS_LEFT:
2596 					*ptr += sprintf(*ptr, "-libcss-left");
2597 					break;
2598 				case TEXT_ALIGN_LIBCSS_CENTER:
2599 					*ptr += sprintf(*ptr, "-libcss-center");
2600 					break;
2601 				case TEXT_ALIGN_LIBCSS_RIGHT:
2602 					*ptr += sprintf(*ptr, "-libcss-right");
2603 					break;
2604 				}
2605 				break;
2606 			case CSS_PROP_TEXT_DECORATION:
2607 				if (value == TEXT_DECORATION_NONE)
2608 					*ptr += sprintf(*ptr, "none");
2609 
2610 				if (value & TEXT_DECORATION_UNDERLINE)
2611 					*ptr += sprintf(*ptr, " underline");
2612 				if (value & TEXT_DECORATION_OVERLINE)
2613 					*ptr += sprintf(*ptr, " overline");
2614 				if (value & TEXT_DECORATION_LINE_THROUGH)
2615 					*ptr += sprintf(*ptr, " line-through");
2616 				if (value & TEXT_DECORATION_BLINK)
2617 					*ptr += sprintf(*ptr, " blink");
2618 				break;
2619 			case CSS_PROP_TEXT_TRANSFORM:
2620 				switch (value) {
2621 				case TEXT_TRANSFORM_CAPITALIZE:
2622 					*ptr += sprintf(*ptr, "capitalize");
2623 					break;
2624 				case TEXT_TRANSFORM_UPPERCASE:
2625 					*ptr += sprintf(*ptr, "uppercase");
2626 					break;
2627 				case TEXT_TRANSFORM_LOWERCASE:
2628 					*ptr += sprintf(*ptr, "lowercase");
2629 					break;
2630 				case TEXT_TRANSFORM_NONE:
2631 					*ptr += sprintf(*ptr, "none");
2632 					break;
2633 				}
2634 				break;
2635 			case CSS_PROP_UNICODE_BIDI:
2636 				switch (value) {
2637 				case UNICODE_BIDI_NORMAL:
2638 					*ptr += sprintf(*ptr, "normal");
2639 					break;
2640 				case UNICODE_BIDI_EMBED:
2641 					*ptr += sprintf(*ptr, "embed");
2642 					break;
2643 				case UNICODE_BIDI_BIDI_OVERRIDE:
2644 					*ptr += sprintf(*ptr, "bidi-override");
2645 					break;
2646 				}
2647 				break;
2648 			case CSS_PROP_VERTICAL_ALIGN:
2649 				switch (value) {
2650 				case VERTICAL_ALIGN_SET:
2651 				{
2652 					uint32_t unit;
2653 					css_fixed val = *((css_fixed *) bytecode);
2654 					ADVANCE(sizeof(val));
2655 					unit = *((uint32_t *) bytecode);
2656 					ADVANCE(sizeof(unit));
2657 					dump_unit(val, unit, ptr);
2658 				}
2659 					break;
2660 				case VERTICAL_ALIGN_BASELINE:
2661 					*ptr += sprintf(*ptr, "baseline");
2662 					break;
2663 				case VERTICAL_ALIGN_SUB:
2664 					*ptr += sprintf(*ptr, "sub");
2665 					break;
2666 				case VERTICAL_ALIGN_SUPER:
2667 					*ptr += sprintf(*ptr, "super");
2668 					break;
2669 				case VERTICAL_ALIGN_TOP:
2670 					*ptr += sprintf(*ptr, "top");
2671 					break;
2672 				case VERTICAL_ALIGN_TEXT_TOP:
2673 					*ptr += sprintf(*ptr, "text-top");
2674 					break;
2675 				case VERTICAL_ALIGN_MIDDLE:
2676 					*ptr += sprintf(*ptr, "middle");
2677 					break;
2678 				case VERTICAL_ALIGN_BOTTOM:
2679 					*ptr += sprintf(*ptr, "bottom");
2680 					break;
2681 				case VERTICAL_ALIGN_TEXT_BOTTOM:
2682 					*ptr += sprintf(*ptr, "text-bottom");
2683 					break;
2684 				}
2685 				break;
2686 			case CSS_PROP_VISIBILITY:
2687 				switch (value) {
2688 				case VISIBILITY_VISIBLE:
2689 					*ptr += sprintf(*ptr, "visible");
2690 					break;
2691 				case VISIBILITY_HIDDEN:
2692 					*ptr += sprintf(*ptr, "hidden");
2693 					break;
2694 				case VISIBILITY_COLLAPSE:
2695 					*ptr += sprintf(*ptr, "collapse");
2696 					break;
2697 				}
2698 				break;
2699 			case CSS_PROP_VOICE_FAMILY:
2700 				while (value != VOICE_FAMILY_END) {
2701 					switch (value) {
2702 					case VOICE_FAMILY_STRING:
2703 					case VOICE_FAMILY_IDENT_LIST:
2704 					{
2705 						uint32_t snum = *((uint32_t *) bytecode);
2706 						lwc_string *he;
2707 						css__stylesheet_string_get(style->sheet, snum, &he);
2708 						ADVANCE(sizeof(snum));
2709 						*ptr += sprintf(*ptr, "'%.*s'",
2710                                                                 (int) lwc_string_length(he),
2711                                                                 lwc_string_data(he));
2712 					}
2713 						break;
2714 					case VOICE_FAMILY_MALE:
2715 						*ptr += sprintf(*ptr, "male");
2716 						break;
2717 					case VOICE_FAMILY_FEMALE:
2718 						*ptr += sprintf(*ptr, "female");
2719 						break;
2720 					case VOICE_FAMILY_CHILD:
2721 						*ptr += sprintf(*ptr, "child");
2722 						break;
2723 					}
2724 
2725 					value = *((uint32_t *) bytecode);
2726 					ADVANCE(sizeof(value));
2727 
2728 					if (value != VOICE_FAMILY_END)
2729 						*ptr += sprintf(*ptr, ", ");
2730 				}
2731 				break;
2732 			case CSS_PROP_VOLUME:
2733 				switch (value) {
2734 				case VOLUME_NUMBER:
2735 				{
2736 					css_fixed val = *((css_fixed *) bytecode);
2737 					ADVANCE(sizeof(val));
2738 					dump_number(val, ptr);
2739 				}
2740 					break;
2741 				case VOLUME_DIMENSION:
2742 				{
2743 					uint32_t unit;
2744 					css_fixed val = *((css_fixed *) bytecode);
2745 					ADVANCE(sizeof(val));
2746 					unit = *((uint32_t *) bytecode);
2747 					ADVANCE(sizeof(unit));
2748 					dump_unit(val, unit, ptr);
2749 				}
2750 					break;
2751 				case VOLUME_SILENT:
2752 					*ptr += sprintf(*ptr, "silent");
2753 					break;
2754 				case VOLUME_X_SOFT:
2755 					*ptr += sprintf(*ptr, "x-soft");
2756 					break;
2757 				case VOLUME_SOFT:
2758 					*ptr += sprintf(*ptr, "soft");
2759 					break;
2760 				case VOLUME_MEDIUM:
2761 					*ptr += sprintf(*ptr, "medium");
2762 					break;
2763 				case VOLUME_LOUD:
2764 					*ptr += sprintf(*ptr, "loud");
2765 					break;
2766 				case VOLUME_X_LOUD:
2767 					*ptr += sprintf(*ptr, "x-loud");
2768 					break;
2769 				}
2770 				break;
2771 			case CSS_PROP_WHITE_SPACE:
2772 				switch (value) {
2773 				case WHITE_SPACE_NORMAL:
2774 					*ptr += sprintf(*ptr, "normal");
2775 					break;
2776 				case WHITE_SPACE_PRE:
2777 					*ptr += sprintf(*ptr, "pre");
2778 					break;
2779 				case WHITE_SPACE_NOWRAP:
2780 					*ptr += sprintf(*ptr, "nowrap");
2781 					break;
2782 				case WHITE_SPACE_PRE_WRAP:
2783 					*ptr += sprintf(*ptr, "pre-wrap");
2784 					break;
2785 				case WHITE_SPACE_PRE_LINE:
2786 					*ptr += sprintf(*ptr, "pre-line");
2787 					break;
2788 				}
2789 				break;
2790 			case CSS_PROP_WRITING_MODE:
2791 				switch (value) {
2792 				case WRITING_MODE_HORIZONTAL_TB:
2793 					*ptr += sprintf(*ptr, "horizontal-tb");
2794 					break;
2795 				case WRITING_MODE_VERTICAL_RL:
2796 					*ptr += sprintf(*ptr, "vertical-rl");
2797 					break;
2798 				case WRITING_MODE_VERTICAL_LR:
2799 					*ptr += sprintf(*ptr, "vertical-lr");
2800 					break;
2801 				}
2802 				break;
2803 			case CSS_PROP_Z_INDEX:
2804 				switch (value) {
2805 				case Z_INDEX_SET:
2806 				{
2807 					css_fixed val = *((css_fixed *) bytecode);
2808 					ADVANCE(sizeof(val));
2809 					dump_number(val, ptr);
2810 				}
2811 					break;
2812 				case Z_INDEX_AUTO:
2813 					*ptr += sprintf(*ptr, "auto");
2814 					break;
2815 				}
2816 				break;
2817 			default:
2818 				*ptr += sprintf(*ptr, "Unknown opcode %x", op);
2819 				return;
2820 			}
2821 		}
2822 
2823 		if (isImportant(opv))
2824 			*ptr += sprintf(*ptr, " !important");
2825 
2826 		*ptr += sprintf(*ptr, "\n");
2827 	}
2828 
2829 #undef ADVANCE
2830 
2831 }
2832 
dump_string(lwc_string * string,char ** ptr)2833 void dump_string(lwc_string *string, char **ptr)
2834 {
2835 	*ptr += sprintf(*ptr, "%.*s",
2836                         (int) lwc_string_length(string),
2837                         lwc_string_data(string));
2838 }
2839 
dump_font_face(css_font_face * font_face,char ** ptr)2840 void dump_font_face(css_font_face *font_face, char **ptr)
2841 {
2842 	uint8_t style, weight;
2843 
2844 	if (font_face->font_family != NULL) {
2845 		*(*ptr)++ = '\n';
2846 		*ptr += sprintf(*ptr, "|  font-family: %.*s",
2847 				(int) lwc_string_length(font_face->font_family),
2848 				lwc_string_data(font_face->font_family));
2849 	}
2850 
2851 	*ptr += sprintf(*ptr, "\n|  font-style: ");
2852 	style = css_font_face_font_style(font_face);
2853 	switch (style) {
2854 	case CSS_FONT_STYLE_INHERIT:
2855 		*ptr += sprintf(*ptr, "unspecified");
2856 		break;
2857 	case CSS_FONT_STYLE_NORMAL:
2858 		*ptr += sprintf(*ptr, "normal");
2859 		break;
2860 	case CSS_FONT_STYLE_ITALIC:
2861 		*ptr += sprintf(*ptr, "italic");
2862 		break;
2863 	case CSS_FONT_STYLE_OBLIQUE:
2864 		*ptr += sprintf(*ptr, "oblique");
2865 		break;
2866 	}
2867 
2868 	*ptr += sprintf(*ptr, "\n|  font-weight: ");
2869 	weight = css_font_face_font_weight(font_face);
2870 	switch (weight) {
2871 	case CSS_FONT_WEIGHT_INHERIT:
2872 		*ptr += sprintf(*ptr, "unspecified");
2873 		break;
2874 	case CSS_FONT_WEIGHT_NORMAL:
2875 		*ptr += sprintf(*ptr, "normal");
2876 		break;
2877 	case CSS_FONT_WEIGHT_BOLD:
2878 		*ptr += sprintf(*ptr, "bold");
2879 		break;
2880 	case CSS_FONT_WEIGHT_100:
2881 		*ptr += sprintf(*ptr, "100");
2882 		break;
2883 	case CSS_FONT_WEIGHT_200:
2884 		*ptr += sprintf(*ptr, "200");
2885 		break;
2886 	case CSS_FONT_WEIGHT_300:
2887 		*ptr += sprintf(*ptr, "300");
2888 		break;
2889 	case CSS_FONT_WEIGHT_400:
2890 		*ptr += sprintf(*ptr, "400");
2891 		break;
2892 	case CSS_FONT_WEIGHT_500:
2893 		*ptr += sprintf(*ptr, "500");
2894 		break;
2895 	case CSS_FONT_WEIGHT_600:
2896 		*ptr += sprintf(*ptr, "600");
2897 		break;
2898 	case CSS_FONT_WEIGHT_700:
2899 		*ptr += sprintf(*ptr, "700");
2900 		break;
2901 	case CSS_FONT_WEIGHT_800:
2902 		*ptr += sprintf(*ptr, "800");
2903 		break;
2904 	case CSS_FONT_WEIGHT_900:
2905 		*ptr += sprintf(*ptr, "900");
2906 		break;
2907 	default:
2908 		*ptr += sprintf(*ptr, "Unhandled weight %d\n", (int)weight);
2909 		break;
2910 	}
2911 
2912 
2913 	if (font_face->srcs != NULL) {
2914 		uint32_t i;
2915 		css_font_face_src *srcs = font_face->srcs;
2916 		for (i = 0; i < font_face->n_srcs; ++i) {
2917 			css_font_face_format format;
2918 			*ptr += sprintf(*ptr, "\n|  src: ");
2919 
2920 			format = css_font_face_src_format(&srcs[i]);
2921 
2922 			*ptr += sprintf(*ptr, "\n|   format: ");
2923 
2924 			switch (format) {
2925 			case CSS_FONT_FACE_FORMAT_UNSPECIFIED:
2926 				*ptr += sprintf(*ptr, "unspecified");
2927 				break;
2928 			case CSS_FONT_FACE_FORMAT_WOFF:
2929 				*ptr += sprintf(*ptr, "WOFF");
2930 				break;
2931 			case CSS_FONT_FACE_FORMAT_OPENTYPE:
2932 				*ptr += sprintf(*ptr, "OTF");
2933 				break;
2934 			case CSS_FONT_FACE_FORMAT_EMBEDDED_OPENTYPE:
2935 				*ptr += sprintf(*ptr, "EOTF");
2936 				break;
2937 			case CSS_FONT_FACE_FORMAT_SVG:
2938 				*ptr += sprintf(*ptr, "SVG");
2939 				break;
2940 			case CSS_FONT_FACE_FORMAT_UNKNOWN:
2941 				*ptr += sprintf(*ptr, "unknown");
2942 				break;
2943 			default:
2944 				*ptr += sprintf(*ptr, "UNEXPECTED");
2945 				break;
2946 			}
2947 
2948 			if (srcs[i].location != NULL) {
2949 				*ptr += sprintf(*ptr, "\n|   location: ");
2950 
2951 				switch (css_font_face_src_location_type(
2952 						&srcs[i])) {
2953 				case CSS_FONT_FACE_LOCATION_TYPE_LOCAL:
2954 					*ptr += sprintf(*ptr, "local");
2955 					break;
2956 				case CSS_FONT_FACE_LOCATION_TYPE_URI:
2957 					*ptr += sprintf(*ptr, "url");
2958 					break;
2959 				default:
2960 					*ptr += sprintf(*ptr, "UNKNOWN");
2961 					break;
2962 				}
2963 
2964 				*ptr += sprintf(*ptr, "(%.*s)",
2965 					(int) lwc_string_length(
2966 							srcs[i].location),
2967 					lwc_string_data(srcs[i].location));
2968 			}
2969 		}
2970 	}
2971 }
2972 
2973 #endif
2974