~ubuntu-branches/debian/sid/genius/sid

« back to all changes in this revision

Viewing changes to gtkextra/gtkplotgdk.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2006-08-21 12:57:45 UTC
  • Revision ID: james.westby@ubuntu.com-20060821125745-sl9ks8v7fq324bdf
Tags: upstream-0.7.6.1
ImportĀ upstreamĀ versionĀ 0.7.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* gtkplotpc - gtkplot print context - a renderer for printing functions
 
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 <stdio.h>
 
21
#include <stdlib.h>
 
22
#include <string.h>
 
23
#include <math.h>
 
24
#include <ctype.h>
 
25
#include <time.h>
 
26
#include <gtk/gtk.h>
 
27
#include <gdk/gdk.h>
 
28
 
 
29
#include "gtkplotpc.h"
 
30
#include "gtkplotgdk.h"
 
31
#include "gtkplot.h"
 
32
#include "gtkpsfont.h"
 
33
#include "gtkplotcanvas.h"
 
34
 
 
35
static void gtk_plot_gdk_init                       (GtkPlotGdk *pc);
 
36
static void gtk_plot_gdk_class_init                 (GtkPlotGdkClass *klass);
 
37
static void gtk_plot_gdk_finalize                   (GObject *object);
 
38
static void gtk_plot_gdk_real_set_drawable          (GtkPlotGdk *gdk,
 
39
                                                     GdkDrawable *drawable);
 
40
static gboolean gtk_plot_gdk_real_init              (GtkPlotPC *pc);
 
41
static void gtk_plot_gdk_set_viewport               (GtkPlotPC *pc,
 
42
                                                     gdouble w, gdouble h);
 
43
static void gtk_plot_gdk_leave                      (GtkPlotPC *pc);
 
44
static void gtk_plot_gdk_gsave                      (GtkPlotPC *pc);
 
45
static void gtk_plot_gdk_grestore                   (GtkPlotPC *pc);
 
46
static void gtk_plot_gdk_clip                       (GtkPlotPC *pc,
 
47
                                                     const GdkRectangle *area);
 
48
static void gtk_plot_gdk_clip_mask                  (GtkPlotPC *pc,
 
49
                                                     gdouble x,
 
50
                                                     gdouble y,
 
51
                                                     const GdkBitmap *mask);
 
52
static void gtk_plot_gdk_set_color                   (GtkPlotPC *pc,
 
53
                                                     const GdkColor *color);
 
54
static void gtk_plot_gdk_set_lineattr           (GtkPlotPC *pc,
 
55
                                                 gfloat line_width,
 
56
                                                 GdkLineStyle line_style,
 
57
                                                 GdkCapStyle cap_style,
 
58
                                                 GdkJoinStyle join_style);
 
59
static void gtk_plot_gdk_set_dash                    (GtkPlotPC *pc,
 
60
                                                     gdouble offset_,
 
61
                                                     gdouble *values,
 
62
                                                     gint num_values);
 
63
static void gtk_plot_gdk_draw_point                  (GtkPlotPC *pc,
 
64
                                                     gdouble x, gdouble y);
 
65
static void gtk_plot_gdk_draw_line                   (GtkPlotPC *pc,
 
66
                                                     gdouble x1, gdouble y1,
 
67
                                                     gdouble x2, gdouble y2);
 
68
static void gtk_plot_gdk_draw_lines                  (GtkPlotPC *pc,
 
69
                                                     GtkPlotPoint *points,
 
70
                                                     gint numpoints);
 
71
static void gtk_plot_gdk_draw_rectangle              (GtkPlotPC *pc,
 
72
                                                     gint filled,
 
73
                                                     gdouble x, gdouble y,
 
74
                                                     gdouble width, 
 
75
                                                     gdouble height);
 
76
static void gtk_plot_gdk_draw_polygon                (GtkPlotPC *pc,
 
77
                                                     gint filled,
 
78
                                                     GtkPlotPoint *points,
 
79
                                                     gint numpoints);
 
80
static void gtk_plot_gdk_draw_circle                 (GtkPlotPC *pc,
 
81
                                                     gint filled,
 
82
                                                     gdouble x, gdouble y,
 
83
                                                     gdouble size);
 
84
static void gtk_plot_gdk_draw_ellipse                (GtkPlotPC *pc,
 
85
                                                     gint filled,
 
86
                                                     gdouble x, gdouble y,
 
87
                                                     gdouble width, 
 
88
                                                     gdouble height);
 
89
static void gtk_plot_gdk_set_font                    (GtkPlotPC *pc,
 
90
                                                     GtkPSFont *psfont,
 
91
                                                     gint height);
 
92
static void gtk_plot_gdk_draw_string                (GtkPlotPC *pc,
 
93
                                                     gint x, gint y,
 
94
                                                     gint angle,
 
95
                                                     const GdkColor *fg,
 
96
                                                     const GdkColor *bg,
 
97
                                                     gboolean transparent,
 
98
                                                     gint border,
 
99
                                                     gint border_space,
 
100
                                                     gint border_width,
 
101
                                                     gint shadow_width,
 
102
                                                     const gchar *font,
 
103
                                                     gint height,
 
104
                                                     GtkJustification just,
 
105
                                                     const gchar *text);
 
106
static void gtk_plot_gdk_draw_pixmap                (GtkPlotPC *pc,
 
107
                                                     GdkPixmap *pixmap,
 
108
                                                     GdkBitmap *mask,
 
109
                                                     gint xsrc, gint ysrc,
 
110
                                                     gint xdest, gint ydest,
 
111
                                                     gint width, gint height,
 
112
                                                     gdouble scale_x, 
 
113
                                                     gdouble scale_y);
 
114
 
 
115
static GdkPixmap * scale_pixmap                     (GdkWindow *window, 
 
116
                                                     GdkPixmap *pixmap, 
 
117
                                                     gdouble scale_x, 
 
118
                                                     gdouble scale_y);
 
119
static GdkBitmap * scale_bitmap                     (GdkWindow *window, 
 
120
                                                     GdkBitmap *bitmap, 
 
121
                                                     gdouble scale_x, 
 
122
                                                     gdouble scale_y);
 
123
 
 
124
static gint roundint                                (gdouble x);
 
125
 
 
126
static GtkPlotPCClass *parent_class = NULL;
 
