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>
|
||||
|
||||
* src/xprops.c (meta_prop_get_values): changed __FUNCTION__
|
||||
|
@ -2246,6 +2246,9 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
GdkPixbuf *pixbuf;
|
||||
MetaColorSpec *colorize_spec = NULL;
|
||||
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,
|
||||
error,
|
||||
@ -2308,7 +2311,7 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
if (fill_type)
|
||||
{
|
||||
fill_type_val = meta_image_fill_type_from_string (fill_type);
|
||||
|
||||
|
||||
if (((int) fill_type_val) == -1)
|
||||
{
|
||||
set_error (error, context, G_MARKUP_ERROR,
|
||||
@ -2330,16 +2333,16 @@ parse_draw_op_element (GMarkupParseContext *context,
|
||||
}
|
||||
|
||||
if (colorize)
|
||||
{
|
||||
colorize_spec = meta_color_spec_new_from_string (colorize, error);
|
||||
|
||||
if (colorize_spec == NULL)
|
||||
{
|
||||
add_context_to_error (error, context);
|
||||
{
|
||||
colorize_spec = meta_color_spec_new_from_string (colorize, error);
|
||||
|
||||
if (colorize_spec == NULL)
|
||||
{
|
||||
add_context_to_error (error, context);
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
alpha_spec = NULL;
|
||||
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.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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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*
|
||||
scale_and_alpha_pixbuf (GdkPixbuf *src,
|
||||
MetaAlphaGradientSpec *alpha_spec,
|
||||
MetaImageFillType fill_type,
|
||||
int width,
|
||||
int height)
|
||||
int height,
|
||||
gboolean vertical_stripes,
|
||||
gboolean horizontal_stripes)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkPixbuf *temp_pixbuf;
|
||||
|
||||
pixbuf = NULL;
|
||||
|
||||
pixbuf = src;
|
||||
|
||||
if (gdk_pixbuf_get_width (pixbuf) == width &&
|
||||
gdk_pixbuf_get_height (pixbuf) == height)
|
||||
{
|
||||
@ -2823,16 +2912,61 @@ scale_and_alpha_pixbuf (GdkPixbuf *src,
|
||||
}
|
||||
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);
|
||||
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,
|
||||
op->data.image.alpha_spec,
|
||||
op->data.image.fill_type,
|
||||
width, height);
|
||||
width, height,
|
||||
op->data.image.vertical_stripes,
|
||||
op->data.image.horizontal_stripes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pixbuf = scale_and_alpha_pixbuf (op->data.image.pixbuf,
|
||||
op->data.image.alpha_spec,
|
||||
op->data.image.alpha_spec,
|
||||
op->data.image.fill_type,
|
||||
width, height);
|
||||
width, height,
|
||||
op->data.image.vertical_stripes,
|
||||
op->data.image.horizontal_stripes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2997,12 +3135,16 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
|
||||
pixbuf = scale_and_alpha_pixbuf (info->mini_icon,
|
||||
op->data.icon.alpha_spec,
|
||||
op->data.icon.fill_type,
|
||||
width, height);
|
||||
width, height,
|
||||
op->data.image.vertical_stripes,
|
||||
op->data.image.horizontal_stripes);
|
||||
else if (info->icon)
|
||||
pixbuf = scale_and_alpha_pixbuf (info->icon,
|
||||
op->data.icon.alpha_spec,
|
||||
op->data.icon.fill_type,
|
||||
width, height);
|
||||
width, height,
|
||||
op->data.image.vertical_stripes,
|
||||
op->data.image.horizontal_stripes);
|
||||
break;
|
||||
|
||||
case META_DRAW_TITLE:
|
||||
|
@ -325,6 +325,8 @@ struct _MetaDrawOp
|
||||
guint32 colorize_cache_pixel;
|
||||
GdkPixbuf *colorize_cache_pixbuf;
|
||||
MetaImageFillType fill_type;
|
||||
unsigned int vertical_stripes : 1;
|
||||
unsigned int horizontal_stripes : 1;
|
||||
} image;
|
||||
|
||||
struct {
|
||||
|
Loading…
Reference in New Issue
Block a user