Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * LibCSS - example1.c
  3.  *
  4.  * Compile this using a command such as:
  5.  *  gcc -g -W -Wall -o example1 example1.c `pkg-config --cflags --libs libcss`
  6.  */
  7.  
  8. #include <assert.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11.  
  12. /* The entire API is available through this header. */
  13. #include <libcss/libcss.h>
  14.  
  15.  
  16. /* This macro is used to silence compiler warnings about unused function
  17.  * arguments. */
  18. #define UNUSED(x) ((x) = (x))
  19.  
  20.  
  21. /* Function declarations. */
  22. static void *myrealloc(void *ptr, size_t len, void *pw);
  23. static css_error resolve_url(void *pw,
  24.                 const char *base, lwc_string *rel, lwc_string **abs);
  25. static void die(const char *text, css_error code);
  26.  
  27. static css_error node_name(void *pw, void *node,
  28.                 css_qname *qname);
  29. static css_error node_classes(void *pw, void *node,
  30.                 lwc_string ***classes, uint32_t *n_classes);
  31. static css_error node_id(void *pw, void *node,
  32.                 lwc_string **id);
  33. static css_error named_ancestor_node(void *pw, void *node,
  34.                 const css_qname *qname,
  35.                 void **ancestor);
  36. static css_error named_parent_node(void *pw, void *node,
  37.                 const css_qname *qname,
  38.                 void **parent);
  39. static css_error named_sibling_node(void *pw, void *node,
  40.                 const css_qname *qname,
  41.                 void **sibling);
  42. static css_error named_generic_sibling_node(void *pw, void *node,
  43.                 const css_qname *qname,
  44.                 void **sibling);
  45. static css_error parent_node(void *pw, void *node, void **parent);
  46. static css_error sibling_node(void *pw, void *node, void **sibling);
  47. static css_error node_has_name(void *pw, void *node,
  48.                 const css_qname *qname,
  49.                 bool *match);
  50. static css_error node_has_class(void *pw, void *node,
  51.                 lwc_string *name,
  52.                 bool *match);
  53. static css_error node_has_id(void *pw, void *node,
  54.                 lwc_string *name,
  55.                 bool *match);
  56. static css_error node_has_attribute(void *pw, void *node,
  57.                 const css_qname *qname,
  58.                 bool *match);
  59. static css_error node_has_attribute_equal(void *pw, void *node,
  60.                 const css_qname *qname,
  61.                 lwc_string *value,
  62.                 bool *match);
  63. static css_error node_has_attribute_dashmatch(void *pw, void *node,
  64.                 const css_qname *qname,
  65.                 lwc_string *value,
  66.                 bool *match);
  67. static css_error node_has_attribute_includes(void *pw, void *node,
  68.                 const css_qname *qname,
  69.                 lwc_string *value,
  70.                 bool *match);
  71. static css_error node_has_attribute_prefix(void *pw, void *node,
  72.                 const css_qname *qname,
  73.                 lwc_string *value,
  74.                 bool *match);
  75. static css_error node_has_attribute_suffix(void *pw, void *node,
  76.                 const css_qname *qname,
  77.                 lwc_string *value,
  78.                 bool *match);
  79. static css_error node_has_attribute_substring(void *pw, void *node,
  80.                 const css_qname *qname,
  81.                 lwc_string *value,
  82.                 bool *match);
  83. static css_error node_is_root(void *pw, void *node, bool *match);
  84. static css_error node_count_siblings(void *pw, void *node,
  85.                 bool same_name, bool after, int32_t *count);
  86. static css_error node_is_empty(void *pw, void *node, bool *match);
  87. static css_error node_is_link(void *pw, void *node, bool *match);
  88. static css_error node_is_visited(void *pw, void *node, bool *match);
  89. static css_error node_is_hover(void *pw, void *node, bool *match);
  90. static css_error node_is_active(void *pw, void *node, bool *match);
  91. static css_error node_is_focus(void *pw, void *node, bool *match);
  92. static css_error node_is_enabled(void *pw, void *node, bool *match);
  93. static css_error node_is_disabled(void *pw, void *node, bool *match);
  94. static css_error node_is_checked(void *pw, void *node, bool *match);
  95. static css_error node_is_target(void *pw, void *node, bool *match);
  96. static css_error node_is_lang(void *pw, void *node,
  97.                 lwc_string *lang, bool *match);
  98. static css_error node_presentational_hint(void *pw, void *node,
  99.                 uint32_t property, css_hint *hint);
  100. static css_error ua_default_for_property(void *pw, uint32_t property,
  101.                 css_hint *hint);
  102. static css_error compute_font_size(void *pw, const css_hint *parent,
  103.                 css_hint *size);
  104.  
  105. /* Table of function pointers for the LibCSS Select API. */
  106. static css_select_handler select_handler = {
  107.         CSS_SELECT_HANDLER_VERSION_1,
  108.  
  109.         node_name,
  110.         node_classes,
  111.         node_id,
  112.         named_ancestor_node,
  113.         named_parent_node,
  114.         named_sibling_node,
  115.         named_generic_sibling_node,
  116.         parent_node,
  117.         sibling_node,
  118.         node_has_name,
  119.         node_has_class,
  120.         node_has_id,
  121.         node_has_attribute,
  122.         node_has_attribute_equal,
  123.         node_has_attribute_dashmatch,
  124.         node_has_attribute_includes,
  125.         node_has_attribute_prefix,
  126.         node_has_attribute_suffix,
  127.         node_has_attribute_substring,
  128.         node_is_root,
  129.         node_count_siblings,
  130.         node_is_empty,
  131.         node_is_link,
  132.         node_is_visited,
  133.         node_is_hover,
  134.         node_is_active,
  135.         node_is_focus,
  136.         node_is_enabled,
  137.         node_is_disabled,
  138.         node_is_checked,
  139.         node_is_target,
  140.         node_is_lang,
  141.         node_presentational_hint,
  142.         ua_default_for_property,
  143.         compute_font_size
  144. };
  145.  
  146.  
  147. int main(int argc, char **argv)
  148. {
  149.         css_error code;
  150.         css_stylesheet *sheet;
  151.         size_t size;
  152.         const char data[] = "body {\
  153.         color: #333333;\
  154.         background: #F4F5F5;\
  155.         line-height: 2em;\
  156.         font-size: 11.5pt;\
  157.         margin: 0;\
  158.         padding: 0;\
  159.         font-family: \"Source Sans Pro\", \"Open Sans\", sans-serif;\
  160. }\
  161. \
  162. a {\
  163.         text-decoration: underline;\
  164.         color: #1F1F1F;\
  165. }\
  166. \
  167. a:hover {\
  168.         text-decoration: none;\
  169. }\
  170. \
  171. a img {\
  172.         filter: alpha(opacity=80);\
  173.         ..-opacity:0.8;\
  174.         opacity: 0.8;\
  175.         -khtml-opacity: 0.8;\
  176. }\
  177. \
  178. a img:hover {\
  179.         filter: alpha(opacity=100);\
  180.         ..-opacity:1.0;\
  181.         opacity: 1.0;\
  182.         -khtml-opacity: 1.0;\
  183. }\
  184. \
  185. #logo {\
  186.         opacity: 1;\
  187.         filter: alpha(opacity=100);\
  188.         border-radius: 2px;\
  189.         border: solid 5px white;\
  190.         box-shadow: 0px 0px 0px 1px #D4D5D5, 0px 0px 10px 0px rgba(0,0,0,0.1);\
  191. }\
  192. \
  193. #show {\
  194.         width:800px;\
  195.         height:600px;\
  196.         cursor:pointer;\
  197.         box-shadow: 0px 0px 0px 1px #D4D5D5, 0px 0px 10px 0px rgba(0,0,0,0.1);\
  198. }\
  199. \
  200. .minislide, .minislide_a {\
  201.         width: 80px;\
  202.         height: 60px;\
  203.         padding: 1px;\
  204. }\
  205. \
  206. .minislide { border: 1px solid #ccc; }\
  207. .minislide_a {\
  208.         border: 1px solid #222;\
  209.         opacity: 1;\
  210.         filter: alpha(opacity=100);\
  211. }\
  212. \
  213. .download_img {\
  214.         width: 32px;\
  215.         height: 32px;\
  216.         border: 0px;\
  217. }\
  218. \
  219. .icon_cell {\
  220.         width: 32px;\
  221.         height:32px;\
  222.         background-repeat: no-repeat;\
  223. }\
  224. \
  225. #footer {\
  226.         padding: 30px 0 30px 0;\
  227.         text-align: center;\
  228.         color: #848585;\
  229.         -khtml-text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);\
  230.         -webkit-text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);\
  231.         text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);\
  232. }\
  233. \
  234. #footer a {\
  235.         color: #848585;\
  236. }\
  237. \
  238. #page {\
  239.         position: relative;\
  240.         margin: 0;\
  241.         background-attachment: scroll;\
  242.         background-repeat: no-repeat;\
  243.         background-position: right bottom;\
  244.         color: #333333;\
  245.         padding: 5px 35px 5px 35px;\
  246.         width: 910px;\
  247. }\
  248. \
  249. \
  250. #inner {\
  251.         background: #fff;\
  252.         border-radius: 4px;\
  253.         box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.1);\
  254.         border: solid 1px #D4D5D5;\
  255. }\
  256. \
  257. *+html #inner { /*IE 7*/\
  258.         background: #fff;\
  259.         filter:\
  260.         progid:DXImageTransform.Microsoft.Shadow(color='#e5e6e6', Direction=45, Strength=3)\
  261.         progid:DXImageTransform.Microsoft.Shadow(color='#e5e6e6', Direction=135, Strength=3)\
  262.         progid:DXImageTransform.Microsoft.Shadow(color='#e5e6e6', Direction=225, Strength=3)\
  263.         progid:DXImageTransform.Microsoft.Shadow(color='#e5e6e6', Direction=315, Strength=3);\
  264.         position: relative;\
  265.         top: -6px;\
  266.         left: -6px;\
  267.         zoom: 1;\
  268. }\
  269. \
  270. *+html #logo { /*IE 7*/\
  271.         border: 1px solid #D4D5D5;\
  272. }\
  273. \
  274. @media \0screen { /*IE 8*/\
  275.         #inner {\
  276.                 background: #fff;\
  277.                 filter:\
  278.                 progid:DXImageTransform.Microsoft.Shadow(color='#e5e6e6', Direction=45, Strength=3)\
  279.                 progid:DXImageTransform.Microsoft.Shadow(color='#e5e6e6', Direction=135, Strength=3)\
  280.                 progid:DXImageTransform.Microsoft.Shadow(color='#e5e6e6', Direction=225, Strength=3)\
  281.                 progid:DXImageTransform.Microsoft.Shadow(color='#e5e6e6', Direction=315, Strength=3);\
  282.                 position: relative;\
  283.                 top: -6px;\
  284.                 left: -6px;\
  285.                 zoom: 1;\
  286.         }\
  287.         #logo {\
  288.                 position: relative;\
  289.                 top: 9px;\
  290.                 left: 9px;\
  291.                 border: 1px solid #D4D5D5;\
  292.         }\
  293. }\
  294. \
  295. #splash {\
  296.         margin: 0;\
  297.         position: relative;\
  298.         padding: 35px 35px 5px 35px;\
  299. }\
  300. \
  301. #wrapper {\
  302.         width: 980px;\
  303.         position: relative;\
  304.         margin-right: auto;\
  305.         margin-bottom: 0;\
  306.         margin-left: auto;\
  307. }\
  308. \
  309. #floatbar {\
  310.         position: fixed; \
  311.         top:0;\
  312.         right:0;\
  313.         bottom:100px;\
  314.         left:0;\
  315.         float: center !important; \
  316.         text-align:center;\
  317.         z-index:9998;\
  318.         height: 30px !important;\
  319. }\
  320. \
  321. #idsel {\
  322.         dispaly: inline;\
  323.         color: white !important; \
  324.         font-weight: bold !important;\
  325.         text-decoration: none !important; \
  326. }\
  327. \
  328. #archnavbar {\
  329.         height: 30px !important;\
  330.         padding: 10px 15px !important;\
  331.         background: #333 !important;\
  332.         border-bottom: 1px #888 solid !important;\
  333.         box-shadow: 0 0 5px black;\
  334.         box-shadow: 0 0 10px rgba(0,0,0,0.4);\
  335.         -moz-box-shadow: 0 0 10px rgba(0,0,0,0.4);\
  336.         -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.4);\
  337.         position: relative;\
  338. }\
  339. \
  340. #archnavbarlist { \
  341.         width: 980px;\
  342.         height: 30px !important;\
  343.         position: relative;\
  344.         margin-top: 0px;\
  345.         margin-right: auto;\
  346.         margin-bottom: 0px;\
  347.         margin-left: auto;\
  348.         float: center !important; \
  349.         list-style: none !important; \
  350.         padding: 0 !important;\
  351. }\
  352. \
  353. #archnavbarlist ul { \
  354.         text-align:center;      \
  355. }\
  356. \
  357. #archnavbarlist li { \
  358.         display: inline-block;\
  359.         float: center !important; \
  360.         font-size: 14px !important; \
  361.         line-height: 25px !important; \
  362.         padding-right: 15px !important; \
  363.         padding-left: 15px !important;\
  364. }\
  365. \
  366. #archnavbarlist li a { \
  367.         color: #999; \
  368.         font-weight: bold !important;\
  369.         text-decoration: none !important;\
  370. }\
  371. \
  372. #archnavbarlist li a:hover { \
  373.         color: white !important; \
  374.         font-weight: bold !important;\
  375.         text-decoration: none !important; \
  376. }\
  377. \
  378. strong {\
  379.         color: #000;\
  380. }";
  381.         css_select_ctx *select_ctx;
  382.         uint32_t count;
  383.         unsigned int hh;
  384.         css_stylesheet_params params;
  385.  
  386.         UNUSED(argc);
  387.         UNUSED(argv);
  388.  
  389.         params.params_version = CSS_STYLESHEET_PARAMS_VERSION_1;
  390.         params.level = CSS_LEVEL_21;
  391.         params.charset = "UTF-8";
  392.         params.url = "foo";
  393.         params.title = "foo";
  394.         params.allow_quirks = false;
  395.         params.inline_style = false;
  396.         params.resolve = resolve_url;
  397.         params.resolve_pw = NULL;
  398.         params.import = NULL;
  399.         params.import_pw = NULL;
  400.         params.color = NULL;
  401.         params.color_pw = NULL;
  402.         params.font = NULL;
  403.         params.font_pw = NULL;
  404.  
  405.         /* create a stylesheet */
  406.         code = css_stylesheet_create(&params, myrealloc, NULL, &sheet);
  407.         if (code != CSS_OK)
  408.                 die("css_stylesheet_create", code);
  409.         code = css_stylesheet_size(sheet, &size);
  410.         if (code != CSS_OK)
  411.                 die("css_stylesheet_size", code);
  412.         printf("created stylesheet, size %zu\n", size);
  413.  
  414.  
  415.         /* parse some CSS source */
  416.         code = css_stylesheet_append_data(sheet, (const uint8_t *) data,
  417.                         sizeof data);
  418.         if (code != CSS_OK && code != CSS_NEEDDATA)
  419.                 die("css_stylesheet_append_data", code);
  420.         code = css_stylesheet_data_done(sheet);
  421.         if (code != CSS_OK)
  422.                 die("css_stylesheet_data_done", code);
  423.         code = css_stylesheet_size(sheet, &size);
  424.         if (code != CSS_OK)
  425.                 die("css_stylesheet_size", code);
  426.         printf("appended data, size now %zu\n", size);
  427.  
  428.  
  429.         /* prepare a selection context containing the stylesheet */
  430.         code = css_select_ctx_create(myrealloc, 0, &select_ctx);
  431.         if (code != CSS_OK)
  432.                 die("css_select_ctx_create", code);
  433.         code = css_select_ctx_append_sheet(select_ctx, sheet, CSS_ORIGIN_AUTHOR,
  434.                         CSS_MEDIA_ALL);
  435.         if (code != CSS_OK)
  436.                 die("css_select_ctx_append_sheet", code);
  437.         code = css_select_ctx_count_sheets(select_ctx, &count);
  438.         if (code != CSS_OK)
  439.                 die("css_select_ctx_count_sheets", code);
  440.         printf("created selection context with %i sheets\n", count);
  441.  
  442.  
  443.         /* select style for each of h1 to h6 */
  444.         //for (hh = 1; hh != 7; hh++) {
  445.                 hh=1;
  446.                 css_select_results *style;
  447.                 char element[20];
  448.                 lwc_string *element_name;
  449.                 uint8_t color_type;
  450.                 css_color color_shade;
  451.  
  452.                 /* in this very simple example our "document tree" is just one
  453.                  * node and is in fact a libwapcaplet string containing the
  454.                  * element name */
  455.                 //snprintf(element, sizeof element, "%i", hh);
  456.                 snprintf(element, sizeof element, "a");
  457.                
  458.                 lwc_intern_string(element, strlen(element), &element_name);
  459.  
  460.                 code = css_select_style(select_ctx, element_name,
  461.                                 CSS_MEDIA_SCREEN, NULL,
  462.                                 &select_handler, 0,
  463.                                 &style);
  464.                 if (code != CSS_OK)
  465.                         die("css_select_style", code);
  466.  
  467.                 lwc_string_unref(element_name);
  468.  
  469.                 color_type = css_computed_color(
  470.                                 style->styles[CSS_PSEUDO_ELEMENT_NONE],
  471.                                 &color_shade);
  472.                 if (color_type == CSS_COLOR_INHERIT)
  473.                         printf("color of h%i is 'inherit'\n", hh);
  474.                 else
  475.                         printf("color of A is %x\n",  color_shade);
  476.  
  477.                 code = css_select_results_destroy(style);
  478.                 if (code != CSS_OK)
  479.                         die("css_computed_style_destroy", code);
  480.         //}
  481.  
  482.  
  483.         /* free everything and shut down libcss */
  484.         code = css_select_ctx_destroy(select_ctx);
  485.         if (code != CSS_OK)
  486.                 die("css_select_ctx_destroy", code);
  487.         code = css_stylesheet_destroy(sheet);
  488.         if (code != CSS_OK)
  489.                 die("css_stylesheet_destroy", code);
  490.  
  491.         return 0;
  492. }
  493.  
  494.  
  495. void *myrealloc(void *ptr, size_t len, void *pw)
  496. {
  497.         UNUSED(pw);
  498.         /*printf("myrealloc(%p, %zu)\n", ptr, len);*/
  499.  
  500.         return realloc(ptr, len);
  501. }
  502.  
  503.  
  504. css_error resolve_url(void *pw,
  505.                 const char *base, lwc_string *rel, lwc_string **abs)
  506. {
  507.         UNUSED(pw);
  508.         UNUSED(base);
  509.  
  510.         /* About as useless as possible */
  511.         *abs = lwc_string_ref(rel);
  512.  
  513.         return CSS_OK;
  514. }
  515.  
  516.  
  517. void die(const char *text, css_error code)
  518. {
  519.         fprintf(stderr, "ERROR: %s: %i: %s\n",
  520.                         text, code, css_error_to_string(code));
  521.         exit(EXIT_FAILURE);
  522. }
  523.  
  524.  
  525.  
  526. /* Select handlers. Our "document tree" is actually just a single node, which is
  527.  * a libwapcaplet string containing the element name. Therefore all the
  528.  * functions below except those getting or testing the element name return empty
  529.  * data or false attributes. */
  530. css_error node_name(void *pw, void *n, css_qname *qname)
  531. {
  532.         lwc_string *node = n;
  533.  
  534.         UNUSED(pw);
  535.        
  536.         qname->name = lwc_string_ref(node);
  537.        
  538.         return CSS_OK;
  539. }
  540.  
  541. css_error node_classes(void *pw, void *n,
  542.                 lwc_string ***classes, uint32_t *n_classes)
  543. {
  544.         UNUSED(pw);
  545.         UNUSED(n);
  546.         *classes = NULL;
  547.         *n_classes = 0;
  548.         return CSS_OK;
  549. }
  550.  
  551. css_error node_id(void *pw, void *n, lwc_string **id)
  552. {
  553.         UNUSED(pw);
  554.         UNUSED(n);
  555.         *id = NULL;
  556.         return CSS_OK;
  557. }
  558.  
  559. css_error named_ancestor_node(void *pw, void *n,
  560.                 const css_qname *qname,
  561.                 void **ancestor)
  562. {
  563.         UNUSED(pw);
  564.         UNUSED(n);
  565.         UNUSED(qname);
  566.         *ancestor = NULL;
  567.         return CSS_OK;
  568. }
  569.  
  570. css_error named_parent_node(void *pw, void *n,
  571.                 const css_qname *qname,
  572.                 void **parent)
  573. {
  574.         UNUSED(pw);
  575.         UNUSED(n);
  576.         UNUSED(qname);
  577.         *parent = NULL;
  578.         return CSS_OK;
  579. }
  580.  
  581. css_error named_generic_sibling_node(void *pw, void *n,
  582.                 const css_qname *qname,
  583.                 void **sibling)
  584. {
  585.         UNUSED(pw);
  586.         UNUSED(n);
  587.         UNUSED(qname);
  588.         *sibling = NULL;
  589.         return CSS_OK;
  590. }
  591.  
  592. css_error named_sibling_node(void *pw, void *n,
  593.                 const css_qname *qname,
  594.                 void **sibling)
  595. {
  596.         UNUSED(pw);
  597.         UNUSED(n);
  598.         UNUSED(qname);
  599.         *sibling = NULL;
  600.         return CSS_OK;
  601. }
  602.  
  603. css_error parent_node(void *pw, void *n, void **parent)
  604. {
  605.         UNUSED(pw);
  606.         UNUSED(n);
  607.         *parent = NULL;
  608.         return CSS_OK;
  609. }
  610.  
  611. css_error sibling_node(void *pw, void *n, void **sibling)
  612. {
  613.         UNUSED(pw);
  614.         UNUSED(n);
  615.         *sibling = NULL;
  616.         return CSS_OK;
  617. }
  618.  
  619. css_error node_has_name(void *pw, void *n,
  620.                 const css_qname *qname,
  621.                 bool *match)
  622. {
  623.         lwc_string *node = n;
  624.         UNUSED(pw);
  625.         assert(lwc_string_caseless_isequal(node, qname->name, match) ==
  626.                         lwc_error_ok);
  627.         return CSS_OK;
  628. }
  629.  
  630. css_error node_has_class(void *pw, void *n,
  631.                 lwc_string *name,
  632.                 bool *match)
  633. {
  634.         UNUSED(pw);
  635.         UNUSED(n);
  636.         UNUSED(name);
  637.         *match = false;
  638.         return CSS_OK;
  639. }
  640.  
  641. css_error node_has_id(void *pw, void *n,
  642.                 lwc_string *name,
  643.                 bool *match)
  644. {
  645.         UNUSED(pw);
  646.         UNUSED(n);
  647.         UNUSED(name);
  648.         *match = false;
  649.         return CSS_OK;
  650. }
  651.  
  652. css_error node_has_attribute(void *pw, void *n,
  653.                 const css_qname *qname,
  654.                 bool *match)
  655. {
  656.         UNUSED(pw);
  657.         UNUSED(n);
  658.         UNUSED(qname);
  659.         *match = false;
  660.         return CSS_OK;
  661. }
  662.  
  663. css_error node_has_attribute_equal(void *pw, void *n,
  664.                 const css_qname *qname,
  665.                 lwc_string *value,
  666.                 bool *match)
  667. {
  668.         UNUSED(pw);
  669.         UNUSED(n);
  670.         UNUSED(qname);
  671.         UNUSED(value);
  672.         *match = false;
  673.         return CSS_OK;
  674. }
  675.  
  676. css_error node_has_attribute_dashmatch(void *pw, void *n,
  677.                 const css_qname *qname,
  678.                 lwc_string *value,
  679.                 bool *match)
  680. {
  681.         UNUSED(pw);
  682.         UNUSED(n);
  683.         UNUSED(qname);
  684.         UNUSED(value);
  685.         *match = false;
  686.         return CSS_OK;
  687. }
  688.  
  689. css_error node_has_attribute_includes(void *pw, void *n,
  690.                 const css_qname *qname,
  691.                 lwc_string *value,
  692.                 bool *match)
  693. {
  694.         UNUSED(pw);
  695.         UNUSED(n);
  696.         UNUSED(qname);
  697.         UNUSED(value);
  698.         *match = false;
  699.         return CSS_OK;
  700. }
  701.  
  702. css_error node_has_attribute_prefix(void *pw, void *n,
  703.                 const css_qname *qname,
  704.                 lwc_string *value,
  705.                 bool *match)
  706. {
  707.         UNUSED(pw);
  708.         UNUSED(n);
  709.         UNUSED(qname);
  710.         UNUSED(value);
  711.         *match = false;
  712.         return CSS_OK;
  713. }
  714.  
  715. css_error node_has_attribute_suffix(void *pw, void *n,
  716.                 const css_qname *qname,
  717.                 lwc_string *value,
  718.                 bool *match)
  719. {
  720.         UNUSED(pw);
  721.         UNUSED(n);
  722.         UNUSED(qname);
  723.         UNUSED(value);
  724.         *match = false;
  725.         return CSS_OK;
  726. }
  727.  
  728. css_error node_has_attribute_substring(void *pw, void *n,
  729.                 const css_qname *qname,
  730.                 lwc_string *value,
  731.                 bool *match)
  732. {
  733.         UNUSED(pw);
  734.         UNUSED(n);
  735.         UNUSED(qname);
  736.         UNUSED(value);
  737.         *match = false;
  738.         return CSS_OK;
  739. }
  740.  
  741. css_error node_is_first_child(void *pw, void *n, bool *match)
  742. {
  743.         UNUSED(pw);
  744.         UNUSED(n);
  745.         *match = false;
  746.         return CSS_OK;
  747. }
  748.  
  749. css_error node_is_root(void *pw, void *n, bool *match)
  750. {
  751.         UNUSED(pw);
  752.         UNUSED(n);
  753.         *match = false;
  754.         return CSS_OK;
  755. }
  756.  
  757. css_error node_count_siblings(void *pw, void *n,
  758.                 bool same_name, bool after, int32_t *count)
  759. {
  760.         UNUSED(pw);
  761.         UNUSED(n);
  762.         UNUSED(same_name);
  763.         UNUSED(after);
  764.         *count = 1;
  765.         return CSS_OK;
  766. }
  767.  
  768. css_error node_is_empty(void *pw, void *n, bool *match)
  769. {
  770.         UNUSED(pw);
  771.         UNUSED(n);
  772.         *match = false;
  773.         return CSS_OK;
  774. }
  775.  
  776. css_error node_is_link(void *pw, void *n, bool *match)
  777. {
  778.         UNUSED(pw);
  779.         UNUSED(n);
  780.         *match = false;
  781.         return CSS_OK;
  782. }
  783.  
  784. css_error node_is_visited(void *pw, void *n, bool *match)
  785. {
  786.         UNUSED(pw);
  787.         UNUSED(n);
  788.         *match = false;
  789.         return CSS_OK;
  790. }
  791.  
  792. css_error node_is_hover(void *pw, void *n, bool *match)
  793. {
  794.         UNUSED(pw);
  795.         UNUSED(n);
  796.         *match = false;
  797.         return CSS_OK;
  798. }
  799.  
  800. css_error node_is_active(void *pw, void *n, bool *match)
  801. {
  802.         UNUSED(pw);
  803.         UNUSED(n);
  804.         *match = false;
  805.         return CSS_OK;
  806. }
  807.  
  808. css_error node_is_focus(void *pw, void *n, bool *match)
  809. {
  810.         UNUSED(pw);
  811.         UNUSED(n);
  812.         *match = false;
  813.         return CSS_OK;
  814. }
  815.  
  816. css_error node_is_enabled(void *pw, void *n, bool *match)
  817. {
  818.         UNUSED(pw);
  819.         UNUSED(n);
  820.         *match = false;
  821.         return CSS_OK;
  822. }
  823.  
  824. css_error node_is_disabled(void *pw, void *n, bool *match)
  825. {
  826.         UNUSED(pw);
  827.         UNUSED(n);
  828.         *match = false;
  829.         return CSS_OK;
  830. }
  831.  
  832. css_error node_is_checked(void *pw, void *n, bool *match)
  833. {
  834.         UNUSED(pw);
  835.         UNUSED(n);
  836.         *match = false;
  837.         return CSS_OK;
  838. }
  839.  
  840. css_error node_is_target(void *pw, void *n, bool *match)
  841. {
  842.         UNUSED(pw);
  843.         UNUSED(n);
  844.         *match = false;
  845.         return CSS_OK;
  846. }
  847.  
  848.  
  849. css_error node_is_lang(void *pw, void *n,
  850.                 lwc_string *lang,
  851.                 bool *match)
  852. {
  853.         UNUSED(pw);
  854.         UNUSED(n);
  855.         UNUSED(lang);
  856.         *match = false;
  857.         return CSS_OK;
  858. }
  859.  
  860. css_error node_presentational_hint(void *pw, void *node,
  861.                 uint32_t property, css_hint *hint)
  862. {
  863.         UNUSED(pw);
  864.         UNUSED(node);
  865.         UNUSED(property);
  866.         UNUSED(hint);
  867.         return CSS_PROPERTY_NOT_SET;
  868. }
  869.  
  870. css_error ua_default_for_property(void *pw, uint32_t property, css_hint *hint)
  871. {
  872.         UNUSED(pw);
  873.  
  874.         if (property == CSS_PROP_COLOR) {
  875.                 hint->data.color = 0x00000000;
  876.                 hint->status = CSS_COLOR_COLOR;
  877.         } else if (property == CSS_PROP_FONT_FAMILY) {
  878.                 hint->data.strings = NULL;
  879.                 hint->status = CSS_FONT_FAMILY_SANS_SERIF;
  880.         } else if (property == CSS_PROP_QUOTES) {
  881.                 /* Not exactly useful :) */
  882.                 hint->data.strings = NULL;
  883.                 hint->status = CSS_QUOTES_NONE;
  884.         } else if (property == CSS_PROP_VOICE_FAMILY) {
  885.                 /** \todo Fix this when we have voice-family done */
  886.                 hint->data.strings = NULL;
  887.                 hint->status = 0;
  888.         } else {
  889.                 return CSS_INVALID;
  890.         }
  891.  
  892.         return CSS_OK;
  893. }
  894.  
  895. css_error compute_font_size(void *pw, const css_hint *parent, css_hint *size)
  896. {
  897.         static css_hint_length sizes[] = {
  898.                 { FLTTOFIX(6.75), CSS_UNIT_PT },
  899.                 { FLTTOFIX(7.50), CSS_UNIT_PT },
  900.                 { FLTTOFIX(9.75), CSS_UNIT_PT },
  901.                 { FLTTOFIX(12.0), CSS_UNIT_PT },
  902.                 { FLTTOFIX(13.5), CSS_UNIT_PT },
  903.                 { FLTTOFIX(18.0), CSS_UNIT_PT },
  904.                 { FLTTOFIX(24.0), CSS_UNIT_PT }
  905.         };
  906.         const css_hint_length *parent_size;
  907.  
  908.         UNUSED(pw);
  909.  
  910.         /* Grab parent size, defaulting to medium if none */
  911.         if (parent == NULL) {
  912.                 parent_size = &sizes[CSS_FONT_SIZE_MEDIUM - 1];
  913.         } else {
  914.                 assert(parent->status == CSS_FONT_SIZE_DIMENSION);
  915.                 assert(parent->data.length.unit != CSS_UNIT_EM);
  916.                 assert(parent->data.length.unit != CSS_UNIT_EX);
  917.                 parent_size = &parent->data.length;
  918.         }
  919.  
  920.         assert(size->status != CSS_FONT_SIZE_INHERIT);
  921.  
  922.         if (size->status < CSS_FONT_SIZE_LARGER) {
  923.                 /* Keyword -- simple */
  924.                 size->data.length = sizes[size->status - 1];
  925.         } else if (size->status == CSS_FONT_SIZE_LARGER) {
  926.                 /** \todo Step within table, if appropriate */
  927.                 size->data.length.value =
  928.                                 FMUL(parent_size->value, FLTTOFIX(1.2));
  929.                 size->data.length.unit = parent_size->unit;
  930.         } else if (size->status == CSS_FONT_SIZE_SMALLER) {
  931.                 /** \todo Step within table, if appropriate */
  932.                 size->data.length.value =
  933.                                 FMUL(parent_size->value, FLTTOFIX(1.2));
  934.                 size->data.length.unit = parent_size->unit;
  935.         } else if (size->data.length.unit == CSS_UNIT_EM ||
  936.                         size->data.length.unit == CSS_UNIT_EX) {
  937.                 size->data.length.value =
  938.                         FMUL(size->data.length.value, parent_size->value);
  939.  
  940.                 if (size->data.length.unit == CSS_UNIT_EX) {
  941.                         size->data.length.value = FMUL(size->data.length.value,
  942.                                         FLTTOFIX(0.6));
  943.                 }
  944.  
  945.                 size->data.length.unit = parent_size->unit;
  946.         } else if (size->data.length.unit == CSS_UNIT_PCT) {
  947.                 size->data.length.value = FDIV(FMUL(size->data.length.value,
  948.                                 parent_size->value), FLTTOFIX(100));
  949.                 size->data.length.unit = parent_size->unit;
  950.         }
  951.  
  952.         size->status = CSS_FONT_SIZE_DIMENSION;
  953.  
  954.         return CSS_OK;
  955. }
  956.  
  957.  
  958.