Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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",
  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. };
  480.  
  481. static void dump_css_fixed(css_fixed f, char **ptr)
  482. {
  483. #define ABS(x) (uint32_t)((x) < 0 ? -(x) : (x))
  484.         uint32_t uintpart = FIXTOINT(ABS(f));
  485.         /* + 500 to ensure round to nearest (division will truncate) */
  486.         uint32_t fracpart = ((ABS(f) & 0x3ff) * 1000 + 500) / (1 << 10);
  487. #undef ABS
  488.         size_t flen = 0;
  489.         char tmp[20];
  490.         size_t tlen = 0;
  491.         char *buf = *ptr;
  492.  
  493.         if (f < 0) {
  494.                 buf[0] = '-';
  495.                 buf++;
  496.         }
  497.  
  498.         do {
  499.                 tmp[tlen] = "0123456789"[uintpart % 10];
  500.                 tlen++;
  501.  
  502.                 uintpart /= 10;
  503.         } while (tlen < 20 && uintpart != 0);
  504.  
  505.         while (tlen > 0) {
  506.                 buf[0] = tmp[--tlen];
  507.                 buf++;
  508.         }
  509.  
  510.         buf[0] = '.';
  511.         buf++;
  512.  
  513.         do {
  514.                 tmp[tlen] = "0123456789"[fracpart % 10];
  515.                 tlen++;
  516.  
  517.                 fracpart /= 10;
  518.         } while (tlen < 20 && fracpart != 0);
  519.  
  520.         while (tlen > 0) {
  521.                 buf[0] = tmp[--tlen];
  522.                 buf++;
  523.                 flen++;
  524.         }
  525.  
  526.         while (flen < 3) {
  527.                 buf[0] = '0';
  528.                 buf++;
  529.                 flen++;
  530.         }
  531.  
  532.         buf[0] = '\0';
  533.  
  534.         *ptr = buf;
  535. }
  536.  
  537. static void dump_number(css_fixed val, char **ptr)
  538. {
  539.         if (INTTOFIX(FIXTOINT(val)) == val)
  540.                 *ptr += sprintf(*ptr, "%d", FIXTOINT(val));
  541.         else
  542.                 dump_css_fixed(val, ptr);
  543. }
  544.  
  545. static void dump_unit(css_fixed val, uint32_t unit, char **ptr)
  546. {
  547.         dump_number(val, ptr);
  548.  
  549.         switch (unit) {
  550.         case UNIT_PX:
  551.                 *ptr += sprintf(*ptr, "px");
  552.                 break;
  553.         case UNIT_EX:
  554.                 *ptr += sprintf(*ptr, "ex");
  555.                 break;
  556.         case UNIT_EM:
  557.                 *ptr += sprintf(*ptr, "em");
  558.                 break;
  559.         case UNIT_IN:
  560.                 *ptr += sprintf(*ptr, "in");
  561.                 break;
  562.         case UNIT_CM:
  563.                 *ptr += sprintf(*ptr, "cm");
  564.                 break;
  565.         case UNIT_MM:
  566.                 *ptr += sprintf(*ptr, "mm");
  567.                 break;
  568.         case UNIT_PT:
  569.                 *ptr += sprintf(*ptr, "pt");
  570.                 break;
  571.         case UNIT_PC:
  572.                 *ptr += sprintf(*ptr, "pc");
  573.                 break;
  574.         case UNIT_PCT:
  575.                 *ptr += sprintf(*ptr, "%%");
  576.                 break;
  577.         case UNIT_DEG:
  578.                 *ptr += sprintf(*ptr, "deg");
  579.                 break;
  580.         case UNIT_GRAD:
  581.                 *ptr += sprintf(*ptr, "grad");
  582.                 break;
  583.         case UNIT_RAD:
  584.                 *ptr += sprintf(*ptr, "rad");
  585.                 break;
  586.         case UNIT_MS:
  587.                 *ptr += sprintf(*ptr, "ms");
  588.                 break;
  589.         case UNIT_S:
  590.                 *ptr += sprintf(*ptr, "s");
  591.                 break;
  592.         case UNIT_HZ:
  593.                 *ptr += sprintf(*ptr, "Hz");
  594.                 break;
  595.         case UNIT_KHZ:
  596.                 *ptr += sprintf(*ptr, "kHz");
  597.                 break;
  598.         }
  599. }
  600.  
  601. static void dump_counter(lwc_string *name, uint32_t value,
  602.                 char **ptr)
  603. {
  604.         *ptr += sprintf(*ptr, "counter(%.*s",
  605.                         (int) lwc_string_length(name), lwc_string_data(name));
  606.  
  607.         value >>= CONTENT_COUNTER_STYLE_SHIFT;
  608.  
  609.         switch (value) {
  610.         case LIST_STYLE_TYPE_DISC:
  611.                 *ptr += sprintf(*ptr, ", disc");
  612.                 break;
  613.         case LIST_STYLE_TYPE_CIRCLE:
  614.                 *ptr += sprintf(*ptr, ", circle");
  615.                 break;
  616.         case LIST_STYLE_TYPE_SQUARE:
  617.                 *ptr += sprintf(*ptr, ", square");
  618.                 break;
  619.         case LIST_STYLE_TYPE_DECIMAL:
  620.                 break;
  621.         case LIST_STYLE_TYPE_DECIMAL_LEADING_ZERO:
  622.                 *ptr += sprintf(*ptr, ", decimal-leading-zero");
  623.                 break;
  624.         case LIST_STYLE_TYPE_LOWER_ROMAN:
  625.                 *ptr += sprintf(*ptr, ", lower-roman");
  626.                 break;
  627.         case LIST_STYLE_TYPE_UPPER_ROMAN:
  628.                 *ptr += sprintf(*ptr, ", upper-roman");
  629.                 break;
  630.         case LIST_STYLE_TYPE_LOWER_GREEK:
  631.                 *ptr += sprintf(*ptr, ", lower-greek");
  632.                 break;
  633.         case LIST_STYLE_TYPE_LOWER_LATIN:
  634.                 *ptr += sprintf(*ptr, ", lower-latin");
  635.                 break;
  636.         case LIST_STYLE_TYPE_UPPER_LATIN:
  637.                 *ptr += sprintf(*ptr, ", upper-latin");
  638.                 break;
  639.         case LIST_STYLE_TYPE_ARMENIAN:
  640.                 *ptr += sprintf(*ptr, ", armenian");
  641.                 break;
  642.         case LIST_STYLE_TYPE_GEORGIAN:
  643.                 *ptr += sprintf(*ptr, ", georgian");
  644.                 break;
  645.         case LIST_STYLE_TYPE_LOWER_ALPHA:
  646.                 *ptr += sprintf(*ptr, ", lower-alpha");
  647.                 break;
  648.         case LIST_STYLE_TYPE_UPPER_ALPHA:
  649.                 *ptr += sprintf(*ptr, ", upper-alpha");
  650.                 break;
  651.         case LIST_STYLE_TYPE_NONE:
  652.                 *ptr += sprintf(*ptr, ", none");
  653.                 break;
  654.         }
  655.  
  656.         *ptr += sprintf(*ptr, ")");
  657. }
  658.  
  659. static void dump_counters(lwc_string *name, lwc_string *separator,
  660.                 uint32_t value, char **ptr)
  661. {
  662.         *ptr += sprintf(*ptr, "counter(%.*s, %.*s",
  663.                         (int) lwc_string_length(name),
  664.                         lwc_string_data(name),
  665.                         (int) lwc_string_length(separator),
  666.                         lwc_string_data(separator));
  667.  
  668.         value >>= CONTENT_COUNTER_STYLE_SHIFT;
  669.  
  670.         switch (value) {
  671.         case LIST_STYLE_TYPE_DISC:
  672.                 *ptr += sprintf(*ptr, ", disc");
  673.                 break;
  674.         case LIST_STYLE_TYPE_CIRCLE:
  675.                 *ptr += sprintf(*ptr, ", circle");
  676.                 break;
  677.         case LIST_STYLE_TYPE_SQUARE:
  678.                 *ptr += sprintf(*ptr, ", square");
  679.                 break;
  680.         case LIST_STYLE_TYPE_DECIMAL:
  681.                 break;
  682.         case LIST_STYLE_TYPE_DECIMAL_LEADING_ZERO:
  683.                 *ptr += sprintf(*ptr, ", decimal-leading-zero");
  684.                 break;
  685.         case LIST_STYLE_TYPE_LOWER_ROMAN:
  686.                 *ptr += sprintf(*ptr, ", lower-roman");
  687.                 break;
  688.         case LIST_STYLE_TYPE_UPPER_ROMAN:
  689.                 *ptr += sprintf(*ptr, ", upper-roman");
  690.                 break;
  691.         case LIST_STYLE_TYPE_LOWER_GREEK:
  692.                 *ptr += sprintf(*ptr, ", lower-greek");
  693.                 break;
  694.         case LIST_STYLE_TYPE_LOWER_LATIN:
  695.                 *ptr += sprintf(*ptr, ", lower-latin");
  696.                 break;
  697.         case LIST_STYLE_TYPE_UPPER_LATIN:
  698.                 *ptr += sprintf(*ptr, ", upper-latin");
  699.                 break;
  700.         case LIST_STYLE_TYPE_ARMENIAN:
  701.                 *ptr += sprintf(*ptr, ", armenian");
  702.                 break;
  703.         case LIST_STYLE_TYPE_GEORGIAN:
  704.                 *ptr += sprintf(*ptr, ", georgian");
  705.                 break;
  706.         case LIST_STYLE_TYPE_LOWER_ALPHA:
  707.                 *ptr += sprintf(*ptr, ", lower-alpha");
  708.                 break;
  709.         case LIST_STYLE_TYPE_UPPER_ALPHA:
  710.                 *ptr += sprintf(*ptr, ", upper-alpha");
  711.                 break;
  712.         case LIST_STYLE_TYPE_NONE:
  713.                 *ptr += sprintf(*ptr, ", none");
  714.                 break;
  715.         }
  716.  
  717.         *ptr += sprintf(*ptr, ")");
  718. }
  719.  
  720. void dump_bytecode(css_style *style, char **ptr, uint32_t depth)
  721. {
  722.         void *bytecode = style->bytecode;
  723.         size_t length = (style->used * sizeof(css_code_t));
  724.         uint32_t offset = 0;
  725.  
  726. #define ADVANCE(n) do {                                 \
  727.         offset += (n);                                  \
  728.         bytecode = ((uint8_t *) bytecode) + (n);        \
  729. } while(0)
  730.  
  731.         while (offset < length) {
  732.                 opcode_t op;
  733.                 uint32_t value;
  734.                 uint32_t opv = *((uint32_t *) bytecode);
  735.  
  736.                 ADVANCE(sizeof(opv));
  737.  
  738.                 op = getOpcode(opv);
  739.  
  740.                 *((*ptr)++) = '|';
  741.                 for (uint32_t i = 0; i < depth; i++)
  742.                         *((*ptr)++) = ' ';
  743.                 *ptr += sprintf(*ptr, "%s: ", opcode_names[op]);
  744.  
  745.                 if (isInherit(opv)) {
  746.                         *ptr += sprintf(*ptr, "inherit");
  747.                 } else {
  748.                         value = getValue(opv);
  749.  
  750.                         switch (op) {
  751.                         case CSS_PROP_AZIMUTH:
  752.                                 switch (value & ~AZIMUTH_BEHIND) {
  753.                                 case AZIMUTH_ANGLE:
  754.                                 {
  755.                                         uint32_t unit;
  756.                                         css_fixed val = *((css_fixed *) bytecode);
  757.                                         ADVANCE(sizeof(val));
  758.                                         unit = *((uint32_t *) bytecode);
  759.                                         ADVANCE(sizeof(unit));
  760.                                         dump_unit(val, unit, ptr);
  761.                                 }
  762.                                         break;
  763.                                 case AZIMUTH_LEFTWARDS:
  764.                                         *ptr += sprintf(*ptr, "leftwards");
  765.                                         break;
  766.                                 case AZIMUTH_RIGHTWARDS:
  767.                                         *ptr += sprintf(*ptr, "rightwards");
  768.                                         break;
  769.                                 case AZIMUTH_LEFT_SIDE:
  770.                                         *ptr += sprintf(*ptr, "left-side");
  771.                                         break;
  772.                                 case AZIMUTH_FAR_LEFT:
  773.                                         *ptr += sprintf(*ptr, "far-left");
  774.                                         break;
  775.                                 case AZIMUTH_LEFT:
  776.                                         *ptr += sprintf(*ptr, "left");
  777.                                         break;
  778.                                 case AZIMUTH_CENTER_LEFT:
  779.                                         *ptr += sprintf(*ptr, "center-left");
  780.                                         break;
  781.                                 case AZIMUTH_CENTER:
  782.                                         *ptr += sprintf(*ptr, "center");
  783.                                         break;
  784.                                 case AZIMUTH_CENTER_RIGHT:
  785.                                         *ptr += sprintf(*ptr, "center-right");
  786.                                         break;
  787.                                 case AZIMUTH_RIGHT:
  788.                                         *ptr += sprintf(*ptr, "right");
  789.                                         break;
  790.                                 case AZIMUTH_FAR_RIGHT:
  791.                                         *ptr += sprintf(*ptr, "far-right");
  792.                                         break;
  793.                                 case AZIMUTH_RIGHT_SIDE:
  794.                                         *ptr += sprintf(*ptr, "right-side");
  795.                                         break;
  796.                                 }
  797.                                 if (value & AZIMUTH_BEHIND)
  798.                                         *ptr += sprintf(*ptr, " behind");
  799.                                 break;
  800.                         case CSS_PROP_BACKGROUND_ATTACHMENT:
  801.                                 switch (value) {
  802.                                 case BACKGROUND_ATTACHMENT_FIXED:
  803.                                         *ptr += sprintf(*ptr, "fixed");
  804.                                         break;
  805.                                 case BACKGROUND_ATTACHMENT_SCROLL:
  806.                                         *ptr += sprintf(*ptr, "scroll");
  807.                                         break;
  808.                                 }
  809.                                 break;
  810.                         case CSS_PROP_BORDER_TOP_COLOR:
  811.                         case CSS_PROP_BORDER_RIGHT_COLOR:
  812.                         case CSS_PROP_BORDER_BOTTOM_COLOR:
  813.                         case CSS_PROP_BORDER_LEFT_COLOR:
  814.                         case CSS_PROP_BACKGROUND_COLOR:
  815.                         case CSS_PROP_COLUMN_RULE_COLOR:
  816.                                 assert(BACKGROUND_COLOR_TRANSPARENT ==
  817.                                                 (enum op_background_color)
  818.                                                 BORDER_COLOR_TRANSPARENT);
  819.                                 assert(BACKGROUND_COLOR_CURRENT_COLOR ==
  820.                                                 (enum op_background_color)
  821.                                                 BORDER_COLOR_CURRENT_COLOR);
  822.                                 assert(BACKGROUND_COLOR_SET ==
  823.                                                 (enum op_background_color)
  824.                                                 BORDER_COLOR_SET);
  825.  
  826.                                 switch (value) {
  827.                                 case BACKGROUND_COLOR_TRANSPARENT:
  828.                                         *ptr += sprintf(*ptr, "transparent");
  829.                                         break;
  830.                                 case BACKGROUND_COLOR_CURRENT_COLOR:
  831.                                         *ptr += sprintf(*ptr, "currentColor");
  832.                                         break;
  833.                                 case BACKGROUND_COLOR_SET:
  834.                                 {
  835.                                         uint32_t colour =
  836.                                                 *((uint32_t *) bytecode);
  837.                                         ADVANCE(sizeof(colour));
  838.                                         *ptr += sprintf(*ptr, "#%08x", colour);
  839.                                 }      
  840.                                         break;
  841.                                 }
  842.                                 break;
  843.                         case CSS_PROP_BACKGROUND_IMAGE:
  844.                         case CSS_PROP_CUE_AFTER:
  845.                         case CSS_PROP_CUE_BEFORE:
  846.                         case CSS_PROP_LIST_STYLE_IMAGE:
  847.                                 assert(BACKGROUND_IMAGE_NONE ==
  848.                                                 (enum op_background_image)
  849.                                                 CUE_AFTER_NONE);
  850.                                 assert(BACKGROUND_IMAGE_URI ==
  851.                                                 (enum op_background_image)
  852.                                                 CUE_AFTER_URI);
  853.                                 assert(BACKGROUND_IMAGE_NONE ==
  854.                                                 (enum op_background_image)
  855.                                                 CUE_BEFORE_NONE);
  856.                                 assert(BACKGROUND_IMAGE_URI ==
  857.                                                 (enum op_background_image)
  858.                                                 CUE_BEFORE_URI);
  859.                                 assert(BACKGROUND_IMAGE_NONE ==
  860.                                                 (enum op_background_image)
  861.                                                 LIST_STYLE_IMAGE_NONE);
  862.                                 assert(BACKGROUND_IMAGE_URI ==
  863.                                                 (enum op_background_image)
  864.                                                 LIST_STYLE_IMAGE_URI);
  865.  
  866.                                 switch (value) {
  867.                                 case BACKGROUND_IMAGE_NONE:
  868.                                         *ptr += sprintf(*ptr, "none");
  869.                                         break;
  870.                                 case BACKGROUND_IMAGE_URI:
  871.                                 {
  872.                                         uint32_t snum = *((uint32_t *) bytecode);
  873.                                         lwc_string *he;
  874.                                         css__stylesheet_string_get(style->sheet,
  875.                                                                   snum,
  876.                                                                   &he);
  877.                                         ADVANCE(sizeof(snum));
  878.                                         *ptr += sprintf(*ptr, "url('%.*s')",
  879.                                                         (int) lwc_string_length(he),
  880.                                                         lwc_string_data(he));
  881.                                 }
  882.                                         break;
  883.                                 }
  884.                                 break;
  885.                         case CSS_PROP_BACKGROUND_POSITION:
  886.                                 switch (value & 0xf0) {
  887.                                 case BACKGROUND_POSITION_HORZ_SET:
  888.                                 {
  889.                                         uint32_t unit;
  890.                                         css_fixed val = *((css_fixed *) bytecode);
  891.                                         ADVANCE(sizeof(val));
  892.                                         unit = *((uint32_t *) bytecode);
  893.                                         ADVANCE(sizeof(unit));
  894.                                         dump_unit(val, unit, ptr);
  895.                                 }
  896.                                         break;
  897.                                 case BACKGROUND_POSITION_HORZ_CENTER:
  898.                                         *ptr += sprintf(*ptr, "center");
  899.                                         break;
  900.                                 case BACKGROUND_POSITION_HORZ_RIGHT:
  901.                                         *ptr += sprintf(*ptr, "right");
  902.                                         break;
  903.                                 case BACKGROUND_POSITION_HORZ_LEFT:
  904.                                         *ptr += sprintf(*ptr, "left");
  905.                                         break;
  906.                                 }
  907.                                 *ptr += sprintf(*ptr, " ");
  908.                                 switch (value & 0x0f) {
  909.                                 case BACKGROUND_POSITION_VERT_SET:
  910.                                 {
  911.                                         uint32_t unit;
  912.                                         css_fixed val = *((css_fixed *) bytecode);
  913.                                         ADVANCE(sizeof(val));
  914.                                         unit = *((uint32_t *) bytecode);
  915.                                         ADVANCE(sizeof(unit));
  916.                                         dump_unit(val, unit, ptr);
  917.                                 }
  918.                                         break;
  919.                                 case BACKGROUND_POSITION_VERT_CENTER:
  920.                                         *ptr += sprintf(*ptr, "center");
  921.                                         break;
  922.                                 case BACKGROUND_POSITION_VERT_BOTTOM:
  923.                                         *ptr += sprintf(*ptr, "bottom");
  924.                                         break;
  925.                                 case BACKGROUND_POSITION_VERT_TOP:
  926.                                         *ptr += sprintf(*ptr, "top");
  927.                                         break;
  928.                                 }
  929.                                 break;
  930.                         case CSS_PROP_BACKGROUND_REPEAT:
  931.                                 switch (value) {
  932.                                 case BACKGROUND_REPEAT_NO_REPEAT:
  933.                                         *ptr += sprintf(*ptr, "no-repeat");
  934.                                         break;
  935.                                 case BACKGROUND_REPEAT_REPEAT_X:
  936.                                         *ptr += sprintf(*ptr, "repeat-x");
  937.                                         break;
  938.                                 case BACKGROUND_REPEAT_REPEAT_Y:
  939.                                         *ptr += sprintf(*ptr, "repeat-y");
  940.                                         break;
  941.                                 case BACKGROUND_REPEAT_REPEAT:
  942.                                         *ptr += sprintf(*ptr, "repeat");
  943.                                         break;
  944.                                 }
  945.                                 break;
  946.                         case CSS_PROP_BORDER_COLLAPSE:
  947.                                 switch (value) {
  948.                                 case BORDER_COLLAPSE_SEPARATE:
  949.                                         *ptr += sprintf(*ptr, "separate");
  950.                                         break;
  951.                                 case BORDER_COLLAPSE_COLLAPSE:
  952.                                         *ptr += sprintf(*ptr, "collapse");
  953.                                         break;
  954.                                 }
  955.                                 break;
  956.                         case CSS_PROP_BORDER_SPACING:
  957.                                 switch (value) {
  958.                                 case BORDER_SPACING_SET:
  959.                                 {
  960.                                         uint32_t unit;
  961.                                         css_fixed val = *((css_fixed *) bytecode);
  962.                                         ADVANCE(sizeof(val));
  963.                                         unit = *((uint32_t *) bytecode);
  964.                                         ADVANCE(sizeof(unit));
  965.                                         dump_unit(val, unit, ptr);
  966.  
  967.                                         val = *((css_fixed *) bytecode);
  968.                                         ADVANCE(sizeof(val));
  969.                                         unit = *((uint32_t *) bytecode);
  970.                                         ADVANCE(sizeof(unit));
  971.                                         dump_unit(val, unit, ptr);
  972.                                 }
  973.                                         break;
  974.                                 }
  975.                                 break;
  976.                         case CSS_PROP_BORDER_TOP_STYLE:
  977.                         case CSS_PROP_BORDER_RIGHT_STYLE:
  978.                         case CSS_PROP_BORDER_BOTTOM_STYLE:
  979.                         case CSS_PROP_BORDER_LEFT_STYLE:
  980.                         case CSS_PROP_COLUMN_RULE_STYLE:
  981.                         case CSS_PROP_OUTLINE_STYLE:
  982.                                 assert(BORDER_STYLE_NONE ==
  983.                                                 (enum op_border_style)
  984.                                                 OUTLINE_STYLE_NONE);
  985.                                 assert(BORDER_STYLE_NONE ==
  986.                                                 (enum op_border_style)
  987.                                                 COLUMN_RULE_STYLE_NONE);
  988.                                 assert(BORDER_STYLE_HIDDEN ==
  989.                                                 (enum op_border_style)
  990.                                                 OUTLINE_STYLE_HIDDEN);
  991.                                 assert(BORDER_STYLE_HIDDEN ==
  992.                                                 (enum op_border_style)
  993.                                                 COLUMN_RULE_STYLE_HIDDEN);
  994.                                 assert(BORDER_STYLE_DOTTED ==
  995.                                                 (enum op_border_style)
  996.                                                 OUTLINE_STYLE_DOTTED);
  997.                                 assert(BORDER_STYLE_DOTTED ==
  998.                                                 (enum op_border_style)
  999.                                                 COLUMN_RULE_STYLE_DOTTED);
  1000.                                 assert(BORDER_STYLE_DASHED ==
  1001.                                                 (enum op_border_style)
  1002.                                                 OUTLINE_STYLE_DASHED);
  1003.                                 assert(BORDER_STYLE_DASHED ==
  1004.                                                 (enum op_border_style)
  1005.                                                 COLUMN_RULE_STYLE_DASHED);
  1006.                                 assert(BORDER_STYLE_SOLID ==
  1007.                                                 (enum op_border_style)
  1008.                                                 OUTLINE_STYLE_SOLID);
  1009.                                 assert(BORDER_STYLE_SOLID ==
  1010.                                                 (enum op_border_style)
  1011.                                                 COLUMN_RULE_STYLE_SOLID);
  1012.                                 assert(BORDER_STYLE_DOUBLE ==
  1013.                                                 (enum op_border_style)
  1014.                                                 OUTLINE_STYLE_DOUBLE);
  1015.                                 assert(BORDER_STYLE_DOUBLE ==
  1016.                                                 (enum op_border_style)
  1017.                                                 COLUMN_RULE_STYLE_DOUBLE);
  1018.                                 assert(BORDER_STYLE_GROOVE ==
  1019.                                                 (enum op_border_style)
  1020.                                                 OUTLINE_STYLE_GROOVE);
  1021.                                 assert(BORDER_STYLE_GROOVE ==
  1022.                                                 (enum op_border_style)
  1023.                                                 COLUMN_RULE_STYLE_GROOVE);
  1024.                                 assert(BORDER_STYLE_RIDGE ==
  1025.                                                 (enum op_border_style)
  1026.                                                 OUTLINE_STYLE_RIDGE);
  1027.                                 assert(BORDER_STYLE_RIDGE ==
  1028.                                                 (enum op_border_style)
  1029.                                                 COLUMN_RULE_STYLE_RIDGE);
  1030.                                 assert(BORDER_STYLE_INSET ==
  1031.                                                 (enum op_border_style)
  1032.                                                 OUTLINE_STYLE_INSET);
  1033.                                 assert(BORDER_STYLE_INSET ==
  1034.                                                 (enum op_border_style)
  1035.                                                 COLUMN_RULE_STYLE_INSET);
  1036.                                 assert(BORDER_STYLE_OUTSET ==
  1037.                                                 (enum op_border_style)
  1038.                                                 OUTLINE_STYLE_OUTSET);
  1039.                                 assert(BORDER_STYLE_OUTSET ==
  1040.                                                 (enum op_border_style)
  1041.                                                 COLUMN_RULE_STYLE_OUTSET);
  1042.  
  1043.                                 switch (value) {
  1044.                                 case BORDER_STYLE_NONE:
  1045.                                         *ptr += sprintf(*ptr, "none");
  1046.                                         break;
  1047.                                 case BORDER_STYLE_HIDDEN:
  1048.                                         *ptr += sprintf(*ptr, "hidden");
  1049.                                         break;
  1050.                                 case BORDER_STYLE_DOTTED:
  1051.                                         *ptr += sprintf(*ptr, "dotted");
  1052.                                         break;
  1053.                                 case BORDER_STYLE_DASHED:
  1054.                                         *ptr += sprintf(*ptr, "dashed");
  1055.                                         break;
  1056.                                 case BORDER_STYLE_SOLID:
  1057.                                         *ptr += sprintf(*ptr, "solid");
  1058.                                         break;
  1059.                                 case BORDER_STYLE_DOUBLE:
  1060.                                         *ptr += sprintf(*ptr, "double");
  1061.                                         break;
  1062.                                 case BORDER_STYLE_GROOVE:
  1063.                                         *ptr += sprintf(*ptr, "groove");
  1064.                                         break;
  1065.                                 case BORDER_STYLE_RIDGE:
  1066.                                         *ptr += sprintf(*ptr, "ridge");
  1067.                                         break;
  1068.                                 case BORDER_STYLE_INSET:
  1069.                                         *ptr += sprintf(*ptr, "inset");
  1070.                                         break;
  1071.                                 case BORDER_STYLE_OUTSET:
  1072.                                         *ptr += sprintf(*ptr, "outset");
  1073.                                         break;
  1074.                                 }
  1075.                                 break;
  1076.                         case CSS_PROP_BORDER_TOP_WIDTH:
  1077.                         case CSS_PROP_BORDER_RIGHT_WIDTH:
  1078.                         case CSS_PROP_BORDER_BOTTOM_WIDTH:
  1079.                         case CSS_PROP_BORDER_LEFT_WIDTH:
  1080.                         case CSS_PROP_COLUMN_RULE_WIDTH:
  1081.                         case CSS_PROP_OUTLINE_WIDTH:
  1082.                                 assert(BORDER_WIDTH_SET ==
  1083.                                                 (enum op_border_width)
  1084.                                                 OUTLINE_WIDTH_SET);
  1085.                                 assert(BORDER_WIDTH_THIN ==
  1086.                                                 (enum op_border_width)
  1087.                                                 OUTLINE_WIDTH_THIN);
  1088.                                 assert(BORDER_WIDTH_MEDIUM ==
  1089.                                                 (enum op_border_width)
  1090.                                                 OUTLINE_WIDTH_MEDIUM);
  1091.                                 assert(BORDER_WIDTH_THICK ==
  1092.                                                 (enum op_border_width)
  1093.                                                 OUTLINE_WIDTH_THICK);
  1094.  
  1095.                                 switch (value) {
  1096.                                 case BORDER_WIDTH_SET:
  1097.                                 {
  1098.                                         uint32_t unit;
  1099.                                         css_fixed val = *((css_fixed *) bytecode);
  1100.                                         ADVANCE(sizeof(val));
  1101.                                         unit = *((uint32_t *) bytecode);
  1102.                                         ADVANCE(sizeof(unit));
  1103.                                         dump_unit(val, unit, ptr);
  1104.                                 }
  1105.                                         break;
  1106.                                 case BORDER_WIDTH_THIN:
  1107.                                         *ptr += sprintf(*ptr, "thin");
  1108.                                         break;
  1109.                                 case BORDER_WIDTH_MEDIUM:
  1110.                                         *ptr += sprintf(*ptr, "medium");
  1111.                                         break;
  1112.                                 case BORDER_WIDTH_THICK:
  1113.                                         *ptr += sprintf(*ptr, "thick");
  1114.                                         break;
  1115.                                 }
  1116.                                 break;
  1117.                         case CSS_PROP_MARGIN_TOP:
  1118.                         case CSS_PROP_MARGIN_RIGHT:
  1119.                         case CSS_PROP_MARGIN_BOTTOM:
  1120.                         case CSS_PROP_MARGIN_LEFT:
  1121.                         case CSS_PROP_BOTTOM:
  1122.                         case CSS_PROP_LEFT:
  1123.                         case CSS_PROP_RIGHT:
  1124.                         case CSS_PROP_TOP:
  1125.                         case CSS_PROP_HEIGHT:
  1126.                         case CSS_PROP_WIDTH:
  1127.                         case CSS_PROP_COLUMN_WIDTH:
  1128.                                 assert(BOTTOM_SET ==
  1129.                                                 (enum op_bottom) LEFT_SET);
  1130.                                 assert(BOTTOM_AUTO ==
  1131.                                                 (enum op_bottom) LEFT_AUTO);
  1132.                                 assert(BOTTOM_SET ==
  1133.                                                 (enum op_bottom) RIGHT_SET);
  1134.                                 assert(BOTTOM_AUTO ==
  1135.                                                 (enum op_bottom) RIGHT_AUTO);
  1136.                                 assert(BOTTOM_SET ==
  1137.                                                 (enum op_bottom) TOP_SET);
  1138.                                 assert(BOTTOM_AUTO ==
  1139.                                                 (enum op_bottom) TOP_AUTO);
  1140.                                 assert(BOTTOM_SET ==
  1141.                                                 (enum op_bottom) HEIGHT_SET);
  1142.                                 assert(BOTTOM_AUTO ==
  1143.                                                 (enum op_bottom) HEIGHT_AUTO);
  1144.                                 assert(BOTTOM_SET ==
  1145.                                                 (enum op_bottom) MARGIN_SET);
  1146.                                 assert(BOTTOM_AUTO ==
  1147.                                                 (enum op_bottom) MARGIN_AUTO);
  1148.                                 assert(BOTTOM_SET ==
  1149.                                                 (enum op_bottom) WIDTH_SET);
  1150.                                 assert(BOTTOM_AUTO ==
  1151.                                                 (enum op_bottom) WIDTH_AUTO);
  1152.                                 assert(BOTTOM_SET ==
  1153.                                                 (enum op_bottom)
  1154.                                                         COLUMN_WIDTH_SET);
  1155.                                 assert(BOTTOM_AUTO ==
  1156.                                                 (enum op_bottom)
  1157.                                                         COLUMN_WIDTH_AUTO);
  1158.  
  1159.                                 switch (value) {
  1160.                                 case BOTTOM_SET:
  1161.                                 {
  1162.                                         uint32_t unit;
  1163.                                         css_fixed val = *((css_fixed *) bytecode);
  1164.                                         ADVANCE(sizeof(val));
  1165.                                         unit = *((uint32_t *) bytecode);
  1166.                                         ADVANCE(sizeof(unit));
  1167.                                         dump_unit(val, unit, ptr);
  1168.                                 }
  1169.                                         break;
  1170.                                 case BOTTOM_AUTO:
  1171.                                         *ptr += sprintf(*ptr, "auto");
  1172.                                         break;
  1173.                                 }
  1174.                                 break;
  1175.                         case CSS_PROP_BREAK_AFTER:
  1176.                         case CSS_PROP_BREAK_BEFORE:
  1177.                                 assert(BREAK_AFTER_AUTO ==
  1178.                                                 (enum op_break_after)
  1179.                                                 BREAK_BEFORE_AUTO);
  1180.                                 assert(BREAK_AFTER_ALWAYS ==
  1181.                                                 (enum op_break_after)
  1182.                                                 BREAK_BEFORE_ALWAYS);
  1183.                                 assert(BREAK_AFTER_AVOID ==
  1184.                                                 (enum op_break_after)
  1185.                                                 BREAK_BEFORE_AVOID);
  1186.                                 assert(BREAK_AFTER_LEFT ==
  1187.                                                 (enum op_break_after)
  1188.                                                 BREAK_BEFORE_LEFT);
  1189.                                 assert(BREAK_AFTER_RIGHT ==
  1190.                                                 (enum op_break_after)
  1191.                                                 BREAK_BEFORE_RIGHT);
  1192.                                 assert(BREAK_AFTER_PAGE ==
  1193.                                                 (enum op_break_after)
  1194.                                                 BREAK_BEFORE_PAGE);
  1195.                                 assert(BREAK_AFTER_COLUMN ==
  1196.                                                 (enum op_break_after)
  1197.                                                 BREAK_BEFORE_COLUMN);
  1198.                                 assert(BREAK_AFTER_AVOID_PAGE ==
  1199.                                                 (enum op_break_after)
  1200.                                                 BREAK_BEFORE_AVOID_PAGE);
  1201.                                 assert(BREAK_AFTER_AVOID_COLUMN ==
  1202.                                                 (enum op_break_after)
  1203.                                                 BREAK_BEFORE_AVOID_COLUMN);
  1204.  
  1205.                                 switch (value) {
  1206.                                 case BREAK_AFTER_AUTO:
  1207.                                         *ptr += sprintf(*ptr, "auto");
  1208.                                         break;
  1209.                                 case BREAK_AFTER_ALWAYS:
  1210.                                         *ptr += sprintf(*ptr, "always");
  1211.                                         break;
  1212.                                 case BREAK_AFTER_AVOID:
  1213.                                         *ptr += sprintf(*ptr, "avoid");
  1214.                                         break;
  1215.                                 case BREAK_AFTER_LEFT:
  1216.                                         *ptr += sprintf(*ptr, "left");
  1217.                                         break;
  1218.                                 case BREAK_AFTER_RIGHT:
  1219.                                         *ptr += sprintf(*ptr, "right");
  1220.                                         break;
  1221.                                 case BREAK_AFTER_PAGE:
  1222.                                         *ptr += sprintf(*ptr, "page");
  1223.                                         break;
  1224.                                 case BREAK_AFTER_COLUMN:
  1225.                                         *ptr += sprintf(*ptr, "column");
  1226.                                         break;
  1227.                                 case BREAK_AFTER_AVOID_PAGE:
  1228.                                         *ptr += sprintf(*ptr, "avoid-page");
  1229.                                         break;
  1230.                                 case BREAK_AFTER_AVOID_COLUMN:
  1231.                                         *ptr += sprintf(*ptr, "avoid-column");
  1232.                                         break;
  1233.                                 }
  1234.                                 break;
  1235.                         case CSS_PROP_BREAK_INSIDE:
  1236.                                 switch (value) {
  1237.                                 case BREAK_INSIDE_AUTO:
  1238.                                         *ptr += sprintf(*ptr, "auto");
  1239.                                         break;
  1240.                                 case BREAK_INSIDE_AVOID:
  1241.                                         *ptr += sprintf(*ptr, "avoid");
  1242.                                         break;
  1243.                                 case BREAK_INSIDE_AVOID_PAGE:
  1244.                                         *ptr += sprintf(*ptr, "avoid-page");
  1245.                                         break;
  1246.                                 case BREAK_INSIDE_AVOID_COLUMN:
  1247.                                         *ptr += sprintf(*ptr, "avoid-column");
  1248.                                         break;
  1249.                                 }
  1250.                                 break;
  1251.                         case CSS_PROP_CAPTION_SIDE:
  1252.                                 switch (value) {
  1253.                                 case CAPTION_SIDE_TOP:
  1254.                                         *ptr += sprintf(*ptr, "top");
  1255.                                         break;
  1256.                                 case CAPTION_SIDE_BOTTOM:
  1257.                                         *ptr += sprintf(*ptr, "bottom");
  1258.                                         break;
  1259.                                 }
  1260.                                 break;
  1261.                         case CSS_PROP_CLEAR:
  1262.                                 switch (value) {
  1263.                                 case CLEAR_NONE:
  1264.                                         *ptr += sprintf(*ptr, "none");
  1265.                                         break;
  1266.                                 case CLEAR_LEFT:
  1267.                                         *ptr += sprintf(*ptr, "left");
  1268.                                         break;
  1269.                                 case CLEAR_RIGHT:
  1270.                                         *ptr += sprintf(*ptr, "right");
  1271.                                         break;
  1272.                                 case CLEAR_BOTH:
  1273.                                         *ptr += sprintf(*ptr, "both");
  1274.                                         break;
  1275.                                 }
  1276.                                 break;
  1277.                         case CSS_PROP_CLIP:
  1278.                                 if ((value & CLIP_SHAPE_MASK) ==
  1279.                                                 CLIP_SHAPE_RECT) {
  1280.                                         *ptr += sprintf(*ptr, "rect(");
  1281.                                         if (value & CLIP_RECT_TOP_AUTO) {
  1282.                                                 *ptr += sprintf(*ptr, "auto");
  1283.                                         } else {
  1284.                                                 uint32_t unit;
  1285.                                                 css_fixed val =
  1286.                                                         *((css_fixed *) bytecode);
  1287.                                                 ADVANCE(sizeof(val));
  1288.                                                 unit = *((uint32_t *) bytecode);
  1289.                                                 ADVANCE(sizeof(unit));
  1290.                                                 dump_unit(val, unit, ptr);
  1291.                                         }
  1292.                                         *ptr += sprintf(*ptr, ", ");
  1293.                                         if (value & CLIP_RECT_RIGHT_AUTO) {
  1294.                                                 *ptr += sprintf(*ptr, "auto");
  1295.                                         } else {
  1296.                                                 uint32_t unit;
  1297.                                                 css_fixed val =
  1298.                                                         *((css_fixed *) bytecode);
  1299.                                                 ADVANCE(sizeof(val));
  1300.                                                 unit = *((uint32_t *) bytecode);
  1301.                                                 ADVANCE(sizeof(unit));
  1302.                                                 dump_unit(val, unit, ptr);
  1303.                                         }
  1304.                                         *ptr += sprintf(*ptr, ", ");
  1305.                                         if (value & CLIP_RECT_BOTTOM_AUTO) {
  1306.                                                 *ptr += sprintf(*ptr, "auto");
  1307.                                         } else {
  1308.                                                 uint32_t unit;
  1309.                                                 css_fixed val =
  1310.                                                         *((css_fixed *) bytecode);
  1311.                                                 ADVANCE(sizeof(val));
  1312.                                                 unit = *((uint32_t *) bytecode);
  1313.                                                 ADVANCE(sizeof(unit));
  1314.                                                 dump_unit(val, unit, ptr);
  1315.                                         }
  1316.                                         *ptr += sprintf(*ptr, ", ");
  1317.                                         if (value & CLIP_RECT_LEFT_AUTO) {
  1318.                                                 *ptr += sprintf(*ptr, "auto");
  1319.                                         } else {
  1320.                                                 uint32_t unit;
  1321.                                                 css_fixed val =
  1322.                                                         *((css_fixed *) bytecode);
  1323.                                                 ADVANCE(sizeof(val));
  1324.                                                 unit = *((uint32_t *) bytecode);
  1325.                                                 ADVANCE(sizeof(unit));
  1326.                                                 dump_unit(val, unit, ptr);
  1327.                                         }
  1328.                                         *ptr += sprintf(*ptr, ")");
  1329.                                 } else
  1330.                                         *ptr += sprintf(*ptr, "auto");
  1331.                                 break;
  1332.                         case CSS_PROP_COLOR:
  1333.                                 switch (value) {
  1334.                                 case COLOR_TRANSPARENT:
  1335.                                         *ptr += sprintf(*ptr, "transparent");
  1336.                                         break;
  1337.                                 case COLOR_CURRENT_COLOR:
  1338.                                         *ptr += sprintf(*ptr, "currentColor");
  1339.                                         break;
  1340.                                 case COLOR_SET:
  1341.                                 {
  1342.                                         uint32_t colour =
  1343.                                                 *((uint32_t *) bytecode);
  1344.                                         ADVANCE(sizeof(colour));
  1345.                                         *ptr += sprintf(*ptr, "#%08x", colour);
  1346.                                 }      
  1347.                                         break;
  1348.                                 }
  1349.                                 break;
  1350.                         case CSS_PROP_COLUMN_COUNT:
  1351.                                 switch (value) {
  1352.                                 case COLUMN_COUNT_SET:
  1353.                                 {
  1354.                                         css_fixed val = *((css_fixed *) bytecode);
  1355.                                         ADVANCE(sizeof(val));
  1356.                                         dump_number(val, ptr);
  1357.                                 }
  1358.                                         break;
  1359.                                 case COLUMN_COUNT_AUTO:
  1360.                                         *ptr += sprintf(*ptr, "auto");
  1361.                                         break;
  1362.                                 }
  1363.                                 break;
  1364.                         case CSS_PROP_COLUMN_FILL:
  1365.                                 switch (value) {
  1366.                                 case COLUMN_FILL_BALANCE:
  1367.                                         *ptr += sprintf(*ptr, "balance");
  1368.                                         break;
  1369.                                 case COLUMN_FILL_AUTO:
  1370.                                         *ptr += sprintf(*ptr, "auto");
  1371.                                         break;
  1372.                                 }
  1373.                                 break;
  1374.                         case CSS_PROP_COLUMN_GAP:
  1375.                                 switch (value) {
  1376.                                 case COLUMN_GAP_SET:
  1377.                                 {
  1378.                                         uint32_t unit;
  1379.                                         css_fixed val = *((css_fixed *) bytecode);
  1380.                                         ADVANCE(sizeof(val));
  1381.                                         unit = *((uint32_t *) bytecode);
  1382.                                         ADVANCE(sizeof(unit));
  1383.                                         dump_unit(val, unit, ptr);
  1384.                                 }
  1385.                                         break;
  1386.                                 case COLUMN_GAP_NORMAL:
  1387.                                         *ptr += sprintf(*ptr, "normal");
  1388.                                         break;
  1389.                                 }
  1390.                                 break;
  1391.                         case CSS_PROP_COLUMN_SPAN:
  1392.                                 switch (value) {
  1393.                                 case COLUMN_SPAN_NONE:
  1394.                                         *ptr += sprintf(*ptr, "none");
  1395.                                         break;
  1396.                                 case COLUMN_SPAN_ALL:
  1397.                                         *ptr += sprintf(*ptr, "all");
  1398.                                         break;
  1399.                                 }
  1400.                                 break;
  1401.                         case CSS_PROP_CONTENT:
  1402.                                 if (value == CONTENT_NORMAL) {
  1403.                                         *ptr += sprintf(*ptr, "normal");
  1404.                                         break;
  1405.                                 } else if (value == CONTENT_NONE) {
  1406.                                         *ptr += sprintf(*ptr, "none");
  1407.                                         break;
  1408.                                 }
  1409.  
  1410.                                 while (value != CONTENT_NORMAL) {
  1411.                                         uint32_t snum = *((uint32_t *) bytecode);                                      
  1412.                                         lwc_string *he;
  1413.                                         const char *end = "";
  1414.  
  1415.                                         switch (value & 0xff) {
  1416.                                         case CONTENT_COUNTER:
  1417.                                                 css__stylesheet_string_get(style->sheet, snum, &he);
  1418.                                                 ADVANCE(sizeof(snum));
  1419.                                                 dump_counter(he, value, ptr);
  1420.                                                 break;
  1421.  
  1422.                                         case CONTENT_COUNTERS:
  1423.                                         {
  1424.                                                 lwc_string *sep;
  1425.                                                 css__stylesheet_string_get(style->sheet, snum, &he);
  1426.                                                 ADVANCE(sizeof(snum));
  1427.  
  1428.                                                 sep = *((lwc_string **) bytecode);
  1429.                                                 ADVANCE(sizeof(sep));
  1430.  
  1431.                                                 dump_counters(he, sep, value,
  1432.                                                         ptr);
  1433.                                         }
  1434.                                                 break;
  1435.  
  1436.                                         case CONTENT_URI:
  1437.                                         case CONTENT_ATTR:     
  1438.                                         case CONTENT_STRING:
  1439.                                                 css__stylesheet_string_get(style->sheet, snum, &he);
  1440.                                                 if (value == CONTENT_URI)
  1441.                                                         *ptr += sprintf(*ptr, "url(");
  1442.                                                 if (value == CONTENT_ATTR)
  1443.                                                         *ptr += sprintf(*ptr, "attr(");
  1444.                                                 if (value != CONTENT_STRING)
  1445.                                                         end = ")";
  1446.  
  1447.                                                 ADVANCE(sizeof(snum));
  1448.  
  1449.                                                 *ptr += sprintf(*ptr, "'%.*s'%s",
  1450.                                                                 (int) lwc_string_length(he),
  1451.                                                                 lwc_string_data(he),
  1452.                                                         end);
  1453.                                                 break;
  1454.  
  1455.                                         case CONTENT_OPEN_QUOTE:
  1456.                                                 *ptr += sprintf(*ptr, "open-quote");
  1457.                                                 break;
  1458.  
  1459.                                         case CONTENT_CLOSE_QUOTE:
  1460.                                                 *ptr += sprintf(*ptr, "close-quote");
  1461.                                                 break;
  1462.  
  1463.                                         case CONTENT_NO_OPEN_QUOTE:
  1464.                                                 *ptr += sprintf(*ptr, "no-open-quote");
  1465.                                                 break;
  1466.  
  1467.                                         case CONTENT_NO_CLOSE_QUOTE:
  1468.                                                 *ptr += sprintf(*ptr, "no-close-quote");
  1469.                                                 break;
  1470.                                         }
  1471.  
  1472.                                         value = *((uint32_t *) bytecode);
  1473.                                         ADVANCE(sizeof(value));
  1474.  
  1475.                                         if (value != CONTENT_NORMAL)
  1476.                                                 *ptr += sprintf(*ptr, " ");
  1477.                                 }
  1478.                                 break;
  1479.                         case CSS_PROP_COUNTER_INCREMENT:
  1480.                         case CSS_PROP_COUNTER_RESET:
  1481.                                 assert(COUNTER_INCREMENT_NONE ==
  1482.                                                 (enum op_counter_increment)
  1483.                                                 COUNTER_RESET_NONE);
  1484.                                 assert(COUNTER_INCREMENT_NAMED ==
  1485.                                                 (enum op_counter_increment)
  1486.                                                 COUNTER_RESET_NAMED);
  1487.  
  1488.                                 switch (value) {
  1489.                                 case COUNTER_INCREMENT_NAMED:
  1490.                                         while (value != COUNTER_INCREMENT_NONE) {
  1491.                                                 css_fixed val;
  1492.                                         uint32_t snum = *((uint32_t *) bytecode);                                       lwc_string *he;
  1493.                                         css__stylesheet_string_get(style->sheet,
  1494.                                                                   snum,
  1495.                                                                   &he);
  1496.                                                 ADVANCE(sizeof(snum));
  1497.                                                 *ptr += sprintf(*ptr, "%.*s ",
  1498.                                                                 (int)lwc_string_length(he),
  1499.                                                                 lwc_string_data(he));
  1500.                                                 val = *((css_fixed *) bytecode);
  1501.                                                 ADVANCE(sizeof(val));
  1502.                                                 dump_number(val, ptr);
  1503.  
  1504.                                                 value = *((uint32_t *) bytecode);
  1505.                                                 ADVANCE(sizeof(value));
  1506.  
  1507.                                                 if (value !=
  1508.                                                         COUNTER_INCREMENT_NONE)
  1509.                                                         *ptr += sprintf(*ptr,
  1510.                                                                         " ");
  1511.                                         }
  1512.                                         break;
  1513.                                 case COUNTER_INCREMENT_NONE:
  1514.                                         *ptr += sprintf(*ptr, "none");
  1515.                                         break;
  1516.                                 }
  1517.                                 break;
  1518.                         case CSS_PROP_CURSOR:
  1519.                                 while (value == CURSOR_URI) {
  1520.                                         uint32_t snum = *((uint32_t *) bytecode);                                       lwc_string *he;
  1521.                                         css__stylesheet_string_get(style->sheet,
  1522.                                                                   snum,
  1523.                                                                   &he);
  1524.                                         ADVANCE(sizeof(snum));
  1525.                                         *ptr += sprintf(*ptr, "url('%.*s'), ",
  1526.                                                         (int) lwc_string_length(he),
  1527.                                                         lwc_string_data(he));
  1528.  
  1529.                                         value = *((uint32_t *) bytecode);
  1530.                                         ADVANCE(sizeof(value));
  1531.                                 }
  1532.  
  1533.                                 switch (value) {
  1534.                                 case CURSOR_AUTO:
  1535.                                         *ptr += sprintf(*ptr, "auto");
  1536.                                         break;
  1537.                                 case CURSOR_CROSSHAIR:
  1538.                                         *ptr += sprintf(*ptr, "crosshair");
  1539.                                         break;
  1540.                                 case CURSOR_DEFAULT:
  1541.                                         *ptr += sprintf(*ptr, "default");
  1542.                                         break;
  1543.                                 case CURSOR_POINTER:
  1544.                                         *ptr += sprintf(*ptr, "pointer");
  1545.                                         break;
  1546.                                 case CURSOR_MOVE:
  1547.                                         *ptr += sprintf(*ptr, "move");
  1548.                                         break;
  1549.                                 case CURSOR_E_RESIZE:
  1550.                                         *ptr += sprintf(*ptr, "e-resize");
  1551.                                         break;
  1552.                                 case CURSOR_NE_RESIZE:
  1553.                                         *ptr += sprintf(*ptr, "ne-resize");
  1554.                                         break;
  1555.                                 case CURSOR_NW_RESIZE:
  1556.                                         *ptr += sprintf(*ptr, "nw-resize");
  1557.                                         break;
  1558.                                 case CURSOR_N_RESIZE:
  1559.                                         *ptr += sprintf(*ptr, "n-resize");
  1560.                                         break;
  1561.                                 case CURSOR_SE_RESIZE:
  1562.                                         *ptr += sprintf(*ptr, "se-resize");
  1563.                                         break;
  1564.                                 case CURSOR_SW_RESIZE:
  1565.                                         *ptr += sprintf(*ptr, "sw-resize");
  1566.                                         break;
  1567.                                 case CURSOR_S_RESIZE:
  1568.                                         *ptr += sprintf(*ptr, "s-resize");
  1569.                                         break;
  1570.                                 case CURSOR_W_RESIZE:
  1571.                                         *ptr += sprintf(*ptr, "w-resize");
  1572.                                         break;
  1573.                                 case CURSOR_TEXT:
  1574.                                         *ptr += sprintf(*ptr, "text");
  1575.                                         break;
  1576.                                 case CURSOR_WAIT:
  1577.                                         *ptr += sprintf(*ptr, "wait");
  1578.                                         break;
  1579.                                 case CURSOR_HELP:
  1580.                                         *ptr += sprintf(*ptr, "help");
  1581.                                         break;
  1582.                                 case CURSOR_PROGRESS:
  1583.                                         *ptr += sprintf(*ptr, "progress");
  1584.                                         break;
  1585.                                 }
  1586.                                 break;
  1587.                         case CSS_PROP_DIRECTION:
  1588.                                 switch (value) {
  1589.                                 case DIRECTION_LTR:
  1590.                                         *ptr += sprintf(*ptr, "ltr");
  1591.                                         break;
  1592.                                 case DIRECTION_RTL:
  1593.                                         *ptr += sprintf(*ptr, "rtl");
  1594.                                         break;
  1595.                                 }
  1596.                                 break;
  1597.                         case CSS_PROP_DISPLAY:
  1598.                                 switch (value) {
  1599.                                 case DISPLAY_INLINE:
  1600.                                         *ptr += sprintf(*ptr, "inline");
  1601.                                         break;
  1602.                                 case DISPLAY_BLOCK:
  1603.                                         *ptr += sprintf(*ptr, "block");
  1604.                                         break;
  1605.                                 case DISPLAY_LIST_ITEM:
  1606.                                         *ptr += sprintf(*ptr, "list-item");
  1607.                                         break;
  1608.                                 case DISPLAY_RUN_IN:
  1609.                                         *ptr += sprintf(*ptr, "run-in");
  1610.                                         break;
  1611.                                 case DISPLAY_INLINE_BLOCK:
  1612.                                         *ptr += sprintf(*ptr, "inline-block");
  1613.                                         break;
  1614.                                 case DISPLAY_TABLE:
  1615.                                         *ptr += sprintf(*ptr, "table");
  1616.                                         break;
  1617.                                 case DISPLAY_INLINE_TABLE:
  1618.                                         *ptr += sprintf(*ptr, "inline-table");
  1619.                                         break;
  1620.                                 case DISPLAY_TABLE_ROW_GROUP:
  1621.                                         *ptr += sprintf(*ptr, "table-row-group");
  1622.                                         break;
  1623.                                 case DISPLAY_TABLE_HEADER_GROUP:
  1624.                                         *ptr += sprintf(*ptr, "table-header-group");
  1625.                                         break;
  1626.                                 case DISPLAY_TABLE_FOOTER_GROUP:
  1627.                                         *ptr += sprintf(*ptr, "table-footer-group");
  1628.                                         break;
  1629.                                 case DISPLAY_TABLE_ROW:
  1630.                                         *ptr += sprintf(*ptr, "table-row");
  1631.                                         break;
  1632.                                 case DISPLAY_TABLE_COLUMN_GROUP:
  1633.                                         *ptr += sprintf(*ptr, "table-column-group");
  1634.                                         break;
  1635.                                 case DISPLAY_TABLE_COLUMN:
  1636.                                         *ptr += sprintf(*ptr, "table-column");
  1637.                                         break;
  1638.                                 case DISPLAY_TABLE_CELL:
  1639.                                         *ptr += sprintf(*ptr, "table-cell");
  1640.                                         break;
  1641.                                 case DISPLAY_TABLE_CAPTION:
  1642.                                         *ptr += sprintf(*ptr, "table-caption");
  1643.                                         break;
  1644.                                 case DISPLAY_NONE:
  1645.                                         *ptr += sprintf(*ptr, "none");
  1646.                                         break;
  1647.                                 }
  1648.                                 break;
  1649.                         case CSS_PROP_ELEVATION:
  1650.                                 switch (value) {
  1651.                                 case ELEVATION_ANGLE:
  1652.                                 {
  1653.                                         uint32_t unit;
  1654.                                         css_fixed val = *((css_fixed *) bytecode);
  1655.                                         ADVANCE(sizeof(val));
  1656.                                         unit = *((uint32_t *) bytecode);
  1657.                                         ADVANCE(sizeof(unit));
  1658.                                         dump_unit(val, unit, ptr);
  1659.                                 }
  1660.                                         break;
  1661.                                 case ELEVATION_BELOW:
  1662.                                         *ptr += sprintf(*ptr, "below");
  1663.                                         break;
  1664.                                 case ELEVATION_LEVEL:
  1665.                                         *ptr += sprintf(*ptr, "level");
  1666.                                         break;
  1667.                                 case ELEVATION_ABOVE:
  1668.                                         *ptr += sprintf(*ptr, "above");
  1669.                                         break;
  1670.                                 case ELEVATION_HIGHER:
  1671.                                         *ptr += sprintf(*ptr, "higher");
  1672.                                         break;
  1673.                                 case ELEVATION_LOWER:
  1674.                                         *ptr += sprintf(*ptr, "lower");
  1675.                                         break;
  1676.                                 }
  1677.                                 break;
  1678.                         case CSS_PROP_EMPTY_CELLS:
  1679.                                 switch (value) {
  1680.                                 case EMPTY_CELLS_SHOW:
  1681.                                         *ptr += sprintf(*ptr, "show");
  1682.                                         break;
  1683.                                 case EMPTY_CELLS_HIDE:
  1684.                                         *ptr += sprintf(*ptr, "hide");
  1685.                                         break;
  1686.                                 }
  1687.                                 break;
  1688.                         case CSS_PROP_FLOAT:
  1689.                                 switch (value) {
  1690.                                 case FLOAT_LEFT:
  1691.                                         *ptr += sprintf(*ptr, "left");
  1692.                                         break;
  1693.                                 case FLOAT_RIGHT:
  1694.                                         *ptr += sprintf(*ptr, "right");
  1695.                                         break;
  1696.                                 case FLOAT_NONE:
  1697.                                         *ptr += sprintf(*ptr, "none");
  1698.                                         break;
  1699.                                 }
  1700.                                 break;
  1701.                         case CSS_PROP_FONT_FAMILY:
  1702.                                 while (value != FONT_FAMILY_END) {
  1703.                                         switch (value) {
  1704.                                         case FONT_FAMILY_STRING:
  1705.                                         case FONT_FAMILY_IDENT_LIST:
  1706.                                         {
  1707.                                                 uint32_t snum = *((uint32_t *) bytecode);                                      
  1708.                                                 lwc_string *he;
  1709.                                                 css__stylesheet_string_get(style->sheet, snum, &he);
  1710.                                                 ADVANCE(sizeof(snum));
  1711.                                                 *ptr += sprintf(*ptr, "'%.*s'",
  1712.                                                                 (int) lwc_string_length(he),
  1713.                                                                 lwc_string_data(he));
  1714.                                         }
  1715.                                                 break;
  1716.                                         case FONT_FAMILY_SERIF:
  1717.                                                 *ptr += sprintf(*ptr, "serif");
  1718.                                                 break;
  1719.                                         case FONT_FAMILY_SANS_SERIF:
  1720.                                                 *ptr += sprintf(*ptr, "sans-serif");
  1721.                                                 break;
  1722.                                         case FONT_FAMILY_CURSIVE:
  1723.                                                 *ptr += sprintf(*ptr, "cursive");
  1724.                                                 break;
  1725.                                         case FONT_FAMILY_FANTASY:
  1726.                                                 *ptr += sprintf(*ptr, "fantasy");
  1727.                                                 break;
  1728.                                         case FONT_FAMILY_MONOSPACE:
  1729.                                                 *ptr += sprintf(*ptr, "monospace");
  1730.                                                 break;
  1731.                                         }
  1732.  
  1733.                                         value = *((uint32_t *) bytecode);
  1734.                                         ADVANCE(sizeof(value));
  1735.  
  1736.                                         if (value != FONT_FAMILY_END)
  1737.                                                 *ptr += sprintf(*ptr, ", ");
  1738.                                 }
  1739.                                 break;
  1740.                         case CSS_PROP_FONT_SIZE:
  1741.                                 switch (value) {
  1742.                                 case FONT_SIZE_DIMENSION:
  1743.                                 {
  1744.                                         uint32_t unit;
  1745.                                         css_fixed val = *((css_fixed *) bytecode);
  1746.                                         ADVANCE(sizeof(val));
  1747.                                         unit = *((uint32_t *) bytecode);
  1748.                                         ADVANCE(sizeof(unit));
  1749.                                         dump_unit(val, unit, ptr);
  1750.                                 }
  1751.                                         break;
  1752.                                 case FONT_SIZE_XX_SMALL:
  1753.                                         *ptr += sprintf(*ptr, "xx-small");
  1754.                                         break;
  1755.                                 case FONT_SIZE_X_SMALL:
  1756.                                         *ptr += sprintf(*ptr, "x-small");
  1757.                                         break;
  1758.                                 case FONT_SIZE_SMALL:
  1759.                                         *ptr += sprintf(*ptr, "small");
  1760.                                         break;
  1761.                                 case FONT_SIZE_MEDIUM:
  1762.                                         *ptr += sprintf(*ptr, "medium");
  1763.                                         break;
  1764.                                 case FONT_SIZE_LARGE:
  1765.                                         *ptr += sprintf(*ptr, "large");
  1766.                                         break;
  1767.                                 case FONT_SIZE_X_LARGE:
  1768.                                         *ptr += sprintf(*ptr, "x-large");
  1769.                                         break;
  1770.                                 case FONT_SIZE_XX_LARGE:
  1771.                                         *ptr += sprintf(*ptr, "xx-large");
  1772.                                         break;
  1773.                                 case FONT_SIZE_LARGER:
  1774.                                         *ptr += sprintf(*ptr, "larger");
  1775.                                         break;
  1776.                                 case FONT_SIZE_SMALLER:
  1777.                                         *ptr += sprintf(*ptr, "smaller");
  1778.                                         break;
  1779.                                 }
  1780.                                 break;
  1781.                         case CSS_PROP_FONT_STYLE:
  1782.                                 switch (value) {
  1783.                                 case FONT_STYLE_NORMAL:
  1784.                                         *ptr += sprintf(*ptr, "normal");
  1785.                                         break;
  1786.                                 case FONT_STYLE_ITALIC:
  1787.                                         *ptr += sprintf(*ptr, "italic");
  1788.                                         break;
  1789.                                 case FONT_STYLE_OBLIQUE:
  1790.                                         *ptr += sprintf(*ptr, "oblique");
  1791.                                         break;
  1792.                                 }
  1793.                                 break;
  1794.                         case CSS_PROP_FONT_VARIANT:
  1795.                                 switch (value) {
  1796.                                 case FONT_VARIANT_NORMAL:
  1797.                                         *ptr += sprintf(*ptr, "normal");
  1798.                                         break;
  1799.                                 case FONT_VARIANT_SMALL_CAPS:
  1800.                                         *ptr += sprintf(*ptr, "small-caps");
  1801.                                         break;
  1802.                                 }
  1803.                                 break;
  1804.                         case CSS_PROP_FONT_WEIGHT:
  1805.                                 switch (value) {
  1806.                                 case FONT_WEIGHT_NORMAL:
  1807.                                         *ptr += sprintf(*ptr, "normal");
  1808.                                         break;
  1809.                                 case FONT_WEIGHT_BOLD:
  1810.                                         *ptr += sprintf(*ptr, "bold");
  1811.                                         break;
  1812.                                 case FONT_WEIGHT_BOLDER:
  1813.                                         *ptr += sprintf(*ptr, "bolder");
  1814.                                         break;
  1815.                                 case FONT_WEIGHT_LIGHTER:
  1816.                                         *ptr += sprintf(*ptr, "lighter");
  1817.                                         break;
  1818.                                 case FONT_WEIGHT_100:
  1819.                                         *ptr += sprintf(*ptr, "100");
  1820.                                         break;
  1821.                                 case FONT_WEIGHT_200:
  1822.                                         *ptr += sprintf(*ptr, "200");
  1823.                                         break;
  1824.                                 case FONT_WEIGHT_300:
  1825.                                         *ptr += sprintf(*ptr, "300");
  1826.                                         break;
  1827.                                 case FONT_WEIGHT_400:
  1828.                                         *ptr += sprintf(*ptr, "400");
  1829.                                         break;
  1830.                                 case FONT_WEIGHT_500:
  1831.                                         *ptr += sprintf(*ptr, "500");
  1832.                                         break;
  1833.                                 case FONT_WEIGHT_600:
  1834.                                         *ptr += sprintf(*ptr, "600");
  1835.                                         break;
  1836.                                 case FONT_WEIGHT_700:
  1837.                                         *ptr += sprintf(*ptr, "700");
  1838.                                         break;
  1839.                                 case FONT_WEIGHT_800:
  1840.                                         *ptr += sprintf(*ptr, "800");
  1841.                                         break;
  1842.                                 case FONT_WEIGHT_900:
  1843.                                         *ptr += sprintf(*ptr, "900");
  1844.                                         break;
  1845.                                 }
  1846.                                 break;
  1847.                         case CSS_PROP_LETTER_SPACING:
  1848.                         case CSS_PROP_WORD_SPACING:
  1849.                                 assert(LETTER_SPACING_SET ==
  1850.                                                 (enum op_letter_spacing)
  1851.                                                 WORD_SPACING_SET);
  1852.                                 assert(LETTER_SPACING_NORMAL ==
  1853.                                                 (enum op_letter_spacing)
  1854.                                                 WORD_SPACING_NORMAL);
  1855.  
  1856.                                 switch (value) {
  1857.                                 case LETTER_SPACING_SET:
  1858.                                 {
  1859.                                         uint32_t unit;
  1860.                                         css_fixed val = *((css_fixed *) bytecode);
  1861.                                         ADVANCE(sizeof(val));
  1862.                                         unit = *((uint32_t *) bytecode);
  1863.                                         ADVANCE(sizeof(unit));
  1864.                                         dump_unit(val, unit, ptr);
  1865.                                 }
  1866.                                         break;
  1867.                                 case LETTER_SPACING_NORMAL:
  1868.                                         *ptr += sprintf(*ptr, "normal");
  1869.                                         break;
  1870.                                 }
  1871.                                 break;
  1872.                         case CSS_PROP_LINE_HEIGHT:
  1873.                                 switch (value) {
  1874.                                 case LINE_HEIGHT_NUMBER:
  1875.                                 {
  1876.                                         css_fixed val = *((css_fixed *) bytecode);
  1877.                                         ADVANCE(sizeof(val));
  1878.                                         dump_number(val, ptr);
  1879.                                 }
  1880.                                         break;
  1881.                                 case LINE_HEIGHT_DIMENSION:
  1882.                                 {
  1883.                                         uint32_t unit;
  1884.                                         css_fixed val = *((css_fixed *) bytecode);
  1885.                                         ADVANCE(sizeof(val));
  1886.                                         unit = *((uint32_t *) bytecode);
  1887.                                         ADVANCE(sizeof(unit));
  1888.                                         dump_unit(val, unit, ptr);
  1889.                                 }
  1890.                                         break;
  1891.                                 case LINE_HEIGHT_NORMAL:
  1892.                                         *ptr += sprintf(*ptr, "normal");
  1893.                                         break;
  1894.                                 }
  1895.                                 break;
  1896.                         case CSS_PROP_LIST_STYLE_POSITION:
  1897.                                 switch (value) {
  1898.                                 case LIST_STYLE_POSITION_INSIDE:
  1899.                                         *ptr += sprintf(*ptr, "inside");
  1900.                                         break;
  1901.                                 case LIST_STYLE_POSITION_OUTSIDE:
  1902.                                         *ptr += sprintf(*ptr, "outside");
  1903.                                         break;
  1904.                                 }
  1905.                                 break;
  1906.                         case CSS_PROP_LIST_STYLE_TYPE:
  1907.                                 switch (value) {
  1908.                                 case LIST_STYLE_TYPE_DISC:
  1909.                                         *ptr += sprintf(*ptr, "disc");
  1910.                                         break;
  1911.                                 case LIST_STYLE_TYPE_CIRCLE:
  1912.                                         *ptr += sprintf(*ptr, "circle");
  1913.                                         break;
  1914.                                 case LIST_STYLE_TYPE_SQUARE:
  1915.                                         *ptr += sprintf(*ptr, "square");
  1916.                                         break;
  1917.                                 case LIST_STYLE_TYPE_DECIMAL:
  1918.                                         *ptr += sprintf(*ptr, "decimal");
  1919.                                         break;
  1920.                                 case LIST_STYLE_TYPE_DECIMAL_LEADING_ZERO:
  1921.                                         *ptr += sprintf(*ptr, "decimal-leading-zero");
  1922.                                         break;
  1923.                                 case LIST_STYLE_TYPE_LOWER_ROMAN:
  1924.                                         *ptr += sprintf(*ptr, "lower-roman");
  1925.                                         break;
  1926.                                 case LIST_STYLE_TYPE_UPPER_ROMAN:
  1927.                                         *ptr += sprintf(*ptr, "upper-roman");
  1928.                                         break;
  1929.                                 case LIST_STYLE_TYPE_LOWER_GREEK:
  1930.                                         *ptr += sprintf(*ptr, "lower-greek");
  1931.                                         break;
  1932.                                 case LIST_STYLE_TYPE_LOWER_LATIN:
  1933.                                         *ptr += sprintf(*ptr, "lower-latin");
  1934.                                         break;
  1935.                                 case LIST_STYLE_TYPE_UPPER_LATIN:
  1936.                                         *ptr += sprintf(*ptr, "upper-latin");
  1937.                                         break;
  1938.                                 case LIST_STYLE_TYPE_ARMENIAN:
  1939.                                         *ptr += sprintf(*ptr, "armenian");
  1940.                                         break;
  1941.                                 case LIST_STYLE_TYPE_GEORGIAN:
  1942.                                         *ptr += sprintf(*ptr, "georgian");
  1943.                                         break;
  1944.                                 case LIST_STYLE_TYPE_LOWER_ALPHA:
  1945.                                         *ptr += sprintf(*ptr, "lower-alpha");
  1946.                                         break;
  1947.                                 case LIST_STYLE_TYPE_UPPER_ALPHA:
  1948.                                         *ptr += sprintf(*ptr, "upper-alpha");
  1949.                                         break;
  1950.                                 case LIST_STYLE_TYPE_NONE:
  1951.                                         *ptr += sprintf(*ptr, "none");
  1952.                                         break;
  1953.                                 }
  1954.                                 break;
  1955.                         case CSS_PROP_MAX_HEIGHT:
  1956.                         case CSS_PROP_MAX_WIDTH:
  1957.                                 assert(MAX_HEIGHT_SET ==
  1958.                                                 (enum op_max_height)
  1959.                                                 MAX_WIDTH_SET);
  1960.                                 assert(MAX_HEIGHT_NONE ==
  1961.                                                 (enum op_max_height)
  1962.                                                 MAX_WIDTH_NONE);
  1963.  
  1964.                                 switch (value) {
  1965.                                 case MAX_HEIGHT_SET:
  1966.                                 {
  1967.                                         uint32_t unit;
  1968.                                         css_fixed val = *((css_fixed *) bytecode);
  1969.                                         ADVANCE(sizeof(val));
  1970.                                         unit = *((uint32_t *) bytecode);
  1971.                                         ADVANCE(sizeof(unit));
  1972.                                         dump_unit(val, unit, ptr);
  1973.                                 }
  1974.                                         break;
  1975.                                 case MAX_HEIGHT_NONE:
  1976.                                         *ptr += sprintf(*ptr, "none");
  1977.                                         break;
  1978.                                 }
  1979.                                 break;
  1980.                         case CSS_PROP_OPACITY:
  1981.                                 switch (value) {
  1982.                                 case OPACITY_SET:
  1983.                                 {
  1984.                                         css_fixed val = *((css_fixed *) bytecode);
  1985.                                         ADVANCE(sizeof(val));
  1986.                                         dump_number(val, ptr);
  1987.                                 }
  1988.                                         break;
  1989.                                 }
  1990.                                 break;
  1991.                         case CSS_PROP_PADDING_TOP:
  1992.                         case CSS_PROP_PADDING_RIGHT:
  1993.                         case CSS_PROP_PADDING_BOTTOM:
  1994.                         case CSS_PROP_PADDING_LEFT:
  1995.                         case CSS_PROP_MIN_HEIGHT:
  1996.                         case CSS_PROP_MIN_WIDTH:
  1997.                         case CSS_PROP_PAUSE_AFTER:
  1998.                         case CSS_PROP_PAUSE_BEFORE:
  1999.                         case CSS_PROP_TEXT_INDENT:
  2000.                                 assert(MIN_HEIGHT_SET ==
  2001.                                                 (enum op_min_height)
  2002.                                                 MIN_WIDTH_SET);
  2003.                                 assert(MIN_HEIGHT_SET ==
  2004.                                                 (enum op_min_height)
  2005.                                                 PADDING_SET);
  2006.                                 assert(MIN_HEIGHT_SET ==
  2007.                                                 (enum op_min_height)
  2008.                                                 PAUSE_AFTER_SET);
  2009.                                 assert(MIN_HEIGHT_SET ==
  2010.                                                 (enum op_min_height)
  2011.                                                 PAUSE_BEFORE_SET);
  2012.                                 assert(MIN_HEIGHT_SET ==
  2013.                                                 (enum op_min_height)
  2014.                                                 TEXT_INDENT_SET);
  2015.  
  2016.                                 switch (value) {
  2017.                                 case MIN_HEIGHT_SET:
  2018.                                 {
  2019.                                         uint32_t unit;
  2020.                                         css_fixed val = *((css_fixed *) bytecode);
  2021.                                         ADVANCE(sizeof(val));
  2022.                                         unit = *((uint32_t *) bytecode);
  2023.                                         ADVANCE(sizeof(unit));
  2024.                                         dump_unit(val, unit, ptr);
  2025.                                 }
  2026.                                         break;
  2027.                                 }
  2028.                                 break;
  2029.                         case CSS_PROP_ORPHANS:
  2030.                         case CSS_PROP_PITCH_RANGE:
  2031.                         case CSS_PROP_RICHNESS:
  2032.                         case CSS_PROP_STRESS:
  2033.                         case CSS_PROP_WIDOWS:
  2034.                                 assert(ORPHANS_SET ==
  2035.                                                 (enum op_orphans)
  2036.                                                 PITCH_RANGE_SET);
  2037.                                 assert(ORPHANS_SET ==
  2038.                                                 (enum op_orphans)
  2039.                                                 RICHNESS_SET);
  2040.                                 assert(ORPHANS_SET ==
  2041.                                                 (enum op_orphans)
  2042.                                                 STRESS_SET);
  2043.                                 assert(ORPHANS_SET ==
  2044.                                                 (enum op_orphans)
  2045.                                                 WIDOWS_SET);
  2046.  
  2047.                                 switch (value) {
  2048.                                 case ORPHANS_SET:
  2049.                                 {
  2050.                                         css_fixed val = *((css_fixed *) bytecode);
  2051.                                         ADVANCE(sizeof(val));
  2052.                                         dump_number(val, ptr);
  2053.                                 }
  2054.                                         break;
  2055.                                 }
  2056.                                 break;
  2057.                         case CSS_PROP_OUTLINE_COLOR:
  2058.                                 switch (value) {
  2059.                                 case OUTLINE_COLOR_TRANSPARENT:
  2060.                                         *ptr += sprintf(*ptr, "transparent");
  2061.                                         break;
  2062.                                 case OUTLINE_COLOR_CURRENT_COLOR:
  2063.                                         *ptr += sprintf(*ptr, "currentColor");
  2064.                                         break;
  2065.                                 case OUTLINE_COLOR_SET:
  2066.                                 {
  2067.                                         uint32_t colour =
  2068.                                                 *((uint32_t *) bytecode);
  2069.                                         ADVANCE(sizeof(colour));
  2070.                                         *ptr += sprintf(*ptr, "#%08x", colour);
  2071.                                 }
  2072.                                         break;
  2073.                                 case OUTLINE_COLOR_INVERT:
  2074.                                         *ptr += sprintf(*ptr, "invert");
  2075.                                         break;
  2076.                                 }
  2077.                                 break;
  2078.                         case CSS_PROP_OVERFLOW:
  2079.                                 switch (value) {
  2080.                                 case OVERFLOW_VISIBLE:
  2081.                                         *ptr += sprintf(*ptr, "visible");
  2082.                                         break;
  2083.                                 case OVERFLOW_HIDDEN:
  2084.                                         *ptr += sprintf(*ptr, "hidden");
  2085.                                         break;
  2086.                                 case OVERFLOW_SCROLL:
  2087.                                         *ptr += sprintf(*ptr, "scroll");
  2088.                                         break;
  2089.                                 case OVERFLOW_AUTO:
  2090.                                         *ptr += sprintf(*ptr, "auto");
  2091.                                         break;
  2092.                                 }
  2093.                                 break;
  2094.                         case CSS_PROP_PAGE_BREAK_AFTER:
  2095.                         case CSS_PROP_PAGE_BREAK_BEFORE:
  2096.                                 assert(PAGE_BREAK_AFTER_AUTO ==
  2097.                                                 (enum op_page_break_after)
  2098.                                                 PAGE_BREAK_BEFORE_AUTO);
  2099.                                 assert(PAGE_BREAK_AFTER_ALWAYS ==
  2100.                                                 (enum op_page_break_after)
  2101.                                                 PAGE_BREAK_BEFORE_ALWAYS);
  2102.                                 assert(PAGE_BREAK_AFTER_AVOID ==
  2103.                                                 (enum op_page_break_after)
  2104.                                                 PAGE_BREAK_BEFORE_AVOID);
  2105.                                 assert(PAGE_BREAK_AFTER_LEFT ==
  2106.                                                 (enum op_page_break_after)
  2107.                                                 PAGE_BREAK_BEFORE_LEFT);
  2108.                                 assert(PAGE_BREAK_AFTER_RIGHT ==
  2109.                                                 (enum op_page_break_after)
  2110.                                                 PAGE_BREAK_BEFORE_RIGHT);
  2111.  
  2112.                                 switch (value) {
  2113.                                 case PAGE_BREAK_AFTER_AUTO:
  2114.                                         *ptr += sprintf(*ptr, "auto");
  2115.                                         break;
  2116.                                 case PAGE_BREAK_AFTER_ALWAYS:
  2117.                                         *ptr += sprintf(*ptr, "always");
  2118.                                         break;
  2119.                                 case PAGE_BREAK_AFTER_AVOID:
  2120.                                         *ptr += sprintf(*ptr, "avoid");
  2121.                                         break;
  2122.                                 case PAGE_BREAK_AFTER_LEFT:
  2123.                                         *ptr += sprintf(*ptr, "left");
  2124.                                         break;
  2125.                                 case PAGE_BREAK_AFTER_RIGHT:
  2126.                                         *ptr += sprintf(*ptr, "right");
  2127.                                         break;
  2128.                                 }
  2129.                                 break;
  2130.                         case CSS_PROP_PAGE_BREAK_INSIDE:
  2131.                                 switch (value) {
  2132.                                 case PAGE_BREAK_INSIDE_AUTO:
  2133.                                         *ptr += sprintf(*ptr, "auto");
  2134.                                         break;
  2135.                                 case PAGE_BREAK_INSIDE_AVOID:
  2136.                                         *ptr += sprintf(*ptr, "avoid");
  2137.                                         break;
  2138.                                 }
  2139.                                 break;
  2140.                         case CSS_PROP_PITCH:
  2141.                                 switch (value) {
  2142.                                 case PITCH_FREQUENCY:
  2143.                                 {
  2144.                                         uint32_t unit;
  2145.                                         css_fixed val = *((css_fixed *) bytecode);
  2146.                                         ADVANCE(sizeof(val));
  2147.                                         unit = *((uint32_t *) bytecode);
  2148.                                         ADVANCE(sizeof(unit));
  2149.                                         dump_unit(val, unit, ptr);
  2150.                                 }
  2151.                                         break;
  2152.                                 case PITCH_X_LOW:
  2153.                                         *ptr += sprintf(*ptr, "x-low");
  2154.                                         break;
  2155.                                 case PITCH_LOW:
  2156.                                         *ptr += sprintf(*ptr, "low");
  2157.                                         break;
  2158.                                 case PITCH_MEDIUM:
  2159.                                         *ptr += sprintf(*ptr, "medium");
  2160.                                         break;
  2161.                                 case PITCH_HIGH:
  2162.                                         *ptr += sprintf(*ptr, "high");
  2163.                                         break;
  2164.                                 case PITCH_X_HIGH:
  2165.                                         *ptr += sprintf(*ptr, "x-high");
  2166.                                         break;
  2167.                                 }
  2168.                                 break;
  2169.                         case CSS_PROP_PLAY_DURING:
  2170.                                 switch (value) {
  2171.                                 case PLAY_DURING_URI:
  2172.                                 {
  2173.                                         uint32_t snum = *((uint32_t *) bytecode);                                      
  2174.                                         lwc_string *he;
  2175.                                         css__stylesheet_string_get(style->sheet, snum, &he);
  2176.                                         ADVANCE(sizeof(snum));
  2177.                                         *ptr += sprintf(*ptr, "'%.*s'",
  2178.                                                         (int) lwc_string_length(he),
  2179.                                                         lwc_string_data(he));
  2180.                                 }
  2181.                                         break;
  2182.                                 case PLAY_DURING_AUTO:
  2183.                                         *ptr += sprintf(*ptr, "auto");
  2184.                                         break;
  2185.                                 case PLAY_DURING_NONE:
  2186.                                         *ptr += sprintf(*ptr, "none");
  2187.                                         break;
  2188.                                 }
  2189.  
  2190.                                 if (value & PLAY_DURING_MIX)
  2191.                                         *ptr += sprintf(*ptr, " mix");
  2192.                                 if (value & PLAY_DURING_REPEAT)
  2193.                                         *ptr += sprintf(*ptr, " repeat");
  2194.                                 break;
  2195.                         case CSS_PROP_POSITION:
  2196.                                 switch (value) {
  2197.                                 case POSITION_STATIC:
  2198.                                         *ptr += sprintf(*ptr, "static");
  2199.                                         break;
  2200.                                 case POSITION_RELATIVE:
  2201.                                         *ptr += sprintf(*ptr, "relative");
  2202.                                         break;
  2203.                                 case POSITION_ABSOLUTE:
  2204.                                         *ptr += sprintf(*ptr, "absolute");
  2205.                                         break;
  2206.                                 case POSITION_FIXED:
  2207.                                         *ptr += sprintf(*ptr, "fixed");
  2208.                                         break;
  2209.                                 }
  2210.                                 break;
  2211.                         case CSS_PROP_QUOTES:
  2212.                                 switch (value) {
  2213.                                 case QUOTES_STRING:
  2214.                                         while (value != QUOTES_NONE) {
  2215.                                                 uint32_t snum = *((uint32_t *) bytecode);                                      
  2216.                                                 lwc_string *he;
  2217.                                                 css__stylesheet_string_get(style->sheet, snum, &he);
  2218.                                                 ADVANCE(sizeof(snum));
  2219.                                                 *ptr += sprintf(*ptr, " '%.*s' ",
  2220.                                                                 (int) lwc_string_length(he),
  2221.                                                                 lwc_string_data(he));
  2222.  
  2223.                                                 css__stylesheet_string_get(style->sheet, snum, &he);
  2224.                                                 ADVANCE(sizeof(he));
  2225.                                                 *ptr += sprintf(*ptr, " '%.*s' ",
  2226.                                                                 (int) lwc_string_length(he),
  2227.                                                                 lwc_string_data(he));
  2228.  
  2229.                                                 value = *((uint32_t *) bytecode);
  2230.                                                 ADVANCE(sizeof(value));
  2231.                                         }
  2232.                                         break;
  2233.                                 case QUOTES_NONE:
  2234.                                         *ptr += sprintf(*ptr, "none");
  2235.                                         break;
  2236.                                 }
  2237.                                 break;
  2238.                         case CSS_PROP_SPEAK_HEADER:
  2239.                                 switch (value) {
  2240.                                 case SPEAK_HEADER_ONCE:
  2241.                                         *ptr += sprintf(*ptr, "once");
  2242.                                         break;
  2243.                                 case SPEAK_HEADER_ALWAYS:
  2244.                                         *ptr += sprintf(*ptr, "always");
  2245.                                         break;
  2246.                                 }
  2247.                                 break;
  2248.                         case CSS_PROP_SPEAK_NUMERAL:
  2249.                                 switch (value) {
  2250.                                 case SPEAK_NUMERAL_DIGITS:
  2251.                                         *ptr += sprintf(*ptr, "digits");
  2252.                                         break;
  2253.                                 case SPEAK_NUMERAL_CONTINUOUS:
  2254.                                         *ptr += sprintf(*ptr, "continuous");
  2255.                                         break;
  2256.                                 }
  2257.                                 break;
  2258.                         case CSS_PROP_SPEAK_PUNCTUATION:
  2259.                                 switch (value) {
  2260.                                 case SPEAK_PUNCTUATION_CODE:
  2261.                                         *ptr += sprintf(*ptr, "code");
  2262.                                         break;
  2263.                                 case SPEAK_PUNCTUATION_NONE:
  2264.                                         *ptr += sprintf(*ptr, "none");
  2265.                                         break;
  2266.                                 }
  2267.                                 break;
  2268.                         case CSS_PROP_SPEAK:
  2269.                                 switch (value) {
  2270.                                 case SPEAK_NORMAL:
  2271.                                         *ptr += sprintf(*ptr, "normal");
  2272.                                         break;
  2273.                                 case SPEAK_NONE:
  2274.                                         *ptr += sprintf(*ptr, "none");
  2275.                                         break;
  2276.                                 case SPEAK_SPELL_OUT:
  2277.                                         *ptr += sprintf(*ptr, "spell-out");
  2278.                                         break;
  2279.                                 }
  2280.                                 break;
  2281.                         case CSS_PROP_SPEECH_RATE:
  2282.                                 switch (value) {
  2283.                                 case SPEECH_RATE_SET:
  2284.                                 {
  2285.                                         css_fixed val = *((css_fixed *) bytecode);
  2286.                                         ADVANCE(sizeof(val));
  2287.                                         dump_number(val, ptr);
  2288.                                 }
  2289.                                         break;
  2290.                                 case SPEECH_RATE_X_SLOW:
  2291.                                         *ptr += sprintf(*ptr, "x-slow");
  2292.                                         break;
  2293.                                 case SPEECH_RATE_SLOW:
  2294.                                         *ptr += sprintf(*ptr, "slow");
  2295.                                         break;
  2296.                                 case SPEECH_RATE_MEDIUM:
  2297.                                         *ptr += sprintf(*ptr, "medium");
  2298.                                         break;
  2299.                                 case SPEECH_RATE_FAST:
  2300.                                         *ptr += sprintf(*ptr, "fast");
  2301.                                         break;
  2302.                                 case SPEECH_RATE_X_FAST:
  2303.                                         *ptr += sprintf(*ptr, "x-fast");
  2304.                                         break;
  2305.                                 case SPEECH_RATE_FASTER:
  2306.                                         *ptr += sprintf(*ptr, "faster");
  2307.                                         break;
  2308.                                 case SPEECH_RATE_SLOWER:
  2309.                                         *ptr += sprintf(*ptr, "slower");
  2310.                                         break;
  2311.                                 }
  2312.                                 break;
  2313.                         case CSS_PROP_TABLE_LAYOUT:
  2314.                                 switch (value) {
  2315.                                 case TABLE_LAYOUT_AUTO:
  2316.                                         *ptr += sprintf(*ptr, "auto");
  2317.                                         break;
  2318.                                 case TABLE_LAYOUT_FIXED:
  2319.                                         *ptr += sprintf(*ptr, "fixed");
  2320.                                         break;
  2321.                                 }
  2322.                                 break;
  2323.                         case CSS_PROP_TEXT_ALIGN:
  2324.                                 switch (value) {
  2325.                                 case TEXT_ALIGN_LEFT:
  2326.                                         *ptr += sprintf(*ptr, "left");
  2327.                                         break;
  2328.                                 case TEXT_ALIGN_RIGHT:
  2329.                                         *ptr += sprintf(*ptr, "right");
  2330.                                         break;
  2331.                                 case TEXT_ALIGN_CENTER:
  2332.                                         *ptr += sprintf(*ptr, "center");
  2333.                                         break;
  2334.                                 case TEXT_ALIGN_JUSTIFY:
  2335.                                         *ptr += sprintf(*ptr, "justify");
  2336.                                         break;
  2337.                                 case TEXT_ALIGN_LIBCSS_LEFT:
  2338.                                         *ptr += sprintf(*ptr, "-libcss-left");
  2339.                                         break;
  2340.                                 case TEXT_ALIGN_LIBCSS_CENTER:
  2341.                                         *ptr += sprintf(*ptr, "-libcss-center");
  2342.                                         break;
  2343.                                 case TEXT_ALIGN_LIBCSS_RIGHT:
  2344.                                         *ptr += sprintf(*ptr, "-libcss-right");
  2345.                                         break;
  2346.                                 }
  2347.                                 break;
  2348.                         case CSS_PROP_TEXT_DECORATION:
  2349.                                 if (value == TEXT_DECORATION_NONE)
  2350.                                         *ptr += sprintf(*ptr, "none");
  2351.  
  2352.                                 if (value & TEXT_DECORATION_UNDERLINE)
  2353.                                         *ptr += sprintf(*ptr, " underline");
  2354.                                 if (value & TEXT_DECORATION_OVERLINE)
  2355.                                         *ptr += sprintf(*ptr, " overline");
  2356.                                 if (value & TEXT_DECORATION_LINE_THROUGH)
  2357.                                         *ptr += sprintf(*ptr, " line-through");
  2358.                                 if (value & TEXT_DECORATION_BLINK)
  2359.                                         *ptr += sprintf(*ptr, " blink");
  2360.                                 break;
  2361.                         case CSS_PROP_TEXT_TRANSFORM:
  2362.                                 switch (value) {
  2363.                                 case TEXT_TRANSFORM_CAPITALIZE:
  2364.                                         *ptr += sprintf(*ptr, "capitalize");
  2365.                                         break;
  2366.                                 case TEXT_TRANSFORM_UPPERCASE:
  2367.                                         *ptr += sprintf(*ptr, "uppercase");
  2368.                                         break;
  2369.                                 case TEXT_TRANSFORM_LOWERCASE:
  2370.                                         *ptr += sprintf(*ptr, "lowercase");
  2371.                                         break;
  2372.                                 case TEXT_TRANSFORM_NONE:
  2373.                                         *ptr += sprintf(*ptr, "none");
  2374.                                         break;
  2375.                                 }
  2376.                                 break;
  2377.                         case CSS_PROP_UNICODE_BIDI:
  2378.                                 switch (value) {
  2379.                                 case UNICODE_BIDI_NORMAL:
  2380.                                         *ptr += sprintf(*ptr, "normal");
  2381.                                         break;
  2382.                                 case UNICODE_BIDI_EMBED:
  2383.                                         *ptr += sprintf(*ptr, "embed");
  2384.                                         break;
  2385.                                 case UNICODE_BIDI_BIDI_OVERRIDE:
  2386.                                         *ptr += sprintf(*ptr, "bidi-override");
  2387.                                         break;
  2388.                                 }
  2389.                                 break;
  2390.                         case CSS_PROP_VERTICAL_ALIGN:
  2391.                                 switch (value) {
  2392.                                 case VERTICAL_ALIGN_SET:
  2393.                                 {
  2394.                                         uint32_t unit;
  2395.                                         css_fixed val = *((css_fixed *) bytecode);
  2396.                                         ADVANCE(sizeof(val));
  2397.                                         unit = *((uint32_t *) bytecode);
  2398.                                         ADVANCE(sizeof(unit));
  2399.                                         dump_unit(val, unit, ptr);
  2400.                                 }
  2401.                                         break;
  2402.                                 case VERTICAL_ALIGN_BASELINE:
  2403.                                         *ptr += sprintf(*ptr, "baseline");
  2404.                                         break;
  2405.                                 case VERTICAL_ALIGN_SUB:
  2406.                                         *ptr += sprintf(*ptr, "sub");
  2407.                                         break;
  2408.                                 case VERTICAL_ALIGN_SUPER:
  2409.                                         *ptr += sprintf(*ptr, "super");
  2410.                                         break;
  2411.                                 case VERTICAL_ALIGN_TOP:
  2412.                                         *ptr += sprintf(*ptr, "top");
  2413.                                         break;
  2414.                                 case VERTICAL_ALIGN_TEXT_TOP:
  2415.                                         *ptr += sprintf(*ptr, "text-top");
  2416.                                         break;
  2417.                                 case VERTICAL_ALIGN_MIDDLE:
  2418.                                         *ptr += sprintf(*ptr, "middle");
  2419.                                         break;
  2420.                                 case VERTICAL_ALIGN_BOTTOM:
  2421.                                         *ptr += sprintf(*ptr, "bottom");
  2422.                                         break;
  2423.                                 case VERTICAL_ALIGN_TEXT_BOTTOM:
  2424.                                         *ptr += sprintf(*ptr, "text-bottom");
  2425.                                         break;
  2426.                                 }
  2427.                                 break;
  2428.                         case CSS_PROP_VISIBILITY:
  2429.                                 switch (value) {
  2430.                                 case VISIBILITY_VISIBLE:
  2431.                                         *ptr += sprintf(*ptr, "visible");
  2432.                                         break;
  2433.                                 case VISIBILITY_HIDDEN:
  2434.                                         *ptr += sprintf(*ptr, "hidden");
  2435.                                         break;
  2436.                                 case VISIBILITY_COLLAPSE:
  2437.                                         *ptr += sprintf(*ptr, "collapse");
  2438.                                         break;
  2439.                                 }
  2440.                                 break;
  2441.                         case CSS_PROP_VOICE_FAMILY:
  2442.                                 while (value != VOICE_FAMILY_END) {
  2443.                                         switch (value) {
  2444.                                         case VOICE_FAMILY_STRING:
  2445.                                         case VOICE_FAMILY_IDENT_LIST:
  2446.                                         {
  2447.                                                 uint32_t snum = *((uint32_t *) bytecode);                                      
  2448.                                                 lwc_string *he;
  2449.                                                 css__stylesheet_string_get(style->sheet, snum, &he);
  2450.                                                 ADVANCE(sizeof(snum));
  2451.                                                 *ptr += sprintf(*ptr, "'%.*s'",
  2452.                                                                 (int) lwc_string_length(he),
  2453.                                                                 lwc_string_data(he));
  2454.                                         }
  2455.                                                 break;
  2456.                                         case VOICE_FAMILY_MALE:
  2457.                                                 *ptr += sprintf(*ptr, "male");
  2458.                                                 break;
  2459.                                         case VOICE_FAMILY_FEMALE:
  2460.                                                 *ptr += sprintf(*ptr, "female");
  2461.                                                 break;
  2462.                                         case VOICE_FAMILY_CHILD:
  2463.                                                 *ptr += sprintf(*ptr, "child");
  2464.                                                 break;
  2465.                                         }
  2466.  
  2467.                                         value = *((uint32_t *) bytecode);
  2468.                                         ADVANCE(sizeof(value));
  2469.  
  2470.                                         if (value != VOICE_FAMILY_END)
  2471.                                                 *ptr += sprintf(*ptr, ", ");
  2472.                                 }
  2473.                                 break;
  2474.                         case CSS_PROP_VOLUME:
  2475.                                 switch (value) {
  2476.                                 case VOLUME_NUMBER:
  2477.                                 {
  2478.                                         css_fixed val = *((css_fixed *) bytecode);
  2479.                                         ADVANCE(sizeof(val));
  2480.                                         dump_number(val, ptr);
  2481.                                 }
  2482.                                         break;
  2483.                                 case VOLUME_DIMENSION:
  2484.                                 {
  2485.                                         uint32_t unit;
  2486.                                         css_fixed val = *((css_fixed *) bytecode);
  2487.                                         ADVANCE(sizeof(val));
  2488.                                         unit = *((uint32_t *) bytecode);
  2489.                                         ADVANCE(sizeof(unit));
  2490.                                         dump_unit(val, unit, ptr);
  2491.                                 }
  2492.                                         break;
  2493.                                 case VOLUME_SILENT:
  2494.                                         *ptr += sprintf(*ptr, "silent");
  2495.                                         break;
  2496.                                 case VOLUME_X_SOFT:
  2497.                                         *ptr += sprintf(*ptr, "x-soft");
  2498.                                         break;
  2499.                                 case VOLUME_SOFT:
  2500.                                         *ptr += sprintf(*ptr, "soft");
  2501.                                         break;
  2502.                                 case VOLUME_MEDIUM:
  2503.                                         *ptr += sprintf(*ptr, "medium");
  2504.                                         break;
  2505.                                 case VOLUME_LOUD:
  2506.                                         *ptr += sprintf(*ptr, "loud");
  2507.                                         break;
  2508.                                 case VOLUME_X_LOUD:
  2509.                                         *ptr += sprintf(*ptr, "x-loud");
  2510.                                         break;
  2511.                                 }
  2512.                                 break;
  2513.                         case CSS_PROP_WHITE_SPACE:
  2514.                                 switch (value) {
  2515.                                 case WHITE_SPACE_NORMAL:
  2516.                                         *ptr += sprintf(*ptr, "normal");
  2517.                                         break;
  2518.                                 case WHITE_SPACE_PRE:
  2519.                                         *ptr += sprintf(*ptr, "pre");
  2520.                                         break;
  2521.                                 case WHITE_SPACE_NOWRAP:
  2522.                                         *ptr += sprintf(*ptr, "nowrap");
  2523.                                         break;
  2524.                                 case WHITE_SPACE_PRE_WRAP:
  2525.                                         *ptr += sprintf(*ptr, "pre-wrap");
  2526.                                         break;
  2527.                                 case WHITE_SPACE_PRE_LINE:
  2528.                                         *ptr += sprintf(*ptr, "pre-line");
  2529.                                         break;
  2530.                                 }
  2531.                                 break;
  2532.                         case CSS_PROP_Z_INDEX:
  2533.                                 switch (value) {
  2534.                                 case Z_INDEX_SET:
  2535.                                 {
  2536.                                         css_fixed val = *((css_fixed *) bytecode);
  2537.                                         ADVANCE(sizeof(val));
  2538.                                         dump_number(val, ptr);
  2539.                                 }
  2540.                                         break;
  2541.                                 case Z_INDEX_AUTO:
  2542.                                         *ptr += sprintf(*ptr, "auto");
  2543.                                         break;
  2544.                                 }
  2545.                                 break;
  2546.                         default:
  2547.                                 *ptr += sprintf(*ptr, "Unknown opcode %x", op);
  2548.                                 return;
  2549.                         }
  2550.                 }
  2551.  
  2552.                 if (isImportant(opv))
  2553.                         *ptr += sprintf(*ptr, " !important");
  2554.  
  2555.                 *ptr += sprintf(*ptr, "\n");
  2556.         }
  2557.  
  2558. #undef ADVANCE
  2559.  
  2560. }
  2561.  
  2562. void dump_string(lwc_string *string, char **ptr)
  2563. {
  2564.         *ptr += sprintf(*ptr, "%.*s",
  2565.                         (int) lwc_string_length(string),
  2566.                         lwc_string_data(string));
  2567. }
  2568.  
  2569. void dump_font_face(css_font_face *font_face, char **ptr)
  2570. {
  2571.         uint8_t style, weight;
  2572.  
  2573.         if (font_face->font_family != NULL) {
  2574.                 *(*ptr)++ = '\n';
  2575.                 *ptr += sprintf(*ptr, "|  font-family: %.*s",
  2576.                                 (int) lwc_string_length(font_face->font_family),
  2577.                                 lwc_string_data(font_face->font_family));
  2578.         }
  2579.        
  2580.         *ptr += sprintf(*ptr, "\n|  font-style: ");
  2581.         style = css_font_face_font_style(font_face);
  2582.         switch (style) {
  2583.         case CSS_FONT_STYLE_INHERIT:
  2584.                 *ptr += sprintf(*ptr, "unspecified");
  2585.                 break;
  2586.         case CSS_FONT_STYLE_NORMAL:
  2587.                 *ptr += sprintf(*ptr, "normal");
  2588.                 break;
  2589.         case CSS_FONT_STYLE_ITALIC:
  2590.                 *ptr += sprintf(*ptr, "italic");
  2591.                 break;
  2592.         case CSS_FONT_STYLE_OBLIQUE:
  2593.                 *ptr += sprintf(*ptr, "oblique");
  2594.                 break;
  2595.         }
  2596.  
  2597.         *ptr += sprintf(*ptr, "\n|  font-weight: ");
  2598.         weight = css_font_face_font_weight(font_face);
  2599.         switch (weight) {
  2600.         case CSS_FONT_WEIGHT_INHERIT:
  2601.                 *ptr += sprintf(*ptr, "unspecified");
  2602.                 break;
  2603.         case CSS_FONT_WEIGHT_NORMAL:
  2604.                 *ptr += sprintf(*ptr, "normal");
  2605.                 break;
  2606.         case CSS_FONT_WEIGHT_BOLD:
  2607.                 *ptr += sprintf(*ptr, "bold");
  2608.                 break;
  2609.         case CSS_FONT_WEIGHT_100:
  2610.                 *ptr += sprintf(*ptr, "100");
  2611.                 break;
  2612.         case CSS_FONT_WEIGHT_200:
  2613.                 *ptr += sprintf(*ptr, "200");
  2614.                 break;
  2615.         case CSS_FONT_WEIGHT_300:
  2616.                 *ptr += sprintf(*ptr, "300");
  2617.                 break;
  2618.         case CSS_FONT_WEIGHT_400:
  2619.                 *ptr += sprintf(*ptr, "400");
  2620.                 break;
  2621.         case CSS_FONT_WEIGHT_500:
  2622.                 *ptr += sprintf(*ptr, "500");
  2623.                 break;
  2624.         case CSS_FONT_WEIGHT_600:
  2625.                 *ptr += sprintf(*ptr, "600");
  2626.                 break;
  2627.         case CSS_FONT_WEIGHT_700:
  2628.                 *ptr += sprintf(*ptr, "700");
  2629.                 break;
  2630.         case CSS_FONT_WEIGHT_800:
  2631.                 *ptr += sprintf(*ptr, "800");
  2632.                 break;
  2633.         case CSS_FONT_WEIGHT_900:
  2634.                 *ptr += sprintf(*ptr, "900");
  2635.                 break;
  2636.         default:
  2637.                 *ptr += sprintf(*ptr, "Unhandled weight %d\n", (int)weight);
  2638.                 break;
  2639.         }
  2640.  
  2641.        
  2642.         if (font_face->srcs != NULL) {
  2643.                 uint32_t i;
  2644.                 css_font_face_src *srcs = font_face->srcs;
  2645.                 for (i = 0; i < font_face->n_srcs; ++i) {
  2646.                         *ptr += sprintf(*ptr, "\n|  src: ");
  2647.                        
  2648.                         css_font_face_format format =
  2649.                                         css_font_face_src_format(&srcs[i]);
  2650.                        
  2651.                         *ptr += sprintf(*ptr, "\n|   format: ");
  2652.                        
  2653.                         switch (format) {
  2654.                         case CSS_FONT_FACE_FORMAT_UNSPECIFIED:
  2655.                                 *ptr += sprintf(*ptr, "unspecified");
  2656.                                 break;
  2657.                         case CSS_FONT_FACE_FORMAT_WOFF:
  2658.                                 *ptr += sprintf(*ptr, "WOFF");
  2659.                                 break;
  2660.                         case CSS_FONT_FACE_FORMAT_OPENTYPE:
  2661.                                 *ptr += sprintf(*ptr, "OTF");
  2662.                                 break;
  2663.                         case CSS_FONT_FACE_FORMAT_EMBEDDED_OPENTYPE:
  2664.                                 *ptr += sprintf(*ptr, "EOTF");
  2665.                                 break;
  2666.                         case CSS_FONT_FACE_FORMAT_SVG:
  2667.                                 *ptr += sprintf(*ptr, "SVG");
  2668.                                 break;
  2669.                         case CSS_FONT_FACE_FORMAT_UNKNOWN:
  2670.                                 *ptr += sprintf(*ptr, "unknown");
  2671.                                 break;
  2672.                         default:
  2673.                                 *ptr += sprintf(*ptr, "UNEXPECTED");
  2674.                                 break;
  2675.                         }
  2676.  
  2677.                         if (srcs[i].location != NULL) {
  2678.                                 *ptr += sprintf(*ptr, "\n|   location: ");
  2679.  
  2680.                                 switch (css_font_face_src_location_type(
  2681.                                                 &srcs[i])) {
  2682.                                 case CSS_FONT_FACE_LOCATION_TYPE_LOCAL:
  2683.                                         *ptr += sprintf(*ptr, "local");
  2684.                                         break;
  2685.                                 case CSS_FONT_FACE_LOCATION_TYPE_URI:
  2686.                                         *ptr += sprintf(*ptr, "url");
  2687.                                         break;
  2688.                                 default:
  2689.                                         *ptr += sprintf(*ptr, "UNKNOWN");
  2690.                                         break;
  2691.                                 }
  2692.                                
  2693.                                 *ptr += sprintf(*ptr, "(%.*s)",
  2694.                                         (int) lwc_string_length(
  2695.                                                         srcs[i].location),
  2696.                                         lwc_string_data(srcs[i].location));
  2697.                         }
  2698.                 }
  2699.         }
  2700. }
  2701.  
  2702. #endif
  2703.