127
 
 
128
GtkType
 
129
gtk_plot_gdk_get_type (void)
 
130
{
 
131
  static GtkType pc_type = 0;
 
132
 
 
133
  if (!pc_type)
 
134
    {
 
135
      GtkTypeInfo pc_info =
 
136
      {
 
137
        "GtkPlotGdk",
 
138
        sizeof (GtkPlotGdk),
 
139
        sizeof (GtkPlotGdkClass),
 
140
        (GtkClassInitFunc) gtk_plot_gdk_class_init,
 
141
        (GtkObjectInitFunc) gtk_plot_gdk_init,
 
142
        /* reserved 1*/ NULL,
 
143
        /* reserved 2 */ NULL,
 
144
        (GtkClassInitFunc) NULL,
 
145
      };
 
146
 
 
147
      pc_type = gtk_type_unique (GTK_TYPE_PLOT_PC, &pc_info);
 
148
    }
 
149
  return pc_type;
 
150
}
 
151
 
 
152
static void
 
153
gtk_plot_gdk_init (GtkPlotGdk *pc)
 
154
{
 
155
  GdkWindowAttr attributes;
 
156
  gint attributes_mask;
 
157
 
 
158
  attributes.window_type = GDK_WINDOW_CHILD;
 
159
  attributes.title = NULL;
 
160
  attributes.wclass = GDK_INPUT_OUTPUT;
 
161
  attributes.visual = gdk_visual_get_system ();
 
162
  attributes.colormap = gdk_colormap_get_system ();
 
163
  attributes.event_mask = 0;
 
164
  attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
 
165
 
 
166
  pc->gc = NULL;
 
167
  pc->drawable = NULL;
 
168
  pc->ref_count = 0;
 
169
 
 
170
  pc->window = gdk_window_new (NULL, &attributes, attributes_mask);
 
171
}
 
172
 
 
173
 
 
174
static void
 
175
gtk_plot_gdk_class_init (GtkPlotGdkClass *klass)
 
176
{
 
177
  GtkObjectClass *object_class;
 
178
  GObjectClass *gobject_class;
 
179
  GtkPlotPCClass *pc_class;
 
180
  GtkPlotGdkClass *gdk_class;
 
181
 
 
182
  parent_class = gtk_type_class (gtk_plot_pc_get_type ());
 
183
 
 
184
  object_class = (GtkObjectClass *) klass;
 
185
  gobject_class = (GObjectClass *) klass;
 
186
 
 
187
  pc_class = (GtkPlotPCClass *) klass;
 
188
  gdk_class = (GtkPlotGdkClass *) klass;
 
189
 
 
190
  gobject_class->finalize = gtk_plot_gdk_finalize;
 
191
 
 
192
  gdk_class->set_drawable = gtk_plot_gdk_real_set_drawable;
 
193
 
 
194
  pc_class->init = gtk_plot_gdk_real_init;
 
195
  pc_class->leave = gtk_plot_gdk_leave;
 
196
  pc_class->set_viewport = gtk_plot_gdk_set_viewport;
 
197
  pc_class->gsave = gtk_plot_gdk_gsave;
 
198
  pc_class->grestore = gtk_plot_gdk_grestore;
 
199
  pc_class->clip = gtk_plot_gdk_clip;
 
200
  pc_class->clip_mask = gtk_plot_gdk_clip_mask;
 
201
  pc_class->set_color = gtk_plot_gdk_set_color;
 
202
  pc_class->set_dash = gtk_plot_gdk_set_dash;
 
203
  pc_class->set_lineattr = gtk_plot_gdk_set_lineattr;
 
204
  pc_class->draw_point = gtk_plot_gdk_draw_point;
 
205
  pc_class->draw_line = gtk_plot_gdk_draw_line;
 
206
  pc_class->draw_lines = gtk_plot_gdk_draw_lines;
 
207
  pc_class->draw_rectangle = gtk_plot_gdk_draw_rectangle;
 
208
  pc_class->draw_polygon = gtk_plot_gdk_draw_polygon;
 
209
  pc_class->draw_circle = gtk_plot_gdk_draw_circle;
 
210
  pc_class->draw_ellipse = gtk_plot_gdk_draw_ellipse;
 
211
  pc_class->set_font = gtk_plot_gdk_set_font;
 
212
  pc_class->draw_string = gtk_plot_gdk_draw_string;
 
213
  pc_class->draw_pixmap = gtk_plot_gdk_draw_pixmap;
 
214
}
 
215
 
 
216
 
 
217
GtkObject *
 
218
gtk_plot_gdk_new                                (GdkDrawable *drawable)
 
219
{
 
220
  GtkObject *object;
 
221
 
 
222
  object = gtk_type_new(gtk_plot_gdk_get_type());
 
223
 
 
224
  gtk_plot_gdk_construct(GTK_PLOT_GDK(object), drawable);
 
225
 
 
226
  return (object);
 
227
}
 
228
 
 
229
void
 
230
gtk_plot_gdk_construct(GtkPlotGdk *pc, GdkDrawable *drawable)
 
231
{
 
232
  if(drawable){ 
 
233
    gtk_plot_gdk_set_drawable(GTK_PLOT_GDK(pc), drawable);
 
234
    gtk_plot_pc_gsave(GTK_PLOT_PC(pc));
 
235
  }
 
236
}
 
237
 
 
238
 
 
239
static void
 
240
gtk_plot_gdk_finalize (GObject *object)
 
241
{
 
242
  gdk_window_destroy(GTK_PLOT_GDK(object)->window);
 
243
  GTK_PLOT_GDK(object)->window = NULL;
 
244
 
 
245
  if(GTK_PLOT_GDK(object)->ref_count > 0 && GTK_PLOT_GDK(object)->gc){
 
246
          gdk_gc_destroy(GTK_PLOT_GDK(object)->gc);
 
247
          GTK_PLOT_GDK(object)->gc = NULL;
 
248
  }
 
249
 
 
250
//  G_OBJECT_CLASS(parent_class)->finalize(object);
 
251
}
 
252
 
 
253
static void
 
254
gtk_plot_gdk_real_set_drawable(GtkPlotGdk *pc, GdkDrawable *drawable)
 
255
{
 
256
  pc->drawable = drawable;
 
257
}
 
258
 
 
259
static gboolean 
 
