1 /*
2 * Copyright (C) 2010, Magnus Hjorth
3 *
4 * This file is part of mhWaveEdit.
5 *
6 * mhWaveEdit is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * mhWaveEdit is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with mhWaveEdit; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21
22 #include <config.h>
23
24 #include "bitmap.h"
25 #include "main.h"
26
27 #include <string.h>
28
29 static GtkWidgetClass *parent_class;
30
bitmap_style_set(GtkWidget * widget,GtkStyle * previous_style)31 static void bitmap_style_set(GtkWidget *widget, GtkStyle *previous_style)
32 {
33 BITMAP(widget)->update_gc = TRUE;
34 if (parent_class->style_set != NULL)
35 parent_class->style_set(widget,previous_style);
36 }
37
bitmap_expose(GtkWidget * widget,GdkEventExpose * event)38 static gboolean bitmap_expose(GtkWidget *widget, GdkEventExpose *event)
39 {
40 Bitmap *b = BITMAP(widget);
41 GdkColor cb,cf,c;
42 gint af,ab;
43 gint allx,ally,allw,allh,ox,oy;
44 g_assert(b->bmp != NULL);
45 if (b->gc == NULL) {
46 b->gc = gdk_gc_new(widget->window);
47 b->update_gc = TRUE;
48 }
49 if (b->update_gc) {
50 if (b->color_mode == 0) {
51 gdk_gc_set_rgb_fg_color(b->gc, &b->clr);
52 } else {
53 cb = widget->style->bg[0];
54 cf = widget->style->fg[0];
55 af = b->alpha;
56 ab = 256-af;
57 c.pixel = 0;
58 c.red = (cf.red*af + cb.red*ab) >> 8;
59 c.green = (cf.green*af + cb.red*ab) >> 8;
60 c.blue = (cf.blue*af + cb.blue*ab) >> 8;
61 gdk_gc_set_rgb_fg_color(b->gc, &c);
62 }
63 gdk_gc_set_fill(b->gc, GDK_STIPPLED);
64 gdk_gc_set_stipple(b->gc, b->bmp);
65 b->update_gc = FALSE;
66 }
67 ox = allx = widget->allocation.x;
68 oy = ally = widget->allocation.y;
69 allw = widget->allocation.width;
70 allh = widget->allocation.height;
71 if (allw != b->bmpw)
72 ox += (allw-b->bmpw) / 2;
73 if (allh != b->bmph)
74 oy += (allh-b->bmph) / 2;
75
76 gdk_gc_set_ts_origin(b->gc, ox, oy);
77
78 gdk_draw_rectangle(widget->window, b->gc, TRUE, ox, oy, b->bmpw, b->bmph);
79
80 if (parent_class->expose_event != NULL)
81 return parent_class->expose_event(widget,event);
82 return FALSE;
83 }
84
bitmap_destroy(GtkObject * object)85 static void bitmap_destroy(GtkObject *object)
86 {
87 Bitmap *b = BITMAP(object);
88 if (b->gc != NULL) {
89 gdk_gc_unref(b->gc);
90 b->gc = NULL;
91 }
92 if (b->bmp != NULL) {
93 gdk_bitmap_unref(b->bmp);
94 b->bmp = NULL;
95 }
96 if (GTK_OBJECT_CLASS(parent_class)->destroy != NULL)
97 GTK_OBJECT_CLASS(parent_class)->destroy(object);
98 }
99
bitmap_class_init(GtkObjectClass * klass)100 static void bitmap_class_init(GtkObjectClass *klass)
101 {
102 GtkWidgetClass *wc = GTK_WIDGET_CLASS(klass);
103 GtkObjectClass *oc = GTK_OBJECT_CLASS(klass);
104 parent_class = gtk_type_class(gtk_widget_get_type());
105 wc->style_set = bitmap_style_set;
106 wc->expose_event = bitmap_expose;
107 oc->destroy = bitmap_destroy;
108 }
109
bitmap_init(GtkObject * obj)110 static void bitmap_init(GtkObject *obj)
111 {
112 Bitmap *b = BITMAP(obj);
113
114 gtk_widget_set_has_window(GTK_WIDGET(obj),FALSE);
115
116 b->gc = NULL;
117 b->bmp = NULL;
118 b->color_mode = 0;
119 memset(&(b->clr), 0, sizeof(b->clr));
120 b->alpha = 1.0;
121 }
122
bitmap_get_type(void)123 GtkType bitmap_get_type(void)
124 {
125 static GtkType id = 0;
126 if (!id) {
127 GtkTypeInfo info = {
128 "Bitmap",
129 sizeof(Bitmap),
130 sizeof(BitmapClass),
131 (GtkClassInitFunc)bitmap_class_init,
132 (GtkObjectInitFunc)bitmap_init
133 };
134 id = gtk_type_unique(gtk_widget_get_type(),&info);
135 }
136 return id;
137 }
138
bitmap_new_from_data(unsigned char * data,int width,int height)139 GtkWidget *bitmap_new_from_data(unsigned char *data, int width, int height)
140 {
141 Bitmap *b;
142 GtkWidget *w;
143 gpointer p;
144 p = gtk_type_new(bitmap_get_type());
145 w = p;
146 b = p;
147 b->bmp = gdk_bitmap_create_from_data(NULL,(const gchar *)data,width,height);
148 w->requisition.width = width;
149 w->requisition.height = height;
150 b->bmpw = width;
151 b->bmph = height;
152 return GTK_WIDGET(b);
153 }
154
bitmap_set_color(Bitmap * bmp,GdkColor * clr)155 void bitmap_set_color(Bitmap *bmp, GdkColor *clr)
156 {
157 memcpy(&bmp->clr, clr, sizeof(bmp->clr));
158 bmp->color_mode = 0;
159 gtk_widget_queue_draw(GTK_WIDGET(bmp));
160 }
161
bitmap_set_fg(Bitmap * bmp,gfloat alpha)162 void bitmap_set_fg(Bitmap *bmp, gfloat alpha)
163 {
164 bmp->alpha = (gint)(alpha * 256.0);
165 bmp->color_mode = 1;
166 gtk_widget_queue_draw(GTK_WIDGET(bmp));
167 }
168