]> Pileus Git - ~andy/gtk/blob - gdk/gdkpixmap.c
Fix typo, where x value was assigned to both x and y.
[~andy/gtk] / gdk / gdkpixmap.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser 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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser 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  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #include "gdkpixmap.h"
28 #include "gdkinternals.h"
29 #include "gdkpixbuf.h"
30
31 static GdkGC *gdk_pixmap_create_gc      (GdkDrawable     *drawable,
32                                          GdkGCValues     *values,
33                                          GdkGCValuesMask  mask);
34 static void   gdk_pixmap_draw_rectangle (GdkDrawable     *drawable,
35                                          GdkGC           *gc,
36                                          gint             filled,
37                                          gint             x,
38                                          gint             y,
39                                          gint             width,
40                                          gint             height);
41 static void   gdk_pixmap_draw_arc       (GdkDrawable     *drawable,
42                                          GdkGC           *gc,
43                                          gint             filled,
44                                          gint             x,
45                                          gint             y,
46                                          gint             width,
47                                          gint             height,
48                                          gint             angle1,
49                                          gint             angle2);
50 static void   gdk_pixmap_draw_polygon   (GdkDrawable     *drawable,
51                                          GdkGC           *gc,
52                                          gint             filled,
53                                          GdkPoint        *points,
54                                          gint             npoints);
55 static void   gdk_pixmap_draw_text      (GdkDrawable     *drawable,
56                                          GdkFont         *font,
57                                          GdkGC           *gc,
58                                          gint             x,
59                                          gint             y,
60                                          const gchar     *text,
61                                          gint             text_length);
62 static void   gdk_pixmap_draw_text_wc   (GdkDrawable     *drawable,
63                                          GdkFont         *font,
64                                          GdkGC           *gc,
65                                          gint             x,
66                                          gint             y,
67                                          const GdkWChar  *text,
68                                          gint             text_length);
69 static void   gdk_pixmap_draw_drawable  (GdkDrawable     *drawable,
70                                          GdkGC           *gc,
71                                          GdkPixmap       *src,
72                                          gint             xsrc,
73                                          gint             ysrc,
74                                          gint             xdest,
75                                          gint             ydest,
76                                          gint             width,
77                                          gint             height);
78 static void   gdk_pixmap_draw_points    (GdkDrawable     *drawable,
79                                          GdkGC           *gc,
80                                          GdkPoint        *points,
81                                          gint             npoints);
82 static void   gdk_pixmap_draw_segments  (GdkDrawable     *drawable,
83                                          GdkGC           *gc,
84                                          GdkSegment      *segs,
85                                          gint             nsegs);
86 static void   gdk_pixmap_draw_lines     (GdkDrawable     *drawable,
87                                          GdkGC           *gc,
88                                          GdkPoint        *points,
89                                          gint             npoints);
90 static void   gdk_pixmap_draw_glyphs    (GdkDrawable      *drawable,
91                                          GdkGC            *gc,
92                                          PangoFont        *font,
93                                          gint              x,
94                                          gint              y,
95                                          PangoGlyphString *glyphs);
96 static void   gdk_pixmap_draw_image     (GdkDrawable     *drawable,
97                                          GdkGC           *gc,
98                                          GdkImage        *image,
99                                          gint             xsrc,
100                                          gint             ysrc,
101                                          gint             xdest,
102                                          gint             ydest,
103                                          gint             width,
104                                          gint             height);
105 static void   gdk_pixmap_draw_pixbuf    (GdkDrawable     *drawable,
106                                          GdkGC           *gc,
107                                          GdkPixbuf       *pixbuf,
108                                          gint             src_x,
109                                          gint             src_y,
110                                          gint             dest_x,
111                                          gint             dest_y,
112                                          gint             width,
113                                          gint             height,
114                                          GdkRgbDither     dither,
115                                          gint             x_dither,
116                                          gint             y_dither);
117
118
119 static void   gdk_pixmap_real_get_size  (GdkDrawable     *drawable,
120                                          gint            *width,
121                                          gint            *height);
122
123 static GdkImage* gdk_pixmap_copy_to_image (GdkDrawable *drawable,
124                                            GdkImage    *image,
125                                            gint         src_x,
126                                            gint         src_y,
127                                            gint         dest_x,
128                                            gint         dest_y,
129                                            gint         width,
130                                            gint         height);
131
132 static GdkVisual*   gdk_pixmap_real_get_visual   (GdkDrawable *drawable);
133 static gint         gdk_pixmap_real_get_depth    (GdkDrawable *drawable);
134 static void         gdk_pixmap_real_set_colormap (GdkDrawable *drawable,
135                                                   GdkColormap *cmap);
136 static GdkColormap* gdk_pixmap_real_get_colormap (GdkDrawable *drawable);
137
138 static void gdk_pixmap_init       (GdkPixmapObject      *pixmap);
139 static void gdk_pixmap_class_init (GdkPixmapObjectClass *klass);
140 static void gdk_pixmap_finalize   (GObject              *object);
141
142 static gpointer parent_class = NULL;
143
144 GType
145 gdk_pixmap_get_type (void)
146 {
147   static GType object_type = 0;
148
149   if (!object_type)
150     {
151       static const GTypeInfo object_info =
152       {
153         sizeof (GdkPixmapObjectClass),
154         (GBaseInitFunc) NULL,
155         (GBaseFinalizeFunc) NULL,
156         (GClassInitFunc) gdk_pixmap_class_init,
157         NULL,           /* class_finalize */
158         NULL,           /* class_data */
159         sizeof (GdkPixmapObject),
160         0,              /* n_preallocs */
161         (GInstanceInitFunc) gdk_pixmap_init,
162       };
163       
164       object_type = g_type_register_static (GDK_TYPE_DRAWABLE,
165                                             "GdkPixmap",
166                                             &object_info, 0);
167     }
168   
169   return object_type;
170 }
171
172 static void
173 gdk_pixmap_init (GdkPixmapObject *pixmap)
174 {
175   /* 0-initialization is good for all other fields. */
176   pixmap->impl = g_object_new (_gdk_pixmap_impl_get_type (), NULL);
177 }
178
179 static void
180 gdk_pixmap_class_init (GdkPixmapObjectClass *klass)
181 {
182   GObjectClass *object_class = G_OBJECT_CLASS (klass);
183   GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
184   
185   parent_class = g_type_class_peek_parent (klass);
186
187   object_class->finalize = gdk_pixmap_finalize;
188
189   drawable_class->create_gc = gdk_pixmap_create_gc;
190   drawable_class->draw_rectangle = gdk_pixmap_draw_rectangle;
191   drawable_class->draw_arc = gdk_pixmap_draw_arc;
192   drawable_class->draw_polygon = gdk_pixmap_draw_polygon;
193   drawable_class->draw_text = gdk_pixmap_draw_text;
194   drawable_class->draw_text_wc = gdk_pixmap_draw_text_wc;
195   drawable_class->draw_drawable = gdk_pixmap_draw_drawable;
196   drawable_class->draw_points = gdk_pixmap_draw_points;
197   drawable_class->draw_segments = gdk_pixmap_draw_segments;
198   drawable_class->draw_lines = gdk_pixmap_draw_lines;
199   drawable_class->draw_glyphs = gdk_pixmap_draw_glyphs;
200   drawable_class->draw_image = gdk_pixmap_draw_image;
201   drawable_class->_draw_pixbuf = gdk_pixmap_draw_pixbuf;
202   drawable_class->get_depth = gdk_pixmap_real_get_depth;
203   drawable_class->get_size = gdk_pixmap_real_get_size;
204   drawable_class->set_colormap = gdk_pixmap_real_set_colormap;
205   drawable_class->get_colormap = gdk_pixmap_real_get_colormap;
206   drawable_class->get_visual = gdk_pixmap_real_get_visual;
207   drawable_class->_copy_to_image = gdk_pixmap_copy_to_image;
208 }
209
210 static void
211 gdk_pixmap_finalize (GObject *object)
212 {
213   GdkPixmapObject *obj = (GdkPixmapObject *) object;
214
215   g_object_unref (G_OBJECT (obj->impl));
216   obj->impl = NULL;
217   
218   G_OBJECT_CLASS (parent_class)->finalize (object);
219 }
220
221 static GdkGC *
222 gdk_pixmap_create_gc (GdkDrawable     *drawable,
223                       GdkGCValues     *values,
224                       GdkGCValuesMask  mask)
225 {
226   return gdk_gc_new_with_values (((GdkPixmapObject *) drawable)->impl,
227                                  values, mask);
228 }
229
230 static void
231 gdk_pixmap_draw_rectangle (GdkDrawable *drawable,
232                            GdkGC       *gc,
233                            gint         filled,
234                            gint         x,
235                            gint         y,
236                            gint         width,
237                            gint         height)
238 {
239   GdkPixmapObject *private = (GdkPixmapObject *)drawable;
240
241   gdk_draw_rectangle (private->impl, gc, filled,
242                       x, y, width, height);
243 }
244
245 static void
246 gdk_pixmap_draw_arc (GdkDrawable *drawable,
247                      GdkGC       *gc,
248                      gint         filled,
249                      gint         x,
250                      gint         y,
251                      gint         width,
252                      gint         height,
253                      gint         angle1,
254                      gint         angle2)
255 {
256   GdkPixmapObject *private = (GdkPixmapObject *)drawable;
257
258   gdk_draw_arc (private->impl, gc, filled,
259                 x, y,
260                 width, height, angle1, angle2);
261 }
262
263 static void
264 gdk_pixmap_draw_polygon (GdkDrawable *drawable,
265                          GdkGC       *gc,
266                          gint         filled,
267                          GdkPoint    *points,
268                          gint         npoints)
269 {
270   GdkPixmapObject *private = (GdkPixmapObject *)drawable;
271
272   gdk_draw_polygon (private->impl, gc, filled, points, npoints);
273 }
274
275 static void
276 gdk_pixmap_draw_text (GdkDrawable *drawable,
277                       GdkFont     *font,
278                       GdkGC       *gc,
279                       gint         x,
280                       gint         y,
281                       const gchar *text,
282                       gint         text_length)
283 {
284   GdkPixmapObject *private = (GdkPixmapObject *)drawable;
285
286   gdk_draw_text (private->impl, font, gc,
287                  x, y, text, text_length);
288 }
289
290 static void
291 gdk_pixmap_draw_text_wc (GdkDrawable    *drawable,
292                          GdkFont        *font,
293                          GdkGC          *gc,
294                          gint            x,
295                          gint            y,
296                          const GdkWChar *text,
297                          gint            text_length)
298 {
299   GdkPixmapObject *private = (GdkPixmapObject *)drawable;
300
301   gdk_draw_text_wc (private->impl, font, gc,
302                     x, y, text, text_length);
303 }
304
305 static void
306 gdk_pixmap_draw_drawable (GdkDrawable *drawable,
307                           GdkGC       *gc,
308                           GdkPixmap   *src,
309                           gint         xsrc,
310                           gint         ysrc,
311                           gint         xdest,
312                           gint         ydest,
313                           gint         width,
314                           gint         height)
315 {
316   GdkPixmapObject *private = (GdkPixmapObject *)drawable;
317
318   gdk_draw_drawable (private->impl, gc, src, xsrc, ysrc,
319                      xdest, ydest,
320                      width, height);
321 }
322
323 static void
324 gdk_pixmap_draw_points (GdkDrawable *drawable,
325                         GdkGC       *gc,
326                         GdkPoint    *points,
327                         gint         npoints)
328 {
329   GdkPixmapObject *private = (GdkPixmapObject *)drawable;
330
331   gdk_draw_points (private->impl, gc, points, npoints);
332 }
333
334 static void
335 gdk_pixmap_draw_segments (GdkDrawable *drawable,
336                           GdkGC       *gc,
337                           GdkSegment  *segs,
338                           gint         nsegs)
339 {
340   GdkPixmapObject *private = (GdkPixmapObject *)drawable;
341
342   gdk_draw_segments (private->impl, gc, segs, nsegs);
343 }
344
345 static void
346 gdk_pixmap_draw_lines (GdkDrawable *drawable,
347                        GdkGC       *gc,
348                        GdkPoint    *points,
349                        gint         npoints)
350 {
351   GdkPixmapObject *private = (GdkPixmapObject *)drawable;
352
353   gdk_draw_lines (private->impl, gc, points, npoints);
354 }
355
356 static void
357 gdk_pixmap_draw_glyphs (GdkDrawable      *drawable,
358                         GdkGC            *gc,
359                         PangoFont        *font,
360                         gint              x,
361                         gint              y,
362                         PangoGlyphString *glyphs)
363 {
364   GdkPixmapObject *private = (GdkPixmapObject *)drawable;
365
366   gdk_draw_glyphs (private->impl, gc, font, x, y, glyphs);
367 }
368
369 static void
370 gdk_pixmap_draw_image (GdkDrawable     *drawable,
371                        GdkGC           *gc,
372                        GdkImage        *image,
373                        gint             xsrc,
374                        gint             ysrc,
375                        gint             xdest,
376                        gint             ydest,
377                        gint             width,
378                        gint             height)
379 {
380   GdkPixmapObject *private = (GdkPixmapObject *)drawable;
381
382   gdk_draw_image (private->impl, gc, image, xsrc, ysrc, xdest, ydest,
383                   width, height);
384 }
385
386 static void
387 gdk_pixmap_draw_pixbuf (GdkDrawable     *drawable,
388                         GdkGC           *gc,
389                         GdkPixbuf       *pixbuf,
390                         gint             src_x,
391                         gint             src_y,
392                         gint             dest_x,
393                         gint             dest_y,
394                         gint             width,
395                         gint             height,
396                         GdkRgbDither     dither,
397                         gint             x_dither,
398                         gint             y_dither)
399 {
400   GdkPixmapObject *private = (GdkPixmapObject *)drawable;
401
402   _gdk_draw_pixbuf (private->impl, gc, pixbuf,
403                     src_x, src_y, dest_x, dest_y, width, height,
404                     dither, x_dither, y_dither);
405 }
406
407 static void
408 gdk_pixmap_real_get_size (GdkDrawable *drawable,
409                           gint *width,
410                           gint *height)
411 {
412   g_return_if_fail (GDK_IS_PIXMAP (drawable));
413
414   gdk_drawable_get_size (GDK_DRAWABLE (((GdkPixmapObject*)drawable)->impl),
415                          width, height);
416 }
417
418 static GdkVisual*
419 gdk_pixmap_real_get_visual (GdkDrawable *drawable)
420 {
421   GdkColormap *colormap;
422
423   g_return_val_if_fail (GDK_IS_PIXMAP (drawable), NULL);
424
425   colormap = gdk_drawable_get_colormap (drawable);
426   return colormap ? gdk_colormap_get_visual (colormap) : NULL;
427 }
428
429 static gint
430 gdk_pixmap_real_get_depth (GdkDrawable *drawable)
431 {
432   gint depth;
433   
434   g_return_val_if_fail (GDK_IS_PIXMAP (drawable), 0);
435
436   depth = GDK_PIXMAP_OBJECT (drawable)->depth;
437
438   return depth;
439 }
440
441 static void
442 gdk_pixmap_real_set_colormap (GdkDrawable *drawable,
443                               GdkColormap *cmap)
444 {
445   g_return_if_fail (GDK_IS_PIXMAP (drawable));  
446   
447   gdk_drawable_set_colormap (((GdkPixmapObject*)drawable)->impl, cmap);
448 }
449
450 static GdkColormap*
451 gdk_pixmap_real_get_colormap (GdkDrawable *drawable)
452 {
453   g_return_val_if_fail (GDK_IS_PIXMAP (drawable), NULL);
454   
455   return gdk_drawable_get_colormap (((GdkPixmapObject*)drawable)->impl);
456 }
457
458 static GdkImage*
459 gdk_pixmap_copy_to_image (GdkDrawable     *drawable,
460                           GdkImage        *image,
461                           gint             src_x,
462                           gint             src_y,
463                           gint             dest_x,
464                           gint             dest_y,
465                           gint             width,
466                           gint             height)
467 {
468   g_return_val_if_fail (GDK_IS_PIXMAP (drawable), NULL);
469   
470   return _gdk_drawable_copy_to_image (((GdkPixmapObject*)drawable)->impl,
471                                       image,
472                                       src_x, src_y, dest_x, dest_y,
473                                       width, height);
474 }
475
476 static GdkBitmap *
477 make_solid_mask (gint width, gint height)
478 {
479   GdkBitmap *bitmap;
480   GdkGC *gc;
481   GdkGCValues gc_values;
482   
483   bitmap = gdk_pixmap_new (NULL, width, height, 1);
484
485   gc_values.foreground.pixel = 1;
486   gc = gdk_gc_new_with_values (bitmap, &gc_values, GDK_GC_FOREGROUND);
487   
488   gdk_draw_rectangle (bitmap, gc, TRUE, 0, 0, width, height);
489   
490   gdk_gc_unref (gc);
491   
492   return bitmap;
493 }
494
495 #define PACKED_COLOR(c) ((((c)->red & 0xff) << 8) | ((c)->green & 0xff) | ((c)->blue >> 8))
496
497 static GdkPixmap *
498 gdk_pixmap_colormap_new_from_pixbuf (GdkColormap *colormap,
499                                      GdkBitmap  **mask,
500                                      GdkColor    *transparent_color,
501                                      GdkPixbuf   *pixbuf)
502 {
503   GdkPixmap *pixmap;
504   GdkPixbuf *render_pixbuf;
505   GdkGC *tmp_gc;
506   
507   pixmap = gdk_pixmap_new (NULL,
508                            gdk_pixbuf_get_width (pixbuf),
509                            gdk_pixbuf_get_height (pixbuf),
510                            gdk_colormap_get_visual (colormap)->depth);
511   gdk_drawable_set_colormap (pixmap, colormap);
512   
513   if (transparent_color)
514     {
515       guint32 packed_color = PACKED_COLOR (transparent_color);
516       render_pixbuf = gdk_pixbuf_composite_color_simple (pixbuf,
517                                                          gdk_pixbuf_get_width (pixbuf),
518                                                          gdk_pixbuf_get_height (pixbuf),
519                                                          GDK_INTERP_NEAREST,
520                                                          255, 16, packed_color, packed_color);
521     }
522   else
523     render_pixbuf = pixbuf;
524
525   tmp_gc = gdk_gc_new (pixmap);
526   gdk_pixbuf_render_to_drawable (render_pixbuf, pixmap, tmp_gc, 0, 0, 0, 0,
527                                  gdk_pixbuf_get_width (render_pixbuf),
528                                  gdk_pixbuf_get_height (render_pixbuf),
529                                  GDK_RGB_DITHER_NORMAL, 0, 0);
530   gdk_gc_unref (tmp_gc);
531
532   if (render_pixbuf != pixbuf)
533     gdk_pixbuf_unref (render_pixbuf);
534
535   if (mask)
536     gdk_pixbuf_render_pixmap_and_mask (pixbuf, NULL, mask, 128);
537
538   if (mask && !*mask)
539     *mask = make_solid_mask (gdk_pixbuf_get_width (pixbuf),
540                              gdk_pixbuf_get_height (pixbuf));
541
542   return pixmap;
543 }
544
545 GdkPixmap*
546 gdk_pixmap_colormap_create_from_xpm (GdkWindow   *window,
547                                      GdkColormap *colormap,
548                                      GdkBitmap  **mask,
549                                      GdkColor    *transparent_color,
550                                      const gchar *filename)
551 {
552   GdkPixbuf *pixbuf;
553   GdkPixmap *pixmap;
554
555   g_return_val_if_fail (window != NULL || colormap != NULL, NULL);
556   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
557   g_return_val_if_fail (colormap == NULL || GDK_IS_COLORMAP (colormap), NULL);
558
559   if (colormap == NULL)
560     colormap = gdk_drawable_get_colormap (window);
561   
562   pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
563   if (!pixbuf)
564     return NULL;
565
566   pixmap = gdk_pixmap_colormap_new_from_pixbuf (colormap, mask, transparent_color, pixbuf);
567
568   gdk_pixbuf_unref (pixbuf);
569   
570   return pixmap;
571 }
572
573 GdkPixmap*
574 gdk_pixmap_create_from_xpm (GdkWindow  *window,
575                             GdkBitmap **mask,
576                             GdkColor   *transparent_color,
577                             const gchar *filename)
578 {
579   return gdk_pixmap_colormap_create_from_xpm (window, NULL, mask,
580                                               transparent_color, filename);
581 }
582
583 GdkPixmap*
584 gdk_pixmap_colormap_create_from_xpm_d (GdkWindow  *window,
585                                        GdkColormap *colormap,
586                                        GdkBitmap **mask,
587                                        GdkColor   *transparent_color,
588                                        gchar     **data)
589 {
590   GdkPixbuf *pixbuf;
591   GdkPixmap *pixmap;
592
593   g_return_val_if_fail (window != NULL || colormap != NULL, NULL);
594   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
595   g_return_val_if_fail (colormap == NULL || GDK_IS_COLORMAP (colormap), NULL);
596
597   if (colormap == NULL)
598     colormap = gdk_drawable_get_colormap (window);
599   
600   pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **)data);
601   if (!pixbuf)
602     return NULL;
603
604   pixmap = gdk_pixmap_colormap_new_from_pixbuf (colormap, mask, transparent_color, pixbuf);
605
606   gdk_pixbuf_unref (pixbuf);
607
608   return pixmap;
609 }
610
611 GdkPixmap*
612 gdk_pixmap_create_from_xpm_d (GdkWindow  *window,
613                               GdkBitmap **mask,
614                               GdkColor   *transparent_color,
615                               gchar     **data)
616 {
617   return gdk_pixmap_colormap_create_from_xpm_d (window, NULL, mask,
618                                                 transparent_color, data);
619 }
620