260
gtk_plot_gdk_real_init (GtkPlotPC *pc)
 
261
{
 
262
  return TRUE;
 
263
}
 
264
 
 
265
static void
 
266
gtk_plot_gdk_leave (GtkPlotPC *pc)
 
267
{
 
268
}
 
269
 
 
270
void 
 
271
gtk_plot_gdk_set_drawable               (GtkPlotGdk *gdk, GdkDrawable *drawable)
 
272
{
 
273
  GTK_PLOT_GDK_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(gdk)))->set_drawable(gdk, drawable);
 
274
}
 
275
 
 
276
static void 
 
277
gtk_plot_gdk_set_viewport               (GtkPlotPC *pc, gdouble w, gdouble h)
 
278
{
 
279
}
 
280
 
 
281
static void 
 
282
gtk_plot_gdk_gsave                                  (GtkPlotPC *pc)
 
283
{
 
284
  if(GTK_PLOT_GDK(pc)->gc) 
 
285
    gdk_gc_ref(GTK_PLOT_GDK(pc)->gc);
 
286
  else{
 
287
    GTK_PLOT_GDK(pc)->gc = gdk_gc_new(GTK_PLOT_GDK(pc)->window);
 
288
  }
 
289
 
 
290
  GTK_PLOT_GDK(pc)->ref_count++;
 
291
}
 
292
 
 
293
static void 
 
294
gtk_plot_gdk_grestore                                  (GtkPlotPC *pc)
 
295
{
 
296
  if(GTK_PLOT_GDK(pc)->gc) gdk_gc_unref(GTK_PLOT_GDK(pc)->gc);
 
297
 
 
298
  GTK_PLOT_GDK(pc)->ref_count--;
 
299
  if(GTK_PLOT_GDK(pc)->ref_count == 0) GTK_PLOT_GDK(pc)->gc = NULL;
 
300
}
 
301
 
 
302
static void 
 
303
gtk_plot_gdk_clip                                   (GtkPlotPC *pc,
 
304
                                                     const GdkRectangle *area)
 
305
{
 
306
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
307
 
 
308
  /* discard GdkRectangle* const: 
 
309
   * gdk_gc_set_clip_rectangle should have a const arg.
 
310
   * I've checked the code and it doesn't change it or keep it. murrayc.
 
311
   */
 
312
 
 
313
  gdk_gc_set_clip_rectangle(GTK_PLOT_GDK(pc)->gc, (GdkRectangle*)area);  
 
314
}
 
315
 
 
316
static void 
 
317
gtk_plot_gdk_clip_mask                              (GtkPlotPC *pc,
 
318
                                                     gdouble x,
 
319
                                                     gdouble y,
 
320
                                                     const GdkBitmap *mask)
 
321
{
 
322
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
323
 
 
324
  if(x >= 0 && y >= 0)
 
325
    gdk_gc_set_clip_origin(GTK_PLOT_GDK(pc)->gc, x, y);
 
326
 
 
327
  gdk_gc_set_clip_mask(GTK_PLOT_GDK(pc)->gc, (GdkBitmap*)mask);  
 
328
}
 
329
 
 
330
static void 
 
331
gtk_plot_gdk_set_color                               (GtkPlotPC *pc,
 
332
                                                     const GdkColor *color)
 
333
{
 
334
  GdkColor new_color;
 
335
 
 
336
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
337
 
 
338
  new_color = *color;
 
339
  gdk_color_alloc(gdk_colormap_get_system(), &new_color);
 
340
  gdk_gc_set_foreground(GTK_PLOT_GDK(pc)->gc, &new_color);
 
341
}
 
342
 
 
343
static void 
 
344
gtk_plot_gdk_set_dash                               (GtkPlotPC *pc,
 
345
                                                    gdouble offset,
 
346
                                                    gdouble *values,
 
347
                                                    gint num_values)
 
348
{
 
349
  gchar list[] = {'\0','\1','\2','\3','\4','\5','\6','\7'};
 
350
  gchar dash[1000] = "";
 
351
  gint i;
 
352
 
 
353
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
354
 
 
355
  if(num_values == 0){
 
356
    return;
 
357
  }
 
358
 
 
359
  for(i = 0; i < num_values; i++){
 
360
     gint value;
 
361
     value = values[i];
 
362
     dash[i] = list[value];
 
363
  }  
 
364
 
 
365
  gdk_gc_set_dashes(GTK_PLOT_GDK(pc)->gc, 0, dash, num_values);
 
366
}
 
367
 
 
368
static void gtk_plot_gdk_set_lineattr           (GtkPlotPC *pc,
 
369
                                                 gfloat line_width,
 
370
                                                 GdkLineStyle line_style,
 
371
                                                 GdkCapStyle cap_style,
 
372
                                                 GdkJoinStyle join_style)
 
373
{
 
374
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
375
 
 
376
  gdk_gc_set_line_attributes(GTK_PLOT_GDK(pc)->gc,  
 
377
                             roundint(line_width),
 
378
                             line_style,
 
379
                             cap_style,
 
380
                             join_style);
 
381
}
 
382
 
 
383
static void 
 
384
gtk_plot_gdk_draw_point                              (GtkPlotPC *pc,
 
385
                                                     gdouble x, gdouble y)
 
386
{
 
387
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
388
  if(!GTK_PLOT_GDK(pc)->drawable) return;
 
389
 
 
390
  gdk_draw_point(GTK_PLOT_GDK(pc)->drawable, GTK_PLOT_GDK(pc)->gc, 
 
391
                 roundint(x), roundint(y));
 
392
}
 
393
 
 
394
static void 
 
395
gtk_plot_gdk_draw_line                               (GtkPlotPC *pc,
 
396
                                                     gdouble x1, gdouble y1,
 
397
                                                     gdouble x2, gdouble y2)
 
398
{
 
399
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
400
  if(!GTK_PLOT_GDK(pc)->drawable) return;
 
401
 
 
402
  gdk_draw_line(GTK_PLOT_GDK(pc)->drawable, GTK_PLOT_GDK(pc)->gc, 
 
403
                roundint(x1), roundint(y1), roundint(x2), roundint(y2));
 
404
}
 
405
 
 
406
static void 
 
407
gtk_plot_gdk_draw_lines                              (GtkPlotPC *pc,
 
408
                                                     GtkPlotPoint *points,
 
409
                                                     gint numpoints)
 
