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 background
  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_background(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.         css_error error = CSS_OK;
  38.         bool attachment = true;
  39.         bool color = true;
  40.         bool image = true;
  41.         bool position = true;
  42.         bool repeat = true;
  43.         css_style * attachment_style;
  44.         css_style * color_style;
  45.         css_style * image_style;
  46.         css_style * position_style;
  47.         css_style * repeat_style;
  48.  
  49.  
  50.         /* Firstly, handle inherit */
  51.         token = parserutils_vector_peek(vector, *ctx);
  52.         if (token == NULL)
  53.                 return CSS_INVALID;
  54.                
  55.         if (is_css_inherit(c, token)) {
  56.                 error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_ATTACHMENT);
  57.                 if (error != CSS_OK)
  58.                         return error;
  59.  
  60.                 error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_COLOR);
  61.                 if (error != CSS_OK)
  62.                         return error;          
  63.  
  64.                 error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_IMAGE);
  65.                 if (error != CSS_OK)
  66.                         return error;
  67.  
  68.                 error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_POSITION);
  69.                 if (error != CSS_OK)
  70.                         return error;
  71.  
  72.                 error = css_stylesheet_style_inherit(result, CSS_PROP_BACKGROUND_REPEAT);
  73.                 if (error == CSS_OK)
  74.                         parserutils_vector_iterate(vector, ctx);
  75.  
  76.                 return error;
  77.         }
  78.  
  79.         /* allocate styles */
  80.         error = css__stylesheet_style_create(c->sheet, &attachment_style);
  81.         if (error != CSS_OK)
  82.                 return error;
  83.  
  84.         error = css__stylesheet_style_create(c->sheet, &color_style);
  85.         if (error != CSS_OK) {
  86.                 css__stylesheet_style_destroy(attachment_style);
  87.                 return error;
  88.         }
  89.  
  90.         error = css__stylesheet_style_create(c->sheet, &image_style);
  91.         if (error != CSS_OK) {
  92.                 css__stylesheet_style_destroy(attachment_style);
  93.                 css__stylesheet_style_destroy(color_style);
  94.                 return error;
  95.         }
  96.  
  97.         error = css__stylesheet_style_create(c->sheet, &position_style);
  98.         if (error != CSS_OK) {
  99.                 css__stylesheet_style_destroy(attachment_style);
  100.                 css__stylesheet_style_destroy(color_style);
  101.                 css__stylesheet_style_destroy(image_style);
  102.                 return error;
  103.         }
  104.  
  105.         error = css__stylesheet_style_create(c->sheet, &repeat_style);
  106.         if (error != CSS_OK) {
  107.                 css__stylesheet_style_destroy(attachment_style);
  108.                 css__stylesheet_style_destroy(color_style);
  109.                 css__stylesheet_style_destroy(image_style);
  110.                 css__stylesheet_style_destroy(position_style);
  111.                 return error;
  112.         }
  113.  
  114.         /* Attempt to parse the various longhand properties */
  115.         do {
  116.                 prev_ctx = *ctx;
  117.                 error = CSS_OK;
  118.  
  119.                 if (is_css_inherit(c, token)) {
  120.                         error = CSS_INVALID;
  121.                         goto css__parse_background_cleanup;
  122.                 }
  123.  
  124.                 /* Try each property parser in turn, but only if we
  125.                  * haven't already got a value for this property.
  126.                  */
  127.                 if ((attachment) &&
  128.                     (error = css__parse_background_attachment(c, vector, ctx,
  129.                                             attachment_style)) == CSS_OK) {
  130.                         attachment = false;
  131.                 } else if ((color) &&
  132.                            (error = css__parse_background_color(c, vector, ctx,
  133.                                             color_style)) == CSS_OK) {
  134.                         color = false;
  135.                 } else if ((image) &&
  136.                            (error = css__parse_background_image(c, vector, ctx,
  137.                                             image_style)) == CSS_OK) {
  138.                         image = false;
  139.                 } else if ((position) &&
  140.                            (error = css__parse_background_position(c, vector, ctx,
  141.                                         position_style)) == CSS_OK) {
  142.                         position = false;
  143.                 } else if ((repeat) &&
  144.                            (error = css__parse_background_repeat(c, vector, ctx,
  145.                                         repeat_style)) == CSS_OK) {
  146.                         repeat = false;
  147.                 }
  148.  
  149.                 if (error == CSS_OK) {
  150.                         consumeWhitespace(vector, ctx);
  151.  
  152.                         token = parserutils_vector_peek(vector, *ctx);
  153.                 } else {
  154.                         /* Forcibly cause loop to exit */
  155.                         token = NULL;
  156.                 }
  157.         } while (*ctx != prev_ctx && token != NULL);
  158.  
  159.         if (attachment) {
  160.                 error = css__stylesheet_style_appendOPV(attachment_style,
  161.                                 CSS_PROP_BACKGROUND_ATTACHMENT, 0,
  162.                                 BACKGROUND_ATTACHMENT_SCROLL);
  163.                 if (error != CSS_OK)
  164.                         goto css__parse_background_cleanup;
  165.         }
  166.  
  167.         if (color) {
  168.                 error = css__stylesheet_style_appendOPV(color_style,
  169.                                 CSS_PROP_BACKGROUND_COLOR, 0,
  170.                                 BACKGROUND_COLOR_TRANSPARENT);
  171.                 if (error != CSS_OK)
  172.                         goto css__parse_background_cleanup;
  173.         }
  174.  
  175.         if (image) {
  176.                 error = css__stylesheet_style_appendOPV(image_style,
  177.                                 CSS_PROP_BACKGROUND_IMAGE,
  178.                                 0, BACKGROUND_IMAGE_NONE);
  179.                 if (error != CSS_OK)
  180.                         goto css__parse_background_cleanup;
  181.         }
  182.  
  183.         if (position) {
  184.                 error = css__stylesheet_style_appendOPV(position_style,
  185.                                 CSS_PROP_BACKGROUND_POSITION,
  186.                                 0, BACKGROUND_POSITION_HORZ_LEFT |
  187.                                 BACKGROUND_POSITION_VERT_TOP);
  188.                 if (error != CSS_OK)
  189.                         goto css__parse_background_cleanup;
  190.         }
  191.  
  192.         if (repeat) {
  193.                 error = css__stylesheet_style_appendOPV(repeat_style,
  194.                                 CSS_PROP_BACKGROUND_REPEAT,
  195.                                 0, BACKGROUND_REPEAT_REPEAT);
  196.                 if (error != CSS_OK)
  197.                         goto css__parse_background_cleanup;
  198.         }
  199.  
  200.         error = css__stylesheet_merge_style(result, attachment_style);
  201.         if (error != CSS_OK)
  202.                 goto css__parse_background_cleanup;
  203.  
  204.         error = css__stylesheet_merge_style(result, color_style);
  205.         if (error != CSS_OK)
  206.                 goto css__parse_background_cleanup;
  207.  
  208.         error = css__stylesheet_merge_style(result, image_style);
  209.         if (error != CSS_OK)
  210.                 goto css__parse_background_cleanup;
  211.  
  212.         error = css__stylesheet_merge_style(result, position_style);
  213.         if (error != CSS_OK)
  214.                 goto css__parse_background_cleanup;
  215.  
  216.         error = css__stylesheet_merge_style(result, repeat_style);
  217.  
  218. css__parse_background_cleanup:
  219.         css__stylesheet_style_destroy(attachment_style);
  220.         css__stylesheet_style_destroy(color_style);
  221.         css__stylesheet_style_destroy(image_style);
  222.         css__stylesheet_style_destroy(position_style);
  223.         css__stylesheet_style_destroy(repeat_style);
  224.  
  225.         if (error != CSS_OK)
  226.                 *ctx = orig_ctx;
  227.  
  228.         return error;
  229.  
  230.  
  231. }
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.