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 /**
21 * SECTION: gtkplotpixmap
22 * @short_description: Pixmap plots widget.
23 *
24 * FIXME:: Need long description.
25 */
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <math.h>
31 #include <gtk/gtk.h>
32 #include "gtkplot.h"
33 #include "gtkplot3d.h"
34 #include "gtkplotdata.h"
35 #include "gtkplotpixmap.h"
36 #include "gtkplotpc.h"
37 #include "gtkplotps.h"
38 #include "gtkpsfont.h"
39
40 #define P_(string) string
41
42 enum {
43 ARG_0,
44 ARG_PIXMAP,
45 ARG_MASK,
46 };
47
48 static void gtk_plot_pixmap_class_init (GtkPlotPixmapClass *klass);
49 static void gtk_plot_pixmap_init (GtkPlotPixmap *data);
50 static void gtk_plot_pixmap_destroy (GtkObject *object);
51 static void gtk_plot_pixmap_draw_symbol (GtkPlotData *data,
52 gdouble x,
53 gdouble y,
54 gdouble z,
55 gdouble a,
56 gdouble dx,
57 gdouble dy,
58 gdouble dz,
59 gdouble da);
60 static void gtk_plot_pixmap_draw_legend (GtkPlotData *data,
61 gint x, gint y);
62 static void gtk_plot_pixmap_get_legend_size (GtkPlotData *data,
63 gint *width, gint *height);
64 static void gtk_plot_pixmap_clone (GtkPlotData *data,
65 GtkPlotData *copy);
66 static void gtk_plot_pixmap_get_property (GObject *object,
67 guint prop_id,
68 GValue *value,
69 GParamSpec *pspec);
70 static void gtk_plot_pixmap_set_property (GObject *object,
71 guint prop_id,
72 const GValue *value,
73 GParamSpec *pspec);
74
75
76
77 extern gint roundint (gdouble x);
78
79 static GtkPlotDataClass *parent_class = NULL;
80
81 GType
gtk_plot_pixmap_get_type(void)82 gtk_plot_pixmap_get_type (void)
83 {
84 static GType data_type = 0;
85
86 if (!data_type)
87 {
88 data_type = g_type_register_static_simple (
89 gtk_plot_data_get_type(),
90 "GtkPlotPixmap",
91 sizeof (GtkPlotPixmapClass),
92 (GClassInitFunc) gtk_plot_pixmap_class_init,
93 sizeof (GtkPlotPixmap),
94 (GInstanceInitFunc) gtk_plot_pixmap_init,
95 0);
96 }
97 return data_type;
98 }
99
100 static void
gtk_plot_pixmap_class_init(GtkPlotPixmapClass * klass)101 gtk_plot_pixmap_class_init (GtkPlotPixmapClass *klass)
102 {
103 GtkObjectClass *object_class;
104 GtkWidgetClass *widget_class;
105 GtkPlotDataClass *data_class;
106 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
107
108 parent_class = g_type_class_ref (gtk_plot_data_get_type ());
109
110 object_class = (GtkObjectClass *) klass;
111 widget_class = (GtkWidgetClass *) klass;
112 data_class = (GtkPlotDataClass *) klass;
113
114 data_class->clone = gtk_plot_pixmap_clone;
115 data_class->draw_legend = gtk_plot_pixmap_draw_legend;
116 data_class->get_legend_size = gtk_plot_pixmap_get_legend_size;
117 data_class->draw_symbol = gtk_plot_pixmap_draw_symbol;
118
119 object_class->destroy = gtk_plot_pixmap_destroy;
120
121 gobject_class->get_property = gtk_plot_pixmap_get_property;
122 gobject_class->set_property = gtk_plot_pixmap_set_property;
123
124 g_object_class_install_property (gobject_class,
125 ARG_PIXMAP,
126 g_param_spec_pointer ("pixmap",
127 P_("Pixmap"),
128 P_("Pixmap"),
129 G_PARAM_READABLE|G_PARAM_WRITABLE));
130 g_object_class_install_property (gobject_class,
131 ARG_MASK,
132 g_param_spec_pointer ("mask_bitmap",
133 P_("Mask"),
134 P_("Mask"),
135 G_PARAM_READABLE|G_PARAM_WRITABLE));
136
137 }
138
139 static void
gtk_plot_pixmap_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)140 gtk_plot_pixmap_get_property (GObject *object,
141 guint prop_id,
142 GValue *value,
143 GParamSpec *pspec)
144 {
145 GtkPlotPixmap *pixmap = GTK_PLOT_PIXMAP (object);
146
147 switch(prop_id){
148 case ARG_PIXMAP:
149 g_value_set_pointer(value, pixmap->pixmap);
150 break;
151 case ARG_MASK:
152 g_value_set_pointer(value, pixmap->mask);
153 break;
154 }
155 }
156
157 static void
gtk_plot_pixmap_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)158 gtk_plot_pixmap_set_property (GObject *object,
159 guint prop_id,
160 const GValue *value,
161 GParamSpec *pspec)
162 {
163 GtkPlotPixmap *pixmap = GTK_PLOT_PIXMAP (object);
164
165 switch(prop_id){
166 case ARG_PIXMAP:
167 if(pixmap->pixmap) gdk_pixmap_unref(pixmap->pixmap);
168 pixmap->pixmap = (GdkPixmap *)g_value_get_pointer(value);
169 if(pixmap->pixmap) gdk_pixmap_ref(pixmap->pixmap);
170 break;
171 case ARG_MASK:
172 if(pixmap->mask) gdk_bitmap_unref(pixmap->mask);
173 pixmap->mask = (GdkBitmap *)g_value_get_pointer(value);
174 if(pixmap->mask) gdk_bitmap_ref(pixmap->mask);
175 break;
176 }
177 }
178
179 static void
gtk_plot_pixmap_init(GtkPlotPixmap * dataset)180 gtk_plot_pixmap_init (GtkPlotPixmap *dataset)
181 {
182 dataset->pixmap = NULL;
183 }
184
185 /**
186 * gtk_plot_pixmap_new:
187 * @pixmap: a GdkPixmap.
188 * @mask:
189 *
190 * Return value: a new GtkWidget.
191 */
192 GtkWidget*
gtk_plot_pixmap_new(GdkPixmap * pixmap,GdkBitmap * mask)193 gtk_plot_pixmap_new (GdkPixmap *pixmap, GdkBitmap *mask)
194 {
195 GtkWidget *widget;
196
197 widget = gtk_widget_new (gtk_plot_pixmap_get_type (), NULL);
198
199 gtk_plot_pixmap_construct(GTK_PLOT_PIXMAP(widget), pixmap, mask);
200
201 return (widget);
202 }
203
204 /**
205 * gtk_plot_pixmap_construct:
206 * @data:
207 * @pixmap: a GdkPixmap
208 * @mask:
209 *
210 *
211 */
212 void
gtk_plot_pixmap_construct(GtkPlotPixmap * data,GdkPixmap * pixmap,GdkBitmap * mask)213 gtk_plot_pixmap_construct(GtkPlotPixmap *data, GdkPixmap *pixmap, GdkBitmap *mask)
214 {
215 data->pixmap = pixmap;
216 data->mask = mask;
217
218 if(pixmap)
219 gdk_pixmap_ref(pixmap);
220 if(mask)
221 gdk_bitmap_ref(mask);
222 }
223
224 static void
gtk_plot_pixmap_destroy(GtkObject * object)225 gtk_plot_pixmap_destroy(GtkObject *object)
226 {
227 GtkPlotPixmap *pixmap = GTK_PLOT_PIXMAP(object);
228
229 if(pixmap->pixmap) gdk_pixmap_unref(pixmap->pixmap);
230 if(pixmap->mask) gdk_bitmap_unref(pixmap->mask);
231 pixmap->pixmap = NULL;
232 pixmap->mask = NULL;
233 }
234
235 static void
gtk_plot_pixmap_clone(GtkPlotData * data,GtkPlotData * copy)236 gtk_plot_pixmap_clone(GtkPlotData *data, GtkPlotData *copy)
237 {
238 GTK_PLOT_DATA_CLASS(parent_class)->clone(data, copy);
239
240 GTK_PLOT_PIXMAP(copy)->pixmap = GTK_PLOT_PIXMAP(data)->pixmap;
241 gdk_pixmap_ref(GTK_PLOT_PIXMAP(data)->pixmap);
242 GTK_PLOT_PIXMAP(copy)->mask = GTK_PLOT_PIXMAP(data)->mask;
243 gdk_bitmap_ref(GTK_PLOT_PIXMAP(data)->mask);
244 }
245
246 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)247 gtk_plot_pixmap_draw_symbol(GtkPlotData *data,
248 gdouble x, gdouble y, gdouble z, gdouble a,
249 gdouble dx, gdouble dy, gdouble dz, gdouble da)
250 {
251 GtkPlot *plot = NULL;
252 GtkPlotPixmap *image;
253 gdouble scale_x, scale_y;
254 gdouble px, py, pz;
255 gint width, height;
256
257 image = GTK_PLOT_PIXMAP(data);
258 if(!image->pixmap) return;
259
260 plot = data->plot;
261
262 scale_x = scale_y = data->plot->magnification;;
263
264 gdk_window_get_size(image->pixmap, &width, &height);
265
266 width = roundint(scale_x * width);
267 height = roundint(scale_y * height);
268
269 if(GTK_IS_PLOT3D(plot))
270 gtk_plot3d_get_pixel(GTK_PLOT3D(plot), x, y, z,
271 &px, &py, &pz);
272 else
273 gtk_plot_get_pixel(plot, x, y, &px, &py);
274
275 /*
276 gtk_plot_pc_clip_mask(data->plot->pc,
277 px - width / 2.,
278 py - height / 2.,
279 image->mask);
280 */
281 gtk_plot_pc_draw_pixmap(data->plot->pc,
282 image->pixmap,
283 image->mask,
284 0, 0,
285 px - width / 2., py - height / 2.,
286 width, height,
287 scale_x, scale_y);
288 /*
289 gtk_plot_pc_clip_mask(data->plot->pc,
290 px - width / 2.,
291 py - height / 2.,
292 NULL);
293 */
294 }
295
296 static void
gtk_plot_pixmap_draw_legend(GtkPlotData * data,gint x,gint y)297 gtk_plot_pixmap_draw_legend(GtkPlotData *data, gint x, gint y)
298 {
299 GtkPlotPixmap *pixmap;
300 GtkPlot *plot = NULL;
301 GtkPlotText legend;
302 GdkRectangle area;
303 gint lascent, ldescent, lheight, lwidth;
304 gdouble m;
305 gint width, height;
306 GtkAllocation allocation;
307
308 g_return_if_fail(data->plot != NULL);
309 g_return_if_fail(GTK_IS_PLOT(data->plot));
310
311 pixmap = GTK_PLOT_PIXMAP(data);
312
313 plot = data->plot;
314 gtk_widget_get_allocation(GTK_WIDGET(plot), &allocation);
315 area.x = allocation.x;
316 area.y = allocation.y;
317 area.width = allocation.width;
318 area.height = allocation.height;
319
320 m = plot->magnification;
321 legend = plot->legends_attr;
322
323 gdk_window_get_size(pixmap->pixmap, &width, &height);
324 width = roundint(m * width);
325 height = roundint(m * height);
326
327 if(data->legend)
328 legend.text = data->legend;
329 else
330 legend.text = "";
331
332 legend.x = (gdouble)(area.x + x);
333 legend.y = (gdouble)(area.y + y);
334
335 /*
336 gtk_plot_pc_clip_mask(data->plot->pc,
337 legend.x,
338 legend.y,
339 pixmap->mask);
340 */
341 gtk_plot_pc_draw_pixmap(data->plot->pc,
342 pixmap->pixmap,
343 pixmap->mask,
344 0, 0,
345 legend.x, legend.y,
346 width, height,
347 m, m);
348 /*
349 gtk_plot_pc_clip_mask(data->plot->pc,
350 legend.x,
351 legend.y,
352 NULL);
353 */
354
355 gtk_plot_text_get_size(legend.text, legend.angle, legend.font,
356 roundint(legend.height * m),
357 &lwidth, &lheight,
358 &lascent, &ldescent);
359
360 legend.x = (gdouble)(area.x + x + width + roundint(4*m)) / (gdouble)area.width;
361 legend.y = (gdouble)(area.y + y + MAX(lheight, height) - lascent / 2) / (gdouble)area.height;
362
363 gtk_plot_draw_text(plot, legend);
364 }
365
366 static void
gtk_plot_pixmap_get_legend_size(GtkPlotData * data,gint * width,gint * height)367 gtk_plot_pixmap_get_legend_size(GtkPlotData *data, gint *width, gint *height)
368 {
369 GtkPlotPixmap *pixmap;
370 GtkPlot *plot = NULL;
371 GtkPlotText legend;
372 gint lascent, ldescent, lheight, lwidth;
373 gint pwidth, pheight;
374 gdouble m;
375
376 g_return_if_fail(data->plot != NULL);
377 g_return_if_fail(GTK_IS_PLOT(data->plot));
378
379 pixmap = GTK_PLOT_PIXMAP(data);
380
381 plot = data->plot;
382 m = plot->magnification;
383
384 legend = plot->legends_attr;
385
386 if(data->legend)
387 legend.text = data->legend;
388 else
389 legend.text = "";
390
391 gdk_window_get_size(pixmap->pixmap, &pwidth, &pheight);
392 pwidth = roundint(m * pwidth);
393 pheight = roundint(m * pheight);
394
395 gtk_plot_text_get_size(legend.text, legend.angle, legend.font,
396 roundint(legend.height * m),
397 &lwidth, &lheight,
398 &lascent, &ldescent);
399
400 *width = lwidth + pwidth + roundint(12 * m);
401 *height = MAX(lascent + ldescent, pheight);
402 }
403 /******************************************************
404 * Public methods
405 ******************************************************/
406
407 /**
408 * gtk_plot_pixmap_get_pixmap:
409 * @pixmap: a #GdkPlotPixmap
410 *
411 * Get pixmap from #GtkPlotPixmap.
412 *
413 * Return value: (transfer none) the #GdkPixmap
414 */
415 GdkPixmap *
gtk_plot_pixmap_get_pixmap(GtkPlotPixmap * pixmap)416 gtk_plot_pixmap_get_pixmap (GtkPlotPixmap *pixmap)
417 {
418 return(pixmap->pixmap);
419 }
420
421 /**
422 * gtk_plot_pixmap_get_mask:
423 * @pixmap: a #GdkPlotPixmap
424 *
425 * Get mask bitmap from #GtkPlotPixmap.
426 *
427 * Return value: (transfer none) the #GdkBitmap
428 */
429 GdkBitmap *
gtk_plot_pixmap_get_mask(GtkPlotPixmap * pixmap)430 gtk_plot_pixmap_get_mask (GtkPlotPixmap *pixmap)
431 {
432 return(pixmap->mask);
433 }
434
435
436