410
{
 
411
  GdkPoint *p = NULL;
 
412
  gint i;
 
413
 
 
414
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
415
  if(!GTK_PLOT_GDK(pc)->drawable) return;
 
416
 
 
417
  p = (GdkPoint *)g_malloc(numpoints * sizeof(GdkPoint));
 
418
  for(i = 0; i < numpoints; i++){
 
419
    p[i].x = roundint(points[i].x);
 
420
    p[i].y = roundint(points[i].y);
 
421
  }
 
422
 
 
423
  gdk_draw_lines(GTK_PLOT_GDK(pc)->drawable, GTK_PLOT_GDK(pc)->gc, p, numpoints);
 
424
 
 
425
  g_free(p);
 
426
}
 
427
 
 
428
static void 
 
429
gtk_plot_gdk_draw_rectangle                          (GtkPlotPC *pc,
 
430
                                                     gint filled,
 
431
                                                     gdouble x, gdouble y,
 
432
                                                     gdouble width, gdouble height)
 
433
{
 
434
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
435
  if(!GTK_PLOT_GDK(pc)->drawable) return;
 
436
 
 
437
  gdk_draw_rectangle (GTK_PLOT_GDK(pc)->drawable, GTK_PLOT_GDK(pc)->gc,
 
438
                      filled,
 
439
                      roundint(x), roundint(y), 
 
440
                      roundint(width), roundint(height));
 
441
 
 
442
}
 
443
 
 
444
static void 
 
445
gtk_plot_gdk_draw_polygon                            (GtkPlotPC *pc,
 
446
                                                     gint filled,
 
447
                                                     GtkPlotPoint *points,
 
448
                                                     gint numpoints)
 
449
{
 
450
  GdkPoint *p = NULL;
 
451
  gint i;
 
452
 
 
453
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
454
  if(!GTK_PLOT_GDK(pc)->drawable) return;
 
455
 
 
456
  p = (GdkPoint *)g_malloc(numpoints * sizeof(GdkPoint));
 
457
  for(i = 0; i < numpoints; i++){
 
458
    p[i].x = roundint(points[i].x);
 
459
    p[i].y = roundint(points[i].y);
 
460
  }
 
461
 
 
462
  gdk_draw_polygon(GTK_PLOT_GDK(pc)->drawable, GTK_PLOT_GDK(pc)->gc, 
 
463
                   filled, p, numpoints);
 
464
 
 
465
  g_free(p);
 
466
}
 
467
 
 
468
static void 
 
469
gtk_plot_gdk_draw_circle                             (GtkPlotPC *pc,
 
470
                                                     gint filled,
 
471
                                                     gdouble x, gdouble y,
 
472
                                                     gdouble size)
 
473
{
 
474
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
475
  if(!GTK_PLOT_GDK(pc)->drawable) return;
 
476
 
 
477
  gdk_draw_arc (GTK_PLOT_GDK(pc)->drawable, GTK_PLOT_GDK(pc)->gc,
 
478
                filled,
 
479
                roundint(x-size/2.0), roundint(y-size/2.0),
 
480
                roundint(size), roundint(size), 0, 25000);
 
481
 
 
482
}
 
483
 
 
484
static void 
 
485
gtk_plot_gdk_draw_ellipse                            (GtkPlotPC *pc,
 
486
                                                     gint filled,
 
487
                                                     gdouble x, gdouble y,
 
488
                                                     gdouble width, gdouble height)
 
489
{
 
490
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
491
  if(!GTK_PLOT_GDK(pc)->drawable) return;
 
492
 
 
493
  gdk_draw_arc (GTK_PLOT_GDK(pc)->drawable, GTK_PLOT_GDK(pc)->gc,
 
494
                filled,
 
495
                roundint(x), roundint(y),
 
496
                roundint(width), roundint(height), 0, 25000);
 
497
}
 
498
 
 
499
static void 
 
500
gtk_plot_gdk_set_font                                (GtkPlotPC *pc,
 
501
                                                     GtkPSFont *psfont,
 
502
                                                     gint height)
 
503
{
 
504
 
 
505
}
 
506
 
 
507
/* subfunction of gtk_plot_gdk_draw_string(). */
 
508
static gint
 
509
drawstring(GtkPlotPC *pc,
 
510
           GdkBitmap *dest,
 
511
           GdkGC *gc,
 
512
           gint dx, gint dy,
 
513
           GtkPSFont *psfont, gint height,
 
514
           GdkWChar wc)
 
515
{
 
516
  GdkBitmap *tmp;
 
517
  GdkFont *font;
 
518
  GdkImage *image;
 
519
  GdkColor mask_color;
 
520
  gint w, h, a, d, x, y, d2;
 
521
  guint32 pixel;
 
522
 
 
523
  font = gtk_psfont_get_gdkfont(psfont, height);
 
524
 
 
525
  if (psfont->i18n_latinfamily && psfont->vertical && (0 > wc || wc > 0x7f)) {
 
526
    /* vertical-writing CJK postscript fonts. */
 
527
 
 
528
    w = gdk_char_width_wc(font, wc);
 
529
    a = font->ascent;
 
530
    d = font->descent;
 
531
    h = a + d;
 
532
    d2 = w * d / h;
 
533
 
 
534
    tmp = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, w, h, 1);
 
535
 
 
536
    mask_color.pixel = 0;
 
537
    gdk_gc_set_foreground(gc, &mask_color);
 
538
    gdk_draw_rectangle(tmp, gc, TRUE, 0, 0, -1, -1);
 
539
    mask_color.pixel = 1;
 
540
    gdk_gc_set_foreground(gc, &mask_color);
 
541
 
 
542
    gdk_draw_text_wc(tmp, font, gc, 0, a, &wc, 1);
 
543
 
 
544
    image = gdk_image_get(tmp, 0, 0, w, h);
 
545
 
 
546
    for (y = 0; y < h; y++) {
 
547
      for (x = 0; x < w; x++) {
 
548
        pixel = gdk_image_get_pixel(image, x, y);
 
549
        if (pixel == 1)
 
550
          gdk_draw_point(dest, gc, dx + y, dy + d2 - x);
 
551
      }
 
552
    }
 
553
 
 
554
    gdk_image_destroy(image);
 
555
    gdk_pixmap_unref(tmp);
 
556
    gdk_font_unref(font);
 
557
 
 
558
    return h;
 
559
  } else {
 
560
    /* horizontal writing */
 
561
 
 
562
    gdk_draw_text_wc(dest, font, gc, dx, dy, &wc, 1);
 
563
    w = gdk_char_width_wc(font, wc);
 
564
    gdk_font_unref(font);
 
565
    
 
566
    return w;
 
567
  }
 
