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