Commit 1ac1bfb9 authored by Owen Taylor's avatar Owen Taylor
Browse files

Initial revision

parent 45cb0268
Sun Feb 6 21:34:30 2000 Owen Taylor <otaylor@redhat.com>
* Started ChangeLog for pixbuf engine, check sources
into CVS.
========== ChangeLog for pixmap engine ===================
1999-11-22 Martin Baulig <martin@home-of-linux.org>
* pixmap_theme_main.c (theme_duplicate_style): Really copy the
`src_data->img_list', not just the pointer that points to it.
Tue Oct 5 15:13:29 1999 Owen Taylor <otaylor@redhat.com>
* pixmap_theme_draw.c (apply_theme_image): Don't set
background pixmap on pixmaps.
1999-02-14 Raja R Harinath <harinath@cs.umn.edu>
* Theme/gtk/Makefile.am.in (Makefile.am): Handle the case when
files are deleted.
Thu Feb 11 21:16:53 1999 Owen Taylor <otaylor@redhat.com>
* pixmap_theme_main.c (theme_data_unref): Free the
theme data structure as well as the contents.
1999-02-03 Raja R Harinath <harinath@cs.umn.edu>
* Theme/gtk/Makefile.am.in: New file. Theme/gtk/Makefile.am is
generated from this file when new *.png files are added.
1999-01-23 Miguel de Icaza <miguel@nuclecu.unam.mx>
* pixmap_theme_main.c (theme_init): Turn on pixmap cache.
Mon Jan 18 13:37:23 1999 Owen Taylor <otaylor@redhat.com>
* Theme/gtk/gtkrc: Give buttons a gray background
color so they look a little less funny when initially
drawing.
Wed Jan 13 18:58:25 1999 Owen Taylor <otaylor@redhat.com>
* pixmap_theme_draw.c: Fixed pervasive mis-bracketing
that was causing drawing if the drawn region and
clipping region did NOT intersect, and a couple
of errors in computing source and destination
regions.
1998-11-09 Federico Mena Quintero <federico@nuclecu.unam.mx>
* pixmap_theme_draw.c: #include <math.h>
1998-11-07 Raja R Harinath <harinath@cs.umn.edu>
* Theme/gtk/Makefile.am (theme_DATA):
Update to new directory contents.
* configure.in: Remove.
Fri Nov 6 17:26:12 1998 Owen Taylor <otaylor@redhat.com>
* pixmap_theme_main.c: Removed some debugging
printf's.
* Theme/gtk/notebook1.c Theme/gtk/menubar.png: new
bigger pixmaps to reduce pixelation.
* Theme/gtk/gtkrc: Reorganized to use several styles
instead of one huge style. Change clist backgrounds
to be prettier.
Thu Nov 5 10:23:46 1998 Owen Taylor <otaylor@redhat.com>
* pixmap_theme_draw.c (draw_shadow_gap): Fixed hard-coded
gap_side of '0'.
Mon Nov 2 14:46:02 1998 Owen Taylor <otaylor@redhat.com>
* pixmap_theme_draw.c (apply_theme_image_shadow_gap): Removed
several hundred lines of duplicated code with a bit of
reoriganization.
Wed Oct 28 16:18:04 1998 Owen Taylor <otaylor@redhat.com>
* pixmap_theme_main.c (theme_symbols): Removed lots
and lots of white space.
The code in this directory is a GTK+ theme engine based on the earlier
pixmap theme engine.
The config files are meant to be compatible, but instead of rendering
using Imlib, it renders using GdkPixbuf. This makes the memory
management much more understandable, and also allows us to use
GdkPixbuf's high quality scaling.
Most of the code was reworked/rewritten in the process to make it more
understandable and maintainable.
There are lots of bugs here, a considersable number of bugs. But it's
cleaned up a great deal from the older pixmap engine. Please don't
make it uglier again.
Owen Taylor <otaylor@redhat.com>
6 February 2000
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
/* GTK+ Pixbuf Engine
* Copyright (C) 1998-2000 Red Hat Software
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Written by Owen Taylor <otaylor@redhat.com>, based on code by
* Carsten Haitzler <raster@rasterman.com>
*/
#include "pixmap_theme.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
GCache *pixbuf_cache = NULL;
static void
pixbuf_render (GdkPixbuf *src,
GdkWindow *window,
GdkBitmap *mask,
GdkRectangle *clip_rect,
gint src_x,
gint src_y,
gint src_width,
gint src_height,
gint dest_x,
gint dest_y,
gint dest_width,
gint dest_height)
{
GdkPixbuf *tmp_pixbuf;
GdkRectangle rect;
int x_offset, y_offset;
art_u32 bg_color = 0xffffff;
if (dest_width <= 0 || dest_height <= 0)
return;
rect.x = dest_x;
rect.y = dest_y;
rect.width = dest_width;
rect.height = dest_height;
/* FIXME: we need the full mask, not a partial mask; the following is, however,
* horribly expensive
*/
if (!mask && clip_rect && !gdk_rectangle_intersect (clip_rect, &rect, &rect))
return;
if (dest_width != src->art_pixbuf->width ||
dest_height != src->art_pixbuf->height)
{
ArtPixBuf *partial_src_art;
GdkPixbuf *partial_src_gdk;
if (src->art_pixbuf->n_channels == 3)
{
partial_src_art =
art_pixbuf_new_const_rgb (src->art_pixbuf->pixels + src_y * src->art_pixbuf->rowstride + src_x * src->art_pixbuf->n_channels,
src_width,
src_height,
src->art_pixbuf->rowstride);
}
else
{
partial_src_art =
art_pixbuf_new_const_rgba (src->art_pixbuf->pixels + src_y * src->art_pixbuf->rowstride + src_x * src->art_pixbuf->n_channels,
src_width,
src_height,
src->art_pixbuf->rowstride);
}
partial_src_gdk = gdk_pixbuf_new_from_art_pixbuf (partial_src_art);
tmp_pixbuf = gdk_pixbuf_new (ART_PIX_RGB, src->art_pixbuf->has_alpha, 8, rect.width, rect.height);
if (mask)
{
gdk_pixbuf_scale (partial_src_gdk, tmp_pixbuf, 0, 0, rect.width, rect.height,
dest_x - rect.x, dest_y - rect.y,
(double)dest_width / src_width, (double)dest_height / src_height,
ART_FILTER_BILINEAR);
}
else
{
gdk_pixbuf_composite_color (partial_src_gdk, tmp_pixbuf, 0, 0, rect.width, rect.height,
dest_x - rect.x, dest_y - rect.y,
(double)dest_width / src_width, (double)dest_height / src_height,
ART_FILTER_BILINEAR, 255, 0, 0, 16, bg_color, bg_color);
}
gdk_pixbuf_unref (partial_src_gdk);
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);
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_unref (tmp_pixbuf);
}
ThemePixbuf *
theme_pixbuf_new (void)
{
ThemePixbuf *result = g_new (ThemePixbuf, 1);
result->filename = NULL;
result->pixbuf = NULL;
result->stretch = TRUE;
result->border_left = 0;
result->border_right = 0;
result->border_bottom = 0;
result->border_top = 0;
return result;
}
void
theme_pixbuf_destroy (ThemePixbuf *theme_pb)
{
if (theme_pb->pixbuf)
g_cache_remove (pixbuf_cache, theme_pb->pixbuf);
}
void
theme_pixbuf_set_filename (ThemePixbuf *theme_pb,
const char *filename)
{
if (theme_pb->pixbuf)
{
g_cache_remove (pixbuf_cache, theme_pb->pixbuf);
theme_pb->pixbuf = NULL;
}
if (theme_pb->filename)
g_free (theme_pb->filename);
theme_pb->filename = g_strdup (filename);
}
void
theme_pixbuf_set_border (ThemePixbuf *theme_pb,
gint left,
gint right,
gint top,
gint bottom)
{
theme_pb->border_left = left;
theme_pb->border_right = right;
theme_pb->border_top = top;
theme_pb->border_bottom = bottom;
}
void
theme_pixbuf_set_stretch (ThemePixbuf *theme_pb,
gboolean stretch)
{
theme_pb->stretch = stretch;
}
GdkPixbuf *
pixbuf_cache_value_new (gchar *filename)
{
GdkPixbuf *result = gdk_pixbuf_new_from_file (filename);
if (!result)
g_warning("Pixbuf theme: Cannot load pixmap file %s\n", filename);
return result;
}
GdkPixbuf *
theme_pixbuf_get_pixbuf (ThemePixbuf *theme_pb)
{
if (!theme_pb->pixbuf)
{
if (!pixbuf_cache)
pixbuf_cache = g_cache_new ((GCacheNewFunc)pixbuf_cache_value_new,
(GCacheDestroyFunc)gdk_pixbuf_unref,
(GCacheDupFunc)g_strdup,
(GCacheDestroyFunc)g_free,
g_str_hash, g_direct_hash, g_str_equal);
theme_pb->pixbuf = g_cache_insert (pixbuf_cache, theme_pb->filename);
}
return theme_pb->pixbuf;
}
void
theme_pixbuf_render (ThemePixbuf *theme_pb,
GdkWindow *window,
GdkBitmap *mask,
GdkRectangle *clip_rect,
guint component_mask,
gboolean center,
gint x,
gint y,
gint width,
gint height)
{
GdkPixbuf *pixbuf = theme_pixbuf_get_pixbuf (theme_pb);
gint src_x[4], src_y[4], dest_x[4], dest_y[4];
if (!pixbuf)
return;
if (theme_pb->stretch)
{
src_x[0] = 0;
src_x[1] = theme_pb->border_left;
src_x[2] = pixbuf->art_pixbuf->width - theme_pb->border_right;
src_x[3] = pixbuf->art_pixbuf->width;
src_y[0] = 0;
src_y[1] = theme_pb->border_top;
src_y[2] = pixbuf->art_pixbuf->height - theme_pb->border_bottom;
src_y[3] = pixbuf->art_pixbuf->height;
dest_x[0] = x;
dest_x[1] = x + theme_pb->border_left;
dest_x[2] = x + width - theme_pb->border_right;
dest_x[3] = x + width;
dest_y[0] = y;
dest_y[1] = y + theme_pb->border_top;
dest_y[2] = y + height - theme_pb->border_bottom;
dest_y[3] = y + height;
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], \
dest_x[X2] - dest_x[X1], dest_y[Y2] - dest_y[Y1]);
if (component_mask & COMPONENT_NORTH_WEST)
RENDER_COMPONENT (0, 1, 0, 1);
if (component_mask & COMPONENT_NORTH)
RENDER_COMPONENT (1, 2, 0, 1);
if (component_mask & COMPONENT_NORTH_EAST)
RENDER_COMPONENT (2, 3, 0, 1);
if (component_mask & COMPONENT_WEST)
RENDER_COMPONENT (0, 1, 1, 2);
if (component_mask & COMPONENT_CENTER)
RENDER_COMPONENT (1, 2, 1, 2);
if (component_mask & COMPONENT_EAST)
RENDER_COMPONENT (2, 3, 1, 2);
if (component_mask & COMPONENT_SOUTH_WEST)
RENDER_COMPONENT (0, 1, 2, 3);
if (component_mask & COMPONENT_SOUTH)
RENDER_COMPONENT (1, 2, 2, 3);
if (component_mask & COMPONENT_SOUTH_EAST)
RENDER_COMPONENT (2, 3, 2, 3);
}
else
{
if (center)
{
x += (width - pixbuf->art_pixbuf->width) / 2;
y += (height - pixbuf->art_pixbuf->height) / 2;
pixbuf_render (pixbuf, window, NULL, clip_rect,
0, 0,
pixbuf->art_pixbuf->width, pixbuf->art_pixbuf->height,
x, y,
pixbuf->art_pixbuf->width, pixbuf->art_pixbuf->height);
}
else
{
GdkPixmap *tmp_pixmap;
GdkGC *tmp_gc;
GdkGCValues gc_values;
tmp_pixmap = gdk_pixmap_new (window,
pixbuf->art_pixbuf->width,
pixbuf->art_pixbuf->height,
-1);
tmp_gc = gdk_gc_new (tmp_pixmap);
gdk_pixbuf_render_to_drawable (pixbuf, tmp_pixmap, tmp_gc,
0, 0,
0, 0,
pixbuf->art_pixbuf->width, pixbuf->art_pixbuf->height,
GDK_RGB_DITHER_NORMAL,
0, 0);
gdk_gc_unref (tmp_gc);
gc_values.fill = GDK_TILED;
gc_values.tile = tmp_pixmap;
tmp_gc = gdk_gc_new_with_values (window,
&gc_values, GDK_GC_FILL | GDK_GC_TILE);
if (clip_rect)
gdk_draw_rectangle (window, tmp_gc, TRUE,
clip_rect->x, clip_rect->y, clip_rect->width, clip_rect->height);
else
gdk_draw_rectangle (window, tmp_gc, TRUE, x, y, width, height);
gdk_gc_unref (tmp_gc);
gdk_pixmap_unref (tmp_pixmap);
}
}
}
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
/* internals */
typedef struct _ThemeData ThemeData;
typedef struct _ThemeImage ThemeImage;
typedef struct _ThemeMatchData ThemeMatchData;
typedef struct _ThemePixbuf ThemePixbuf;
enum
{
TOKEN_IMAGE = G_TOKEN_LAST + 1,
TOKEN_FUNCTION,
TOKEN_FILE,
TOKEN_STRETCH,
TOKEN_RECOLORABLE,
TOKEN_BORDER,
TOKEN_DETAIL,
TOKEN_STATE,
TOKEN_SHADOW,
TOKEN_GAP_SIDE,
TOKEN_GAP_FILE,
TOKEN_GAP_BORDER,
TOKEN_GAP_START_FILE,
TOKEN_GAP_START_BORDER,
TOKEN_GAP_END_FILE,
TOKEN_GAP_END_BORDER,
TOKEN_OVERLAY_FILE,
TOKEN_OVERLAY_BORDER,
TOKEN_OVERLAY_STRETCH,
TOKEN_ARROW_DIRECTION,
TOKEN_D_HLINE,
TOKEN_D_VLINE,
TOKEN_D_SHADOW,
TOKEN_D_POLYGON,
TOKEN_D_ARROW,
TOKEN_D_DIAMOND,
TOKEN_D_OVAL,
TOKEN_D_STRING,
TOKEN_D_BOX,
TOKEN_D_FLAT_BOX,
TOKEN_D_CHECK,
TOKEN_D_OPTION,
TOKEN_D_CROSS,
TOKEN_D_RAMP,
TOKEN_D_TAB,
TOKEN_D_SHADOW_GAP,
TOKEN_D_BOX_GAP,
TOKEN_D_EXTENSION,
TOKEN_D_FOCUS,
TOKEN_D_SLIDER,
TOKEN_D_ENTRY,
TOKEN_D_HANDLE,
TOKEN_TRUE,
TOKEN_FALSE,
TOKEN_TOP,
TOKEN_UP,
TOKEN_BOTTOM,
TOKEN_DOWN,
TOKEN_LEFT,
TOKEN_RIGHT,
TOKEN_NORMAL,
TOKEN_ACTIVE,
TOKEN_PRELIGHT,
TOKEN_SELECTED,
TOKEN_INSENSITIVE,
TOKEN_NONE,
TOKEN_IN,
TOKEN_OUT,
TOKEN_ETCHED_IN,
TOKEN_ETCHED_OUT,
TOKEN_ORIENTATION,
TOKEN_HORIZONTAL,
TOKEN_VERTICAL,
};
typedef enum
{
COMPONENT_NORTH_WEST = 1 << 0,
COMPONENT_NORTH = 1 << 1,
COMPONENT_NORTH_EAST = 1 << 2,
COMPONENT_WEST = 1 << 3,
COMPONENT_CENTER = 1 << 4,
COMPONENT_EAST = 1 << 5,
COMPONENT_SOUTH_EAST = 1 << 6,
COMPONENT_SOUTH = 1 << 7,
COMPONENT_SOUTH_WEST = 1 << 8,
COMPONENT_ALL = 1 << 9
} ThemePixbufComponent;
typedef enum {
THEME_MATCH_GAP_SIDE = 1 << 0,
THEME_MATCH_ORIENTATION = 1 << 1,
THEME_MATCH_STATE = 1 << 2,
THEME_MATCH_SHADOW = 1 << 3,
THEME_MATCH_ARROW_DIRECTION = 1 << 4
} ThemeMatchFlags;
struct _ThemeData
{
guint refcount;
GList *img_list;
};
struct _ThemePixbuf
{
gchar *filename;
GdkPixbuf *pixbuf;
gboolean stretch;
gint border_left;
gint border_right;
gint border_bottom;
gint border_top;
};
struct _ThemeMatchData
{
guint function; /* Mandatory */
gchar *detail;
ThemeMatchFlags flags;
GtkPositionType gap_side;
GtkOrientation orientation;
GtkStateType state;
GtkShadowType shadow;
GtkArrowType arrow_direction;
};
struct _ThemeImage
{
guint refcount;
ThemePixbuf *background;
ThemePixbuf *overlay;
ThemePixbuf *gap_start;
ThemePixbuf *gap;
ThemePixbuf *gap_end;
gchar recolorable;
ThemeMatchData match_data;
};
ThemePixbuf *theme_pixbuf_new (void);
void theme_pixbuf_destroy (ThemePixbuf *theme_pb);
void theme_pixbuf_set_filename (ThemePixbuf *theme_pb,
const char *filename);