568
}
 
569
 
 
570
static void 
 
571
gtk_plot_gdk_draw_string                        (GtkPlotPC *pc,
 
572
                                                gint tx, gint ty,
 
573
                                                gint angle,
 
574
                                                const GdkColor *fg,
 
575
                                                const GdkColor *bg,
 
576
                                                gboolean transparent,
 
577
                                                gint border,
 
578
                                                gint border_space,
 
579
                                                gint border_width,
 
580
                                                gint shadow_width,
 
581
                                                const gchar *font_name,
 
582
                                                gint font_height,
 
583
                                                GtkJustification just,
 
584
                                                const gchar *text)
 
585
{
 
586
  GdkBitmap *text_bitmap;
 
587
  GdkPixmap *text_pixmap;
 
588
  GdkBitmap *text_mask;
 
589
  GdkImage *image;
 
590
  GdkGC *gc, *bitmap_gc;
 
591
  GdkColormap *colormap;
 
592
  GdkColor mask_color;
 
593
  GList *family = NULL;
 
594
  gint y0;
 
595
  gint old_width, old_height;
 
596
  gboolean bold, italic;
 
597
  gint fontsize;
 
598
  gint ascent, descent, w;
 
599
  gint numf;
 
600
  gint xp = 0, yp = 0;
 
601
  gint width, height;
 
602
  gint x, y;
 
603
  gint i;
 
604
  GdkFont *font = NULL, *latin_font = NULL;
 
605
  GtkPSFont *psfont, *base_psfont, *latin_psfont;
 
606
  gchar subs[2], insert_char;
 
607
  GdkWChar *aux, *wtext, *lastchar = NULL, *xaux;
 
608
  gchar num[4];
 
609
 
 
610
  if(!GTK_PLOT_GDK(pc)->drawable) return;
 
611
  if(!GTK_PLOT_GDK(pc)->window) return;
 
612
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
613
  if(!text || strlen(text) == 0) return;
 
614
 
 
615
  colormap = gdk_colormap_get_system ();
 
616
  gc = GTK_PLOT_GDK(pc)->gc;
 
617
 
 
618
  if(!gc) return;
 
619
 
 
620
  gtk_plot_text_get_size(text, angle, font_name, font_height, &width, &height, &ascent, &descent);
 
621
 
 
622
  if(height == 0 || width == 0) return;
 
623
 
 
624
  old_width = width;
 
625
  old_height = height;
 
626
  if(angle == 90 || angle == 270)
 
627
    {
 
628
      old_width = height;
 
629
      old_height = width;
 
630
    }
 
631
 
 
632
  gtk_psfont_get_families(&family, &numf);
 
633
  base_psfont = psfont = gtk_psfont_get_by_name(font_name);
 
634
  font = gtk_psfont_get_gdkfont(psfont, font_height);
 
635
  italic = psfont->italic;
 
636
  bold = psfont->bold;
 
637
  fontsize = font_height;
 
638
  x = 0;
 
639
  y0 = y = ascent;
 
640
 
 
641
  if (psfont->i18n_latinfamily) {
 
642
    latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily, italic,
 
643
                                             bold);
 
644
    latin_font = gtk_psfont_get_gdkfont(latin_psfont, fontsize);
 
645
  } else {
 
646
    latin_psfont = NULL; 
 
647
    latin_font = NULL;
 
648
  }
 
649
 
 
650
  i = strlen(text) + 2;
 
651
  aux = wtext = g_malloc0(sizeof(GdkWChar) * i);
 
652
  gdk_mbstowcs(wtext, text, i - 1);
 
653
 
 
654
  /* initializing text bitmap - ajd */
 
655
  text_bitmap = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window,
 
656
                              old_width, old_height, 1);
 
657
  bitmap_gc = gdk_gc_new(text_bitmap);
 
658
  mask_color.pixel = 0;
 
659
  gdk_gc_set_foreground(bitmap_gc, &mask_color);
 
660
  gdk_draw_rectangle(text_bitmap, bitmap_gc, TRUE,
 
661
                     0, 0, -1, -1);
 
662
  mask_color.pixel = 1;
 
663
  gdk_gc_set_foreground(bitmap_gc, &mask_color);
 
