mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-05 16:20:10 +00:00
Add an extrodinarily ugly example.
Sat Jan 19 00:32:14 2002 Owen Taylor <otaylor@redhat.com> * examples/*: Add an extrodinarily ugly example. * src/pixbuf-draw.c (draw_simple_image): Never shape the window, even if we are allowed to. Shaping is ugly -- if the widget isn't NO_WINDOW (most are), you'll just have to draw it rectangular. * src/pixbuf-render.c (pixbuf_render): Always use gdk_pixbuf_render_alpha() with FULL_ALPHA() as the type. * pixbuf.h src/pixbuf-render.c (theme_pixbuf_compute_hints): To speed up scaling, cache whether pixbufs have constant rows or constant columns. * src/pixbuf-render.c (pixbuf_render): Speed up scaling by using the hints from compute_hints().
This commit is contained in:
parent
3f100bb819
commit
c77a8b9183
@ -1,3 +1,28 @@
|
||||
Sat Jan 19 00:32:14 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* examples/*: Add an extrodinarily ugly example.
|
||||
|
||||
* src/pixbuf-draw.c (draw_simple_image): Never shape
|
||||
the window, even if we are allowed to. Shaping is
|
||||
ugly -- if the widget isn't NO_WINDOW (most are),
|
||||
you'll just have to draw it rectangular.
|
||||
|
||||
* src/pixbuf-render.c (pixbuf_render): Always use
|
||||
gdk_pixbuf_render_alpha() with FULL_ALPHA() as the
|
||||
type.
|
||||
|
||||
* pixbuf.h src/pixbuf-render.c (theme_pixbuf_compute_hints): To
|
||||
speed up scaling, cache whether pixbufs have constant rows
|
||||
or constant columns.
|
||||
|
||||
* src/pixbuf-render.c (pixbuf_render): Speed up scaling
|
||||
by using the hints from compute_hints().
|
||||
|
||||
Fri Jan 18 20:49:48 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* configure.in: Use pkg-config to get the binray version
|
||||
of GTK+ that we use for an install path.
|
||||
|
||||
Fri Jan 18 18:14:11 2002 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* src/pixbuf-draw.c (draw_focus): Fix for changes to draw_focus.
|
||||
|
14
modules/engines/pixbuf/examples/bubble/README
Normal file
14
modules/engines/pixbuf/examples/bubble/README
Normal file
@ -0,0 +1,14 @@
|
||||
gtk-2.0/triangle-background.png is copyright Owen Taylor, 1997
|
||||
and may be used without restriction as long as this attribution
|
||||
is reproduced.
|
||||
|
||||
images/bc.pnm images/bc-dark.pnm images/bc-light.png are
|
||||
from the BrushedMetalClean theme; I believe Tuomas Kuosmanen
|
||||
and Carsten Haitzler had something to do with the original
|
||||
BrushedMetal artwork.
|
||||
|
||||
This theme is truly hideous for a reason ... to demonstrate
|
||||
that alpha-compositing is going on.
|
||||
|
||||
Owen Taylor
|
||||
19 Jan 2002x
|
BIN
modules/engines/pixbuf/examples/bubble/gtk-2.0/bc-dark.png
Normal file
BIN
modules/engines/pixbuf/examples/bubble/gtk-2.0/bc-dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
BIN
modules/engines/pixbuf/examples/bubble/gtk-2.0/bc-light.png
Normal file
BIN
modules/engines/pixbuf/examples/bubble/gtk-2.0/bc-light.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
BIN
modules/engines/pixbuf/examples/bubble/gtk-2.0/bc.png
Normal file
BIN
modules/engines/pixbuf/examples/bubble/gtk-2.0/bc.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
BIN
modules/engines/pixbuf/examples/bubble/gtk-2.0/bubble-blue.png
Normal file
BIN
modules/engines/pixbuf/examples/bubble/gtk-2.0/bubble-blue.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 836 B |
BIN
modules/engines/pixbuf/examples/bubble/gtk-2.0/bubble-parts.xcf
Normal file
BIN
modules/engines/pixbuf/examples/bubble/gtk-2.0/bubble-parts.xcf
Normal file
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
@ -127,27 +127,11 @@ draw_simple_image(GtkStyle *style,
|
||||
{
|
||||
if (image->background)
|
||||
{
|
||||
GdkBitmap *mask = NULL;
|
||||
|
||||
if (image->background->stretch && setbg &&
|
||||
!GDK_IS_PIXMAP (window))
|
||||
{
|
||||
GdkPixbuf *pixbuf = theme_pixbuf_get_pixbuf (image->background);
|
||||
if (pixbuf && gdk_pixbuf_get_has_alpha (pixbuf))
|
||||
mask = gdk_pixmap_new (window, width, height, 1);
|
||||
}
|
||||
|
||||
theme_pixbuf_render (image->background,
|
||||
window, mask, area,
|
||||
window, NULL, area,
|
||||
draw_center ? COMPONENT_ALL : COMPONENT_ALL | COMPONENT_CENTER,
|
||||
FALSE,
|
||||
x, y, width, height);
|
||||
|
||||
if (mask)
|
||||
{
|
||||
gdk_window_shape_combine_mask (window, mask, 0, 0);
|
||||
gdk_pixmap_unref (mask);
|
||||
}
|
||||
}
|
||||
|
||||
if (image->overlay && draw_center)
|
||||
|
@ -20,17 +20,139 @@
|
||||
* Carsten Haitzler <raster@rasterman.com>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "pixbuf.h"
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
GCache *pixbuf_cache = NULL;
|
||||
|
||||
static GdkPixbuf *
|
||||
replicate_single (GdkPixbuf *src,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
guint n_channels = gdk_pixbuf_get_n_channels (src);
|
||||
guchar *pixels = (gdk_pixbuf_get_pixels (src) +
|
||||
src_y * gdk_pixbuf_get_rowstride (src) +
|
||||
src_x * n_channels);
|
||||
guchar r = *(pixels++);
|
||||
guchar g = *(pixels++);
|
||||
guchar b = *(pixels++);
|
||||
guint dest_rowstride;
|
||||
guchar *dest_pixels;
|
||||
guchar a = 0;
|
||||
GdkPixbuf *result;
|
||||
int i, j;
|
||||
|
||||
if (n_channels == 4)
|
||||
a = *(pixels++);
|
||||
|
||||
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++)
|
||||
{
|
||||
guchar *p = dest_pixels + dest_rowstride *i;
|
||||
|
||||
for (j = 0; j < width; j++)
|
||||
{
|
||||
*(p++) = r;
|
||||
*(p++) = g;
|
||||
*(p++) = b;
|
||||
|
||||
if (n_channels == 4)
|
||||
*(p++) = a;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
replicate_rows (GdkPixbuf *src,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
guint n_channels = gdk_pixbuf_get_n_channels (src);
|
||||
guint src_rowstride = gdk_pixbuf_get_rowstride (src);
|
||||
guchar *pixels = (gdk_pixbuf_get_pixels (src) + src_y * src_rowstride + src_x * n_channels);
|
||||
guchar *dest_pixels;
|
||||
GdkPixbuf *result;
|
||||
guint 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,
|
||||
gint src_x,
|
||||
gint src_y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
guint n_channels = gdk_pixbuf_get_n_channels (src);
|
||||
guint src_rowstride = gdk_pixbuf_get_rowstride (src);
|
||||
guchar *pixels = (gdk_pixbuf_get_pixels (src) + src_y * src_rowstride + src_x * n_channels);
|
||||
guchar *dest_pixels;
|
||||
GdkPixbuf *result;
|
||||
guint 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++)
|
||||
{
|
||||
guchar *p = dest_pixels + dest_rowstride * i;
|
||||
guchar *q = pixels + src_rowstride * i;
|
||||
|
||||
guchar r = *(q++);
|
||||
guchar g = *(q++);
|
||||
guchar b = *(q++);
|
||||
guchar a = 0;
|
||||
|
||||
if (n_channels == 4)
|
||||
a = *(q++);
|
||||
|
||||
for (j = 0; j < width; j++)
|
||||
{
|
||||
*(p++) = r;
|
||||
*(p++) = g;
|
||||
*(p++) = b;
|
||||
|
||||
if (n_channels == 4)
|
||||
*(p++) = a;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Scale the rectangle (src_x, src_y, src_width, src_height)
|
||||
* onto the rectangle (dest_x, dest_y, dest_width, dest_height)
|
||||
* of the destination, clip by clip_rect and render
|
||||
*/
|
||||
static void
|
||||
pixbuf_render (GdkPixbuf *src,
|
||||
guint hints,
|
||||
GdkWindow *window,
|
||||
GdkBitmap *mask,
|
||||
GdkRectangle *clip_rect,
|
||||
@ -65,18 +187,39 @@ pixbuf_render (GdkPixbuf *src,
|
||||
*/
|
||||
if (!mask && clip_rect)
|
||||
{
|
||||
/* The temporary is necessary only for GDK+-1.2, and not
|
||||
* for later versions of GDK, where you can have the
|
||||
* same source and dest for gdk_rectangle_intersect().
|
||||
*/
|
||||
GdkRectangle tmp_rect = rect;
|
||||
|
||||
if (!gdk_rectangle_intersect (clip_rect, &tmp_rect, &rect))
|
||||
if (!gdk_rectangle_intersect (clip_rect, &rect, &rect))
|
||||
return;
|
||||
}
|
||||
|
||||
if (dest_width != src_width ||
|
||||
dest_height != src_height)
|
||||
|
||||
if (dest_width == src_width && dest_height == src_height)
|
||||
{
|
||||
tmp_pixbuf = g_object_ref (src);
|
||||
|
||||
x_offset = src_x + rect.x - dest_x;
|
||||
y_offset = src_y + rect.y - dest_y;
|
||||
}
|
||||
else if ((hints & THEME_CONSTANT_COLS) && (hints & THEME_CONSTANT_ROWS))
|
||||
{
|
||||
tmp_pixbuf = replicate_single (src, src_x, src_y, dest_width, dest_height);
|
||||
|
||||
x_offset = rect.x - dest_x;
|
||||
y_offset = rect.y - dest_y;
|
||||
}
|
||||
else if (dest_width == src_width && (hints & THEME_CONSTANT_COLS))
|
||||
{
|
||||
tmp_pixbuf = replicate_rows (src, src_x, src_y, dest_width, dest_height);
|
||||
|
||||
x_offset = rect.x - dest_x;
|
||||
y_offset = rect.y - dest_y;
|
||||
}
|
||||
else if (dest_height == src_height && (hints & THEME_CONSTANT_ROWS))
|
||||
{
|
||||
tmp_pixbuf = replicate_cols (src, src_x, src_y, dest_width, dest_height);
|
||||
|
||||
x_offset = rect.x - dest_x;
|
||||
y_offset = rect.y - dest_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
double x_scale = (double)dest_width / src_width;
|
||||
double y_scale = (double)dest_height / src_height;
|
||||
@ -108,52 +251,30 @@ pixbuf_render (GdkPixbuf *src,
|
||||
x_offset = 0;
|
||||
y_offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_pixbuf = src;
|
||||
gdk_pixbuf_ref (tmp_pixbuf);
|
||||
|
||||
x_offset = src_x + rect.x - dest_x;
|
||||
y_offset = src_y + rect.y - dest_y;
|
||||
}
|
||||
|
||||
if (mask)
|
||||
{
|
||||
GdkGC *tmp_gc;
|
||||
|
||||
gdk_pixbuf_render_threshold_alpha (tmp_pixbuf, mask,
|
||||
x_offset, y_offset,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
128);
|
||||
|
||||
tmp_gc = gdk_gc_new (window);
|
||||
if (clip_rect)
|
||||
gdk_gc_set_clip_rectangle (tmp_gc, clip_rect);
|
||||
|
||||
gdk_pixbuf_render_to_drawable (tmp_pixbuf, window, tmp_gc,
|
||||
x_offset, y_offset,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
gdk_gc_unref (tmp_gc);
|
||||
}
|
||||
else
|
||||
gdk_pixbuf_render_to_drawable_alpha (tmp_pixbuf, window,
|
||||
x_offset, y_offset,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
GDK_PIXBUF_ALPHA_BILEVEL, 128,
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
|
||||
gdk_pixbuf_render_to_drawable_alpha (tmp_pixbuf, window,
|
||||
x_offset, y_offset,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
GDK_PIXBUF_ALPHA_FULL, 128,
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
gdk_pixbuf_unref (tmp_pixbuf);
|
||||
}
|
||||
|
||||
ThemePixbuf *
|
||||
theme_pixbuf_new (void)
|
||||
{
|
||||
ThemePixbuf *result = g_new (ThemePixbuf, 1);
|
||||
ThemePixbuf *result = g_new0 (ThemePixbuf, 1);
|
||||
result->filename = NULL;
|
||||
result->pixbuf = NULL;
|
||||
|
||||
@ -189,6 +310,116 @@ theme_pixbuf_set_filename (ThemePixbuf *theme_pb,
|
||||
theme_pb->filename = g_strdup (filename);
|
||||
}
|
||||
|
||||
static guint
|
||||
compute_hint (GdkPixbuf *pixbuf,
|
||||
gint x0,
|
||||
gint x1,
|
||||
gint y0,
|
||||
gint y1)
|
||||
{
|
||||
int i, j;
|
||||
int hints = THEME_CONSTANT_ROWS | THEME_CONSTANT_COLS;
|
||||
int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
|
||||
|
||||
guchar *data = gdk_pixbuf_get_pixels (pixbuf);
|
||||
int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
|
||||
if (x0 == x1 || y0 == y1)
|
||||
return 0;
|
||||
|
||||
for (i = y0; i < y1; i++)
|
||||
{
|
||||
guchar *p = data + i * rowstride + x0 * n_channels;
|
||||
guchar r = *(p++);
|
||||
guchar g = *(p++);
|
||||
guchar b = *(p++);
|
||||
guchar a = 0;
|
||||
|
||||
if (n_channels == 4)
|
||||
a = *(p++);
|
||||
|
||||
for (j = x0 + 1; j < x1 ; j++)
|
||||
{
|
||||
if (r != *(p++) ||
|
||||
g != *(p++) ||
|
||||
b != *(p++) ||
|
||||
(n_channels == 4 && a != *(p++)))
|
||||
{
|
||||
hints &= ~THEME_CONSTANT_ROWS;
|
||||
goto cols;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cols:
|
||||
for (i = y0 + 1; i < y1; i++)
|
||||
{
|
||||
guchar *base = data + y0 * rowstride + x0 * n_channels;
|
||||
guchar *p = data + i * rowstride + x0 * n_channels;
|
||||
|
||||
if (memcmp (p, base, n_channels * (x1 - x0)) != 0)
|
||||
{
|
||||
hints &= ~THEME_CONSTANT_COLS;
|
||||
return hints;
|
||||
}
|
||||
}
|
||||
|
||||
return hints;
|
||||
}
|
||||
|
||||
static void
|
||||
theme_pixbuf_compute_hints (ThemePixbuf *theme_pb)
|
||||
{
|
||||
int i, j;
|
||||
gint width = gdk_pixbuf_get_width (theme_pb->pixbuf);
|
||||
gint height = gdk_pixbuf_get_height (theme_pb->pixbuf);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
gint y0, y1;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
y0 = 0;
|
||||
y1 = theme_pb->border_top;
|
||||
break;
|
||||
case 1:
|
||||
y0 = theme_pb->border_top;
|
||||
y1 = height - theme_pb->border_bottom;
|
||||
break;
|
||||
default:
|
||||
y0 = height - theme_pb->border_bottom;
|
||||
y1 = height;
|
||||
break;
|
||||
}
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
gint x0, x1;
|
||||
|
||||
switch (j)
|
||||
{
|
||||
case 0:
|
||||
x0 = 0;
|
||||
x1 = theme_pb->border_left;
|
||||
break;
|
||||
case 1:
|
||||
x0 = theme_pb->border_left;
|
||||
x1 = width - theme_pb->border_right;
|
||||
break;
|
||||
default:
|
||||
x0 = width - theme_pb->border_right;
|
||||
x1 = width;
|
||||
break;
|
||||
}
|
||||
|
||||
theme_pb->hints[i][j] = compute_hint (theme_pb->pixbuf, x0, x1, y0, y1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
theme_pixbuf_set_border (ThemePixbuf *theme_pb,
|
||||
gint left,
|
||||
@ -200,6 +431,9 @@ theme_pixbuf_set_border (ThemePixbuf *theme_pb,
|
||||
theme_pb->border_right = right;
|
||||
theme_pb->border_top = top;
|
||||
theme_pb->border_bottom = bottom;
|
||||
|
||||
if (theme_pb->pixbuf)
|
||||
theme_pixbuf_compute_hints (theme_pb);
|
||||
}
|
||||
|
||||
void
|
||||
@ -207,6 +441,9 @@ theme_pixbuf_set_stretch (ThemePixbuf *theme_pb,
|
||||
gboolean stretch)
|
||||
{
|
||||
theme_pb->stretch = stretch;
|
||||
|
||||
if (theme_pb->pixbuf)
|
||||
theme_pixbuf_compute_hints (theme_pb);
|
||||
}
|
||||
|
||||
GdkPixbuf *
|
||||
@ -238,6 +475,9 @@ theme_pixbuf_get_pixbuf (ThemePixbuf *theme_pb)
|
||||
g_str_hash, g_direct_hash, g_str_equal);
|
||||
|
||||
theme_pb->pixbuf = g_cache_insert (pixbuf_cache, theme_pb->filename);
|
||||
|
||||
if (theme_pb->stretch)
|
||||
theme_pixbuf_compute_hints (theme_pb);
|
||||
}
|
||||
|
||||
return theme_pb->pixbuf;
|
||||
@ -288,11 +528,11 @@ theme_pixbuf_render (ThemePixbuf *theme_pb,
|
||||
if (component_mask & COMPONENT_ALL)
|
||||
component_mask = (COMPONENT_ALL - 1) & ~component_mask;
|
||||
|
||||
#define RENDER_COMPONENT(X1,X2,Y1,Y2) \
|
||||
pixbuf_render (pixbuf, window, mask, clip_rect, \
|
||||
src_x[X1], src_y[Y1], \
|
||||
src_x[X2] - src_x[X1], src_y[Y2] - src_y[Y1], \
|
||||
dest_x[X1], dest_y[Y1], \
|
||||
#define RENDER_COMPONENT(X1,X2,Y1,Y2) \
|
||||
pixbuf_render (pixbuf, theme_pb->hints[Y1][X1], window, mask, clip_rect, \
|
||||
src_x[X1], src_y[Y1], \
|
||||
src_x[X2] - src_x[X1], src_y[Y2] - src_y[Y1], \
|
||||
dest_x[X1], dest_y[Y1], \
|
||||
dest_x[X2] - dest_x[X1], dest_y[Y2] - dest_y[Y1]);
|
||||
|
||||
if (component_mask & COMPONENT_NORTH_WEST)
|
||||
@ -329,7 +569,7 @@ theme_pixbuf_render (ThemePixbuf *theme_pb,
|
||||
x += (width - pixbuf_width) / 2;
|
||||
y += (height - pixbuf_height) / 2;
|
||||
|
||||
pixbuf_render (pixbuf, window, NULL, clip_rect,
|
||||
pixbuf_render (pixbuf, 0, window, NULL, clip_rect,
|
||||
0, 0,
|
||||
pixbuf_width, pixbuf_height,
|
||||
x, y,
|
||||
|
@ -119,6 +119,11 @@ typedef enum {
|
||||
THEME_MATCH_ARROW_DIRECTION = 1 << 4
|
||||
} ThemeMatchFlags;
|
||||
|
||||
typedef enum {
|
||||
THEME_CONSTANT_ROWS = 1 << 0,
|
||||
THEME_CONSTANT_COLS = 1 << 1
|
||||
} ThemeRenderHints;
|
||||
|
||||
struct _ThemePixbuf
|
||||
{
|
||||
gchar *filename;
|
||||
@ -128,6 +133,7 @@ struct _ThemePixbuf
|
||||
gint border_right;
|
||||
gint border_bottom;
|
||||
gint border_top;
|
||||
guint hints[3][3];
|
||||
};
|
||||
|
||||
struct _ThemeMatchData
|
||||
|
Loading…
Reference in New Issue
Block a user