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
This commit is contained in:
parent
bea4faacd4
commit
25948f214e
@ -60,6 +60,7 @@ StScrollBar StBin#trough {
|
|||||||
StScrollBar StButton#vhandle
|
StScrollBar StButton#vhandle
|
||||||
{
|
{
|
||||||
background-image: url("scroll-vhandle.svg");
|
background-image: url("scroll-vhandle.svg");
|
||||||
|
background-size: contain;
|
||||||
background-color: #252525;
|
background-color: #252525;
|
||||||
border: 1px solid #080808;
|
border: 1px solid #080808;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@ -68,6 +69,7 @@ StScrollBar StButton#vhandle
|
|||||||
StScrollBar StButton#hhandle
|
StScrollBar StButton#hhandle
|
||||||
{
|
{
|
||||||
background-image: url("scroll-hhandle.svg");
|
background-image: url("scroll-hhandle.svg");
|
||||||
|
background-size: contain;
|
||||||
background-color: #252525;
|
background-color: #252525;
|
||||||
border: 1px solid #080808;
|
border: 1px solid #080808;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@ -224,16 +226,20 @@ StTooltip StLabel {
|
|||||||
|
|
||||||
.toggle-switch-us {
|
.toggle-switch-us {
|
||||||
background-image: url("toggle-off-us.svg");
|
background-image: url("toggle-off-us.svg");
|
||||||
|
background-size: contain;
|
||||||
}
|
}
|
||||||
.toggle-switch-us:checked {
|
.toggle-switch-us:checked {
|
||||||
background-image: url("toggle-on-us.svg");
|
background-image: url("toggle-on-us.svg");
|
||||||
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-switch-intl {
|
.toggle-switch-intl {
|
||||||
background-image: url("toggle-off-intl.svg");
|
background-image: url("toggle-off-intl.svg");
|
||||||
|
background-size: contain;
|
||||||
}
|
}
|
||||||
.toggle-switch-intl:checked {
|
.toggle-switch-intl:checked {
|
||||||
background-image: url("toggle-on-intl.svg");
|
background-image: url("toggle-on-intl.svg");
|
||||||
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nm-menu-item-icons {
|
.nm-menu-item-icons {
|
||||||
@ -356,6 +362,7 @@ StTooltip StLabel {
|
|||||||
.panel-button:focus {
|
.panel-button:focus {
|
||||||
border-image: url("panel-button-border.svg") 10 10 0 2;
|
border-image: url("panel-button-border.svg") 10 10 0 2;
|
||||||
background-image: url("panel-button-highlight-wide.svg");
|
background-image: url("panel-button-highlight-wide.svg");
|
||||||
|
background-size: contain;
|
||||||
color: white;
|
color: white;
|
||||||
text-shadow: black 0px 2px 2px;
|
text-shadow: black 0px 2px 2px;
|
||||||
}
|
}
|
||||||
@ -364,6 +371,7 @@ StTooltip StLabel {
|
|||||||
.panel-status-button:checked,
|
.panel-status-button:checked,
|
||||||
.panel-status-button:focus {
|
.panel-status-button:focus {
|
||||||
background-image: url("panel-button-highlight-narrow.svg");
|
background-image: url("panel-button-highlight-narrow.svg");
|
||||||
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-button:active > .system-status-icon,
|
.panel-button:active > .system-status-icon,
|
||||||
@ -477,6 +485,7 @@ StTooltip StLabel {
|
|||||||
|
|
||||||
.window-close {
|
.window-close {
|
||||||
background-image: url("close-window.svg");
|
background-image: url("close-window.svg");
|
||||||
|
background-size: 34px;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
width: 34px;
|
width: 34px;
|
||||||
-shell-close-overlap: 20px;
|
-shell-close-overlap: 20px;
|
||||||
@ -511,6 +520,7 @@ StTooltip StLabel {
|
|||||||
|
|
||||||
.placeholder {
|
.placeholder {
|
||||||
background-image: url("dash-placeholder.svg");
|
background-image: url("dash-placeholder.svg");
|
||||||
|
background-size: contain;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,11 +707,13 @@ StTooltip StLabel {
|
|||||||
.app-filter:selected {
|
.app-filter:selected {
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
background-image: url("filter-selected-ltr.svg");
|
background-image: url("filter-selected-ltr.svg");
|
||||||
|
background-size: contain;
|
||||||
background-position: 190px 10px;
|
background-position: 190px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-filter:selected:rtl {
|
.app-filter:selected:rtl {
|
||||||
background-image: url("filter-selected-rtl.svg");
|
background-image: url("filter-selected-rtl.svg");
|
||||||
|
background-size: contain;
|
||||||
background-position: 10px 10px;
|
background-position: 10px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -782,6 +794,7 @@ StTooltip StLabel {
|
|||||||
.app-well-app.running > .overview-icon {
|
.app-well-app.running > .overview-icon {
|
||||||
text-shadow: black 0px 2px 2px;
|
text-shadow: black 0px 2px 2px;
|
||||||
background-image: url("running-indicator.svg");
|
background-image: url("running-indicator.svg");
|
||||||
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contact:selected,
|
.contact:selected,
|
||||||
@ -1443,6 +1456,7 @@ StTooltip StLabel {
|
|||||||
|
|
||||||
.summary-source-button:selected .summary-source {
|
.summary-source-button:selected .summary-source {
|
||||||
background-image: url("panel-button-highlight-narrow.svg");
|
background-image: url("panel-button-highlight-narrow.svg");
|
||||||
|
background-size: contain;
|
||||||
border-image: url("source-button-border.svg") 10 10 0 1;
|
border-image: url("source-button-border.svg") 10 10 0 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1453,6 +1467,7 @@ StTooltip StLabel {
|
|||||||
|
|
||||||
.summary-source-button:expanded:selected {
|
.summary-source-button:expanded:selected {
|
||||||
background-image: url("panel-button-highlight-wide.svg");
|
background-image: url("panel-button-highlight-wide.svg");
|
||||||
|
background-size: contain;
|
||||||
border-image: url("source-button-border.svg") 10 10 0 1;
|
border-image: url("source-button-border.svg") 10 10 0 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1566,6 +1581,7 @@ StTooltip StLabel {
|
|||||||
width: 52px;
|
width: 52px;
|
||||||
height: 52px;
|
height: 52px;
|
||||||
background-image: url("corner-ripple-ltr.png");
|
background-image: url("corner-ripple-ltr.png");
|
||||||
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ripple-box:rtl {
|
.ripple-box:rtl {
|
||||||
@ -1607,6 +1623,7 @@ StTooltip StLabel {
|
|||||||
border: 0px;
|
border: 0px;
|
||||||
background: rgba(255,255,255,0.5);
|
background: rgba(255,255,255,0.5);
|
||||||
background-image: url("ws-switch-arrow-up.svg");
|
background-image: url("ws-switch-arrow-up.svg");
|
||||||
|
background-size: contain;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1615,6 +1632,7 @@ StTooltip StLabel {
|
|||||||
border: 0px;
|
border: 0px;
|
||||||
background: rgba(255,255,255,0.5);
|
background: rgba(255,255,255,0.5);
|
||||||
background-image: url("ws-switch-arrow-down.svg");
|
background-image: url("ws-switch-arrow-down.svg");
|
||||||
|
background-size: contain;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
* Copyright 2009, 2010 Red Hat, Inc.
|
* Copyright 2009, 2010 Red Hat, Inc.
|
||||||
* Copyright 2009, 2010 Florian Müllner
|
* Copyright 2009, 2010 Florian Müllner
|
||||||
* Copyright 2010 Intel Corporation.
|
* Copyright 2010 Intel Corporation.
|
||||||
|
* Copyright 2011 Quentin "Sardem FF7" Glidic
|
||||||
*
|
*
|
||||||
* Contains code derived from:
|
* Contains code derived from:
|
||||||
* rectangle.c: Rounded rectangle.
|
* rectangle.c: Rounded rectangle.
|
||||||
@ -390,69 +391,110 @@ st_theme_node_lookup_corner (StThemeNode *node,
|
|||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
*scale_w = -1.0;
|
||||||
|
*scale_h = -1.0;
|
||||||
|
|
||||||
|
switch (node->background_size)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
/* 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
|
static void
|
||||||
get_background_position (StThemeNode *self,
|
get_background_position (StThemeNode *self,
|
||||||
const ClutterActorBox *allocation,
|
const ClutterActorBox *allocation,
|
||||||
ClutterActorBox *result)
|
ClutterActorBox *result)
|
||||||
{
|
{
|
||||||
gfloat w, h;
|
gdouble painting_area_width, painting_area_height;
|
||||||
|
gdouble background_image_width, background_image_height;
|
||||||
|
gdouble x, y;
|
||||||
|
gdouble scale_w, scale_h;
|
||||||
|
|
||||||
result->x1 = result->y1 = 0;
|
/* get the background image size */
|
||||||
result->x2 = allocation->x2 - allocation->x1;
|
background_image_width = allocation->x2 - allocation->x1;
|
||||||
result->y2 = allocation->y2 - allocation->y1;
|
background_image_height = allocation->y2 - allocation->y1;
|
||||||
|
|
||||||
w = cogl_texture_get_width (self->background_texture);
|
/* get the painting area size */
|
||||||
h = cogl_texture_get_height (self->background_texture);
|
painting_area_width = cogl_texture_get_width (self->background_texture);
|
||||||
|
painting_area_height = cogl_texture_get_height (self->background_texture);
|
||||||
|
|
||||||
/* scale the background into the allocated bounds, when not being absolutely positioned */
|
/* scale if requested */
|
||||||
if ((w > result->x2 || h > result->y2) && !self->background_position_set)
|
get_background_scale (self,
|
||||||
{
|
painting_area_width, painting_area_height,
|
||||||
gint new_h, new_w, offset;
|
background_image_width, background_image_height,
|
||||||
gint box_w, box_h;
|
&scale_w, &scale_h);
|
||||||
|
background_image_width *= scale_w;
|
||||||
|
background_image_height *= scale_h;
|
||||||
|
|
||||||
box_w = (int) result->x2;
|
/* get coordinates */
|
||||||
box_h = (int) result->y2;
|
get_background_coordinates (self,
|
||||||
|
painting_area_width, painting_area_height,
|
||||||
|
background_image_width, background_image_height,
|
||||||
|
&x, &y);
|
||||||
|
|
||||||
/* scale to fit */
|
/* place the background image */
|
||||||
new_h = (int)((h / w) * ((gfloat) box_w));
|
result->x1 = x;
|
||||||
new_w = (int)((w / h) * ((gfloat) box_h));
|
result->y1 = y;
|
||||||
|
result->x2 = result->x1 + background_image_width;
|
||||||
if (new_h > box_h)
|
result->y2 = result->y1 + background_image_height;
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
result->x2 = box_w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use of this function marks code which doesn't support
|
/* Use of this function marks code which doesn't support
|
||||||
@ -533,12 +575,13 @@ create_cairo_pattern_of_background_image (StThemeNode *node,
|
|||||||
cairo_content_t content;
|
cairo_content_t content;
|
||||||
cairo_matrix_t matrix;
|
cairo_matrix_t matrix;
|
||||||
const char *file;
|
const char *file;
|
||||||
double height_ratio, width_ratio;
|
|
||||||
int file_width;
|
|
||||||
int file_height;
|
|
||||||
|
|
||||||
StTextureCache *texture_cache;
|
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);
|
file = st_theme_node_get_background_image (node);
|
||||||
|
|
||||||
texture_cache = st_texture_cache_get_default ();
|
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);
|
content = cairo_surface_get_content (surface);
|
||||||
pattern = cairo_pattern_create_for_surface (surface);
|
pattern = cairo_pattern_create_for_surface (surface);
|
||||||
|
|
||||||
file_width = cairo_image_surface_get_width (surface);
|
background_image_width = cairo_image_surface_get_width (surface);
|
||||||
file_height = cairo_image_surface_get_height (surface);
|
background_image_height = cairo_image_surface_get_height (surface);
|
||||||
|
|
||||||
height_ratio = file_height / node->alloc_height;
|
|
||||||
width_ratio = file_width / node->alloc_width;
|
|
||||||
|
|
||||||
*needs_background_fill = TRUE;
|
*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)
|
cairo_matrix_init_identity (&matrix);
|
||||||
{
|
|
||||||
double scaled_height;
|
|
||||||
|
|
||||||
/* center vertically */
|
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;
|
||||||
|
|
||||||
scale_factor = width_ratio;
|
get_background_coordinates (node,
|
||||||
scaled_height = file_height / scale_factor;
|
node->alloc_width, node->alloc_height,
|
||||||
|
background_image_width, background_image_height,
|
||||||
|
&x, &y);
|
||||||
|
cairo_matrix_translate (&matrix, -x, -y);
|
||||||
|
|
||||||
x_offset = 0.;
|
/* If it's opaque, fills up the entire allocated
|
||||||
y_offset = - (node->alloc_height / 2. - scaled_height / 2.);
|
* area, then don't bother doing a background fill first
|
||||||
}
|
*/
|
||||||
else
|
if (content != CAIRO_CONTENT_COLOR_ALPHA
|
||||||
{
|
&& x >= 0
|
||||||
double scaled_width;
|
&& -x + background_image_width >= node->alloc_width
|
||||||
|
&& y >= 0
|
||||||
|
&& -y + background_image_height >= node->alloc_height)
|
||||||
|
*needs_background_fill = FALSE;
|
||||||
|
|
||||||
/* center horizontally */
|
cairo_pattern_set_matrix (pattern, &matrix);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
* st-theme-node-private.h: private structures and functions for StThemeNode
|
* st-theme-node-private.h: private structures and functions for StThemeNode
|
||||||
*
|
*
|
||||||
* Copyright 2009, 2010 Red Hat, Inc.
|
* Copyright 2009, 2010 Red Hat, Inc.
|
||||||
|
* Copyright 2011 Quentin "Sardem FF7" Glidic
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as
|
* it under the terms of the GNU Lesser General Public License as
|
||||||
@ -24,6 +25,7 @@
|
|||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
|
|
||||||
#include "st-theme-node.h"
|
#include "st-theme-node.h"
|
||||||
|
#include "st-types.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -44,6 +46,9 @@ struct _StThemeNode {
|
|||||||
int background_position_x;
|
int background_position_x;
|
||||||
int background_position_y;
|
int background_position_y;
|
||||||
gboolean background_position_set : 1;
|
gboolean background_position_set : 1;
|
||||||
|
StBackgroundSize background_size;
|
||||||
|
gint background_size_w;
|
||||||
|
gint background_size_h;
|
||||||
|
|
||||||
ClutterColor foreground_color;
|
ClutterColor foreground_color;
|
||||||
ClutterColor border_color[4];
|
ClutterColor border_color[4];
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
* Copyright 2009, 2010 Florian Müllner
|
* Copyright 2009, 2010 Florian Müllner
|
||||||
* Copyright 2010 Adel Gadllah
|
* Copyright 2010 Adel Gadllah
|
||||||
* Copyright 2010 Giovanni Campagna
|
* Copyright 2010 Giovanni Campagna
|
||||||
|
* Copyright 2011 Quentin "Sardem FF7" Glidic
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as
|
* 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_color = TRANSPARENT_COLOR;
|
||||||
node->background_gradient_type = ST_GRADIENT_NONE;
|
node->background_gradient_type = ST_GRADIENT_NONE;
|
||||||
node->background_position_set = FALSE;
|
node->background_position_set = FALSE;
|
||||||
|
node->background_size = ST_BACKGROUND_SIZE_AUTO;
|
||||||
|
|
||||||
ensure_properties (node);
|
ensure_properties (node);
|
||||||
|
|
||||||
@ -1606,6 +1608,7 @@ _st_theme_node_ensure_background (StThemeNode *node)
|
|||||||
g_free (node->background_image);
|
g_free (node->background_image);
|
||||||
node->background_image = NULL;
|
node->background_image = NULL;
|
||||||
node->background_position_set = FALSE;
|
node->background_position_set = FALSE;
|
||||||
|
node->background_size = ST_BACKGROUND_SIZE_AUTO;
|
||||||
|
|
||||||
for (term = decl->value; term; term = term->next)
|
for (term = decl->value; term; term = term->next)
|
||||||
{
|
{
|
||||||
@ -1662,6 +1665,44 @@ _st_theme_node_ensure_background (StThemeNode *node)
|
|||||||
else
|
else
|
||||||
node->background_position_set = TRUE;
|
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)
|
else if (strcmp (property_name, "-color") == 0)
|
||||||
{
|
{
|
||||||
GetFromTermResult result;
|
GetFromTermResult result;
|
||||||
|
@ -49,6 +49,13 @@ typedef enum {
|
|||||||
ST_ICON_DOCUMENT
|
ST_ICON_DOCUMENT
|
||||||
} StIconType;
|
} StIconType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ST_BACKGROUND_SIZE_AUTO,
|
||||||
|
ST_BACKGROUND_SIZE_CONTAIN,
|
||||||
|
ST_BACKGROUND_SIZE_COVER,
|
||||||
|
ST_BACKGROUND_SIZE_FIXED
|
||||||
|
} StBackgroundSize;
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __ST_TYPES_H__ */
|
#endif /* __ST_TYPES_H__ */
|
||||||
|
89
tests/interactive/background-size.js
Normal file
89
tests/interactive/background-size.js
Normal file
@ -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();
|
21
tests/testcommon/100-200.svg
Normal file
21
tests/testcommon/100-200.svg
Normal file
@ -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>
|
After Width: | Height: | Size: 518 B |
21
tests/testcommon/200-100.svg
Normal file
21
tests/testcommon/200-100.svg
Normal file
@ -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>
|
After Width: | Height: | Size: 518 B |
21
tests/testcommon/200-200.svg
Normal file
21
tests/testcommon/200-200.svg
Normal file
@ -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>
|
After Width: | Height: | Size: 522 B |
@ -37,6 +37,18 @@ stage {
|
|||||||
border-image: url('border-image.png') 16;
|
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 {
|
||||||
background-gradient-start: rgba(127, 255, 127, .6);
|
background-gradient-start: rgba(127, 255, 127, .6);
|
||||||
background-gradient-end: rgba(127, 127, 255, .6);
|
background-gradient-end: rgba(127, 127, 255, .6);
|
||||||
|
Loading…
Reference in New Issue
Block a user