664
 
 
665
  while(aux && *aux != '\0' && *aux != '\n'){
 
666
   if(*aux == '\\'){
 
667
     aux++;
 
668
     switch(*aux){
 
669
       case '0': case '1': case '2': case '3':
 
670
       case '4': case '5': case '6': case '7': case '9':
 
671
           psfont = gtk_psfont_get_by_family((gchar *)g_list_nth_data(family, *aux-'0'), italic, bold);
 
672
           gdk_font_unref(font);
 
673
           font = gtk_psfont_get_gdkfont(psfont, fontsize);
 
674
           aux++;
 
675
           break;
 
676
       case '8': case 'g':
 
677
           psfont = gtk_psfont_get_by_family("Symbol", italic, bold);
 
678
           gdk_font_unref(font);
 
679
           font = gtk_psfont_get_gdkfont(psfont, fontsize);
 
680
           aux++;
 
681
           break;
 
682
       case 'B':
 
683
           bold = TRUE;
 
684
           gdk_font_unref(font);
 
685
           psfont = gtk_psfont_get_by_family(psfont->family, italic, bold);
 
686
           font = gtk_psfont_get_gdkfont(psfont, fontsize);
 
687
           if(latin_font){
 
688
             gdk_font_unref(latin_font);
 
689
             latin_font = NULL;
 
690
           }
 
691
           if (psfont->i18n_latinfamily) {
 
692
             latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily,
 
693
                                                      italic, bold);
 
694
             latin_font = gtk_psfont_get_gdkfont(latin_psfont, fontsize);
 
695
           }
 
696
           aux++;
 
697
           break;
 
698
       case 'x':
 
699
           xaux = aux + 1;
 
700
           for (i=0; i<3; i++){
 
701
            if (xaux[i] >= '0' && xaux[i] <= '9')
 
702
              num[i] = xaux[i];
 
703
            else
 
704
              break;
 
705
           }
 
706
           if (i < 3){
 
707
              aux++;
 
708
              break;
 
709
           }
 
710
           num[3] = '\0';
 
711
           insert_char = (gchar)atoi(num);
 
712
           subs[0] = insert_char;
 
713
           subs[1] = '\0';
 
714
           x += gdk_char_width(font, insert_char);
 
715
           aux += 4;
 
716
           lastchar = aux - 1;
 
717
           break;
 
718
       case 'i':
 
719
           italic = TRUE;
 
720
           psfont = gtk_psfont_get_by_family(psfont->family, italic, bold);
 
721
           gdk_font_unref(font);
 
722
           font = gtk_psfont_get_gdkfont(psfont, fontsize);
 
723
           if (latin_font) {
 
724
             gdk_font_unref(latin_font);
 
725
             latin_font = NULL;
 
726
           }
 
727
           if (psfont->i18n_latinfamily) {
 
728
             latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily,
 
729
                                                      italic, bold);
 
730
             latin_font = gtk_psfont_get_gdkfont(latin_psfont, fontsize);
 
731
           }
 
732
           aux++;
 
733
           break;
 
734
       case 'S': case '^':
 
735
           fontsize = (int)((gdouble)fontsize * 0.6 + 0.5);
 
736
           gdk_font_unref(font);
 
737
           font = gtk_psfont_get_gdkfont(psfont, fontsize);
 
738
           y -= font->ascent;
 
739
           if (latin_font) {
 
740
             gdk_font_unref(latin_font);
 
741
             latin_font = NULL;
 
742
           }
 
743
           if (psfont->i18n_latinfamily) {
 
744
             latin_font = gtk_psfont_get_gdkfont(latin_psfont, fontsize);
 
745
           }
 
746
           aux++;
 
747
           break;
 
748
       case 's': case '_':
 
749
           fontsize = (int)((gdouble)fontsize * 0.6 + 0.5);
 
750
           gdk_font_unref(font);
 
751
           font = gtk_psfont_get_gdkfont(psfont, fontsize);
 
752
           y += font->descent;
 
753
           if (latin_font) {
 
754
             gdk_font_unref(latin_font);
 
755
             latin_font = NULL;
 
756
           }
 
757
           if (psfont->i18n_latinfamily) {
 
758
             latin_font = gtk_psfont_get_gdkfont(latin_psfont, fontsize);
 
759
           }
 
760
           aux++;
 
761
           break;
 
762
       case '+':
 
763
           fontsize += 3;
 
764
           gdk_font_unref(font);
 
765
           font = gtk_psfont_get_gdkfont(psfont, fontsize);
 
766
           if (latin_font) {
 
767
             gdk_font_unref(latin_font);
 
768
             latin_font = NULL;
 
769
           }
 
770
           if (psfont->i18n_latinfamily) {
 
771
             latin_font = gtk_psfont_get_gdkfont(latin_psfont, fontsize);
 
772
           }
 
773
           aux++;
 
774
           break;
 
775
       case '-':
 
776
           fontsize -= 3;
 
777
           gdk_font_unref(font);
 
778
           font = gtk_psfont_get_gdkfont(psfont, fontsize);
 
779
           if (latin_font) {
 
780
             gdk_font_unref(latin_font);
 
781
             latin_font = NULL;
 
782
           }
 
783
           if (psfont->i18n_latinfamily) {
 
784
             latin_font = gtk_psfont_get_gdkfont(latin_psfont, fontsize);
 
785
           }
 
786
           aux++;
 
787
           break;
 
788
       case 'N':
 
789
           psfont = base_psfont;
 
790
           gdk_font_unref(font);
 
791
           fontsize = font_height;
 
792
           font = gtk_psfont_get_gdkfont(psfont, fontsize);
 
793
           y = y0;
 
794
           italic = psfont->italic;
 
795
           bold = psfont->bold;
 
796
           aux++;
 
797
           break;
 
798
       case 'b':
 
799
           if (lastchar) {
 
800
             gtk_psfont_get_char_size(psfont, font, latin_font, *lastchar, &w,
 
801
                                      NULL, NULL);
 
802
             x -= w;
 
803
 
 
804
             if (lastchar == wtext)
 
805
               lastchar = NULL;
 
806
             else
 
807
               lastchar--;
 
808
           } else {
 
809
             gtk_psfont_get_char_size(psfont, font, latin_font, 'X', &w, NULL,
 
810
                                    NULL);
 
811
             x -= w;
 
812
           }
 
813
           aux++;
 
814
           break;
 
815
       default:
 
816
           if(aux && *aux != '\0' && *aux !='\n'){
 
817
             x += drawstring(pc, text_bitmap, bitmap_gc, x, y,
 
818
                             psfont, fontsize, *aux);
 
819
             lastchar = aux;
 
820
             aux++;
 
821
           }
 
822
           break;
 
823
     }
 
824
   } else {
 
825
     if(aux && *aux != '\0' && *aux !='\n'){
 
826
       x += drawstring(pc, text_bitmap, bitmap_gc, x, y,
 
827
                       psfont, fontsize, *aux);
 
828
       lastchar = aux;
 
829
       aux++;
 
830
     }
 
831
   }
 
832
  }
 
833
 
 
834
  g_free(wtext);
 
835
 
 
836
  /* initializing clip mask bitmap - ajd */
 
837
  text_mask = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, width, height, 1);
 
838
  mask_color.pixel = 0;
 
839
  gdk_gc_set_foreground(bitmap_gc, &mask_color);
 
840
  gdk_draw_rectangle(text_mask, bitmap_gc, TRUE, 0, 0, -1, -1);
 
841
  mask_color.pixel = 1;
 
842
  gdk_gc_set_foreground(bitmap_gc, &mask_color);
 
843
 
 
844
  /* performing text rotation and saving it onto clip mask bitmap - ajd */
 
845
  image = gdk_image_get(text_bitmap, 0, 0, old_width, old_height);
 
846
  for(y = 0; y < old_height; y++)
 
847
      for(x = 0; x < old_width; x++)
 
