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