[gnome-shell] St: Implement background-size CSS property



commit 25948f214ea0dbe08e99124b6c408b184905e021
Author: Quentin Glidic <sardemff7+git sardemff7 net>
Date:   Fri Dec 23 18:59:20 2011 +0100

    St: Implement background-size CSS property
    
    Implement the background-size CSS property, specified by the CSS
    Backgrounds and Borders Module Level 3, including the keywords
    "contain", "cover", and fixed-size backgrounds.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=633462

 data/theme/gnome-shell.css           |   18 +++
 src/st/st-theme-node-drawing.c       |  268 ++++++++++++++++-----------------
 src/st/st-theme-node-private.h       |    5 +
 src/st/st-theme-node.c               |   41 +++++
 src/st/st-types.h                    |    7 +
 tests/interactive/background-size.js |   89 +++++++++++
 tests/testcommon/100-200.svg         |   21 +++
 tests/testcommon/200-100.svg         |   21 +++
 tests/testcommon/200-200.svg         |   21 +++
 tests/testcommon/test.css            |   12 ++
 10 files changed, 365 insertions(+), 138 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 4294e5e..afd4d6e 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -60,6 +60,7 @@ StScrollBar StBin#trough {
 StScrollBar StButton#vhandle
 {
     background-image: url("scroll-vhandle.svg");
+    background-size: contain;
     background-color: #252525;
     border: 1px solid #080808;
     border-radius: 8px;
@@ -68,6 +69,7 @@ StScrollBar StButton#vhandle
 StScrollBar StButton#hhandle
 {
     background-image: url("scroll-hhandle.svg");
+    background-size: contain;
     background-color: #252525;
     border: 1px solid #080808;
     border-radius: 8px;
@@ -224,16 +226,20 @@ StTooltip StLabel {
 
 .toggle-switch-us {
     background-image: url("toggle-off-us.svg");
+    background-size: contain;
 }
 .toggle-switch-us:checked {
     background-image: url("toggle-on-us.svg");
+    background-size: contain;
 }
 
 .toggle-switch-intl {
     background-image: url("toggle-off-intl.svg");
+    background-size: contain;
 }
 .toggle-switch-intl:checked {
     background-image: url("toggle-on-intl.svg");
+    background-size: contain;
 }
 
 .nm-menu-item-icons {
@@ -356,6 +362,7 @@ StTooltip StLabel {
 .panel-button:focus {
     border-image: url("panel-button-border.svg") 10 10 0 2;
     background-image: url("panel-button-highlight-wide.svg");
+    background-size: contain;
     color: white;
     text-shadow: black 0px 2px 2px;
 }
@@ -364,6 +371,7 @@ StTooltip StLabel {
 .panel-status-button:checked,
 .panel-status-button:focus {
     background-image: url("panel-button-highlight-narrow.svg");
+    background-size: contain;
 }
 
 .panel-button:active > .system-status-icon,
@@ -477,6 +485,7 @@ StTooltip StLabel {
 
 .window-close {
     background-image: url("close-window.svg");
+    background-size: 34px;
     height: 34px;
     width: 34px;
     -shell-close-overlap: 20px;
@@ -511,6 +520,7 @@ StTooltip StLabel {
 
 .placeholder {
     background-image: url("dash-placeholder.svg");
+    background-size: contain;
     height: 24px;
 }
 
@@ -697,11 +707,13 @@ StTooltip StLabel {
 .app-filter:selected {
     color: #ffffff;
     background-image: url("filter-selected-ltr.svg");
+    background-size: contain;
     background-position: 190px 10px;
 }
 
 .app-filter:selected:rtl {
     background-image: url("filter-selected-rtl.svg");
+    background-size: contain;
     background-position: 10px 10px;
 }
 
@@ -782,6 +794,7 @@ StTooltip StLabel {
 .app-well-app.running > .overview-icon {
     text-shadow: black 0px 2px 2px;
     background-image: url("running-indicator.svg");
+    background-size: contain;
 }
 
 .contact:selected,
@@ -1443,6 +1456,7 @@ StTooltip StLabel {
 
 .summary-source-button:selected .summary-source {
     background-image: url("panel-button-highlight-narrow.svg");
+    background-size: contain;
     border-image: url("source-button-border.svg") 10 10 0 1;
 }
 
@@ -1453,6 +1467,7 @@ StTooltip StLabel {
 
 .summary-source-button:expanded:selected {
     background-image: url("panel-button-highlight-wide.svg");
+    background-size: contain;
     border-image: url("source-button-border.svg") 10 10 0 1;
 }
 
@@ -1566,6 +1581,7 @@ StTooltip StLabel {
     width: 52px;
     height: 52px;
     background-image: url("corner-ripple-ltr.png");
+    background-size: contain;
 }
 
 .ripple-box:rtl {
@@ -1607,6 +1623,7 @@ StTooltip StLabel {
     border: 0px;
     background: rgba(255,255,255,0.5);
     background-image: url("ws-switch-arrow-up.svg");
+    background-size: contain;
     border-radius: 8px;
 }
 
@@ -1615,6 +1632,7 @@ StTooltip StLabel {
     border: 0px;
     background: rgba(255,255,255,0.5);
     background-image: url("ws-switch-arrow-down.svg");
+    background-size: contain;
     border-radius: 8px;
 }
 
diff --git a/src/st/st-theme-node-drawing.c b/src/st/st-theme-node-drawing.c
index 440ca13..8533107 100644
--- a/src/st/st-theme-node-drawing.c
+++ b/src/st/st-theme-node-drawing.c
@@ -5,6 +5,7 @@
  * Copyright 2009, 2010 Red Hat, Inc.
  * Copyright 2009, 2010 Florian MÃllner
  * Copyright 2010 Intel Corporation.
+ * Copyright 2011 Quentin "Sardem FF7" Glidic
  *
  * Contains code derived from:
  *   rectangle.c: Rounded rectangle.
@@ -391,70 +392,111 @@ st_theme_node_lookup_corner (StThemeNode    *node,
 }
 
 static void
-get_background_position (StThemeNode             *self,
-                         const ClutterActorBox   *allocation,
-                         ClutterActorBox         *result)
+get_background_scale (StThemeNode *node,
+                      gdouble      painting_area_width,
+                      gdouble      painting_area_height,
+                      gdouble      background_image_width,
+                      gdouble      background_image_height,
+                      gdouble     *scale_w,
+                      gdouble     *scale_h)
 {
-  gfloat w, h;
-
-  result->x1 = result->y1 = 0;
-  result->x2 = allocation->x2 - allocation->x1;
-  result->y2 = allocation->y2 - allocation->y1;
-
-  w = cogl_texture_get_width (self->background_texture);
-  h = cogl_texture_get_height (self->background_texture);
+  *scale_w = -1.0;
+  *scale_h = -1.0;
 
-  /* scale the background into the allocated bounds, when not being absolutely positioned */
-  if ((w > result->x2 || h > result->y2) && !self->background_position_set)
+  switch (node->background_size)
     {
-      gint new_h, new_w, offset;
-      gint box_w, box_h;
-
-      box_w = (int) result->x2;
-      box_h = (int) result->y2;
-
-      /* scale to fit */
-      new_h = (int)((h / w) * ((gfloat) box_w));
-      new_w = (int)((w / h) * ((gfloat) box_h));
-
-      if (new_h > box_h)
-        {
-          /* center for new width */
-          offset = ((box_w) - new_w) * 0.5;
-          result->x1 = offset;
-          result->x2 = offset + new_w;
-
-          result->y2 = box_h;
-        }
-      else
-        {
-          /* center for new height */
-          offset = ((box_h) - new_h) * 0.5;
-          result->y1 = offset;
-          result->y2 = offset + new_h;
+      case ST_BACKGROUND_SIZE_AUTO:
+        *scale_w = 1.0;
+        break;
+      case ST_BACKGROUND_SIZE_CONTAIN:
+        if (background_image_width > background_image_height)
+          *scale_w = painting_area_width / background_image_width;
+        else
+          *scale_w = painting_area_height / background_image_height;
+        break;
+      case ST_BACKGROUND_SIZE_COVER:
+        if (background_image_width < background_image_height)
+          *scale_w = painting_area_width / background_image_width;
+        else
+          *scale_w = painting_area_height / background_image_height;
+        break;
+      case ST_BACKGROUND_SIZE_FIXED:
+        if (node->background_size_w > -1)
+          {
+            *scale_w = node->background_size_w / background_image_width;
+            if (node->background_size_h > -1)
+              *scale_h = node->background_size_h / background_image_height;
+          }
+        else if (node->background_size_h > -1)
+          *scale_w = node->background_size_h / background_image_height;
+        break;
+    }
+  if (*scale_h < 0.0)
+    *scale_h = *scale_w;
+}
 
-          result->x2 = box_w;
-        }
+static void
+get_background_coordinates (StThemeNode *node,
+                            gdouble      painting_area_width,
+                            gdouble      painting_area_height,
+                            gdouble      background_image_width,
+                            gdouble      background_image_height,
+                            gdouble     *x,
+                            gdouble     *y)
+{
+  /* honor the specified position if any */
+  if (node->background_position_set)
+    {
+      *x = node->background_position_x;
+      *y = node->background_position_y;
     }
   else
     {
-      /* honor the specified position if any */
-      if (self->background_position_set)
-        {
-          result->x1 = self->background_position_x;
-          result->y1 = self->background_position_y;
-        }
-      else
-        {
-          /* center the background on the widget */
-          result->x1 = (int)(((allocation->x2 - allocation->x1) / 2) - (w / 2));
-          result->y1 = (int)(((allocation->y2 - allocation->y1) / 2) - (h / 2));
-        }
-      result->x2 = result->x1 + w;
-      result->y2 = result->y1 + h;
+      /* center the background on the widget */
+      *x = (painting_area_width / 2.0) - (background_image_width / 2.0);
+      *y = (painting_area_height / 2.0) - (background_image_height / 2.0);
     }
 }
 
+static void
+get_background_position (StThemeNode             *self,
+                         const ClutterActorBox   *allocation,
+                         ClutterActorBox         *result)
+{
+  gdouble painting_area_width, painting_area_height;
+  gdouble background_image_width, background_image_height;
+  gdouble x, y;
+  gdouble scale_w, scale_h;
+
+  /* get the background image size */
+  background_image_width = allocation->x2 - allocation->x1;
+  background_image_height = allocation->y2 - allocation->y1;
+
+  /* get the painting area size */
+  painting_area_width = cogl_texture_get_width (self->background_texture);
+  painting_area_height = cogl_texture_get_height (self->background_texture);
+
+  /* scale if requested */
+  get_background_scale (self,
+                        painting_area_width, painting_area_height,
+                        background_image_width, background_image_height,
+                        &scale_w, &scale_h);
+  background_image_width *= scale_w;
+  background_image_height *= scale_h;
+
+  /* get coordinates */
+  get_background_coordinates (self,
+                              painting_area_width, painting_area_height,
+                              background_image_width, background_image_height,
+                              &x, &y);
+
+  /* place the background image */
+  result->x1 = x;
+  result->y1 = y;
+  result->x2 = result->x1 + background_image_width;
+  result->y2 = result->y1 + background_image_height;
+}
+
 /* Use of this function marks code which doesn't support
  * non-uniform colors.
  */
@@ -533,12 +575,13 @@ create_cairo_pattern_of_background_image (StThemeNode *node,
   cairo_content_t  content;
   cairo_matrix_t   matrix;
   const char *file;
-  double height_ratio, width_ratio;
-  int file_width;
-  int file_height;
 
   StTextureCache *texture_cache;
 
+  gdouble background_image_width, background_image_height;
+  gdouble x, y;
+  gdouble scale_w, scale_h;
+
   file = st_theme_node_get_background_image (node);
 
   texture_cache = st_texture_cache_get_default ();
@@ -553,90 +596,39 @@ create_cairo_pattern_of_background_image (StThemeNode *node,
   content = cairo_surface_get_content (surface);
   pattern = cairo_pattern_create_for_surface (surface);
 
-  file_width = cairo_image_surface_get_width (surface);
-  file_height = cairo_image_surface_get_height (surface);
-
-  height_ratio = file_height / node->alloc_height;
-  width_ratio = file_width / node->alloc_width;
+  background_image_width = cairo_image_surface_get_width (surface);
+  background_image_height = cairo_image_surface_get_height (surface);
 
   *needs_background_fill = TRUE;
-  if ((file_width > node->alloc_width || file_height > node->alloc_height)
-      && !node->background_position_set)
-    {
-      double scale_factor;
-      double x_offset, y_offset;
-
-      if (width_ratio > height_ratio)
-        {
-          double scaled_height;
-
-          /* center vertically */
-
-          scale_factor = width_ratio;
-          scaled_height = file_height / scale_factor;
-
-          x_offset = 0.;
-          y_offset = - (node->alloc_height / 2. - scaled_height / 2.);
-        }
-      else
-        {
-          double scaled_width;
-
-          /* center horizontally */
-
-          scale_factor = height_ratio;
-          scaled_width = file_width / scale_factor;
-
-          y_offset = 0.;
-          x_offset = - (node->alloc_width / 2. - scaled_width / 2.);
-        }
-
-      cairo_matrix_init_scale (&matrix, scale_factor, scale_factor);
-      cairo_matrix_translate (&matrix, x_offset, y_offset);
 
-      cairo_pattern_set_matrix (pattern, &matrix);
-
-      /* If it's opaque, and when scaled, fills up the entire allocated
-       * area, then don't bother doing a background fill first
-       */
-      if (content != CAIRO_CONTENT_COLOR_ALPHA && width_ratio == height_ratio)
-        *needs_background_fill = FALSE;
-    }
-  else
-    {
-      double x_offset, y_offset;
-
-      if (node->background_position_set)
-        {
-          x_offset = -node->background_position_x;
-          y_offset = -node->background_position_y;
-        }
-      else
-        {
-          if (node->alloc_width > file_width)
-            x_offset = - (node->alloc_width / 2.0 - file_width / 2.0);
-          else
-            x_offset = - (file_width / 2.0 - node->alloc_width / 2.0);
-
-          if (node->alloc_height > file_height)
-            y_offset = - (node->alloc_height / 2.0 - file_height / 2.0);
-          else
-            y_offset = - (file_height / 2.0 - node->alloc_height / 2.0);
-        }
-
-      /* If it's opaque, and when translated, fills up the entire allocated
-       * area, then don't bother doing a background fill first
-       */
-      if (content != CAIRO_CONTENT_COLOR_ALPHA
-          && -x_offset <= 0
-          && -x_offset + file_width >= node->alloc_width
-          && -y_offset <= 0
-          && -y_offset + file_height >= node->alloc_height)
-        *needs_background_fill = FALSE;
-
-      cairo_matrix_init_translate (&matrix, x_offset, y_offset);
-      cairo_pattern_set_matrix (pattern, &matrix);
-    }
+  cairo_matrix_init_identity (&matrix);
+
+  get_background_scale (node,
+                        node->alloc_width, node->alloc_height,
+                        background_image_width, background_image_height,
+                        &scale_w, &scale_h);
+  if ((scale_w != 1) || (scale_h != 1))
+    cairo_matrix_scale (&matrix, 1.0/scale_w, 1.0/scale_h);
+  background_image_width *= scale_w;
+  background_image_height *= scale_h;
+
+  get_background_coordinates (node,
+                              node->alloc_width, node->alloc_height,
+                              background_image_width, background_image_height,
+                              &x, &y);
+  cairo_matrix_translate (&matrix, -x, -y);
+
+  /* If it's opaque, fills up the entire allocated
+   * area, then don't bother doing a background fill first
+   */
+  if (content != CAIRO_CONTENT_COLOR_ALPHA
+      && x >= 0
+      && -x + background_image_width >= node->alloc_width
+      && y >= 0
+      && -y + background_image_height >= node->alloc_height)
+    *needs_background_fill = FALSE;
+
+  cairo_pattern_set_matrix (pattern, &matrix);
 
   return pattern;
 }
diff --git a/src/st/st-theme-node-private.h b/src/st/st-theme-node-private.h
index f42cf40..b6cd2a4 100644
--- a/src/st/st-theme-node-private.h
+++ b/src/st/st-theme-node-private.h
@@ -3,6 +3,7 @@
  * st-theme-node-private.h: private structures and functions for StThemeNode
  *
  * Copyright 2009, 2010 Red Hat, Inc.
+ * Copyright 2011 Quentin "Sardem FF7" Glidic
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as
@@ -24,6 +25,7 @@
 #include <gdk/gdk.h>
 
 #include "st-theme-node.h"
+#include "st-types.h"
 
 G_BEGIN_DECLS
 
@@ -44,6 +46,9 @@ struct _StThemeNode {
   int background_position_x;
   int background_position_y;
   gboolean background_position_set : 1;
+  StBackgroundSize background_size;
+  gint background_size_w;
+  gint background_size_h;
 
   ClutterColor foreground_color;
   ClutterColor border_color[4];
diff --git a/src/st/st-theme-node.c b/src/st/st-theme-node.c
index cc51498..47b117c 100644
--- a/src/st/st-theme-node.c
+++ b/src/st/st-theme-node.c
@@ -7,6 +7,7 @@
  * Copyright 2009, 2010 Florian MÃllner
  * Copyright 2010 Adel Gadllah
  * Copyright 2010 Giovanni Campagna
+ * Copyright 2011 Quentin "Sardem FF7" Glidic
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as
@@ -1579,6 +1580,7 @@ _st_theme_node_ensure_background (StThemeNode *node)
   node->background_color = TRANSPARENT_COLOR;
   node->background_gradient_type = ST_GRADIENT_NONE;
   node->background_position_set = FALSE;
+  node->background_size = ST_BACKGROUND_SIZE_AUTO;
 
   ensure_properties (node);
 
@@ -1606,6 +1608,7 @@ _st_theme_node_ensure_background (StThemeNode *node)
           g_free (node->background_image);
           node->background_image = NULL;
           node->background_position_set = FALSE;
+          node->background_size = ST_BACKGROUND_SIZE_AUTO;
 
           for (term = decl->value; term; term = term->next)
             {
@@ -1662,6 +1665,44 @@ _st_theme_node_ensure_background (StThemeNode *node)
           else
             node->background_position_set = TRUE;
         }
+      else if (strcmp (property_name, "-size") == 0)
+        {
+          if (decl->value->type == TERM_IDENT)
+            {
+              if (strcmp (decl->value->content.str->stryng->str, "contain") == 0)
+                node->background_size = ST_BACKGROUND_SIZE_CONTAIN;
+              else if (strcmp (decl->value->content.str->stryng->str, "cover") == 0)
+                node->background_size = ST_BACKGROUND_SIZE_COVER;
+              else if ((strcmp (decl->value->content.str->stryng->str, "auto") == 0) && (decl->value->next) && (decl->value->next->type == TERM_NUMBER))
+                {
+                  GetFromTermResult result = get_length_from_term_int (node, decl->value->next, FALSE, &node->background_size_h);
+
+                  node->background_size_w = -1;
+                  node->background_size = (result == VALUE_FOUND) ? ST_BACKGROUND_SIZE_FIXED : ST_BACKGROUND_SIZE_AUTO;
+                }
+              else
+                node->background_size = ST_BACKGROUND_SIZE_AUTO;
+            }
+          else if (decl->value->type == TERM_NUMBER)
+            {
+              GetFromTermResult result = get_length_from_term_int (node, decl->value, FALSE, &node->background_size_w);
+              if (result == VALUE_NOT_FOUND)
+                continue;
+
+              node->background_size = ST_BACKGROUND_SIZE_FIXED;
+
+              if ((decl->value->next) && (decl->value->next->type == TERM_NUMBER))
+                {
+                  result = get_length_from_term_int (node, decl->value->next, FALSE, &node->background_size_h);
+
+                  if (result == VALUE_FOUND)
+                    continue;
+                }
+              node->background_size_h = -1;
+            }
+          else
+            node->background_size = ST_BACKGROUND_SIZE_AUTO;
+        }
       else if (strcmp (property_name, "-color") == 0)
         {
           GetFromTermResult result;
diff --git a/src/st/st-types.h b/src/st/st-types.h
index 335c2a0..edcbbfd 100644
--- a/src/st/st-types.h
+++ b/src/st/st-types.h
@@ -49,6 +49,13 @@ typedef enum {
   ST_ICON_DOCUMENT
 } StIconType;
 
+typedef enum {
+  ST_BACKGROUND_SIZE_AUTO,
+  ST_BACKGROUND_SIZE_CONTAIN,
+  ST_BACKGROUND_SIZE_COVER,
+  ST_BACKGROUND_SIZE_FIXED
+} StBackgroundSize;
+
 G_END_DECLS
 
 #endif /* __ST_TYPES_H__ */
diff --git a/tests/interactive/background-size.js b/tests/interactive/background-size.js
new file mode 100644
index 0000000..00f967d
--- /dev/null
+++ b/tests/interactive/background-size.js
@@ -0,0 +1,89 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const Clutter = imports.gi.Clutter;
+const St = imports.gi.St;
+
+const UI = imports.testcommon.ui;
+
+UI.init();
+let stage = Clutter.Stage.get_default();
+stage.width = 1024;
+stage.height = 768;
+
+let vbox = new St.BoxLayout({ width: stage.width,
+                              height: stage.height,
+                              style: 'background: #ffee88;' });
+stage.add_actor(vbox);
+
+let scroll = new St.ScrollView();
+vbox.add(scroll, { expand: true });
+
+let vbox = new St.BoxLayout({ vertical: true,
+                              style: 'padding: 10px;'
+                                     + 'spacing: 20px;' });
+scroll.add_actor(vbox);
+
+let tbox = null;
+
+function addTestCase(image, size, backgroundSize) {
+    let obin = new St.Bin({ style: 'border: 3px solid green;' });
+    tbox.add(obin);
+
+    let bin = new St.Bin({ style_class: 'background-image-' + image,
+                           width: size.width,
+                           height: size.height,
+                           style: 'border: 1px solid transparent;'
+                                  + 'background-size: ' + backgroundSize + ';',
+                           x_fill: true,
+                           y_fill: true
+                         });
+    obin.set_child(bin);
+
+    bin.set_child(new St.Label({ text: backgroundSize,
+                                 style: 'font-size: 15px;'
+                                        + 'text-align: center;'
+                               }));
+}
+
+function addTestLine(image, size, backgroundSizes) {
+    vbox.add(new St.Label({ text: image + '.svg / ' + size.width + 'Ã' + size.height,
+                            style: 'font-size: 15px;'
+                                   + 'text-align: center;'
+                          }));
+
+    tbox = new St.BoxLayout({ style: 'spacing: 20px;' });
+    vbox.add(tbox);
+
+    if (backgroundSizes.length == 2)
+        addTestCase(image, size, "auto");
+    for each (let s in backgroundSizes)
+        addTestCase(image, size, s);
+}
+
+let size1 = { width: 200, height: 200 }
+let size2 = { width: 250, height: 250 }
+let size3 = { width: 100, height: 100 }
+
+// fixed size
+addTestLine('200-200', size1, ["200px 200px", "100px 100px", "100px 200px"]);
+
+// same size
+addTestLine('200-200', size1, ["contain", "cover"]);
+// smaller
+addTestLine('200-200', size2, ["contain", "cover"]);
+// larger
+addTestLine('200-200', size3, ["contain", "cover"]);
+
+
+addTestLine('200-100', size1, ["contain", "cover"]);
+addTestLine('200-100', size2, ["contain", "cover"]);
+addTestLine('200-100', size3, ["contain", "cover"]);
+
+
+addTestLine('100-200', size1, ["contain", "cover"]);
+addTestLine('100-200', size2, ["contain", "cover"]);
+addTestLine('100-200', size3, ["contain", "cover"]);
+
+stage.show();
+Clutter.main();
+stage.destroy();
diff --git a/tests/testcommon/100-200.svg b/tests/testcommon/100-200.svg
new file mode 100644
index 0000000..59a5307
--- /dev/null
+++ b/tests/testcommon/100-200.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
+<svg xmlns="http://www.w3.org/2000/svg";
+	viewBox="0 0 100 200" width="100" height="200">
+  <path
+    d="
+      M 2,2 h 96 v 196 h -96 v -196
+      M 8,8 h 84 v 184 h -84 v -184
+    "
+    fill="white"
+    stroke="blue"
+    stroke-width="2"
+    stroke-linecap="square"
+    />
+  <path
+    d="
+      M 10,10 h 20 v 20 h -20 v -20
+    "
+    fill="green"
+    />
+</svg>
diff --git a/tests/testcommon/200-100.svg b/tests/testcommon/200-100.svg
new file mode 100644
index 0000000..e149b5f
--- /dev/null
+++ b/tests/testcommon/200-100.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
+<svg xmlns="http://www.w3.org/2000/svg";
+	viewBox="0 0 200 100" width="200" height="100">
+  <path
+    d="
+      M 2,2 h 196 v 96 h -196 v -96
+      M 8,8 h 184 v 84 h -184 v -84
+    "
+    fill="white"
+    stroke="blue"
+    stroke-width="2"
+    stroke-linecap="square"
+    />
+  <path
+    d="
+      M 10,10 h 20 v 20 h -20 v -20
+    "
+    fill="green"
+    />
+</svg>
diff --git a/tests/testcommon/200-200.svg b/tests/testcommon/200-200.svg
new file mode 100644
index 0000000..9965a2a
--- /dev/null
+++ b/tests/testcommon/200-200.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
+<svg xmlns="http://www.w3.org/2000/svg";
+	viewBox="0 0 200 200" width="200" height="200">
+  <path
+    d="
+      M 2,2 h 196 v 196 h -196 v -196
+      M 8,8 h 184 v 184 h -184 v -184
+    "
+    fill="white"
+    stroke="blue"
+    stroke-width="2"
+    stroke-linecap="square"
+    />
+  <path
+    d="
+      M 10,10 h 20 v 20 h -20 v -20
+    "
+    fill="green"
+    />
+</svg>
diff --git a/tests/testcommon/test.css b/tests/testcommon/test.css
index 5e60254..49f5b65 100644
--- a/tests/testcommon/test.css
+++ b/tests/testcommon/test.css
@@ -37,6 +37,18 @@ stage {
     border-image: url('border-image.png') 16;
 }
 
+.background-image-200-200 {
+    background-image: url('200-200.svg');
+}
+
+.background-image-100-200 {
+    background-image: url('100-200.svg');
+}
+
+.background-image-200-100 {
+    background-image: url('200-100.svg');
+}
+
 .background-gradient {
     background-gradient-start: rgba(127, 255, 127, .6);
     background-gradient-end: rgba(127, 127, 255, .6);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]