848
         {
 
849
           if( gdk_image_get_pixel(image, x, y) == 1 ){
 
850
           switch(angle){
 
851
            case 0:
 
852
                xp = x;
 
853
                yp = y;
 
854
                break;
 
855
            case 90:
 
856
                xp = y;
 
857
                yp = old_width - x;
 
858
                break;
 
859
            case 180:
 
860
                xp = old_width - x;
 
861
                yp = old_height - y;
 
862
                break;
 
863
            case 270:
 
864
                xp = old_height - y;
 
865
                yp = x;
 
866
                break;
 
867
            }
 
868
            gdk_draw_point(text_mask, bitmap_gc, xp, yp);
 
869
           }
 
870
         }
 
871
  gdk_image_destroy(image);
 
872
 
 
873
 
 
874
  /* initializing text pixmap - ajd */
 
875
  text_pixmap = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, width, height, -1);
 
876
  gdk_gc_set_foreground(gc, (GdkColor *) bg);
 
877
  gdk_draw_rectangle(text_pixmap, gc, TRUE, 0, 0, -1, -1);
 
878
  gdk_gc_set_foreground(gc, (GdkColor *) fg);
 
879
 
 
880
  /* copying clip mask bitmap onto text pixmap - ajd */
 
881
  gdk_gc_set_clip_mask(gc, text_mask);
 
882
  gdk_gc_set_clip_origin(gc, 0, 0);
 
883
  gdk_draw_rectangle(text_pixmap, gc, TRUE, 0, 0, -1, -1);
 
884
  gdk_gc_set_clip_mask(gc, NULL);
 
885
 
 
886
  gtk_plot_text_get_area(text, angle, just, font_name, font_height,
 
887
                         &x, &y, &width, &height);
 
888
  tx += x;
 
889
  ty += y;
 
890
 
 
891
  if(transparent){
 
892
    gdk_gc_set_clip_mask (gc, text_mask);
 
893
    gdk_gc_set_clip_origin (gc, tx, ty);
 
894
  } else {
 
895
    gdk_gc_set_foreground(gc, (GdkColor *) bg);
 
896
    gtk_plot_pc_draw_rectangle(pc,
 
897
                         TRUE, 
 
898
                         tx - border_space, ty - border_space, 
 
899
                         width + 2*border_space, height + 2*border_space);
 
900
  }
 
901
 
 
902
  gdk_draw_pixmap(GTK_PLOT_GDK(pc)->drawable, gc,
 
903
                  text_pixmap, 0, 0,
 
904
                  tx, ty, -1, -1);
 
905
  gdk_gc_set_clip_mask(gc, NULL);
 
906
 
 
907
  gdk_pixmap_unref(text_pixmap);
 
908
  gdk_bitmap_unref(text_mask);
 
909
  gdk_font_unref(font);
 
910
  if(latin_font)
 
911
    gdk_font_unref(latin_font);
 
912
  gdk_gc_unref(bitmap_gc);
 
913
  gdk_pixmap_unref(text_bitmap);
 
914
 
 
915
 
 
916
/* border */
 
917
 
 
918
  gdk_gc_set_foreground(gc, (GdkColor *) fg);
 
919
  gtk_plot_pc_set_dash(pc, 0, NULL, 0);
 
920
  gtk_plot_pc_set_lineattr(pc, border_width, 0, 0, 0);
 
921
  switch(border){
 
922
    case GTK_PLOT_BORDER_SHADOW: 
 
923
      gtk_plot_pc_draw_rectangle(pc,
 
924
                         TRUE, 
 
925
                         tx - border_space + shadow_width, 
 
926
                         ty + height + border_space, 
 
927
                         width + 2 * border_space, shadow_width);
 
928
      gtk_plot_pc_draw_rectangle(pc,
 
929
                         TRUE, 
 
930
                         tx + width + border_space, 
 
931
                         ty - border_space + shadow_width, 
 
932
                         shadow_width, height + 2 * border_space);
 
933
    case GTK_PLOT_BORDER_LINE: 
 
934
      gtk_plot_pc_draw_rectangle(pc,
 
935
                         FALSE, 
 
936
                         tx - border_space, ty - border_space, 
 
937
                         width + 2*border_space, height + 2*border_space);
 
938
    case GTK_PLOT_BORDER_NONE: 
 
939
    default:
 
940
        break; 
 
941
  }
 
942
 
 
943
  return;
 
944
}
 
945
 
 
946
static void gtk_plot_gdk_draw_pixmap                (GtkPlotPC *pc,
 
947
                                                     GdkPixmap *pixmap,
 
948
                                                     GdkBitmap *mask,
 
949
                                                     gint xsrc, gint ysrc,
 
950
                                                     gint xdest, gint ydest,
 
951
                                                     gint width,
 
952
                                                     gint height,
 
953
                                                     gdouble scale_x, 
 
954
                                                     gdouble scale_y)
 
955
{
 
956
  GdkGC *gc;
 
957
  GdkPixmap *new_pixmap;
 
958
  GdkBitmap *new_mask = NULL;
 
959
 
 
960
  if(!GTK_PLOT_GDK(pc)->drawable) return;
 
961
  if(!GTK_PLOT_GDK(pc)->window) return;
 
962
  if(!GTK_PLOT_GDK(pc)->gc) return;
 
963
 
 
964
  gc = GTK_PLOT_GDK(pc)->gc;
 
965
 
 
966
  if(!gc) return;
 
967
 
 
968
  new_pixmap = scale_pixmap(GTK_PLOT_GDK(pc)->window, pixmap, scale_x, scale_y);
 
969
  
 
970
  if(mask)
 
971
     new_mask = scale_bitmap(GTK_PLOT_GDK(pc)->window, mask, scale_x, scale_y);
 
972
 
 
973
  gtk_plot_pc_clip_mask(pc, xdest, ydest, new_mask);
 
974
  gdk_draw_pixmap(GTK_PLOT_GDK(pc)->drawable, gc, new_pixmap,
 
975
                  xsrc, ysrc, xdest, ydest, width*scale_x, height*scale_y);
 
976
  gtk_plot_pc_clip_mask(pc, xdest, ydest, NULL);
 
977
 
 
978
  if(new_mask) gdk_bitmap_unref(new_mask);
 
979
  gdk_pixmap_unref(new_pixmap);
 
980
}
 
981
 
 
982
static GdkPixmap *
 
