Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * This file is part of LibCSS
  3.  * Licensed under the MIT License,
  4.  *                http://www.opensource.org/licenses/mit-license.php
  5.  * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
  6.  */
  7.  
  8. #include "bytecode/bytecode.h"
  9. #include "bytecode/opcodes.h"
  10. #include "select/propset.h"
  11. #include "select/propget.h"
  12. #include "utils/utils.h"
  13.  
  14. #include "select/properties/properties.h"
  15. #include "select/properties/helpers.h"
  16.  
  17. css_error css__cascade_content(uint32_t opv, css_style *style,
  18.                 css_select_state *state)
  19. {
  20.         uint16_t value = CSS_CONTENT_INHERIT;
  21.         css_computed_content_item *content = NULL;
  22.         uint32_t n_contents = 0;
  23.  
  24.         if (isInherit(opv) == false) {
  25.                 uint32_t v = getValue(opv);
  26.  
  27.                 if (v == CONTENT_NORMAL) {
  28.                         value = CSS_CONTENT_NORMAL;
  29.                 } else if (v == CONTENT_NONE) {
  30.                         value = CSS_CONTENT_NONE;
  31.                 } else {
  32.                         value = CSS_CONTENT_SET;
  33.                        
  34.                         while (v != CONTENT_NORMAL) {
  35.                                 lwc_string *he;
  36.                                 css_computed_content_item *temp;
  37.  
  38.                                 css__stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &he);
  39.                                
  40.                                 temp = state->computed->alloc(content,
  41.                                                 (n_contents + 1) *
  42.                                                 sizeof(css_computed_content_item),
  43.                                                 state->computed->pw);
  44.                                 if (temp == NULL) {
  45.                                         if (content != NULL) {
  46.                                                 state->computed->alloc(content,
  47.                                                         0, state->computed->pw);
  48.                                         }
  49.                                         return CSS_NOMEM;
  50.                                 }
  51.  
  52.                                 content = temp;
  53.  
  54.                                 switch (v & 0xff) {
  55.                                 case CONTENT_COUNTER:
  56.                                         advance_bytecode(style, sizeof(css_code_t));
  57.  
  58.                                         content[n_contents].type =
  59.                                                 CSS_COMPUTED_CONTENT_COUNTER;
  60.                                         content[n_contents].data.counter.name = he;
  61.                                         content[n_contents].data.counter.style = v >> CONTENT_COUNTER_STYLE_SHIFT;
  62.                                         break;
  63.                                 case CONTENT_COUNTERS:
  64.                                 {
  65.                                         lwc_string *sep;
  66.        
  67.                                         advance_bytecode(style, sizeof(css_code_t));
  68.  
  69.                                         css__stylesheet_string_get(style->sheet, *((css_code_t *) style->bytecode), &sep);
  70.                                         advance_bytecode(style, sizeof(css_code_t));
  71.  
  72.                                         content[n_contents].type =
  73.                                                 CSS_COMPUTED_CONTENT_COUNTERS;
  74.                                         content[n_contents].data.counters.name = he;
  75.                                         content[n_contents].data.counters.sep = sep;
  76.                                         content[n_contents].data.counters.style = v >> CONTENT_COUNTERS_STYLE_SHIFT;
  77.                                 }
  78.                                         break;
  79.                                 case CONTENT_URI:
  80.                                         advance_bytecode(style, sizeof(css_code_t));
  81.  
  82.                                         content[n_contents].type =
  83.                                                 CSS_COMPUTED_CONTENT_URI;
  84.                                         content[n_contents].data.uri = he;
  85.                                         break;
  86.                                 case CONTENT_ATTR:
  87.                                         advance_bytecode(style, sizeof(css_code_t));
  88.  
  89.                                         content[n_contents].type =
  90.                                                 CSS_COMPUTED_CONTENT_ATTR;
  91.                                         content[n_contents].data.attr = he;
  92.                                         break;
  93.                                 case CONTENT_STRING:
  94.                                         advance_bytecode(style, sizeof(css_code_t));
  95.  
  96.                                         content[n_contents].type =
  97.                                                 CSS_COMPUTED_CONTENT_STRING;
  98.                                         content[n_contents].data.string = he;
  99.                                         break;
  100.                                 case CONTENT_OPEN_QUOTE:
  101.                                         content[n_contents].type =
  102.                                                 CSS_COMPUTED_CONTENT_OPEN_QUOTE;
  103.                                         break;
  104.                                 case CONTENT_CLOSE_QUOTE:
  105.                                         content[n_contents].type =
  106.                                                 CSS_COMPUTED_CONTENT_CLOSE_QUOTE;
  107.                                         break;
  108.                                 case CONTENT_NO_OPEN_QUOTE:
  109.                                         content[n_contents].type =
  110.                                                 CSS_COMPUTED_CONTENT_NO_OPEN_QUOTE;
  111.                                         break;
  112.                                 case CONTENT_NO_CLOSE_QUOTE:
  113.                                         content[n_contents].type =
  114.                                                 CSS_COMPUTED_CONTENT_NO_CLOSE_QUOTE;
  115.                                         break;
  116.                                 }
  117.  
  118.                                 n_contents++;
  119.  
  120.                                 v = *((uint32_t *) style->bytecode);
  121.                                 advance_bytecode(style, sizeof(v));
  122.                         }
  123.                 }
  124.         }
  125.  
  126.         /* If we have some content, terminate the array with a blank entry */
  127.         if (n_contents > 0) {
  128.                 css_computed_content_item *temp;
  129.  
  130.                 temp = state->computed->alloc(content,
  131.                                 (n_contents + 1) * sizeof(css_computed_content_item),
  132.                                 state->computed->pw);
  133.                 if (temp == NULL) {
  134.                         state->computed->alloc(content, 0, state->computed->pw);
  135.                         return CSS_NOMEM;
  136.                 }
  137.  
  138.                 content = temp;
  139.  
  140.                 content[n_contents].type = CSS_COMPUTED_CONTENT_NONE;
  141.         }
  142.  
  143.         if (css__outranks_existing(getOpcode(opv), isImportant(opv), state,
  144.                         isInherit(opv))) {
  145.                 css_error error;
  146.  
  147.                 error = set_content(state->computed, value, content);
  148.                 if (error != CSS_OK && content != NULL)
  149.                         state->computed->alloc(content, 0, state->computed->pw);
  150.  
  151.                 return error;
  152.         } else if (content != NULL) {
  153.                 state->computed->alloc(content, 0, state->computed->pw);
  154.         }
  155.  
  156.         return CSS_OK;
  157. }
  158.  
  159. css_error css__set_content_from_hint(const css_hint *hint,
  160.                 css_computed_style *style)
  161. {
  162.         css_computed_content_item *item;
  163.         css_error error;
  164.  
  165.         error = set_content(style, hint->status, hint->data.content);
  166.  
  167.         for (item = hint->data.content; item != NULL &&
  168.                         item->type != CSS_COMPUTED_CONTENT_NONE;
  169.                         item++) {
  170.                 switch (item->type) {
  171.                 case CSS_COMPUTED_CONTENT_STRING:
  172.                         lwc_string_unref(item->data.string);
  173.                         break;
  174.                 case CSS_COMPUTED_CONTENT_URI:
  175.                         lwc_string_unref(item->data.uri);
  176.                         break;
  177.                 case CSS_COMPUTED_CONTENT_COUNTER:
  178.                         lwc_string_unref(item->data.counter.name);
  179.                         break;
  180.                 case CSS_COMPUTED_CONTENT_COUNTERS:
  181.                         lwc_string_unref(item->data.counters.name);
  182.                         lwc_string_unref(item->data.counters.sep);
  183.                         break;
  184.                 case CSS_COMPUTED_CONTENT_ATTR:
  185.                         lwc_string_unref(item->data.attr);
  186.                         break;
  187.                 default:
  188.                         break;
  189.                 }
  190.         }
  191.  
  192.         if (error != CSS_OK && hint->data.content != NULL)
  193.                 style->alloc(hint->data.content, 0, style->pw);
  194.  
  195.         return error;
  196. }
  197.  
  198. css_error css__initial_content(css_select_state *state)
  199. {
  200.         return set_content(state->computed, CSS_CONTENT_NORMAL, NULL);
  201. }
  202.  
  203. css_error css__compose_content(const css_computed_style *parent,
  204.                 const css_computed_style *child,
  205.                 css_computed_style *result)
  206. {
  207.         css_error error;
  208.         const css_computed_content_item *items = NULL;
  209.         uint8_t type = get_content(child, &items);
  210.  
  211.         if ((child->uncommon == NULL && parent->uncommon != NULL) ||
  212.                         type == CSS_CONTENT_INHERIT ||
  213.                         (child->uncommon != NULL && result != child)) {
  214.                 size_t n_items = 0;
  215.                 css_computed_content_item *copy = NULL;
  216.  
  217.                 if ((child->uncommon == NULL && parent->uncommon != NULL) ||
  218.                                 type == CSS_CONTENT_INHERIT) {
  219.                         type = get_content(parent, &items);
  220.                 }
  221.  
  222.                 if (type == CSS_CONTENT_SET) {
  223.                         const css_computed_content_item *i;
  224.  
  225.                         for (i = items; i->type != CSS_COMPUTED_CONTENT_NONE;
  226.                                         i++)
  227.                                 n_items++;
  228.  
  229.                         copy = result->alloc(NULL, (n_items + 1) *
  230.                                         sizeof(css_computed_content_item),
  231.                                         result->pw);
  232.                         if (copy == NULL)
  233.                                 return CSS_NOMEM;
  234.  
  235.                         memcpy(copy, items, (n_items + 1) *
  236.                                         sizeof(css_computed_content_item));
  237.                 }
  238.  
  239.                 error = set_content(result, type, copy);
  240.                 if (error != CSS_OK && copy != NULL)
  241.                         result->alloc(copy, 0, result->pw);
  242.  
  243.                 return error;
  244.         }
  245.  
  246.         return CSS_OK;
  247. }
  248.  
  249.