mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 09:30:45 -05:00
Patch from Brian Cameron to implement the vertical/horizontal striped
2002-11-04 Havoc Pennington <hp@pobox.com> Patch from Brian Cameron to implement the vertical/horizontal striped image accelerated scaling from the gtk pixbuf engine. * src/theme.c (scale_and_alpha_pixbuf): if an image is vertical/horizontal stripes, use special extra-fast scaling routines. * src/theme-parser.c (parse_draw_op_element): when loading an image, mark it as vertically/horizontally striped when appropriate
This commit is contained in:
parent
373f6de13e
commit
5efd276a22
12
ChangeLog
12
ChangeLog
@ -1,3 +1,15 @@
|
|||||||
|
2002-11-04 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
|
Patch from Brian Cameron to implement the vertical/horizontal
|
||||||
|
striped image accelerated scaling from the gtk pixbuf engine.
|
||||||
|
|
||||||
|
* src/theme.c (scale_and_alpha_pixbuf): if an image is
|
||||||
|
vertical/horizontal stripes, use special extra-fast scaling
|
||||||
|
routines.
|
||||||
|
|
||||||
|
* src/theme-parser.c (parse_draw_op_element): when loading an
|
||||||
|
image, mark it as vertically/horizontally striped when appropriate
|
||||||
|
|
||||||
2002-11-04 Erwann Chenede - <erwann.chenede@sun.com>
|
2002-11-04 Erwann Chenede - <erwann.chenede@sun.com>
|
||||||
|
|
||||||
* src/xprops.c (meta_prop_get_values): changed __FUNCTION__
|
* src/xprops.c (meta_prop_get_values): changed __FUNCTION__
|
||||||
|
@ -2246,6 +2246,9 @@ parse_draw_op_element (GMarkupParseContext *context,
|
|||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
MetaColorSpec *colorize_spec = NULL;
|
MetaColorSpec *colorize_spec = NULL;
|
||||||
MetaImageFillType fill_type_val;
|
MetaImageFillType fill_type_val;
|
||||||
|
int h, w, c;
|
||||||
|
int pixbuf_width, pixbuf_height, pixbuf_n_channels, pixbuf_rowstride;
|
||||||
|
guchar *pixbuf_pixels;
|
||||||
|
|
||||||
if (!locate_attributes (context, element_name, attribute_names, attribute_values,
|
if (!locate_attributes (context, element_name, attribute_names, attribute_values,
|
||||||
error,
|
error,
|
||||||
@ -2330,16 +2333,16 @@ parse_draw_op_element (GMarkupParseContext *context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (colorize)
|
if (colorize)
|
||||||
{
|
{
|
||||||
colorize_spec = meta_color_spec_new_from_string (colorize, error);
|
colorize_spec = meta_color_spec_new_from_string (colorize, error);
|
||||||
|
|
||||||
if (colorize_spec == NULL)
|
if (colorize_spec == NULL)
|
||||||
{
|
{
|
||||||
add_context_to_error (error, context);
|
add_context_to_error (error, context);
|
||||||
g_object_unref (G_OBJECT (pixbuf));
|
g_object_unref (G_OBJECT (pixbuf));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
alpha_spec = NULL;
|
alpha_spec = NULL;
|
||||||
if (alpha && !parse_alpha (alpha, &alpha_spec, context, error))
|
if (alpha && !parse_alpha (alpha, &alpha_spec, context, error))
|
||||||
@ -2359,6 +2362,67 @@ parse_draw_op_element (GMarkupParseContext *context,
|
|||||||
op->data.image.alpha_spec = alpha_spec;
|
op->data.image.alpha_spec = alpha_spec;
|
||||||
op->data.image.fill_type = fill_type_val;
|
op->data.image.fill_type = fill_type_val;
|
||||||
|
|
||||||
|
/* Check for vertical & horizontal stripes */
|
||||||
|
pixbuf_n_channels = gdk_pixbuf_get_n_channels(pixbuf);
|
||||||
|
pixbuf_width = gdk_pixbuf_get_width(pixbuf);
|
||||||
|
pixbuf_height = gdk_pixbuf_get_height(pixbuf);
|
||||||
|
pixbuf_rowstride = gdk_pixbuf_get_rowstride(pixbuf);
|
||||||
|
pixbuf_pixels = gdk_pixbuf_get_pixels(pixbuf);
|
||||||
|
|
||||||
|
/* Check for horizontal stripes */
|
||||||
|
for (h = 0; h < pixbuf_height; h++)
|
||||||
|
{
|
||||||
|
for (w = 1; w < pixbuf_width; w++)
|
||||||
|
{
|
||||||
|
for (c = 0; c < pixbuf_n_channels; c++)
|
||||||
|
{
|
||||||
|
if (pixbuf_pixels[(h * pixbuf_rowstride) + c] !=
|
||||||
|
pixbuf_pixels[(h * pixbuf_rowstride) + w + c])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c < pixbuf_n_channels)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (w < pixbuf_width)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h >= pixbuf_height)
|
||||||
|
{
|
||||||
|
op->data.image.horizontal_stripes = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
op->data.image.horizontal_stripes = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for vertical stripes */
|
||||||
|
for (w = 0; w < pixbuf_width; w++)
|
||||||
|
{
|
||||||
|
for (h = 1; h < pixbuf_height; h++)
|
||||||
|
{
|
||||||
|
for (c = 0; c < pixbuf_n_channels; c++)
|
||||||
|
{
|
||||||
|
if (pixbuf_pixels[w + c] !=
|
||||||
|
pixbuf_pixels[(h * pixbuf_rowstride) + w + c])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c < pixbuf_n_channels)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (h < pixbuf_height)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w >= pixbuf_width)
|
||||||
|
{
|
||||||
|
op->data.image.vertical_stripes = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
op->data.image.vertical_stripes = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
g_assert (info->op_list);
|
g_assert (info->op_list);
|
||||||
|
|
||||||
meta_draw_op_list_append (info->op_list, op);
|
meta_draw_op_list_append (info->op_list, op);
|
||||||
|
170
src/theme.c
170
src/theme.c
@ -2804,18 +2804,107 @@ pixbuf_tile (GdkPixbuf *tile,
|
|||||||
return pixbuf;
|
return pixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GdkPixbuf *
|
||||||
|
replicate_rows (GdkPixbuf *src,
|
||||||
|
int src_x,
|
||||||
|
int src_y,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
unsigned int n_channels = gdk_pixbuf_get_n_channels (src);
|
||||||
|
unsigned int src_rowstride = gdk_pixbuf_get_rowstride (src);
|
||||||
|
unsigned char *pixels = (gdk_pixbuf_get_pixels (src) + src_y * src_rowstride + src_x
|
||||||
|
* n_channels);
|
||||||
|
unsigned char *dest_pixels;
|
||||||
|
GdkPixbuf *result;
|
||||||
|
unsigned int dest_rowstride;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, n_channels == 4, 8,
|
||||||
|
width, height);
|
||||||
|
dest_rowstride = gdk_pixbuf_get_rowstride (result);
|
||||||
|
dest_pixels = gdk_pixbuf_get_pixels (result);
|
||||||
|
|
||||||
|
for (i = 0; i < height; i++)
|
||||||
|
memcpy (dest_pixels + dest_rowstride * i, pixels, n_channels * width);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GdkPixbuf *
|
||||||
|
replicate_cols (GdkPixbuf *src,
|
||||||
|
int src_x,
|
||||||
|
int src_y,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
unsigned int n_channels = gdk_pixbuf_get_n_channels (src);
|
||||||
|
unsigned int src_rowstride = gdk_pixbuf_get_rowstride (src);
|
||||||
|
unsigned char *pixels = (gdk_pixbuf_get_pixels (src) + src_y * src_rowstride + src_x
|
||||||
|
* n_channels);
|
||||||
|
unsigned char *dest_pixels;
|
||||||
|
GdkPixbuf *result;
|
||||||
|
unsigned int dest_rowstride;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, n_channels == 4, 8,
|
||||||
|
width, height);
|
||||||
|
dest_rowstride = gdk_pixbuf_get_rowstride (result);
|
||||||
|
dest_pixels = gdk_pixbuf_get_pixels (result);
|
||||||
|
|
||||||
|
for (i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
unsigned char *p = dest_pixels + dest_rowstride * i;
|
||||||
|
unsigned char *q = pixels + src_rowstride * i;
|
||||||
|
|
||||||
|
unsigned char r = *(q++);
|
||||||
|
unsigned char g = *(q++);
|
||||||
|
unsigned char b = *(q++);
|
||||||
|
|
||||||
|
if (n_channels == 4)
|
||||||
|
{
|
||||||
|
unsigned char a;
|
||||||
|
|
||||||
|
a = *(q++);
|
||||||
|
|
||||||
|
for (j = 0; j < width; j++)
|
||||||
|
{
|
||||||
|
*(p++) = r;
|
||||||
|
*(p++) = g;
|
||||||
|
*(p++) = b;
|
||||||
|
*(p++) = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (j = 0; j < width; j++)
|
||||||
|
{
|
||||||
|
*(p++) = r;
|
||||||
|
*(p++) = g;
|
||||||
|
*(p++) = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static GdkPixbuf*
|
static GdkPixbuf*
|
||||||
scale_and_alpha_pixbuf (GdkPixbuf *src,
|
scale_and_alpha_pixbuf (GdkPixbuf *src,
|
||||||
MetaAlphaGradientSpec *alpha_spec,
|
MetaAlphaGradientSpec *alpha_spec,
|
||||||
MetaImageFillType fill_type,
|
MetaImageFillType fill_type,
|
||||||
int width,
|
int width,
|
||||||
int height)
|
int height,
|
||||||
|
gboolean vertical_stripes,
|
||||||
|
gboolean horizontal_stripes)
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
|
GdkPixbuf *temp_pixbuf;
|
||||||
|
|
||||||
pixbuf = NULL;
|
pixbuf = NULL;
|
||||||
|
|
||||||
pixbuf = src;
|
pixbuf = src;
|
||||||
|
|
||||||
if (gdk_pixbuf_get_width (pixbuf) == width &&
|
if (gdk_pixbuf_get_width (pixbuf) == width &&
|
||||||
gdk_pixbuf_get_height (pixbuf) == height)
|
gdk_pixbuf_get_height (pixbuf) == height)
|
||||||
{
|
{
|
||||||
@ -2823,16 +2912,61 @@ scale_and_alpha_pixbuf (GdkPixbuf *src,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (fill_type)
|
if (fill_type == META_IMAGE_FILL_TILE)
|
||||||
{
|
{
|
||||||
case META_IMAGE_FILL_SCALE:
|
|
||||||
pixbuf = gdk_pixbuf_scale_simple (pixbuf,
|
|
||||||
width, height,
|
|
||||||
GDK_INTERP_BILINEAR);
|
|
||||||
break;
|
|
||||||
case META_IMAGE_FILL_TILE:
|
|
||||||
pixbuf = pixbuf_tile (pixbuf, width, height);
|
pixbuf = pixbuf_tile (pixbuf, width, height);
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int src_h, src_w, dest_h, dest_w, pixbuf_width, pixbuf_height;
|
||||||
|
src_h = gdk_pixbuf_get_height (src);
|
||||||
|
src_w = gdk_pixbuf_get_width (src);
|
||||||
|
|
||||||
|
if (vertical_stripes)
|
||||||
|
{
|
||||||
|
dest_w = width;
|
||||||
|
dest_h = gdk_pixbuf_get_height (src);
|
||||||
|
}
|
||||||
|
else if (horizontal_stripes)
|
||||||
|
{
|
||||||
|
dest_w = gdk_pixbuf_get_width (src);
|
||||||
|
dest_h = height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dest_w = width;
|
||||||
|
dest_h = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dest_w == src_w && dest_h == src_h)
|
||||||
|
{
|
||||||
|
temp_pixbuf = src;
|
||||||
|
g_object_ref (G_OBJECT (tmp_pixbuf));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp_pixbuf = gdk_pixbuf_scale_simple (src,
|
||||||
|
dest_w, dest_h,
|
||||||
|
GDK_INTERP_BILINEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prefer to replicate_cols if possible, as that
|
||||||
|
* is faster (no memory reads)
|
||||||
|
*/
|
||||||
|
if (horizontal_stripes)
|
||||||
|
{
|
||||||
|
pixbuf = replicate_cols (temp_pixbuf, 0, 0, width, height);
|
||||||
|
g_object_unref (G_OBJECT (temp_pixbuf));
|
||||||
|
}
|
||||||
|
else if (vertical_stripes)
|
||||||
|
{
|
||||||
|
pixbuf = replicate_rows (temp_pixbuf, 0, 0, width, height);
|
||||||
|
g_object_unref (G_OBJECT (temp_pixbuf));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pixbuf = temp_pixbuf;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2972,15 +3106,19 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
|
|||||||
pixbuf = scale_and_alpha_pixbuf (op->data.image.colorize_cache_pixbuf,
|
pixbuf = scale_and_alpha_pixbuf (op->data.image.colorize_cache_pixbuf,
|
||||||
op->data.image.alpha_spec,
|
op->data.image.alpha_spec,
|
||||||
op->data.image.fill_type,
|
op->data.image.fill_type,
|
||||||
width, height);
|
width, height,
|
||||||
|
op->data.image.vertical_stripes,
|
||||||
|
op->data.image.horizontal_stripes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pixbuf = scale_and_alpha_pixbuf (op->data.image.pixbuf,
|
pixbuf = scale_and_alpha_pixbuf (op->data.image.pixbuf,
|
||||||
op->data.image.alpha_spec,
|
op->data.image.alpha_spec,
|
||||||
op->data.image.fill_type,
|
op->data.image.fill_type,
|
||||||
width, height);
|
width, height,
|
||||||
|
op->data.image.vertical_stripes,
|
||||||
|
op->data.image.horizontal_stripes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2997,12 +3135,16 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
|
|||||||
pixbuf = scale_and_alpha_pixbuf (info->mini_icon,
|
pixbuf = scale_and_alpha_pixbuf (info->mini_icon,
|
||||||
op->data.icon.alpha_spec,
|
op->data.icon.alpha_spec,
|
||||||
op->data.icon.fill_type,
|
op->data.icon.fill_type,
|
||||||
width, height);
|
width, height,
|
||||||
|
op->data.image.vertical_stripes,
|
||||||
|
op->data.image.horizontal_stripes);
|
||||||
else if (info->icon)
|
else if (info->icon)
|
||||||
pixbuf = scale_and_alpha_pixbuf (info->icon,
|
pixbuf = scale_and_alpha_pixbuf (info->icon,
|
||||||
op->data.icon.alpha_spec,
|
op->data.icon.alpha_spec,
|
||||||
op->data.icon.fill_type,
|
op->data.icon.fill_type,
|
||||||
width, height);
|
width, height,
|
||||||
|
op->data.image.vertical_stripes,
|
||||||
|
op->data.image.horizontal_stripes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case META_DRAW_TITLE:
|
case META_DRAW_TITLE:
|
||||||
|
@ -325,6 +325,8 @@ struct _MetaDrawOp
|
|||||||
guint32 colorize_cache_pixel;
|
guint32 colorize_cache_pixel;
|
||||||
GdkPixbuf *colorize_cache_pixbuf;
|
GdkPixbuf *colorize_cache_pixbuf;
|
||||||
MetaImageFillType fill_type;
|
MetaImageFillType fill_type;
|
||||||
|
unsigned int vertical_stripes : 1;
|
||||||
|
unsigned int horizontal_stripes : 1;
|
||||||
} image;
|
} image;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user