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 <assert.h>
  9. #include <string.h>
  10.  
  11. #include "bytecode/bytecode.h"
  12. #include "bytecode/opcodes.h"
  13. #include "parse/properties/properties.h"
  14. #include "parse/properties/utils.h"
  15.  
  16. /**
  17.  * Parse border-style shorthand
  18.  *
  19.  * \param c       Parsing context
  20.  * \param vector  Vector of tokens to process
  21.  * \param ctx     Pointer to vector iteration context
  22.  * \param result  Pointer to location to receive resulting style
  23.  * \return CSS_OK on success,
  24.  *         CSS_NOMEM on memory exhaustion,
  25.  *         CSS_INVALID if the input is not valid
  26.  *
  27.  * Post condition: \a *ctx is updated with the next token to process
  28.  *                 If the input is invalid, then \a *ctx remains unchanged.
  29.  */
  30. css_error css__parse_border_style(css_language *c,
  31.                 const parserutils_vector *vector, int *ctx,
  32.                 css_style *result)
  33. {
  34.         int orig_ctx = *ctx;
  35.         int prev_ctx;
  36.         const css_token *token;
  37.         uint16_t side_val[4];
  38.         uint32_t side_count = 0;
  39.         bool match;
  40.         css_error error;
  41.  
  42.         /* Firstly, handle inherit */
  43.         token = parserutils_vector_peek(vector, *ctx);
  44.         if (token == NULL)
  45.                 return CSS_INVALID;
  46.                
  47.         if (is_css_inherit(c, token)) {
  48.                 error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_TOP_STYLE);
  49.                 if (error != CSS_OK)
  50.                         return error;
  51.  
  52.                 error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_RIGHT_STYLE);
  53.                 if (error != CSS_OK)
  54.                         return error;          
  55.  
  56.                 error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_BOTTOM_STYLE);
  57.                 if (error != CSS_OK)
  58.                         return error;
  59.  
  60.                 error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_LEFT_STYLE);
  61.                 if (error == CSS_OK)
  62.                         parserutils_vector_iterate(vector, ctx);
  63.  
  64.                 return error;
  65.         }
  66.  
  67.         /* Attempt to parse up to 4 styles */
  68.         do {
  69.                 prev_ctx = *ctx;
  70.  
  71.                 if ((token != NULL) && is_css_inherit(c, token)) {
  72.                         *ctx = orig_ctx;
  73.                         return CSS_INVALID;
  74.                 }
  75.  
  76.                 if (token->type != CSS_TOKEN_IDENT)
  77.                         break;
  78.  
  79.                 if ((lwc_string_caseless_isequal(token->idata, c->strings[NONE], &match) == lwc_error_ok && match)) {
  80.                         side_val[side_count] = BORDER_STYLE_NONE;
  81.                 } else if ((lwc_string_caseless_isequal(token->idata, c->strings[HIDDEN], &match) == lwc_error_ok && match)) {
  82.                         side_val[side_count] = BORDER_STYLE_HIDDEN;
  83.                 } else if ((lwc_string_caseless_isequal(token->idata, c->strings[DOTTED], &match) == lwc_error_ok && match)) {
  84.                         side_val[side_count] = BORDER_STYLE_DOTTED;
  85.                 } else if ((lwc_string_caseless_isequal(token->idata, c->strings[DASHED], &match) == lwc_error_ok && match)) {
  86.                         side_val[side_count] = BORDER_STYLE_DASHED;
  87.                 } else if ((lwc_string_caseless_isequal(token->idata, c->strings[SOLID], &match) == lwc_error_ok && match)) {
  88.                         side_val[side_count] = BORDER_STYLE_SOLID;
  89.                 } else if ((lwc_string_caseless_isequal(token->idata, c->strings[LIBCSS_DOUBLE], &match) == lwc_error_ok && match)) {
  90.                         side_val[side_count] = BORDER_STYLE_DOUBLE;
  91.                 } else if ((lwc_string_caseless_isequal(token->idata, c->strings[GROOVE], &match) == lwc_error_ok && match)) {
  92.                         side_val[side_count] = BORDER_STYLE_GROOVE;
  93.                 } else if ((lwc_string_caseless_isequal(token->idata, c->strings[RIDGE], &match) == lwc_error_ok && match)) {
  94.                         side_val[side_count] = BORDER_STYLE_RIDGE;
  95.                 } else if ((lwc_string_caseless_isequal(token->idata, c->strings[INSET], &match) == lwc_error_ok && match)) {
  96.                         side_val[side_count] = BORDER_STYLE_INSET;
  97.                 } else if ((lwc_string_caseless_isequal(token->idata, c->strings[OUTSET], &match) == lwc_error_ok && match)) {
  98.                         side_val[side_count] = BORDER_STYLE_OUTSET;
  99.                 } else {
  100.                         break;
  101.                 }
  102.  
  103.                 side_count++;
  104.                                
  105.                 parserutils_vector_iterate(vector, ctx);
  106.                
  107.                 consumeWhitespace(vector, ctx);
  108.  
  109.                 token = parserutils_vector_peek(vector, *ctx);
  110.         } while ((*ctx != prev_ctx) && (token != NULL) && (side_count < 4));
  111.  
  112.  
  113. #define SIDE_APPEND(OP,NUM)                                                             \
  114.         error = css__stylesheet_style_appendOPV(result, (OP), 0, side_val[(NUM)]);      \
  115.         if (error != CSS_OK)                                                            \
  116.                 break
  117.  
  118.         switch (side_count) {
  119.         case 1:
  120.                 SIDE_APPEND(CSS_PROP_BORDER_TOP_STYLE, 0);
  121.                 SIDE_APPEND(CSS_PROP_BORDER_RIGHT_STYLE, 0);
  122.                 SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_STYLE, 0);
  123.                 SIDE_APPEND(CSS_PROP_BORDER_LEFT_STYLE, 0);
  124.                 break;
  125.         case 2:
  126.                 SIDE_APPEND(CSS_PROP_BORDER_TOP_STYLE, 0);
  127.                 SIDE_APPEND(CSS_PROP_BORDER_RIGHT_STYLE, 1);
  128.                 SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_STYLE, 0);
  129.                 SIDE_APPEND(CSS_PROP_BORDER_LEFT_STYLE, 1);
  130.                 break;
  131.         case 3:
  132.                 SIDE_APPEND(CSS_PROP_BORDER_TOP_STYLE, 0);
  133.                 SIDE_APPEND(CSS_PROP_BORDER_RIGHT_STYLE, 1);
  134.                 SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_STYLE, 2);
  135.                 SIDE_APPEND(CSS_PROP_BORDER_LEFT_STYLE, 1);
  136.                 break;
  137.         case 4:
  138.                 SIDE_APPEND(CSS_PROP_BORDER_TOP_STYLE, 0);
  139.                 SIDE_APPEND(CSS_PROP_BORDER_RIGHT_STYLE, 1);
  140.                 SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_STYLE, 2);
  141.                 SIDE_APPEND(CSS_PROP_BORDER_LEFT_STYLE, 3);
  142.                 break;
  143.  
  144.         default:
  145.                 error = CSS_INVALID;
  146.                 break;
  147.         }
  148.  
  149.         if (error != CSS_OK)
  150.                 *ctx = orig_ctx;
  151.  
  152.         return error;
  153. }
  154.