983
scale_pixmap (GdkWindow *window, GdkPixmap *pixmap, gdouble scale_x, gdouble scale_y)
 
984
{
 
985
  GdkGC *gc;
 
986
  GdkVisual *visual;
 
987
  GdkImage *image, *new_image;
 
988
  GdkPixmap *new_pixmap;
 
989
  gint x, y, width, height, new_width, new_height;
 
990
  guint32 pixel;
 
991
 
 
992
  if(!pixmap) return NULL;
 
993
  if(!window) return NULL;
 
994
 
 
995
  gc = gdk_gc_new(pixmap);
 
996
  visual = gdk_visual_get_system ();
 
997
 
 
998
  gdk_window_get_size(pixmap, &width, &height);
 
999
 
 
1000
  if(scale_x == 1.0 && scale_y == 1.0){
 
1001
    new_pixmap = gdk_pixmap_new(window, width, height, -1);
 
1002
    gdk_draw_pixmap(new_pixmap,
 
1003
                    gc,
 
1004
                    pixmap,
 
1005
                    0, 0,
 
1006
                    0, 0,
 
1007
                    width, height);
 
1008
    return new_pixmap;
 
1009
  }
 
1010
 
 
1011
  new_width = roundint(width * scale_x);
 
1012
  new_height = roundint(height * scale_y);
 
1013
 
 
1014
  /* make a client side image of the pixmap, and
 
1015
   * scale the data into a another client side image */
 
1016
  new_image = gdk_image_new(GDK_IMAGE_FASTEST,visual,new_width,new_height);
 
1017
  image = gdk_drawable_get_image(pixmap,
 
1018
                        0, 0,
 
1019
                        width, height);
 
1020
 
 
1021
  for(x = 0; x < new_width; x++){
 
1022
    for(y = 0; y < new_height; y++){
 
1023
      gint px, py;
 
1024
 
 
1025
      px = MIN(roundint(x / scale_x), width - 1);
 
1026
      py = MIN(roundint(y / scale_y), height - 1);
 
1027
 
 
1028
      pixel = gdk_image_get_pixel(image, px, py);
 
1029
      gdk_image_put_pixel(new_image, x, y, pixel);
 
1030
    }
 
1031
  }
 
1032
 
 
1033
  /* draw the image into a new pixmap */
 
1034
  new_pixmap = gdk_pixmap_new(window, new_width, new_height, -1);
 
1035
  gdk_draw_image(new_pixmap,gc,new_image,0,0,0,0,new_width,new_height);
 
1036
 
 
1037
  gdk_image_destroy(image);
 
1038
  gdk_image_destroy(new_image);
 
1039
 
 
1040
  return new_pixmap;
 
1041
}
 
1042
 
 
1043
static GdkBitmap *
 
1044
scale_bitmap (GdkWindow *window, GdkBitmap *bitmap, gdouble scale_x, gdouble scale_y)
 
1045
{
 
1046
  GdkGC *gc;
 
1047
  GdkVisual *visual;
 
1048
  GdkImage *image, *new_image;
 
1049
  GdkBitmap *new_bitmap;
 
1050
  gint x, y, width, height, new_width, new_height;
 
1051
  GdkColor color;
 
1052
 
 
1053
  if(!bitmap) return NULL;
 
1054
  if(!window) return NULL;
 
1055
 
 
1056
  gc = gdk_gc_new(bitmap);
 
1057
  visual = gdk_visual_get_system ();
 
1058
 
 
1059
  gdk_window_get_size(bitmap, &width, &height);
 
1060
 
 
1061
  if(scale_x == 1.0 && scale_y == 1.0){
 
1062
    new_bitmap = gdk_pixmap_new(window, width, height, 1);
 
1063
    color.pixel = 0;
 
1064
    gdk_gc_set_foreground(gc, &color);
 
1065
    gdk_draw_rectangle(new_bitmap, gc, TRUE, 0, 0, width, height); 
 
1066
    color.pixel = 1;
 
1067
    gdk_gc_set_foreground(gc, &color);
 
1068
 
 
1069
    gdk_draw_pixmap(new_bitmap,
 
1070
                    gc,
 
1071
                    bitmap,
 
1072
                    0, 0,
 
1073
                    0, 0,
 
1074
                    width, height);
 
1075
    return new_bitmap;
 
1076
  }
 
1077
 
 
1078
  new_width = roundint(width * scale_x);
 
1079
  new_height = roundint(height * scale_y);
 
1080
 
 
1081
  /* make a client side image of the bitmap, and
 
1082
   * scale the data into a another client side image */
 
1083
  image = gdk_drawable_get_image(bitmap,
 
1084
                        0, 0,
 
1085
                        width, height);
 
1086
 
 
1087
  new_image = gdk_image_new(GDK_IMAGE_FASTEST,visual,new_width,new_height);
 
1088
  new_bitmap = gdk_pixmap_new(window, new_width, new_height, 1);
 
1089
 
 
1090
  color.pixel = 0;
 
1091
  gdk_gc_set_foreground(gc, &color);
 
1092
  gdk_draw_rectangle(new_bitmap, gc, TRUE, 0, 0, width, height); 
 
1093
  color.pixel = 1;
 
1094
  gdk_gc_set_foreground(gc, &color);
 
1095
 
 
1096
  for(x = 0; x < new_width; x++){
 
1097
    for(y = 0; y < new_height; y++){
 
1098
      gint px, py;
 
1099
      gulong pixel;
 
1100
 
 
1101
      px = MIN(roundint(x / scale_x), width - 1);
 
1102
      py = MIN(roundint(y / scale_y), height - 1);
 
1103
 
 
1104
      pixel = gdk_image_get_pixel(image, px, py);
 
1105
      gdk_image_put_pixel(new_image, x, y, pixel);
 
1106
 
 
1107
    }
 
1108
  }
 
1109
 
 
1110
  /* draw the image into a new pixmap */
 
1111
  gdk_draw_image(new_bitmap,gc,new_image,0,0,0,0,new_width,new_height);
 
1112
 
 
1113
  gdk_image_destroy(image);
 
1114
  gdk_image_destroy(new_image);
 
1115
 
 
1116
  return new_bitmap;
 
1117
}
 
1118
static gint
 
1119
roundint(gdouble x)
 
1120
{
 
1121
 return (x+.50999999471);
 
1122
}