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