ROOT  6.05/03
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
gdkgc-win32.c
Go to the documentation of this file.
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 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  * Modified by the GTK+ Team and others 1997-1999. 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 "config.h"
28 
29 #include <string.h>
30 
31 #include "gdkgc.h"
32 #include "gdkfont.h"
33 #include "gdkpixmap.h"
34 #include "gdkprivate.h"
35 #include "gdkwin32.h"
36 
37 static UINT text_align = TA_BASELINE;
38 
39 static void gdk_win32_gc_destroy(GdkGC * gc);
40 static void gdk_win32_gc_get_values(GdkGC * gc, GdkGCValues * values);
41 static void gdk_win32_gc_set_values(GdkGC * gc,
42  GdkGCValues * values,
43  GdkGCValuesMask values_mask);
44 static void gdk_win32_gc_set_dashes(GdkGC * gc,
45  gint dash_offset,
46  gchar dash_list[], gint n);
47 
48 static GdkGCClass gdk_win32_gc_class = {
53 };
54 
56 {
57 
58 // GdkGCWin32Data *data = GDK_GC_WIN32DATA ((GdkGCPrivate *)gc);
59 
60  guint old_val = text_align;
61  switch (tAlign) {
62  case 7:
63  text_align = TA_LEFT | TA_BOTTOM;
64  break;
65  case 4:
66  text_align = TA_LEFT | TA_BASELINE;
67  break;
68  case 1:
69  text_align = TA_LEFT | TA_TOP;
70  break;
71  case 8:
72  text_align = TA_CENTER | TA_BOTTOM;
73  break;
74  case 5:
75  text_align = TA_CENTER | TA_BASELINE;
76  break;
77  case 2:
78  text_align = TA_CENTER | TA_TOP;
79  break;
80  case 9:
81  text_align = TA_RIGHT | TA_BOTTOM;
82  break;
83  case 6:
84  text_align = TA_RIGHT | TA_BASELINE;
85  break;
86  case 3:
87  text_align = TA_RIGHT | TA_TOP;
88  break;
89  case 0:
90  text_align = TA_BASELINE;
91  break;
92  }
93 // if (SetTextAlign (data->xgc, text_align) == GDI_ERROR)
94 // WIN32_GDI_FAILED ("SetTextAlign");
95  return (old_val);
96 }
97 
98 static void
100  GdkGCValuesMask mask,
102 {
103  char *s = "";
104  gint sw, sh;
105 
106  GDK_NOTE(MISC, g_print("{"));
107 
108  if (mask & GDK_GC_FOREGROUND) {
109  data->foreground = values->foreground.pixel;
111  GDK_NOTE(MISC, (g_print("fg=%.06x", data->foreground), s = ","));
112  }
113 
114  if (mask & GDK_GC_BACKGROUND) {
115  data->background = values->background.pixel;
117  GDK_NOTE(MISC, (g_print("%sbg=%.06x", s, data->background),
118  s = ","));
119  }
120 
121  if ((mask & GDK_GC_FONT) && (values->font->type == GDK_FONT_FONT
122  || values->font->type == GDK_FONT_FONTSET))
123  {
124  if (data->font != NULL)
125  gdk_font_unref(data->font);
126  data->font = values->font;
127  if (data->font != NULL) {
128  gchar *xlfd;
129 
130  gdk_font_ref(data->font);
131  data->values_mask |= GDK_GC_FONT;
132  GDK_NOTE(MISC, (xlfd = gdk_font_full_name_get(data->font),
133  g_print("%sfont=%s", s, xlfd),
134  s = ",", gdk_font_full_name_free(xlfd)));
135  } else {
136  data->values_mask &= ~GDK_GC_FONT;
137  GDK_NOTE(MISC, (g_print("%sfont=NULL"), s = ","));
138  }
139  }
140 
141  if (mask & GDK_GC_FUNCTION) {
142  GDK_NOTE(MISC,
143  (g_print("%srop2=%s ",
144  s,
145  gdk_win32_function_to_string(values->function)),
146  s = ","));
147  switch (values->function) {
148  case GDK_COPY:
149  data->rop2 = R2_COPYPEN;
150  GDK_NOTE(MISC, g_print("(COPYPEN)"));
151  break;
152  case GDK_INVERT:
153  data->rop2 = R2_NOT;
154  GDK_NOTE(MISC, g_print("(NOT)"));
155  break;
156  case GDK_XOR:
157  data->rop2 = R2_XORPEN;
158  GDK_NOTE(MISC, g_print("(XORPEN)"));
159  break;
160  case GDK_CLEAR:
161  data->rop2 = R2_BLACK;
162  GDK_NOTE(MISC, g_print("(BLACK)"));
163  break;
164  case GDK_AND:
165  data->rop2 = R2_MASKPEN;
166  GDK_NOTE(MISC, g_print("(MASKPEN)"));
167  break;
168  case GDK_AND_REVERSE:
169  data->rop2 = R2_MASKPENNOT;
170  GDK_NOTE(MISC, g_print("(MASKPENNOT)"));
171  break;
172  case GDK_AND_INVERT:
173  data->rop2 = R2_MASKNOTPEN;
174  GDK_NOTE(MISC, g_print("(MASKNOTPEN)"));
175  break;
176  case GDK_NOOP:
177  data->rop2 = R2_NOP;
178  GDK_NOTE(MISC, g_print("(NOP)"));
179  break;
180  case GDK_OR:
181  data->rop2 = R2_MERGEPEN;
182  GDK_NOTE(MISC, g_print("(MERGEPEN)"));
183  break;
184  case GDK_EQUIV:
185  data->rop2 = R2_NOTXORPEN;
186  GDK_NOTE(MISC, g_print("(NOTXORPEN)"));
187  break;
188  case GDK_OR_REVERSE:
189  data->rop2 = R2_MERGEPENNOT;
190  GDK_NOTE(MISC, g_print("(MERGEPENNOT)"));
191  break;
192  case GDK_COPY_INVERT:
193  data->rop2 = R2_NOTCOPYPEN;
194  GDK_NOTE(MISC, g_print("(NOTCOPYPEN)"));
195  break;
196  case GDK_OR_INVERT:
197  data->rop2 = R2_MERGENOTPEN;
198  GDK_NOTE(MISC, g_print("(MERGENOTPEN)"));
199  break;
200  case GDK_NAND:
201  data->rop2 = R2_NOTMASKPEN;
202  GDK_NOTE(MISC, g_print("(NOTMASKPEN)"));
203  break;
204  case GDK_SET:
205  data->rop2 = R2_WHITE;
206  GDK_NOTE(MISC, g_print("(WHITE)"));
207  break;
208  }
209  GDK_NOTE(MISC, g_print(" "));
210  data->values_mask |= GDK_GC_FUNCTION;
211  }
212 
213  if (mask & GDK_GC_FILL) {
214  data->fill_style = values->fill;
215  data->values_mask |= GDK_GC_FILL;
216  GDK_NOTE(MISC,
217  (g_print("%sfill=%s",
218  s,
219  gdk_win32_fill_style_to_string(data->fill_style)),
220  s = ","));
221  }
222 
223  if (mask & GDK_GC_TILE) {
224  if (data->tile != NULL)
225  gdk_drawable_unref(data->tile);
226  data->tile = values->tile;
227  if (data->tile != NULL) {
228  gdk_drawable_ref(data->tile);
229  data->values_mask |= GDK_GC_TILE;
230  GDK_NOTE(MISC, (g_print("%stile=%#x", s,
231  GDK_DRAWABLE_XID(data->tile)), s = ","));
232  } else {
233  data->values_mask &= ~GDK_GC_TILE;
234  GDK_NOTE(MISC, (g_print("%stile=NULL", s), s = ","));
235  }
236  }
237 
238  if (mask & GDK_GC_STIPPLE) {
239  if (data->stipple != NULL)
241  data->stipple = values->stipple;
242  if (data->stipple != NULL) {
243  gdk_drawable_get_size(data->stipple, &sw, &sh);
244 #if 0 // not valid anymore, it was not possible to create brushes (stipples)
245  // larger than 8x8 on Windows 95...
246  if (sw != 8 || sh != 8) {
247  /* It seems that it *must* be 8x8, at least on my machine.
248  * Thus, tile an 8x8 bitmap with the stipple in case it is
249  * smaller, or simply use just the top left 8x8 in case it is
250  * larger.
251  */
252  gchar dummy[8];
253  GdkPixmap *bm = gdk_bitmap_create_from_data(NULL, dummy, 8, 8);
254  GdkGC *gc = gdk_gc_new(bm);
255  gint i, j;
256 
257  i = 0;
258  while (i < 8) {
259  j = 0;
260  while (j < 8) {
261  gdk_draw_drawable(bm, gc, data->stipple, 0, 0, i, j, sw,
262  sh);
263  j += sh;
264  }
265  i += sw;
266  }
267  data->stipple = bm;
268  gdk_gc_unref(gc);
269  } else
270 #endif
271  gdk_drawable_ref(data->stipple);
272  data->values_mask |= GDK_GC_STIPPLE;
273  GDK_NOTE(MISC, (g_print("%sstipple=%#x", s,
274  GDK_DRAWABLE_XID(data->stipple)),
275  s = ","));
276  } else {
277  data->values_mask &= ~GDK_GC_STIPPLE;
278  GDK_NOTE(MISC, (g_print("%sstipple=NULL", s), s = ","));
279  }
280  }
281 
282  if (mask & GDK_GC_CLIP_MASK) {
283  if (data->clip_region != NULL)
284  if (!DeleteObject(data->clip_region))
285  WIN32_GDI_FAILED("DeleteObject");
286  if (values->clip_mask != NULL) {
287  data->clip_region =
288  BitmapToRegion((HBITMAP) GDK_DRAWABLE_XID(values->clip_mask));
289  data->values_mask |= GDK_GC_CLIP_MASK;
290  } else {
291  data->clip_region = NULL;
292  data->values_mask &= ~GDK_GC_CLIP_MASK;
293  }
294  GDK_NOTE(MISC, (g_print("%sclip=%#x", s, data->clip_region),
295  s = ","));
296  }
297 
298  if (mask & GDK_GC_SUBWINDOW) {
299  data->subwindow_mode = values->subwindow_mode;
300  data->values_mask |= GDK_GC_SUBWINDOW;
301  GDK_NOTE(MISC, (g_print("%ssubw=%d", s, data->subwindow_mode),
302  s = ","));
303  }
304 
305  if (mask & GDK_GC_TS_X_ORIGIN) {
306  data->ts_x_origin = values->ts_x_origin;
308  GDK_NOTE(MISC, (g_print("%sts_x=%d", s, data->ts_x_origin),
309  s = ","));
310  }
311 
312  if (mask & GDK_GC_TS_Y_ORIGIN) {
313  data->ts_y_origin = values->ts_y_origin;
315  GDK_NOTE(MISC, (g_print("%sts_y=%d", s, data->ts_y_origin),
316  s = ","));
317  }
318 
319  if (mask & GDK_GC_CLIP_X_ORIGIN) {
320  data->clip_x_origin = values->clip_x_origin;
322  GDK_NOTE(MISC, (g_print("%sclip_x=%d", s, data->clip_x_origin),
323  s = ","));
324  }
325 
326  if (mask & GDK_GC_CLIP_Y_ORIGIN) {
327  data->clip_y_origin = values->clip_y_origin;
329  GDK_NOTE(MISC, (g_print("%sclip_y=%d", s, data->clip_y_origin),
330  s = ","));
331  }
332 
333  if (mask & GDK_GC_EXPOSURES) {
334  data->graphics_exposures = values->graphics_exposures;
335  data->values_mask |= GDK_GC_EXPOSURES;
336  GDK_NOTE(MISC, (g_print("%sexp=%d", s, data->graphics_exposures),
337  s = ","));
338  }
339 
340  if (mask & GDK_GC_LINE_WIDTH) {
341  data->pen_width = values->line_width;
343  GDK_NOTE(MISC, (g_print("%spw=%d", s, data->pen_width), s = ","));
344  }
345 
346  if (mask & GDK_GC_LINE_STYLE) {
347  data->pen_style &= ~(PS_STYLE_MASK);
348  GDK_NOTE(MISC, (g_print("%sps|=", s), s = ","));
349  switch (values->line_style) {
350  case GDK_LINE_SOLID:
351  GDK_NOTE(MISC, g_print("LINE_SOLID"));
352  data->pen_style |= PS_SOLID;
353  break;
355  case GDK_LINE_DOUBLE_DASH: /* ??? */
356  GDK_NOTE(MISC, g_print("DASH"));
357  data->pen_style |= PS_DASH;
358  break;
359  }
361  }
362 
363  if (mask & GDK_GC_CAP_STYLE) {
364  data->pen_style &= ~(PS_ENDCAP_MASK);
365  GDK_NOTE(MISC, (g_print("%sps|=", s), s = ","));
366  switch (values->cap_style) {
367  case GDK_CAP_NOT_LAST: /* ??? */
368  case GDK_CAP_BUTT:
369  GDK_NOTE(MISC, g_print("ENDCAP_FLAT"));
370  data->pen_style |= PS_ENDCAP_FLAT;
371  break;
372  case GDK_CAP_ROUND:
373  GDK_NOTE(MISC, g_print("ENDCAP_ROUND"));
374  data->pen_style |= PS_ENDCAP_ROUND;
375  break;
376  case GDK_CAP_PROJECTING:
377  GDK_NOTE(MISC, g_print("ENDCAP_SQUARE"));
378  data->pen_style |= PS_ENDCAP_SQUARE;
379  break;
380  }
381  data->values_mask |= GDK_GC_CAP_STYLE;
382  }
383 
384  if (mask & GDK_GC_JOIN_STYLE) {
385  data->pen_style &= ~(PS_JOIN_MASK);
386  GDK_NOTE(MISC, (g_print("%sps|=", s), s = ","));
387  switch (values->join_style) {
388  case GDK_JOIN_MITER:
389  GDK_NOTE(MISC, g_print("JOIN_MITER"));
390  data->pen_style |= PS_JOIN_MITER;
391  break;
392  case GDK_JOIN_ROUND:
393  GDK_NOTE(MISC, g_print("JOIN_ROUND"));
394  data->pen_style |= PS_JOIN_ROUND;
395  break;
396  case GDK_JOIN_BEVEL:
397  GDK_NOTE(MISC, g_print("JOIN_BEVEL"));
398  data->pen_style |= PS_JOIN_BEVEL;
399  break;
400  }
402  }
403  GDK_NOTE(MISC, g_print("}\n"));
404 }
405 
407  GdkGCValues * values, GdkGCValuesMask mask)
408 {
409  GdkGC *gc;
410  GdkGCPrivate *private;
412 #if 0
413  static GdkColor black;
414  static GdkColor white;
415  static gboolean beenhere = FALSE;
416 
417  if (!beenhere) {
420  beenhere = TRUE;
421  }
422 #endif
423  gc = gdk_gc_alloc();
424  private = (GdkGCPrivate *) gc;
425 
426  private->klass = &gdk_win32_gc_class;
427  private->klass_data = data = g_new(GdkGCWin32Data, 1);
428 
429 #if 0
430  data->foreground = black.pixel;
431  data->background = white.pixel;
432 #else
433  data->foreground = 0;
434  data->background = 1;
435 #endif
436  data->font = NULL;
437  data->rop2 = R2_COPYPEN;
438  data->fill_style = GDK_SOLID;
439  data->tile = NULL;
440  data->stipple = NULL;
441  data->clip_region = NULL;
442  data->ts_x_origin = data->ts_y_origin =
443  data->clip_x_origin = data->clip_y_origin = 0;
444  data->pen_style = PS_GEOMETRIC | PS_ENDCAP_FLAT | PS_JOIN_MITER;
445  data->pen_width = 0;
446 
448 
449  GDK_NOTE(MISC, g_print("_gdk_win32_gc_new: "));
450  gdk_win32_gc_values_to_win32values(values, mask, data);
451 
452  data->hwnd = NULL;
453  data->xgc = NULL;
454 
455  GDK_NOTE(MISC, g_print(" = %p\n", gc));
456 
457  return gc;
458 }
459 
460 static void gdk_win32_gc_destroy(GdkGC * gc)
461 {
463 
464  if (data->values_mask & GDK_GC_FONT)
465  gdk_font_unref(data->font);
466 
467  if (data->values_mask & GDK_GC_TILE)
468  gdk_drawable_unref(data->tile);
469 
470  if (data->values_mask & GDK_GC_STIPPLE)
472 
473  if (data->values_mask & GDK_GC_CLIP_MASK)
474  DeleteObject(data->clip_region);
475 
477 }
478 
479 static void gdk_win32_gc_get_values(GdkGC * gc, GdkGCValues * values)
480 {
482 
483  values->foreground.pixel = data->foreground;
484  values->background.pixel = data->background;
485  values->font = data->font;
486 
487  switch (data->rop2) {
488  case R2_COPYPEN:
489  values->function = GDK_COPY;
490  break;
491  case R2_NOT:
492  values->function = GDK_INVERT;
493  break;
494  case R2_XORPEN:
495  values->function = GDK_XOR;
496  break;
497  case R2_BLACK:
498  values->function = GDK_CLEAR;
499  break;
500  case R2_MASKPEN:
501  values->function = GDK_AND;
502  break;
503  case R2_MASKPENNOT:
504  values->function = GDK_AND_REVERSE;
505  break;
506  case R2_MASKNOTPEN:
507  values->function = GDK_AND_INVERT;
508  break;
509  case R2_NOP:
510  values->function = GDK_NOOP;
511  break;
512  case R2_MERGEPEN:
513  values->function = GDK_OR;
514  break;
515  case R2_NOTXORPEN:
516  values->function = GDK_EQUIV;
517  break;
518  case R2_MERGEPENNOT:
519  values->function = GDK_OR_REVERSE;
520  break;
521  case R2_NOTCOPYPEN:
522  values->function = GDK_COPY_INVERT;
523  break;
524  case R2_MERGENOTPEN:
525  values->function = GDK_OR_INVERT;
526  break;
527  case R2_NOTMASKPEN:
528  values->function = GDK_NAND;
529  break;
530  case R2_WHITE:
531  values->function = GDK_SET;
532  break;
533  }
534 
535  values->fill = data->fill_style;
536 
537  values->tile = data->tile;
538  values->stipple = data->stipple;
539 
540  values->clip_mask = NULL;
541 #if 0 // bb mod 15.02.06
542  if (data->clip_region != NULL) {
543  RECT rect;
544  HBRUSH hbr;
545  HDC hdc;
546  HGDIOBJ oldbitmap;
547  GdkPixmap *pixmap;
548  gboolean ok = TRUE;
549 
550  /* Build pixmap for clip region; if anything fails, do so w/o invoking */
551  /* more code on failed objects, just in case this is the cause of one */
552  /* of the rare crashes we're seeing */
553  GetRgnBox (data->clip_region, &rect);
554  pixmap = gdk_pixmap_new (NULL, rect.right - rect.left, rect.bottom - rect.top,1);
555  hbr = GetStockObject (WHITE_BRUSH);
556  if ((hdc = CreateCompatibleDC (NULL)) == NULL)
557  WIN32_GDI_FAILED ("CreateCompatibleDC"), ok = FALSE;
558  if (ok && (oldbitmap =
559  SelectObject (hdc, GDK_DRAWABLE_XID (pixmap))) == NULL)
560  WIN32_GDI_FAILED ("SelectObject"), ok = FALSE;
561  if (ok) {
562  hbr = GetStockObject (BLACK_BRUSH);
563  if (hbr == NULL || !FillRect (hdc, &rect, hbr))
564  WIN32_GDI_FAILED ("FillRect"), ok = FALSE;
565  }
566  if (ok) {
567  hbr = GetStockObject (WHITE_BRUSH);
568  if (hbr == NULL || !FillRgn (hdc, data->clip_region, hbr))
569  WIN32_GDI_FAILED ("FillRgn"), ok = FALSE;
570  }
571  if (hdc != NULL && oldbitmap != NULL) {
572  if (SelectObject (hdc, oldbitmap) == NULL)
573  WIN32_GDI_FAILED ("SelectObject"), ok = FALSE;
574  }
575  if (hdc != NULL)
576  DeleteDC (hdc);
577  if (ok)
578  values->clip_mask = pixmap;
579  else if (pixmap != NULL)
580  gdk_drawable_unref(pixmap);
581  }
582 #endif // bb mod 15.02.06
583 
584  values->subwindow_mode = data->subwindow_mode;
585  values->ts_x_origin = data->ts_x_origin;
586  values->ts_y_origin = data->ts_y_origin;
587  values->clip_x_origin = data->clip_x_origin;
588  values->clip_y_origin = data->clip_y_origin;
589  values->graphics_exposures = data->graphics_exposures;
590  values->line_width = data->pen_width;
591 
592  if (data->pen_style & PS_SOLID)
593  values->line_style = GDK_LINE_SOLID;
594  else if (data->pen_style & PS_DASH)
596  else
597  values->line_style = GDK_LINE_SOLID;
598 
599  /* PS_ENDCAP_ROUND is zero */
600  if (data->pen_style & PS_ENDCAP_FLAT)
601  values->cap_style = GDK_CAP_BUTT;
602  else if (data->pen_style & PS_ENDCAP_SQUARE)
603  values->cap_style = GDK_CAP_PROJECTING;
604  else
605  values->cap_style = GDK_CAP_ROUND;
606 
607  /* PS_JOIN_ROUND is zero */
608  if (data->pen_style & PS_JOIN_MITER)
609  values->join_style = GDK_JOIN_MITER;
610  else if (data->pen_style & PS_JOIN_BEVEL)
611  values->join_style = GDK_JOIN_BEVEL;
612  else
613  values->join_style = GDK_JOIN_ROUND;
614 }
615 
616 static void
618  GdkGCValues * values, GdkGCValuesMask mask)
619 {
621 
622  GDK_NOTE(MISC, g_print("gdk_win32_gc_set_values: "));
623 
624  gdk_win32_gc_values_to_win32values(values, mask, data);
625 }
626 
627 static void
629  gint dash_offset, gchar dash_list[], gint n)
630 {
631  int i;
633 
634  data->pen_style &= ~(PS_STYLE_MASK);
635 // data->pen_style |= PS_DASH; // bb removed 28.01.2003
636 
637  /*
638  * Set the extended line style. This could be done by
639  * PS_USERSTYLE and ExtCreatePen; but ONLY on WinNT,
640  * so let's make a guess (based on the implementation
641  * in DIA). On Win9x this does only work for lines
642  * with width one ...
643  *
644  * More workarounds for Win9x descibed at:
645  * http://www.codeguru.com/gdi/dashed.shtml
646  */
647  if (!IS_WIN_NT(windows_version) && data->pen_width > 1) {
648  GDK_NOTE(MISC,
649  g_print("gdk_win32_gc_set_dashes: not fully supported\n"));
650  data->pen_style |= PS_SOLID;
651  return;
652  }
653  // bb changes 29.01.2003
654  if (!IS_WIN_NT(windows_version)) {
655  /* data->pen_style = PS_COSMETIC; ??? */
656  if (2 == n) {
657  if ((dash_list[0] == dash_list[1]) && (dash_list[0] > 2)) {
658  data->pen_style |= PS_DASH;
659  GDK_NOTE(MISC,
660  g_print("gdk_win32_gc_set_dashes: PS_DASH (%d,%d)\n",
661  dash_list[0], dash_list[1]));
662  } else {
663  data->pen_style |= PS_DOT;
664  GDK_NOTE(MISC,
665  g_print("gdk_win32_gc_set_dashes: PS_DOT (%d,%d)\n",
666  dash_list[0], dash_list[1]));
667  }
668  } else if (4 == n) {
669  data->pen_style |= PS_DASHDOT;
670  GDK_NOTE(MISC,
671  g_print
672  ("gdk_win32_gc_set_dashes: PS_DASHDOT (%d,%d,%d,%d)\n",
673  dash_list[0], dash_list[1], dash_list[2],
674  dash_list[3]));
675  } else if (6 == n) {
676  data->pen_style |= PS_DASHDOTDOT;
677  GDK_NOTE(MISC,
678  g_print
679  ("gdk_win32_gc_set_dashes: PS_DASHDOTDOT (%d,%d,%d,%d,%d,%d)\n",
680  dash_list[0], dash_list[1], dash_list[2], dash_list[3],
681  dash_list[4], dash_list[5]));
682  } else {
683  data->pen_style |= PS_DASH;
684  GDK_NOTE(MISC,
685  g_print
686  ("gdk_win32_gc_set_dashes: no guess for %d dashes\n",
687  n));
688  }
689  } else {
690 
691 // vo add
692  if (IS_WIN_NT(windows_version)) {
693  if ((data->pen_width <= 1) && (n == 0)) {
694  data->pen_style = PS_COSMETIC;
695  data->luser_dash = 0;
696  data->pen_width = 1;
697  return;
698  }
699  }
700 
701  data->pen_style |= PS_USERSTYLE;
702  data->luser_dash = n; // not for Windows 95
703  for (i = 0; i < n; i++)
704  data->user_dash[i] = (int) dash_list[i];
705  }
706 }
707 
709 {
711 
712  g_return_if_fail(gc != NULL);
713 
714  data = GDK_GC_WIN32DATA(gc);
715 
716  if (data->clip_region != NULL)
717  if (!DeleteObject(data->clip_region))
718  WIN32_GDI_FAILED("DeleteObject");
719  if (rectangle) {
720  GDK_NOTE(MISC,
721  g_print("gdk_gc_set_clip_rectangle: (%d) %dx%d@+%d+%d\n",
722  data,
723  rectangle->width, rectangle->height,
724  rectangle->x, rectangle->y));
725  if ((data->clip_region =
726  CreateRectRgn(rectangle->x, rectangle->y,
727  rectangle->x + rectangle->width,
728  rectangle->y + rectangle->height)) == NULL)
729  WIN32_GDI_FAILED("CreateRectRgn");
730 
731  data->values_mask |= GDK_GC_CLIP_MASK;
732  } else {
733  GDK_NOTE(MISC, g_print("gdk_gc_set_clip_rectangle: (%d) NULL\n",
734  data));
735  data->clip_region = NULL;
736  data->values_mask &= ~GDK_GC_CLIP_MASK;
737  }
739 }
740 
742 {
744 
745  g_return_if_fail(gc != NULL);
746 
747  data = GDK_GC_WIN32DATA(gc);
748 
749  GDK_NOTE(MISC, g_print("gdk_gc_set_clip_region: (%d) %s\n",
750  data, (region != NULL ? "xxx" : "None")));
751 
752  if (data->clip_region != NULL)
753  if (!DeleteObject(data->clip_region))
754  WIN32_GDI_FAILED("DeleteObject");
755  if (region) {
756  GdkRegionPrivate *region_private;
757 
758  region_private = (GdkRegionPrivate *) region;
759  data->clip_region = CreateRectRgn(1, 1, 0, 0);
760  CombineRgn(data->clip_region, region_private->xregion, NULL,
761  RGN_COPY);
762  data->values_mask |= GDK_GC_CLIP_MASK;
763  } else {
764  data->clip_region = NULL;
765  data->values_mask &= ~GDK_GC_CLIP_MASK;
766  }
767 }
768 
769 void gdk_gc_copy(GdkGC * dst_gc, GdkGC * src_gc)
770 {
771  GdkGCWin32Data *dst_data = GDK_GC_WIN32DATA(dst_gc);
772  GdkGCWin32Data *src_data = GDK_GC_WIN32DATA(src_gc);
773  DWORD nbytes;
774  LPRGNDATA rgn;
775 
776  if (dst_data->font != NULL)
777  gdk_font_unref(dst_data->font);
778  if (dst_data->tile != NULL)
779  gdk_drawable_unref(dst_data->tile);
780  if (dst_data->stipple != NULL)
781  gdk_drawable_unref(dst_data->stipple);
782  if (dst_data->clip_region != NULL)
783  if (!DeleteObject(dst_data->clip_region))
784  WIN32_GDI_FAILED("DeleteObject");
785 
786  *dst_data = *src_data;
787 
788  if (dst_data->clip_region != NULL) {
789  nbytes = GetRegionData(dst_data->clip_region, 0, NULL);
790  rgn = g_malloc(nbytes);
791  GetRegionData(dst_data->clip_region, nbytes, rgn);
792  if ((dst_data->clip_region =
793  ExtCreateRegion(NULL, nbytes, rgn)) == NULL)
794  WIN32_GDI_FAILED("ExtCreateRegion");
795  g_free(rgn);
796  }
797 
798  if (dst_data->font != NULL)
799  gdk_font_ref(dst_data->font);
800  if (dst_data->tile != NULL)
801  gdk_drawable_ref(dst_data->tile);
802  if (dst_data->stipple != NULL)
803  gdk_drawable_ref(dst_data->stipple);
804 }
805 
806 static guint bitmask[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
807 
808 COLORREF
810  gulong pixel)
811 {
812  GdkVisual *visual;
813  guchar r, g, b;
814 
815  if (colormap_private == NULL || colormap_private->xcolormap->rc_palette)
816  return PALETTEINDEX(pixel);
817  else {
818  visual = colormap_private->base.visual;
819  r = (pixel & visual->red_mask) >> visual->red_shift;
820  r = (r * 255) / bitmask[visual->red_prec];
821  g = (pixel & visual->green_mask) >> visual->green_shift;
822  g = (g * 255) / bitmask[visual->green_prec];
823  b = (pixel & visual->blue_mask) >> visual->blue_shift;
824  b = (b * 255) / bitmask[visual->blue_prec];
825 
826  return RGB(r, g, b);
827  }
828 }
829 
830 static void
832  GdkColormapPrivateWin32 * colormap_private)
833 {
834  COLORREF fg;
835  LOGBRUSH logbrush;
836  HPEN hpen;
837  HBRUSH hbr;
838 
839  if (colormap_private == NULL) {
840  /* A 1 bit deep bitmap */
841  struct {
842  WORD palVersion;
843  WORD palNumEntries;
844  PALETTEENTRY palPalEntry[2];
845  } logpal;
846  static HPALETTE hpal = NULL;
847 
848  if (hpal == NULL) {
849  /* Create a b&w palette */
850  logpal.palVersion = 0x300;
851  logpal.palNumEntries = 2;
852  logpal.palPalEntry[0].peRed =
853  logpal.palPalEntry[0].peGreen =
854  logpal.palPalEntry[0].peBlue = 0x00;
855  logpal.palPalEntry[0].peFlags = 0x00;
856  logpal.palPalEntry[1].peRed =
857  logpal.palPalEntry[1].peGreen =
858  logpal.palPalEntry[1].peBlue = 0xFF;
859  logpal.palPalEntry[1].peFlags = 0x00;
860  if ((hpal = CreatePalette((LOGPALETTE *) & logpal)) == NULL)
861  WIN32_GDI_FAILED("CreatePalette");
862  }
863  SelectPalette(data->xgc, hpal, FALSE);
864  RealizePalette(data->xgc);
865  fg = PALETTEINDEX(data->foreground);
866  } else if (colormap_private->xcolormap->rc_palette) {
867  int k;
868  if (SelectPalette(data->xgc, colormap_private->xcolormap->palette,
869  FALSE) == NULL)
870  WIN32_GDI_FAILED("SelectPalette");
871  if (TRUE || colormap_private->xcolormap->stale) {
872  if ((k = RealizePalette(data->xgc)) == GDI_ERROR)
873  WIN32_GDI_FAILED("RealizePalette");
874  colormap_private->xcolormap->stale = FALSE;
875  }
876 #if 0
877  g_print("Selected palette %#x for gc %#x, realized %d colors\n",
878  colormap_private->xcolormap->palette, data->xgc, k);
879 #endif
880  }
881 
882  fg = gdk_colormap_color(colormap_private, data->foreground);
883 
884  if (SetTextColor(data->xgc, fg) == CLR_INVALID)
885  WIN32_GDI_FAILED("SetTextColor");
886 
887  /* Create and select pen and brush. */
888 
889  logbrush.lbStyle = BS_SOLID;
890  logbrush.lbColor = fg;
891  logbrush.lbHatch = 0;
892 
893 // vo add
894  if (data->pen_width <= 1) {
895  data->pen_width = 1;
896 
897  if (IS_WIN_NT(windows_version)) {
898  if ((data->pen_style & PS_STYLE_MASK) == PS_SOLID) {
899  data->pen_style = PS_COSMETIC;
900  }
901  }
902 
903  } else {
904  data->pen_style |= PS_GEOMETRIC;
905  }
906 
907 // bb add
908  if (IS_WIN_NT(windows_version) && (data->pen_style & PS_USERSTYLE)) {
909  if ((hpen = ExtCreatePen(data->pen_style, data->pen_width,
910  &logbrush, data->luser_dash,
911  (CONST DWORD *) data->user_dash)) == NULL)
912  WIN32_GDI_FAILED("ExtCreatePen");
913  } else {
914  if ((hpen = ExtCreatePen(data->pen_style, data->pen_width,
915  &logbrush, 0, NULL)) == NULL)
916  WIN32_GDI_FAILED("ExtCreatePen");
917  if (SetBkMode(data->xgc, TRANSPARENT) == 0)
918  WIN32_GDI_FAILED("SetBkMode");
919  }
920  if (SelectObject(data->xgc, hpen) == NULL)
921  WIN32_GDI_FAILED("SelectObject");
922 
923  switch (data->fill_style) {
924  case GDK_OPAQUE_STIPPLED:
925  if ((hbr =
926  CreatePatternBrush(GDK_DRAWABLE_XID(data->stipple))) == NULL)
927  WIN32_GDI_FAILED("CreatePatternBrush");
928 
929  SetBrushOrgEx(data->xgc, data->ts_x_origin, data->ts_y_origin, NULL);
930 
931  break;
932 // bb add
933  case GDK_STIPPLED:
934  if ((hbr =
935  CreatePatternBrush(GDK_DRAWABLE_XID(data->stipple))) == NULL)
936  WIN32_GDI_FAILED("CreatePatternBrush");
937 
938  SetBrushOrgEx(data->xgc, data->ts_x_origin, data->ts_y_origin, NULL);
939 
940  break;
941 // end bb add
942  case GDK_SOLID:
943  default:
944  if ((hbr = CreateSolidBrush(fg)) == NULL)
945  WIN32_GDI_FAILED("CreateSolidBrush");
946  break;
947  }
948  if (SelectObject(data->xgc, hbr) == NULL)
949  WIN32_GDI_FAILED("SelectObject");
950 }
951 
952 void
954  GdkColormapPrivateWin32 * colormap_private)
955 {
956  COLORREF bg = gdk_colormap_color(colormap_private, data->background);
957 
958  if (SetBkColor(data->xgc, bg) == CLR_INVALID)
959  WIN32_GDI_FAILED("SetBkColor");
960 }
961 
962 HDC
964  GdkGCPrivate * gc_private, GdkGCValuesMask usage)
965 {
966  GdkDrawablePrivate *drawable_private = (GdkDrawablePrivate *) drawable;
967  GdkColormapPrivateWin32 *colormap_private =
968  (GdkColormapPrivateWin32 *) drawable_private->colormap;
969  GdkGCWin32Data *data = GDK_GC_WIN32DATA(gc_private);
970 
971  g_assert(data->xgc == NULL);
972 
973  data->hwnd = GDK_DRAWABLE_XID(drawable);
974 
975  if (GDK_DRAWABLE_TYPE(drawable) == GDK_DRAWABLE_PIXMAP) {
976  if ((data->xgc = CreateCompatibleDC(NULL)) == NULL)
977  WIN32_GDI_FAILED("CreateCompatibleDC");
978 
979  if ((data->saved_dc = SaveDC(data->xgc)) == 0)
980  WIN32_GDI_FAILED("SaveDC");
981 
982  if (SelectObject(data->xgc, data->hwnd) == NULL)
983  WIN32_GDI_FAILED("SelectObject");
984  } else {
985  if ((data->xgc = GetDC(data->hwnd)) == NULL)
986  WIN32_GDI_FAILED("GetDC");
987 
988  if ((data->saved_dc = SaveDC(data->xgc)) == 0)
989  WIN32_GDI_FAILED("SaveDC");
990  }
991 
992  if (usage & GDK_GC_FOREGROUND)
993  predraw_set_foreground(data, colormap_private);
994 
995  if ((usage & GDK_GC_BACKGROUND)
996  && (data->values_mask & GDK_GC_BACKGROUND))
997  predraw_set_background(data, colormap_private);
998 
999 // vo add
1000  if (!IS_WIN_NT(windows_version)) {
1001  if (SetBkMode(data->xgc, TRANSPARENT) == 0)
1002  WIN32_GDI_FAILED("SetBkMode");
1003  }
1004 
1005  if (usage & GDK_GC_FONT) {
1006  if (SetBkMode(data->xgc, TRANSPARENT) == 0)
1007  WIN32_GDI_FAILED("SetBkMode");
1008 
1009 // if (SetTextAlign (data->xgc, TA_BASELINE) == GDI_ERROR)
1010  if (SetTextAlign(data->xgc, text_align) == GDI_ERROR)
1011  WIN32_GDI_FAILED("SetTextAlign");
1012  }
1013 
1014  if (data->rop2 != R2_COPYPEN)
1015  if (SetROP2(data->xgc, data->rop2) == 0)
1016  WIN32_GDI_FAILED("SetROP2");
1017 
1018  if ((data->values_mask & GDK_GC_CLIP_MASK)
1019  && data->clip_region != NULL) {
1020  if (data->
1021  values_mask & (GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN))
1022  OffsetRgn(data->clip_region, data->clip_x_origin,
1023  data->clip_y_origin);
1024  SelectClipRgn(data->xgc, data->clip_region);
1025  }
1026 
1027  return data->xgc;
1028 }
1029 
1030 void
1032  GdkGCPrivate * gc_private, GdkGCValuesMask usage)
1033 {
1034  GdkDrawablePrivate *drawable_private = (GdkDrawablePrivate *) drawable;
1035  GdkColormapPrivateWin32 *colormap_private =
1036  (GdkColormapPrivateWin32 *) drawable_private->colormap;
1037  GdkGCWin32Data *data = GDK_GC_WIN32DATA(gc_private);
1038  HGDIOBJ hpen = NULL;
1039  HGDIOBJ hbr = NULL;
1040 
1041  if (usage & GDK_GC_FOREGROUND) {
1042  if ((hpen = GetCurrentObject(data->xgc, OBJ_PEN)) == NULL)
1043  WIN32_GDI_FAILED("GetCurrentObject");
1044 
1045  if ((hbr = GetCurrentObject(data->xgc, OBJ_BRUSH)) == NULL)
1046  WIN32_GDI_FAILED("GetCurrentObject");
1047  }
1048 
1049  if (!RestoreDC(data->xgc, data->saved_dc))
1050  WIN32_GDI_FAILED("RestoreDC");
1051 #if 0
1052  if (colormap_private != NULL
1053  && colormap_private->xcolormap->rc_palette
1054  && colormap_private->xcolormap->stale) {
1055  SelectPalette(data->xgc, GetStockObject(DEFAULT_PALETTE), FALSE);
1056  if (!UnrealizeObject(colormap_private->xcolormap->palette))
1057  WIN32_GDI_FAILED("UnrealizeObject");
1058  }
1059 #endif
1060  if (GDK_DRAWABLE_TYPE(drawable) == GDK_DRAWABLE_PIXMAP) {
1061  if (!DeleteDC(data->xgc))
1062  WIN32_GDI_FAILED("DeleteDC");
1063  } else {
1064  ReleaseDC(data->hwnd, data->xgc);
1065  }
1066 
1067  if (hpen != NULL)
1068  if (!DeleteObject(hpen))
1069  WIN32_GDI_FAILED("DeleteObject");
1070 
1071  if (hbr != NULL)
1072  if (!DeleteObject(hbr))
1073  WIN32_GDI_FAILED("DeleteObject");
1074 
1075  if ((data->values_mask & GDK_GC_CLIP_MASK)
1076  && data->clip_region != NULL
1077  && (data->
1078  values_mask & (GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN)))
1079  OffsetRgn(data->clip_region, -data->clip_x_origin,
1080  -data->clip_y_origin);
1081  data->xgc = NULL;
1082 }
1083 
1084 HDC
1086  GdkGC * gc, GdkGCValuesMask usage)
1087 {
1088  return gdk_gc_predraw(drawable, (GdkGCPrivate *) gc, usage);
1089 }
1090 
1091 void
1093  GdkGC * gc, GdkGCValuesMask usage)
1094 {
1095  gdk_gc_postdraw(drawable, (GdkGCPrivate *) gc, usage);
1096 }
1097 
1098 /* This function originally from Jean-Edouard Lachand-Robert, and
1099  * available at www.codeguru.com. Simplified for our needs, now
1100  * handles just one-bit deep bitmaps (in Window parlance, ie those
1101  * that GDK calls bitmaps (and not pixmaps), with zero pixels being
1102  * transparent.
1103  */
1104 
1105 /*
1106  * BitmapToRegion : Create a region from the "non-transparent" pixels of
1107  * a bitmap
1108  * Author : Jean-Edouard Lachand-Robert
1109  * (http://www.geocities.com/Paris/LeftBank/1160/resume.htm), June 1998.
1110  */
1111 
1112 HRGN BitmapToRegion(HBITMAP hBmp)
1113 {
1114  HRGN hRgn = NULL;
1115  HDC hMemDC;
1116  BITMAP bm;
1117 
1118  struct {
1119  BITMAPINFOHEADER bmiHeader;
1120 #if 1
1121  WORD bmiColors[2];
1122 #else
1123  RGBQUAD bmiColors[2];
1124 #endif
1125  } bmi;
1126  VOID *pbits8;
1127  HBITMAP hbm8;
1128  struct {
1129  WORD palVersion;
1130  WORD palNumEntries;
1131  PALETTEENTRY palPalEntry[2];
1132  } logpal;
1133  static HPALETTE bwPalette = NULL;
1134 
1135  HBITMAP holdBmp;
1136  HDC hDC;
1137 
1138  BITMAP bm8;
1139  HBITMAP holdBmp2;
1140  DWORD maxRects;
1141  RGNDATA *pData;
1142  BYTE *p8;
1143  int x, y;
1144  HRGN h;
1145 
1146  /* Create a B&W palette */
1147  if (bwPalette == NULL) {
1148  /* Create a b&w palette */
1149  logpal.palVersion = 0x300;
1150  logpal.palNumEntries = 2;
1151  logpal.palPalEntry[0].peRed =
1152  logpal.palPalEntry[0].peGreen = logpal.palPalEntry[0].peBlue = 0;
1153  logpal.palPalEntry[0].peFlags = 0;
1154  logpal.palPalEntry[1].peRed =
1155  logpal.palPalEntry[1].peGreen =
1156  logpal.palPalEntry[1].peBlue = 0xFF;
1157  logpal.palPalEntry[1].peFlags = 0;
1158  if ((bwPalette = CreatePalette((LOGPALETTE *) & logpal)) == NULL)
1159  WIN32_GDI_FAILED("CreatePalette");
1160  }
1161 
1162  /* Create a memory DC inside which we will scan the bitmap content */
1163  hMemDC = CreateCompatibleDC(NULL);
1164  if (!hMemDC) {
1165  WIN32_GDI_FAILED("CreateCompatibleDC");
1166  return NULL;
1167  }
1168 
1169  SelectPalette(hMemDC, bwPalette, FALSE);
1170  RealizePalette(hMemDC);
1171 
1172  /* Get bitmap size */
1173  GetObject(hBmp, sizeof(bm), &bm);
1174 
1175  /* Create a 8 bits depth bitmap and select it into the memory DC */
1176  bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1177  bmi.bmiHeader.biWidth = bm.bmWidth;
1178  bmi.bmiHeader.biHeight = bm.bmHeight;
1179  bmi.bmiHeader.biPlanes = 1;
1180  bmi.bmiHeader.biBitCount = 8;
1181  bmi.bmiHeader.biCompression = BI_RGB;
1182  bmi.bmiHeader.biSizeImage = 0;
1183  bmi.bmiHeader.biXPelsPerMeter = 0;
1184  bmi.bmiHeader.biYPelsPerMeter = 0;
1185  bmi.bmiHeader.biClrUsed = 2;
1186  bmi.bmiHeader.biClrImportant = 2;
1187 #if 1
1188  bmi.bmiColors[0] = 0;
1189  bmi.bmiColors[1] = 1;
1190  hbm8 = CreateDIBSection(hMemDC, (BITMAPINFO *) & bmi,
1191  DIB_PAL_COLORS, &pbits8, NULL, 0);
1192 #else
1193  bmi.bmiColors[0].rgbBlue =
1194  bmi.bmiColors[0].rgbGreen = bmi.bmiColors[0].rgbRed = 0x00;
1195  bmi.bmiColors[0].rgbReserved = 0x00;
1196 
1197  bmi.bmiColors[1].rgbBlue =
1198  bmi.bmiColors[1].rgbGreen = bmi.bmiColors[1].rgbRed = 0xFF;
1199  bmi.bmiColors[0].rgbReserved = 0x00;
1200 
1201  hbm8 = CreateDIBSection(hMemDC, (BITMAPINFO *) & bmi,
1202  DIB_RGB_COLORS, &pbits8, NULL, 0);
1203 #endif
1204  if (!hbm8) {
1205  WIN32_GDI_FAILED("CreateDIBSection");
1206  DeleteDC(hMemDC);
1207  return NULL;
1208  }
1209 
1210  holdBmp = (HBITMAP) SelectObject(hMemDC, hbm8);
1211 
1212  /* Create a DC just to copy the bitmap into the memory DC */
1213  hDC = CreateCompatibleDC(hMemDC);
1214  if (!hDC) {
1215  WIN32_GDI_FAILED("CreateCompatibleDC #2");
1216  SelectObject(hMemDC, holdBmp);
1217  DeleteObject(hbm8);
1218  DeleteDC(hMemDC);
1219  return NULL;
1220  }
1221 
1222  /* Get how many bytes per row we have for the bitmap bits */
1223  GetObject(hbm8, sizeof(bm8), &bm8);
1224 
1225  /* Hans Breuer found a fix to the long-standing erroneous behaviour
1226  * on NT 4.0: There seems to be a bug in Win NT 4.0 GDI: scanlines
1227  * in bitmaps are dword aligned on both Win95 and NT. In the case of
1228  * a bitmap with 22 bytes worth of width, GetObject above returns
1229  * with bmWidth == 22. On Win95 bmWidthBytes == 24, as it should be,
1230  * but on NT is it 22. We need to correct this here.
1231  */
1232  bm8.bmWidthBytes = (((bm8.bmWidthBytes - 1) / 4) + 1) * 4; /* dword aligned!! */
1233 
1234  /* Copy the bitmap into the memory DC */
1235  holdBmp2 = (HBITMAP) SelectObject(hDC, hBmp);
1236 
1237  if (!BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY)) {
1238  WIN32_GDI_FAILED("BitBlt");
1239  SelectObject(hDC, holdBmp2);
1240  SelectObject(hMemDC, holdBmp);
1241  DeleteObject(hbm8);
1242  DeleteDC(hMemDC);
1243  return NULL;
1244  }
1245  SelectObject(hDC, holdBmp2);
1246  DeleteDC(hDC);
1247 
1248  /* For better performances, we will use the ExtCreateRegion()
1249  * function to create the region. This function take a RGNDATA
1250  * structure on entry. We will add rectangles by amount of
1251  * ALLOC_UNIT number in this structure.
1252  */
1253 #define ALLOC_UNIT 200
1254  maxRects = ALLOC_UNIT;
1255 
1256  pData = g_malloc(sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
1257  memset(pData, 0, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
1258  pData->rdh.dwSize = sizeof(RGNDATAHEADER);
1259  pData->rdh.iType = RDH_RECTANGLES;
1260  pData->rdh.nCount = pData->rdh.nRgnSize = 0;
1261  SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
1262 
1263  /* Scan each bitmap from bottom to top (the bitmap is inverted vertically) */
1264  p8 = (BYTE *) pbits8 + (bm8.bmHeight - 1) * bm8.bmWidthBytes;
1265  for (y = 0; y < bm.bmHeight; y++) {
1266  /* Scan each bitmap row from left to right */
1267  for (x = 0; x < bm.bmWidth; x++) {
1268  /* Search for a continuous range of "non transparent pixels" */
1269  int x0 = x;
1270  BYTE *p = p8 + x;
1271  while (x < bm.bmWidth) {
1272  if (*p == 0)
1273  /* This pixel is "transparent" */
1274  break;
1275  p++;
1276  x++;
1277  }
1278 
1279  if (x > x0) {
1280  RECT *pr;
1281  /* Add the pixels (x0, y) to (x, y+1) as a new rectangle
1282  * in the region
1283  */
1284  if (pData->rdh.nCount >= maxRects) {
1285  maxRects += ALLOC_UNIT;
1286  pData = g_realloc(pData, sizeof(RGNDATAHEADER)
1287  + (sizeof(RECT) * maxRects));
1288  }
1289  pr = (RECT *) & pData->Buffer;
1290  SetRect(&pr[pData->rdh.nCount], x0, y, x, y + 1);
1291  if (x0 < pData->rdh.rcBound.left)
1292  pData->rdh.rcBound.left = x0;
1293  if (y < pData->rdh.rcBound.top)
1294  pData->rdh.rcBound.top = y;
1295  if (x > pData->rdh.rcBound.right)
1296  pData->rdh.rcBound.right = x;
1297  if (y + 1 > pData->rdh.rcBound.bottom)
1298  pData->rdh.rcBound.bottom = y + 1;
1299  pData->rdh.nCount++;
1300 
1301  /* On Windows98, ExtCreateRegion() may fail if the
1302  * number of rectangles is too large (ie: >
1303  * 4000). Therefore, we have to create the region by
1304  * multiple steps.
1305  */
1306  if (pData->rdh.nCount == 2000) {
1307  HRGN h = ExtCreateRegion(NULL,
1308  sizeof(RGNDATAHEADER) +
1309  (sizeof(RECT) * maxRects), pData);
1310  if (hRgn) {
1311  CombineRgn(hRgn, hRgn, h, RGN_OR);
1312  DeleteObject(h);
1313  } else
1314  hRgn = h;
1315  pData->rdh.nCount = 0;
1316  SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
1317  }
1318  }
1319  }
1320 
1321  /* Go to next row (remember, the bitmap is inverted vertically) */
1322  p8 -= bm8.bmWidthBytes;
1323  }
1324 
1325  /* Create or extend the region with the remaining rectangles */
1326  h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER)
1327  + (sizeof(RECT) * maxRects), pData);
1328  if (hRgn) {
1329  CombineRgn(hRgn, hRgn, h, RGN_OR);
1330  DeleteObject(h);
1331  } else
1332  hRgn = h;
1333 
1334  /* Clean up */
1335  g_free(pData);
1336  SelectObject(hMemDC, holdBmp);
1337  DeleteObject(hbm8);
1338  DeleteDC(hMemDC);
1339 
1340  return hRgn;
1341 }
1342 
1343 #ifdef G_ENABLE_DEBUG
1344 
1345 gchar *gdk_win32_cap_style_to_string(GdkCapStyle cap_style)
1346 {
1347  switch (cap_style) {
1348 #define CASE(x) case x: return #x + strlen ("GDK_CAP_")
1349  CASE(GDK_CAP_NOT_LAST);
1350  CASE(GDK_CAP_BUTT);
1351  CASE(GDK_CAP_ROUND);
1352  CASE(GDK_CAP_PROJECTING);
1353 #undef CASE
1354  default:
1355  return ("illegal GdkCapStyle value");
1356  }
1357  /* NOTREACHED */
1358  return NULL;
1359 }
1360 
1361 gchar *gdk_win32_fill_style_to_string(GdkFill fill)
1362 {
1363  switch (fill) {
1364 #define CASE(x) case x: return #x + strlen ("GDK_")
1365  CASE(GDK_SOLID);
1366  CASE(GDK_TILED);
1367  CASE(GDK_STIPPLED);
1368  CASE(GDK_OPAQUE_STIPPLED);
1369 #undef CASE
1370  default:
1371  return ("illegal GdkFill value");
1372  }
1373  /* NOTREACHED */
1374  return NULL;
1375 }
1376 
1377 gchar *gdk_win32_function_to_string(GdkFunction function)
1378 {
1379  switch (function) {
1380 #define CASE(x) case x: return #x + strlen ("GDK_")
1381  CASE(GDK_COPY);
1382  CASE(GDK_INVERT);
1383  CASE(GDK_XOR);
1384  CASE(GDK_CLEAR);
1385  CASE(GDK_AND);
1386  CASE(GDK_AND_REVERSE);
1387  CASE(GDK_AND_INVERT);
1388  CASE(GDK_NOOP);
1389  CASE(GDK_OR);
1390  CASE(GDK_EQUIV);
1391  CASE(GDK_OR_REVERSE);
1392  CASE(GDK_COPY_INVERT);
1393  CASE(GDK_OR_INVERT);
1394  CASE(GDK_NAND);
1395  CASE(GDK_SET);
1396 #undef CASE
1397  default:
1398  return ("illegal GdkFunction value");
1399  }
1400  /* NOTREACHED */
1401  return NULL;
1402 }
1403 
1404 gchar *gdk_win32_join_style_to_string(GdkJoinStyle join_style)
1405 {
1406  switch (join_style) {
1407 #define CASE(x) case x: return #x + strlen ("GDK_JOIN_")
1408  CASE(GDK_JOIN_MITER);
1409  CASE(GDK_JOIN_ROUND);
1410  CASE(GDK_JOIN_BEVEL);
1411 #undef CASE
1412  default:
1413  return ("illegal GdkJoinStyle value");
1414  }
1415  /* NOTREACHED */
1416  return NULL;
1417 }
1418 
1419 gchar *gdk_win32_line_style_to_string(GdkLineStyle line_style)
1420 {
1421  switch (line_style) {
1422 #define CASE(x) case x: return #x + strlen ("GDK_LINE_")
1423  CASE(GDK_LINE_SOLID);
1424  CASE(GDK_LINE_ON_OFF_DASH);
1425  CASE(GDK_LINE_DOUBLE_DASH);
1426 #undef CASE
1427  default:
1428  return ("illegal GdkLineStyle value");
1429  }
1430  /* NOTREACHED */
1431  return NULL;
1432 }
1433 #endif
GdkPixmap * gdk_pixmap_new(GdkWindow *window, gint width, gint height, gint depth)
#define CLR_INVALID
guint32 red_mask
Definition: gdkvisual.h:46
gint16 x
Definition: gdktypes.h:146
gint blue_prec
Definition: gdkvisual.h:56
void gdk_gc_unref(GdkGC *gc)
Definition: gdkgc.c:78
unsigned int guint
Definition: g_types.h:51
void gdk_drawable_get_size(GdkDrawable *drawable, gint *width, gint *height)
Definition: gdkdraw.c:75
unsigned char guchar
Definition: g_types.h:48
GdkJoinStyle join_style
Definition: gdkgc.h:142
gint ts_y_origin
Definition: gdkgc.h:135
gint red_shift
Definition: gdkvisual.h:47
gint red_prec
Definition: gdkvisual.h:48
gint clip_x_origin
Definition: gdkgc.h:136
Definition: gdkgc.h:67
th1 SetTextAlign(11)
Definition: gdkgc.h:73
guint16 width
Definition: gdktypes.h:148
GdkSubwindowMode subwindow_mode
TH1 * h
Definition: legend2.C:5
#define GDK_NOTE(type, action)
Definition: gdkprivate.h:276
Definition: gdkgc.h:66
GdkLineStyle
Definition: gdkgc.h:92
guint16 height
Definition: gdktypes.h:149
GdkColormapPrivate base
gpointer g_malloc(gulong n_bytes)
Definition: gmem.c:130
GdkDrawable * gdk_drawable_ref(GdkDrawable *drawable)
Definition: gdkdraw.c:99
gint ts_x_origin
Definition: gdkgc.h:134
gboolean gdk_color_white(GdkColormap *colormap, GdkColor *color)
Definition: gdkcolor.c:133
static void gdk_win32_gc_get_values(GdkGC *gc, GdkGCValues *values)
Definition: gdkgc-win32.c:479
DWORD windows_version
GdkPixmap * clip_mask
Definition: gdkgc.h:132
G_BEGIN_DECLS typedef char gchar
Definition: g_types.h:41
static GdkColor white
Definition: testgdk.c:100
GdkColormap * colormap
Definition: gdkprivate.h:77
#define IS_WIN_NT(dwVersion)
Double_t x[n]
Definition: legend1.C:17
gint gboolean
Definition: g_types.h:45
HDC gdk_win32_hdc_get(GdkDrawable *drawable, GdkGC *gc, GdkGCValuesMask usage)
Definition: gdkgc-win32.c:1085
Definition: gdkgc.h:63
COLORREF gdk_colormap_color(GdkColormapPrivateWin32 *colormap_private, gulong pixel)
Definition: gdkgc-win32.c:809
gint blue_shift
Definition: gdkvisual.h:55
void gdk_font_unref(GdkFont *font)
Definition: gdkfont.c:41
gint16 y
Definition: gdktypes.h:147
Definition: gdkgc.h:145
gchar * gdk_font_full_name_get(GdkFont *font)
guint gdk_gc_set_text_align(GdkGC *gc, guint tAlign)
Definition: gdkgc-win32.c:55
unsigned long gulong
Definition: g_types.h:50
GdkJoinStyle
Definition: gdkgc.h:81
#define g_return_if_fail(expr)
Definition: gmessages.h:288
GdkFunction function
Definition: gdkgc.h:128
GdkGC * gdk_gc_new(GdkDrawable *drawable)
Definition: gdkgc.c:44
gint line_width
Definition: gdkgc.h:139
GdkPixmap * tile
Definition: gdkgc.h:130
#define g_new(struct_type, n_structs)
Definition: gmem.h:60
static guint bitmask[9]
Definition: gdkgc-win32.c:806
int gint
Definition: g_types.h:44
Definition: gdkgc.h:72
ROOT::R::TRInterface & r
Definition: Object.C:4
GdkBitmap * gdk_bitmap_create_from_data(GdkWindow *window, const gchar *data, gint width, gint height)
#define ALLOC_UNIT
#define FALSE
Definition: gmacros.h:126
HDC gdk_gc_predraw(GdkDrawable *drawable, GdkGCPrivate *gc_private, GdkGCValuesMask usage)
Definition: gdkgc-win32.c:963
GdkGCValuesMask
Definition: gdkgc.h:103
gint graphics_exposures
Definition: gdkgc.h:138
void gdk_win32_hdc_release(GdkDrawable *drawable, GdkGC *gc, GdkGCValuesMask usage)
Definition: gdkgc-win32.c:1092
GdkFill
Definition: gdkgc.h:33
gboolean gdk_color_black(GdkColormap *colormap, GdkColor *color)
Definition: gdkcolor.c:151
static void gdk_win32_gc_set_values(GdkGC *gc, GdkGCValues *values, GdkGCValuesMask values_mask)
Definition: gdkgc-win32.c:617
GdkFontType type
Definition: gdkfont.h:20
#define VOID
Definition: triangle.h:286
Definition: gdkgc.h:59
Definition: gdkgc.h:61
GdkColormap * gdk_colormap_get_system(void)
static GdkColor black
Definition: testgdk.c:100
guint32 blue_mask
Definition: gdkvisual.h:54
void gdk_gc_set_clip_rectangle(GdkGC *gc, GdkRectangle *rectangle)
Definition: gdkgc-win32.c:708
GdkColor background
Definition: gdkgc.h:126
static void gdk_win32_gc_destroy(GdkGC *gc)
Definition: gdkgc-win32.c:460
#define WIN32_GDI_FAILED(api)
static void usage(const char *argv0)
Definition: main.cpp:558
gchar data[7]
void g_free(gpointer mem)
Definition: gmem.c:183
void gdk_gc_set_clip_region(GdkGC *gc, GdkRegion *region)
Definition: gdkgc-win32.c:741
GdkGCValuesMask values_mask
static GdkGCClass gdk_win32_gc_class
Definition: gdkgc-win32.c:48
#define PS_JOIN_MASK
GdkFont * font
Definition: gdkgc.h:127
static void gdk_win32_gc_values_to_win32values(GdkGCValues *values, GdkGCValuesMask mask, GdkGCWin32Data *data)
Definition: gdkgc-win32.c:99
gint green_prec
Definition: gdkvisual.h:52
void gdk_gc_copy(GdkGC *dst_gc, GdkGC *src_gc)
Definition: gdkgc-win32.c:769
static RooMathCoreReg dummy
Double_t y[n]
Definition: legend1.C:17
GdkFill fill
Definition: gdkgc.h:129
HRGN BitmapToRegion(HBITMAP hBmp)
Definition: gdkgc-win32.c:1112
void gdk_font_full_name_free(gchar *name)
GdkFunction
Definition: gdkgc.h:58
gpointer g_realloc(gpointer mem, gulong n_bytes)
Definition: gmem.c:164
GdkFont * gdk_font_ref(GdkFont *font)
Definition: gdkfont.c:30
virtual void SetTextColor(Color_t cindex)
GdkPixmap * stipple
Definition: gdkgc.h:131
#define g_assert(expr)
Definition: gmessages.h:210
#define GDK_DRAWABLE_TYPE(d)
Definition: gdkprivate.h:44
GdkSubwindowMode subwindow_mode
Definition: gdkgc.h:133
GdkGC * gdk_gc_alloc(void)
Definition: gdkgc.c:32
GdkColor foreground
Definition: gdkgc.h:125
gulong pixel
Definition: gdkcolor.h:18
#define TRUE
Definition: gmacros.h:130
void gdk_drawable_unref(GdkDrawable *drawable)
Definition: gdkdraw.c:108
#define NULL
Definition: Rtypes.h:82
void * GetObject() const
guint32 green_mask
Definition: gdkvisual.h:50
#define GDK_DRAWABLE_XID(win)
Definition: gdkwin32.h:42
static void gdk_win32_gc_set_dashes(GdkGC *gc, gint dash_offset, gchar dash_list[], gint n)
Definition: gdkgc-win32.c:628
static UINT text_align
Definition: gdkgc-win32.c:37
GdkPixmap * stipple
void g_print(const gchar *format,...)
Definition: gmessages.c:788
GdkGC * _gdk_win32_gc_new(GdkDrawable *drawable, GdkGCValues *values, GdkGCValuesMask mask)
Definition: gdkgc-win32.c:406
static void predraw_set_foreground(GdkGCWin32Data *data, GdkColormapPrivateWin32 *colormap_private)
Definition: gdkgc-win32.c:831
void gdk_draw_drawable(GdkDrawable *drawable, GdkGC *gc, GdkDrawable *src, gint xsrc, gint ysrc, gint xdest, gint ydest, gint width, gint height)
Definition: gdkdraw.c:290
GdkCapStyle
Definition: gdkgc.h:20
void gdk_gc_postdraw(GdkDrawable *drawable, GdkGCPrivate *gc_private, GdkGCValuesMask usage)
Definition: gdkgc-win32.c:1031
const Int_t n
Definition: legend1.C:16
void predraw_set_background(GdkGCWin32Data *data, GdkColormapPrivateWin32 *colormap_private)
Definition: gdkgc-win32.c:953
GdkLineStyle line_style
Definition: gdkgc.h:140
gint green_shift
Definition: gdkvisual.h:51
#define GDK_GC_WIN32DATA(gc)
GdkCapStyle cap_style
Definition: gdkgc.h:141
GdkVisual * visual
Definition: gdkprivate.h:137
gint clip_y_origin
Definition: gdkgc.h:137