1 /* gtkplotpixmap - pixmap plots widget for gtk+
2 * Copyright 1999-2001 Adrian E. Feiguin <feiguin@ifir.edu.ar>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <math.h>
24 #include <gtk/gtk.h>
25 #include "gtkplot.h"
26 #include "gtkplot3d.h"
27 #include "gtkplotdata.h"
28 #include "gtkplotpixmap.h"
29 #include "gtkplotpc.h"
30 #include "gtkplotps.h"
31 #include "gtkpsfont.h"
32
33 #define P_(string) string
34
35 enum {
36 ARG_0,
37 ARG_PIXMAP,
38 ARG_MASK,
39 };
40
41 static void gtk_plot_pixmap_class_init (GtkPlotPixmapClass *klass);
42 static void gtk_plot_pixmap_init (GtkPlotPixmap *data);
43 static void gtk_plot_pixmap_destroy (GtkObject *object);
44 static void gtk_plot_pixmap_draw_symbol (GtkPlotData *data,
45 gdouble x,
46 gdouble y,
47 gdouble z,
48 gdouble a,
49 gdouble dx,
50 gdouble dy,
51 gdouble dz,
52 gdouble da);
53 static void gtk_plot_pixmap_draw_legend (GtkPlotData *data,
54 gint x, gint y);
55 static void gtk_plot_pixmap_get_legend_size (GtkPlotData *data,
56 gint *width, gint *height);
57 static void gtk_plot_pixmap_clone (GtkPlotData *data,
58 GtkPlotData *copy);
59 static void gtk_plot_pixmap_get_property (GObject *object,
60 guint prop_id,
61 GValue *value,
62 GParamSpec *pspec);
63 static void gtk_plot_pixmap_set_property (GObject *object,
64 guint prop_id,
65 const GValue *value,
66 GParamSpec *pspec);
67
68
69
70 extern gint roundint (gdouble x);
71
72 static GtkPlotDataClass *parent_class = NULL;
73
74 GtkType
gtk_plot_pixmap_get_type(void)75 gtk_plot_pixmap_get_type (void)
76 {
77 static GtkType data_type = 0;
78
79 if (!data_type)
80 {
81 GtkTypeInfo data_info =
82 {
83 "GtkPlotPixmap",
84 sizeof (GtkPlotPixmap),
85 sizeof (GtkPlotPixmapClass),
86 (GtkClassInitFunc) gtk_plot_pixmap_class_init,
87 (GtkObjectInitFunc) gtk_plot_pixmap_init,
88 /* reserved 1*/ NULL,
89 /* reserved 2 */ NULL,
90 (GtkClassInitFunc) NULL,
91 };
92
93 data_type = gtk_type_unique (gtk_plot_data_get_type(), &data_info);
94 }
95 return data_type;
96 }
97
98 static void
gtk_plot_pixmap_class_init(GtkPlotPixmapClass * klass)99 gtk_plot_pixmap_class_init (GtkPlotPixmapClass *klass)
100 {
101 GtkObjectClass *object_class;
102 GtkWidgetClass *widget_class;
103 GtkPlotDataClass *data_class;
104 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
105
106 parent_class = gtk_type_class (gtk_plot_data_get_type ());
107
108 object_class = (GtkObjectClass *) klass;
109 widget_class = (GtkWidgetClass *) klass;
110 data_class = (GtkPlotDataClass *) klass;
111
112 data_class->clone = gtk_plot_pixmap_clone;
113 data_class->draw_legend = gtk_plot_pixmap_draw_legend;
114 data_class->get_legend_size = gtk_plot_pixmap_get_legend_size;
115 data_class->draw_symbol = gtk_plot_pixmap_draw_symbol;
116
117 object_class->destroy = gtk_plot_pixmap_destroy;
118
119 gobject_class->get_property = gtk_plot_pixmap_get_property;
120 gobject_class->set_property = gtk_plot_pixmap_set_property;
121
122 g_object_class_install_property (gobject_class,
123 ARG_PIXMAP,
124 g_param_spec_pointer ("pixmap",
125 P_("Pixmap"),
126 P_("Pixmap"),
127 G_PARAM_READABLE|G_PARAM_WRITABLE));
128 g_object_class_install_property (gobject_class,
129 ARG_MASK,
130 g_param_spec_pointer ("mask_bitmap",
131 P_("Mask"),
132 P_("Mask"),
133 G_PARAM_READABLE|G_PARAM_WRITABLE));
134
135 }
136
137 static void
gtk_plot_pixmap_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)138 gtk_plot_pixmap_get_property (GObject *object,
139 guint prop_id,
140 GValue *value,
141 GParamSpec *pspec)
142 {
143 GtkPlotPixmap *pixmap = GTK_PLOT_PIXMAP (object);
144
145 switch(prop_id){
146 case ARG_PIXMAP:
147 g_value_set_pointer(value, pixmap->pixmap);
148 break;
149 case ARG_MASK:
150 g_value_set_pointer(value, pixmap->mask);
151 break;
152 }
153 }
154
155 static void
gtk_plot_pixmap_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)156 gtk_plot_pixmap_set_property (GObject *object,
157 guint prop_id,
158 const GValue *value,
159 GParamSpec *pspec)
160 {
161 GtkPlotPixmap *pixmap = GTK_PLOT_PIXMAP (object);
162
163 switch(prop_id){
164 case ARG_PIXMAP:
165 if(pixmap->pixmap) gdk_pixmap_unref(pixmap->pixmap);
166 pixmap->pixmap = (GdkPixmap *)g_value_get_pointer(value);
167 if(pixmap->pixmap) gdk_pixmap_ref(pixmap->pixmap);
168 break;
169 case ARG_MASK:
170 if(pixmap->mask) gdk_bitmap_unref(pixmap->mask);
171 pixmap->mask = (GdkBitmap *)g_value_get_pointer(value);
172 if(pixmap->mask) gdk_bitmap_ref(pixmap->mask);
173 break;
174 }
175 }
176
177 static void
gtk_plot_pixmap_init(GtkPlotPixmap * dataset)178 gtk_plot_pixmap_init (GtkPlotPixmap *dataset)
179 {
180 dataset->pixmap = NULL;
181 }
182
183 GtkWidget*
gtk_plot_pixmap_new(GdkPixmap * pixmap,GdkBitmap * mask)184 gtk_plot_pixmap_new (GdkPixmap *pixmap, GdkBitmap *mask)
185 {
186 GtkWidget *widget;
187
188 widget = gtk_type_new (gtk_plot_pixmap_get_type ());
189
190 gtk_plot_pixmap_construct(GTK_PLOT_PIXMAP(widget), pixmap, mask);
191
192 return (widget);
193 }
194
195 void
gtk_plot_pixmap_construct(GtkPlotPixmap * data,GdkPixmap * pixmap,GdkBitmap * mask)196 gtk_plot_pixmap_construct(GtkPlotPixmap *data, GdkPixmap *pixmap, GdkBitmap *mask)
197 {
198 data->pixmap = pixmap;
199 data->mask = mask;
200
201 if(pixmap)
202 gdk_pixmap_ref(pixmap);
203 if(mask)
204 gdk_bitmap_ref(mask);
205 }
206
207 static void
gtk_plot_pixmap_destroy(GtkObject * object)208 gtk_plot_pixmap_destroy(GtkObject *object)
209 {
210 GtkPlotPixmap *pixmap = GTK_PLOT_PIXMAP(object);
211
212 if(pixmap->pixmap) gdk_pixmap_unref(pixmap->pixmap);
213 if(pixmap->mask) gdk_bitmap_unref(pixmap->mask);
214 pixmap->pixmap = NULL;
215 pixmap->mask = NULL;
216 }
217
218 static void
gtk_plot_pixmap_clone(GtkPlotData * data,GtkPlotData * copy)219 gtk_plot_pixmap_clone(GtkPlotData *data, GtkPlotData *copy)
220 {
221 GTK_PLOT_DATA_CLASS(parent_class)->clone(data, copy);
222
223 GTK_PLOT_PIXMAP(copy)->pixmap = GTK_PLOT_PIXMAP(data)->pixmap;
224 gdk_pixmap_ref(GTK_PLOT_PIXMAP(data)->pixmap);
225 GTK_PLOT_PIXMAP(copy)->mask = GTK_PLOT_PIXMAP(data)->mask;
226 gdk_bitmap_ref(GTK_PLOT_PIXMAP(data)->mask);
227 }
228
229 static void
gtk_plot_pixmap_draw_symbol(GtkPlotData * data,gdouble x,gdouble y,gdouble z,gdouble a,gdouble dx,gdouble dy,gdouble dz,gdouble da)230 gtk_plot_pixmap_draw_symbol(GtkPlotData *data,
231 gdouble x, gdouble y, gdouble z, gdouble a,
232 gdouble dx, gdouble dy, gdouble dz, gdouble da)
233 {
234 GtkPlot *plot = NULL;
235 GtkPlotPixmap *image;
236 gdouble scale_x, scale_y;
237 gdouble px, py, pz;
238 gint width, height;
239
240 image = GTK_PLOT_PIXMAP(data);
241 if(!image->pixmap) return;
242
243 plot = data->plot;
244
245 scale_x = scale_y = data->plot->magnification;;
246
247 gdk_window_get_size(image->pixmap, &width, &height);
248
249 width = roundint(scale_x * width);
250 height = roundint(scale_y * height);
251
252 if(GTK_IS_PLOT3D(plot))
253 gtk_plot3d_get_pixel(GTK_PLOT3D(plot), x, y, z,
254 &px, &py, &pz);
255 else
256 gtk_plot_get_pixel(plot, x, y, &px, &py);
257
258 /*
259 gtk_plot_pc_clip_mask(data->plot->pc,
260 px - width / 2.,
261 py - height / 2.,
262 image->mask);
263 */
264 gtk_plot_pc_draw_pixmap(data->plot->pc,
265 image->pixmap,
266 image->mask,
267 0, 0,
268 px - width / 2., py - height / 2.,
269 width, height,
270 scale_x, scale_y);
271 /*
272 gtk_plot_pc_clip_mask(data->plot->pc,
273 px - width / 2.,
274 py - height / 2.,
275 NULL);
276 */
277 }
278
279 static void
gtk_plot_pixmap_draw_legend(GtkPlotData * data,gint x,gint y)280 gtk_plot_pixmap_draw_legend(GtkPlotData *data, gint x, gint y)
281 {
282 GtkPlotPixmap *pixmap;
283 GtkPlot *plot = NULL;
284 GtkPlotText legend;
285 GdkRectangle area;
286 gint lascent, ldescent, lheight, lwidth;
287 gdouble m;
288 gint width, height;
289
290 g_return_if_fail(data->plot != NULL);
291 g_return_if_fail(GTK_IS_PLOT(data->plot));
292
293 pixmap = GTK_PLOT_PIXMAP(data);
294
295 plot = data->plot;
296 area.x = GTK_WIDGET(plot)->allocation.x;
297 area.y = GTK_WIDGET(plot)->allocation.y;
298 area.width = GTK_WIDGET(plot)->allocation.width;
299 area.height = GTK_WIDGET(plot)->allocation.height;
300
301 m = plot->magnification;
302 legend = plot->legends_attr;
303
304 gdk_window_get_size(pixmap->pixmap, &width, &height);
305 width = roundint(m * width);
306 height = roundint(m * height);
307
308 if(data->legend)
309 legend.text = data->legend;
310 else
311 legend.text = "";
312
313 legend.x = (gdouble)(area.x + x);
314 legend.y = (gdouble)(area.y + y);
315
316 /*
317 gtk_plot_pc_clip_mask(data->plot->pc,
318 legend.x,
319 legend.y,
320 pixmap->mask);
321 */
322 gtk_plot_pc_draw_pixmap(data->plot->pc,
323 pixmap->pixmap,
324 pixmap->mask,
325 0, 0,
326 legend.x, legend.y,
327 width, height,
328 m, m);
329 /*
330 gtk_plot_pc_clip_mask(data->plot->pc,
331 legend.x,
332 legend.y,
333 NULL);
334 */
335
336 gtk_plot_text_get_size(legend.text, legend.angle, legend.font,
337 roundint(legend.height * m),
338 &lwidth, &lheight,
339 &lascent, &ldescent);
340
341 legend.x = (gdouble)(area.x + x + width + roundint(4*m)) / (gdouble)area.width;
342 legend.y = (gdouble)(area.y + y + MAX(lheight, height) - lascent / 2) / (gdouble)area.height;
343
344 gtk_plot_draw_text(plot, legend);
345 }
346
347 static void
gtk_plot_pixmap_get_legend_size(GtkPlotData * data,gint * width,gint * height)348 gtk_plot_pixmap_get_legend_size(GtkPlotData *data, gint *width, gint *height)
349 {
350 GtkPlotPixmap *pixmap;
351 GtkPlot *plot = NULL;
352 GtkPlotText legend;
353 gint lascent, ldescent, lheight, lwidth;
354 gint pwidth, pheight;
355 gdouble m;
356
357 g_return_if_fail(data->plot != NULL);
358 g_return_if_fail(GTK_IS_PLOT(data->plot));
359
360 pixmap = GTK_PLOT_PIXMAP(data);
361
362 plot = data->plot;
363 m = plot->magnification;
364
365 legend = plot->legends_attr;
366
367 if(data->legend)
368 legend.text = data->legend;
369 else
370 legend.text = "";
371
372 gdk_window_get_size(pixmap->pixmap, &pwidth, &pheight);
373 pwidth = roundint(m * pwidth);
374 pheight = roundint(m * pheight);
375
376 gtk_plot_text_get_size(legend.text, legend.angle, legend.font,
377 roundint(legend.height * m),
378 &lwidth, &lheight,
379 &lascent, &ldescent);
380
381 *width = lwidth + pwidth + roundint(12 * m);
382 *height = MAX(lascent + ldescent, pheight);
383 }
384 /******************************************************
385 * Public methods
386 ******************************************************/
387
388 GdkPixmap *
gtk_plot_pixmap_get_pixmap(GtkPlotPixmap * pixmap)389 gtk_plot_pixmap_get_pixmap (GtkPlotPixmap *pixmap)
390 {
391 return(pixmap->pixmap);
392 }
393
394 GdkBitmap *
gtk_plot_pixmap_get_mask(GtkPlotPixmap * pixmap)395 gtk_plot_pixmap_get_mask (GtkPlotPixmap *pixmap)
396 {
397 return(pixmap->mask);
398 }
399
400
401