00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028
00029 #include <string.h>
00030
00031 #include "gdkgc.h"
00032 #include "gdkfont.h"
00033 #include "gdkpixmap.h"
00034 #include "gdkprivate.h"
00035 #include "gdkwin32.h"
00036
00037 static UINT text_align = TA_BASELINE;
00038
00039 static void gdk_win32_gc_destroy(GdkGC * gc);
00040 static void gdk_win32_gc_get_values(GdkGC * gc, GdkGCValues * values);
00041 static void gdk_win32_gc_set_values(GdkGC * gc,
00042 GdkGCValues * values,
00043 GdkGCValuesMask values_mask);
00044 static void gdk_win32_gc_set_dashes(GdkGC * gc,
00045 gint dash_offset,
00046 gchar dash_list[], gint n);
00047
00048 static GdkGCClass gdk_win32_gc_class = {
00049 gdk_win32_gc_destroy,
00050 gdk_win32_gc_get_values,
00051 gdk_win32_gc_set_values,
00052 gdk_win32_gc_set_dashes
00053 };
00054
00055 guint gdk_gc_set_text_align(GdkGC * gc, guint tAlign)
00056 {
00057
00058
00059
00060 guint old_val = text_align;
00061 switch (tAlign) {
00062 case 7:
00063 text_align = TA_LEFT | TA_BOTTOM;
00064 break;
00065 case 4:
00066 text_align = TA_LEFT | TA_BASELINE;
00067 break;
00068 case 1:
00069 text_align = TA_LEFT | TA_TOP;
00070 break;
00071 case 8:
00072 text_align = TA_CENTER | TA_BOTTOM;
00073 break;
00074 case 5:
00075 text_align = TA_CENTER | TA_BASELINE;
00076 break;
00077 case 2:
00078 text_align = TA_CENTER | TA_TOP;
00079 break;
00080 case 9:
00081 text_align = TA_RIGHT | TA_BOTTOM;
00082 break;
00083 case 6:
00084 text_align = TA_RIGHT | TA_BASELINE;
00085 break;
00086 case 3:
00087 text_align = TA_RIGHT | TA_TOP;
00088 break;
00089 case 0:
00090 text_align = TA_BASELINE;
00091 break;
00092 }
00093
00094
00095 return (old_val);
00096 }
00097
00098 static void
00099 gdk_win32_gc_values_to_win32values(GdkGCValues * values,
00100 GdkGCValuesMask mask,
00101 GdkGCWin32Data * data)
00102 {
00103 char *s = "";
00104 gint sw, sh;
00105
00106 GDK_NOTE(MISC, g_print("{"));
00107
00108 if (mask & GDK_GC_FOREGROUND) {
00109 data->foreground = values->foreground.pixel;
00110 data->values_mask |= GDK_GC_FOREGROUND;
00111 GDK_NOTE(MISC, (g_print("fg=%.06x", data->foreground), s = ","));
00112 }
00113
00114 if (mask & GDK_GC_BACKGROUND) {
00115 data->background = values->background.pixel;
00116 data->values_mask |= GDK_GC_BACKGROUND;
00117 GDK_NOTE(MISC, (g_print("%sbg=%.06x", s, data->background),
00118 s = ","));
00119 }
00120
00121 if ((mask & GDK_GC_FONT) && (values->font->type == GDK_FONT_FONT
00122 || values->font->type == GDK_FONT_FONTSET))
00123 {
00124 if (data->font != NULL)
00125 gdk_font_unref(data->font);
00126 data->font = values->font;
00127 if (data->font != NULL) {
00128 gchar *xlfd;
00129
00130 gdk_font_ref(data->font);
00131 data->values_mask |= GDK_GC_FONT;
00132 GDK_NOTE(MISC, (xlfd = gdk_font_full_name_get(data->font),
00133 g_print("%sfont=%s", s, xlfd),
00134 s = ",", gdk_font_full_name_free(xlfd)));
00135 } else {
00136 data->values_mask &= ~GDK_GC_FONT;
00137 GDK_NOTE(MISC, (g_print("%sfont=NULL"), s = ","));
00138 }
00139 }
00140
00141 if (mask & GDK_GC_FUNCTION) {
00142 GDK_NOTE(MISC,
00143 (g_print("%srop2=%s ",
00144 s,
00145 gdk_win32_function_to_string(values->function)),
00146 s = ","));
00147 switch (values->function) {
00148 case GDK_COPY:
00149 data->rop2 = R2_COPYPEN;
00150 GDK_NOTE(MISC, g_print("(COPYPEN)"));
00151 break;
00152 case GDK_INVERT:
00153 data->rop2 = R2_NOT;
00154 GDK_NOTE(MISC, g_print("(NOT)"));
00155 break;
00156 case GDK_XOR:
00157 data->rop2 = R2_XORPEN;
00158 GDK_NOTE(MISC, g_print("(XORPEN)"));
00159 break;
00160 case GDK_CLEAR:
00161 data->rop2 = R2_BLACK;
00162 GDK_NOTE(MISC, g_print("(BLACK)"));
00163 break;
00164 case GDK_AND:
00165 data->rop2 = R2_MASKPEN;
00166 GDK_NOTE(MISC, g_print("(MASKPEN)"));
00167 break;
00168 case GDK_AND_REVERSE:
00169 data->rop2 = R2_MASKPENNOT;
00170 GDK_NOTE(MISC, g_print("(MASKPENNOT)"));
00171 break;
00172 case GDK_AND_INVERT:
00173 data->rop2 = R2_MASKNOTPEN;
00174 GDK_NOTE(MISC, g_print("(MASKNOTPEN)"));
00175 break;
00176 case GDK_NOOP:
00177 data->rop2 = R2_NOP;
00178 GDK_NOTE(MISC, g_print("(NOP)"));
00179 break;
00180 case GDK_OR:
00181 data->rop2 = R2_MERGEPEN;
00182 GDK_NOTE(MISC, g_print("(MERGEPEN)"));
00183 break;
00184 case GDK_EQUIV:
00185 data->rop2 = R2_NOTXORPEN;
00186 GDK_NOTE(MISC, g_print("(NOTXORPEN)"));
00187 break;
00188 case GDK_OR_REVERSE:
00189 data->rop2 = R2_MERGEPENNOT;
00190 GDK_NOTE(MISC, g_print("(MERGEPENNOT)"));
00191 break;
00192 case GDK_COPY_INVERT:
00193 data->rop2 = R2_NOTCOPYPEN;
00194 GDK_NOTE(MISC, g_print("(NOTCOPYPEN)"));
00195 break;
00196 case GDK_OR_INVERT:
00197 data->rop2 = R2_MERGENOTPEN;
00198 GDK_NOTE(MISC, g_print("(MERGENOTPEN)"));
00199 break;
00200 case GDK_NAND:
00201 data->rop2 = R2_NOTMASKPEN;
00202 GDK_NOTE(MISC, g_print("(NOTMASKPEN)"));
00203 break;
00204 case GDK_SET:
00205 data->rop2 = R2_WHITE;
00206 GDK_NOTE(MISC, g_print("(WHITE)"));
00207 break;
00208 }
00209 GDK_NOTE(MISC, g_print(" "));
00210 data->values_mask |= GDK_GC_FUNCTION;
00211 }
00212
00213 if (mask & GDK_GC_FILL) {
00214 data->fill_style = values->fill;
00215 data->values_mask |= GDK_GC_FILL;
00216 GDK_NOTE(MISC,
00217 (g_print("%sfill=%s",
00218 s,
00219 gdk_win32_fill_style_to_string(data->fill_style)),
00220 s = ","));
00221 }
00222
00223 if (mask & GDK_GC_TILE) {
00224 if (data->tile != NULL)
00225 gdk_drawable_unref(data->tile);
00226 data->tile = values->tile;
00227 if (data->tile != NULL) {
00228 gdk_drawable_ref(data->tile);
00229 data->values_mask |= GDK_GC_TILE;
00230 GDK_NOTE(MISC, (g_print("%stile=%#x", s,
00231 GDK_DRAWABLE_XID(data->tile)), s = ","));
00232 } else {
00233 data->values_mask &= ~GDK_GC_TILE;
00234 GDK_NOTE(MISC, (g_print("%stile=NULL", s), s = ","));
00235 }
00236 }
00237
00238 if (mask & GDK_GC_STIPPLE) {
00239 if (data->stipple != NULL)
00240 gdk_drawable_unref(data->stipple);
00241 data->stipple = values->stipple;
00242 if (data->stipple != NULL) {
00243 gdk_drawable_get_size(data->stipple, &sw, &sh);
00244
00245 if (sw != 8 || sh != 8) {
00246
00247
00248
00249
00250
00251 gchar dummy[8];
00252 GdkPixmap *bm = gdk_bitmap_create_from_data(NULL, dummy, 8, 8);
00253 GdkGC *gc = gdk_gc_new(bm);
00254 gint i, j;
00255
00256 i = 0;
00257 while (i < 8) {
00258 j = 0;
00259 while (j < 8) {
00260 gdk_draw_drawable(bm, gc, data->stipple, 0, 0, i, j, sw,
00261 sh);
00262 j += sh;
00263 }
00264 i += sw;
00265 }
00266 data->stipple = bm;
00267 gdk_gc_unref(gc);
00268 } else
00269 gdk_drawable_ref(data->stipple);
00270 data->values_mask |= GDK_GC_STIPPLE;
00271 GDK_NOTE(MISC, (g_print("%sstipple=%#x", s,
00272 GDK_DRAWABLE_XID(data->stipple)),
00273 s = ","));
00274 } else {
00275 data->values_mask &= ~GDK_GC_STIPPLE;
00276 GDK_NOTE(MISC, (g_print("%sstipple=NULL", s), s = ","));
00277 }
00278 }
00279
00280 if (mask & GDK_GC_CLIP_MASK) {
00281 if (data->clip_region != NULL)
00282 if (!DeleteObject(data->clip_region))
00283 WIN32_GDI_FAILED("DeleteObject");
00284 if (values->clip_mask != NULL) {
00285 data->clip_region =
00286 BitmapToRegion((HBITMAP) GDK_DRAWABLE_XID(values->clip_mask));
00287 data->values_mask |= GDK_GC_CLIP_MASK;
00288 } else {
00289 data->clip_region = NULL;
00290 data->values_mask &= ~GDK_GC_CLIP_MASK;
00291 }
00292 GDK_NOTE(MISC, (g_print("%sclip=%#x", s, data->clip_region),
00293 s = ","));
00294 }
00295
00296 if (mask & GDK_GC_SUBWINDOW) {
00297 data->subwindow_mode = values->subwindow_mode;
00298 data->values_mask |= GDK_GC_SUBWINDOW;
00299 GDK_NOTE(MISC, (g_print("%ssubw=%d", s, data->subwindow_mode),
00300 s = ","));
00301 }
00302
00303 if (mask & GDK_GC_TS_X_ORIGIN) {
00304 data->ts_x_origin = values->ts_x_origin;
00305 data->values_mask |= GDK_GC_TS_X_ORIGIN;
00306 GDK_NOTE(MISC, (g_print("%sts_x=%d", s, data->ts_x_origin),
00307 s = ","));
00308 }
00309
00310 if (mask & GDK_GC_TS_Y_ORIGIN) {
00311 data->ts_y_origin = values->ts_y_origin;
00312 data->values_mask |= GDK_GC_TS_Y_ORIGIN;
00313 GDK_NOTE(MISC, (g_print("%sts_y=%d", s, data->ts_y_origin),
00314 s = ","));
00315 }
00316
00317 if (mask & GDK_GC_CLIP_X_ORIGIN) {
00318 data->clip_x_origin = values->clip_x_origin;
00319 data->values_mask |= GDK_GC_CLIP_X_ORIGIN;
00320 GDK_NOTE(MISC, (g_print("%sclip_x=%d", s, data->clip_x_origin),
00321 s = ","));
00322 }
00323
00324 if (mask & GDK_GC_CLIP_Y_ORIGIN) {
00325 data->clip_y_origin = values->clip_y_origin;
00326 data->values_mask |= GDK_GC_CLIP_Y_ORIGIN;
00327 GDK_NOTE(MISC, (g_print("%sclip_y=%d", s, data->clip_y_origin),
00328 s = ","));
00329 }
00330
00331 if (mask & GDK_GC_EXPOSURES) {
00332 data->graphics_exposures = values->graphics_exposures;
00333 data->values_mask |= GDK_GC_EXPOSURES;
00334 GDK_NOTE(MISC, (g_print("%sexp=%d", s, data->graphics_exposures),
00335 s = ","));
00336 }
00337
00338 if (mask & GDK_GC_LINE_WIDTH) {
00339 data->pen_width = values->line_width;
00340 data->values_mask |= GDK_GC_LINE_WIDTH;
00341 GDK_NOTE(MISC, (g_print("%spw=%d", s, data->pen_width), s = ","));
00342 }
00343
00344 if (mask & GDK_GC_LINE_STYLE) {
00345 data->pen_style &= ~(PS_STYLE_MASK);
00346 GDK_NOTE(MISC, (g_print("%sps|=", s), s = ","));
00347 switch (values->line_style) {
00348 case GDK_LINE_SOLID:
00349 GDK_NOTE(MISC, g_print("LINE_SOLID"));
00350 data->pen_style |= PS_SOLID;
00351 break;
00352 case GDK_LINE_ON_OFF_DASH:
00353 case GDK_LINE_DOUBLE_DASH:
00354 GDK_NOTE(MISC, g_print("DASH"));
00355 data->pen_style |= PS_DASH;
00356 break;
00357 }
00358 data->values_mask |= GDK_GC_LINE_STYLE;
00359 }
00360
00361 if (mask & GDK_GC_CAP_STYLE) {
00362 data->pen_style &= ~(PS_ENDCAP_MASK);
00363 GDK_NOTE(MISC, (g_print("%sps|=", s), s = ","));
00364 switch (values->cap_style) {
00365 case GDK_CAP_NOT_LAST:
00366 case GDK_CAP_BUTT:
00367 GDK_NOTE(MISC, g_print("ENDCAP_FLAT"));
00368 data->pen_style |= PS_ENDCAP_FLAT;
00369 break;
00370 case GDK_CAP_ROUND:
00371 GDK_NOTE(MISC, g_print("ENDCAP_ROUND"));
00372 data->pen_style |= PS_ENDCAP_ROUND;
00373 break;
00374 case GDK_CAP_PROJECTING:
00375 GDK_NOTE(MISC, g_print("ENDCAP_SQUARE"));
00376 data->pen_style |= PS_ENDCAP_SQUARE;
00377 break;
00378 }
00379 data->values_mask |= GDK_GC_CAP_STYLE;
00380 }
00381
00382 if (mask & GDK_GC_JOIN_STYLE) {
00383 data->pen_style &= ~(PS_JOIN_MASK);
00384 GDK_NOTE(MISC, (g_print("%sps|=", s), s = ","));
00385 switch (values->join_style) {
00386 case GDK_JOIN_MITER:
00387 GDK_NOTE(MISC, g_print("JOIN_MITER"));
00388 data->pen_style |= PS_JOIN_MITER;
00389 break;
00390 case GDK_JOIN_ROUND:
00391 GDK_NOTE(MISC, g_print("JOIN_ROUND"));
00392 data->pen_style |= PS_JOIN_ROUND;
00393 break;
00394 case GDK_JOIN_BEVEL:
00395 GDK_NOTE(MISC, g_print("JOIN_BEVEL"));
00396 data->pen_style |= PS_JOIN_BEVEL;
00397 break;
00398 }
00399 data->values_mask |= GDK_GC_JOIN_STYLE;
00400 }
00401 GDK_NOTE(MISC, g_print("}\n"));
00402 }
00403
00404 GdkGC *_gdk_win32_gc_new(GdkDrawable * drawable,
00405 GdkGCValues * values, GdkGCValuesMask mask)
00406 {
00407 GdkGC *gc;
00408 GdkGCPrivate *private;
00409 GdkGCWin32Data *data;
00410 #if 0
00411 static GdkColor black;
00412 static GdkColor white;
00413 static gboolean beenhere = FALSE;
00414
00415 if (!beenhere) {
00416 gdk_color_black(gdk_colormap_get_system(), &black);
00417 gdk_color_white(gdk_colormap_get_system(), &white);
00418 beenhere = TRUE;
00419 }
00420 #endif
00421 gc = gdk_gc_alloc();
00422 private = (GdkGCPrivate *) gc;
00423
00424 private->klass = &gdk_win32_gc_class;
00425 private->klass_data = data = g_new(GdkGCWin32Data, 1);
00426
00427 #if 0
00428 data->foreground = black.pixel;
00429 data->background = white.pixel;
00430 #else
00431 data->foreground = 0;
00432 data->background = 1;
00433 #endif
00434 data->font = NULL;
00435 data->rop2 = R2_COPYPEN;
00436 data->fill_style = GDK_SOLID;
00437 data->tile = NULL;
00438 data->stipple = NULL;
00439 data->clip_region = NULL;
00440 data->ts_x_origin = data->ts_y_origin =
00441 data->clip_x_origin = data->clip_y_origin = 0;
00442 data->pen_style = PS_GEOMETRIC | PS_ENDCAP_FLAT | PS_JOIN_MITER;
00443 data->pen_width = 0;
00444
00445 data->values_mask = GDK_GC_FUNCTION | GDK_GC_FILL;
00446
00447 GDK_NOTE(MISC, g_print("_gdk_win32_gc_new: "));
00448 gdk_win32_gc_values_to_win32values(values, mask, data);
00449
00450 data->hwnd = NULL;
00451 data->xgc = NULL;
00452
00453 GDK_NOTE(MISC, g_print(" = %p\n", gc));
00454
00455 return gc;
00456 }
00457
00458 static void gdk_win32_gc_destroy(GdkGC * gc)
00459 {
00460 GdkGCWin32Data *data = GDK_GC_WIN32DATA(gc);
00461
00462 if (data->values_mask & GDK_GC_FONT)
00463 gdk_font_unref(data->font);
00464
00465 if (data->values_mask & GDK_GC_TILE)
00466 gdk_drawable_unref(data->tile);
00467
00468 if (data->values_mask & GDK_GC_STIPPLE)
00469 gdk_drawable_unref(data->stipple);
00470
00471 if (data->values_mask & GDK_GC_CLIP_MASK)
00472 DeleteObject(data->clip_region);
00473
00474 g_free(GDK_GC_WIN32DATA(gc));
00475 }
00476
00477 static void gdk_win32_gc_get_values(GdkGC * gc, GdkGCValues * values)
00478 {
00479 GdkGCWin32Data *data = GDK_GC_WIN32DATA(gc);
00480
00481 values->foreground.pixel = data->foreground;
00482 values->background.pixel = data->background;
00483 values->font = data->font;
00484
00485 switch (data->rop2) {
00486 case R2_COPYPEN:
00487 values->function = GDK_COPY;
00488 break;
00489 case R2_NOT:
00490 values->function = GDK_INVERT;
00491 break;
00492 case R2_XORPEN:
00493 values->function = GDK_XOR;
00494 break;
00495 case R2_BLACK:
00496 values->function = GDK_CLEAR;
00497 break;
00498 case R2_MASKPEN:
00499 values->function = GDK_AND;
00500 break;
00501 case R2_MASKPENNOT:
00502 values->function = GDK_AND_REVERSE;
00503 break;
00504 case R2_MASKNOTPEN:
00505 values->function = GDK_AND_INVERT;
00506 break;
00507 case R2_NOP:
00508 values->function = GDK_NOOP;
00509 break;
00510 case R2_MERGEPEN:
00511 values->function = GDK_OR;
00512 break;
00513 case R2_NOTXORPEN:
00514 values->function = GDK_EQUIV;
00515 break;
00516 case R2_MERGEPENNOT:
00517 values->function = GDK_OR_REVERSE;
00518 break;
00519 case R2_NOTCOPYPEN:
00520 values->function = GDK_COPY_INVERT;
00521 break;
00522 case R2_MERGENOTPEN:
00523 values->function = GDK_OR_INVERT;
00524 break;
00525 case R2_NOTMASKPEN:
00526 values->function = GDK_NAND;
00527 break;
00528 case R2_WHITE:
00529 values->function = GDK_SET;
00530 break;
00531 }
00532
00533 values->fill = data->fill_style;
00534
00535 values->tile = data->tile;
00536 values->stipple = data->stipple;
00537
00538 values->clip_mask = NULL;
00539 #if 0 // bb mod 15.02.06
00540 if (data->clip_region != NULL) {
00541 RECT rect;
00542 HBRUSH hbr;
00543 HDC hdc;
00544 HGDIOBJ oldbitmap;
00545 GdkPixmap *pixmap;
00546 gboolean ok = TRUE;
00547
00548
00549
00550
00551 GetRgnBox (data->clip_region, &rect);
00552 pixmap = gdk_pixmap_new (NULL, rect.right - rect.left, rect.bottom - rect.top,1);
00553 hbr = GetStockObject (WHITE_BRUSH);
00554 if ((hdc = CreateCompatibleDC (NULL)) == NULL)
00555 WIN32_GDI_FAILED ("CreateCompatibleDC"), ok = FALSE;
00556 if (ok && (oldbitmap =
00557 SelectObject (hdc, GDK_DRAWABLE_XID (pixmap))) == NULL)
00558 WIN32_GDI_FAILED ("SelectObject"), ok = FALSE;
00559 if (ok) {
00560 hbr = GetStockObject (BLACK_BRUSH);
00561 if (hbr == NULL || !FillRect (hdc, &rect, hbr))
00562 WIN32_GDI_FAILED ("FillRect"), ok = FALSE;
00563 }
00564 if (ok) {
00565 hbr = GetStockObject (WHITE_BRUSH);
00566 if (hbr == NULL || !FillRgn (hdc, data->clip_region, hbr))
00567 WIN32_GDI_FAILED ("FillRgn"), ok = FALSE;
00568 }
00569 if (hdc != NULL && oldbitmap != NULL) {
00570 if (SelectObject (hdc, oldbitmap) == NULL)
00571 WIN32_GDI_FAILED ("SelectObject"), ok = FALSE;
00572 }
00573 if (hdc != NULL)
00574 DeleteDC (hdc);
00575 if (ok)
00576 values->clip_mask = pixmap;
00577 else if (pixmap != NULL)
00578 gdk_drawable_unref(pixmap);
00579 }
00580 #endif // bb mod 15.02.06
00581
00582 values->subwindow_mode = data->subwindow_mode;
00583 values->ts_x_origin = data->ts_x_origin;
00584 values->ts_y_origin = data->ts_y_origin;
00585 values->clip_x_origin = data->clip_x_origin;
00586 values->clip_y_origin = data->clip_y_origin;
00587 values->graphics_exposures = data->graphics_exposures;
00588 values->line_width = data->pen_width;
00589
00590 if (data->pen_style & PS_SOLID)
00591 values->line_style = GDK_LINE_SOLID;
00592 else if (data->pen_style & PS_DASH)
00593 values->line_style = GDK_LINE_ON_OFF_DASH;
00594 else
00595 values->line_style = GDK_LINE_SOLID;
00596
00597
00598 if (data->pen_style & PS_ENDCAP_FLAT)
00599 values->cap_style = GDK_CAP_BUTT;
00600 else if (data->pen_style & PS_ENDCAP_SQUARE)
00601 values->cap_style = GDK_CAP_PROJECTING;
00602 else
00603 values->cap_style = GDK_CAP_ROUND;
00604
00605
00606 if (data->pen_style & PS_JOIN_MITER)
00607 values->join_style = GDK_JOIN_MITER;
00608 else if (data->pen_style & PS_JOIN_BEVEL)
00609 values->join_style = GDK_JOIN_BEVEL;
00610 else
00611 values->join_style = GDK_JOIN_ROUND;
00612 }
00613
00614 static void
00615 gdk_win32_gc_set_values(GdkGC * gc,
00616 GdkGCValues * values, GdkGCValuesMask mask)
00617 {
00618 GdkGCWin32Data *data = GDK_GC_WIN32DATA(gc);
00619
00620 GDK_NOTE(MISC, g_print("gdk_win32_gc_set_values: "));
00621
00622 gdk_win32_gc_values_to_win32values(values, mask, data);
00623 }
00624
00625 static void
00626 gdk_win32_gc_set_dashes(GdkGC * gc,
00627 gint dash_offset, gchar dash_list[], gint n)
00628 {
00629 int i;
00630 GdkGCWin32Data *data = GDK_GC_WIN32DATA(gc);
00631
00632 data->pen_style &= ~(PS_STYLE_MASK);
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 if (!IS_WIN_NT(windows_version) && data->pen_width > 1) {
00646 GDK_NOTE(MISC,
00647 g_print("gdk_win32_gc_set_dashes: not fully supported\n"));
00648 data->pen_style |= PS_SOLID;
00649 return;
00650 }
00651
00652 if (!IS_WIN_NT(windows_version)) {
00653
00654 if (2 == n) {
00655 if ((dash_list[0] == dash_list[1]) && (dash_list[0] > 2)) {
00656 data->pen_style |= PS_DASH;
00657 GDK_NOTE(MISC,
00658 g_print("gdk_win32_gc_set_dashes: PS_DASH (%d,%d)\n",
00659 dash_list[0], dash_list[1]));
00660 } else {
00661 data->pen_style |= PS_DOT;
00662 GDK_NOTE(MISC,
00663 g_print("gdk_win32_gc_set_dashes: PS_DOT (%d,%d)\n",
00664 dash_list[0], dash_list[1]));
00665 }
00666 } else if (4 == n) {
00667 data->pen_style |= PS_DASHDOT;
00668 GDK_NOTE(MISC,
00669 g_print
00670 ("gdk_win32_gc_set_dashes: PS_DASHDOT (%d,%d,%d,%d)\n",
00671 dash_list[0], dash_list[1], dash_list[2],
00672 dash_list[3]));
00673 } else if (6 == n) {
00674 data->pen_style |= PS_DASHDOTDOT;
00675 GDK_NOTE(MISC,
00676 g_print
00677 ("gdk_win32_gc_set_dashes: PS_DASHDOTDOT (%d,%d,%d,%d,%d,%d)\n",
00678 dash_list[0], dash_list[1], dash_list[2], dash_list[3],
00679 dash_list[4], dash_list[5]));
00680 } else {
00681 data->pen_style |= PS_DASH;
00682 GDK_NOTE(MISC,
00683 g_print
00684 ("gdk_win32_gc_set_dashes: no guess for %d dashes\n",
00685 n));
00686 }
00687 } else {
00688
00689
00690 if (IS_WIN_NT(windows_version)) {
00691 if ((data->pen_width <= 1) && (n == 0)) {
00692 data->pen_style = PS_COSMETIC;
00693 data->luser_dash = 0;
00694 data->pen_width = 1;
00695 return;
00696 }
00697 }
00698
00699 data->pen_style |= PS_USERSTYLE;
00700 data->luser_dash = n;
00701 for (i = 0; i < n; i++)
00702 data->user_dash[i] = (int) dash_list[i];
00703 }
00704 }
00705
00706 void gdk_gc_set_clip_rectangle(GdkGC * gc, GdkRectangle * rectangle)
00707 {
00708 GdkGCWin32Data *data;
00709
00710 g_return_if_fail(gc != NULL);
00711
00712 data = GDK_GC_WIN32DATA(gc);
00713
00714 if (data->clip_region != NULL)
00715 if (!DeleteObject(data->clip_region))
00716 WIN32_GDI_FAILED("DeleteObject");
00717 if (rectangle) {
00718 GDK_NOTE(MISC,
00719 g_print("gdk_gc_set_clip_rectangle: (%d) %dx%d@+%d+%d\n",
00720 data,
00721 rectangle->width, rectangle->height,
00722 rectangle->x, rectangle->y));
00723 if ((data->clip_region =
00724 CreateRectRgn(rectangle->x, rectangle->y,
00725 rectangle->x + rectangle->width,
00726 rectangle->y + rectangle->height)) == NULL)
00727 WIN32_GDI_FAILED("CreateRectRgn");
00728
00729 data->values_mask |= GDK_GC_CLIP_MASK;
00730 } else {
00731 GDK_NOTE(MISC, g_print("gdk_gc_set_clip_rectangle: (%d) NULL\n",
00732 data));
00733 data->clip_region = NULL;
00734 data->values_mask &= ~GDK_GC_CLIP_MASK;
00735 }
00736 data->values_mask &= ~(GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN);
00737 }
00738
00739 void gdk_gc_set_clip_region(GdkGC * gc, GdkRegion * region)
00740 {
00741 GdkGCWin32Data *data;
00742
00743 g_return_if_fail(gc != NULL);
00744
00745 data = GDK_GC_WIN32DATA(gc);
00746
00747 GDK_NOTE(MISC, g_print("gdk_gc_set_clip_region: (%d) %s\n",
00748 data, (region != NULL ? "xxx" : "None")));
00749
00750 if (data->clip_region != NULL)
00751 if (!DeleteObject(data->clip_region))
00752 WIN32_GDI_FAILED("DeleteObject");
00753 if (region) {
00754 GdkRegionPrivate *region_private;
00755
00756 region_private = (GdkRegionPrivate *) region;
00757 data->clip_region = CreateRectRgn(1, 1, 0, 0);
00758 CombineRgn(data->clip_region, region_private->xregion, NULL,
00759 RGN_COPY);
00760 data->values_mask |= GDK_GC_CLIP_MASK;
00761 } else {
00762 data->clip_region = NULL;
00763 data->values_mask &= ~GDK_GC_CLIP_MASK;
00764 }
00765 }
00766
00767 void gdk_gc_copy(GdkGC * dst_gc, GdkGC * src_gc)
00768 {
00769 GdkGCWin32Data *dst_data = GDK_GC_WIN32DATA(dst_gc);
00770 GdkGCWin32Data *src_data = GDK_GC_WIN32DATA(src_gc);
00771 DWORD nbytes;
00772 LPRGNDATA rgn;
00773
00774 if (dst_data->font != NULL)
00775 gdk_font_unref(dst_data->font);
00776 if (dst_data->tile != NULL)
00777 gdk_drawable_unref(dst_data->tile);
00778 if (dst_data->stipple != NULL)
00779 gdk_drawable_unref(dst_data->stipple);
00780 if (dst_data->clip_region != NULL)
00781 if (!DeleteObject(dst_data->clip_region))
00782 WIN32_GDI_FAILED("DeleteObject");
00783
00784 *dst_data = *src_data;
00785
00786 if (dst_data->clip_region != NULL) {
00787 nbytes = GetRegionData(dst_data->clip_region, 0, NULL);
00788 rgn = g_malloc(nbytes);
00789 GetRegionData(dst_data->clip_region, nbytes, rgn);
00790 if ((dst_data->clip_region =
00791 ExtCreateRegion(NULL, nbytes, rgn)) == NULL)
00792 WIN32_GDI_FAILED("ExtCreateRegion");
00793 g_free(rgn);
00794 }
00795
00796 if (dst_data->font != NULL)
00797 gdk_font_ref(dst_data->font);
00798 if (dst_data->tile != NULL)
00799 gdk_drawable_ref(dst_data->tile);
00800 if (dst_data->stipple != NULL)
00801 gdk_drawable_ref(dst_data->stipple);
00802 }
00803
00804 static guint bitmask[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
00805
00806 COLORREF
00807 gdk_colormap_color(GdkColormapPrivateWin32 * colormap_private,
00808 gulong pixel)
00809 {
00810 GdkVisual *visual;
00811 guchar r, g, b;
00812
00813 if (colormap_private == NULL || colormap_private->xcolormap->rc_palette)
00814 return PALETTEINDEX(pixel);
00815 else {
00816 visual = colormap_private->base.visual;
00817 r = (pixel & visual->red_mask) >> visual->red_shift;
00818 r = (r * 255) / bitmask[visual->red_prec];
00819 g = (pixel & visual->green_mask) >> visual->green_shift;
00820 g = (g * 255) / bitmask[visual->green_prec];
00821 b = (pixel & visual->blue_mask) >> visual->blue_shift;
00822 b = (b * 255) / bitmask[visual->blue_prec];
00823
00824 return RGB(r, g, b);
00825 }
00826 }
00827
00828 static void
00829 predraw_set_foreground(GdkGCWin32Data * data,
00830 GdkColormapPrivateWin32 * colormap_private)
00831 {
00832 COLORREF fg;
00833 LOGBRUSH logbrush;
00834 HPEN hpen;
00835 HBRUSH hbr;
00836
00837 if (colormap_private == NULL) {
00838
00839 struct {
00840 WORD palVersion;
00841 WORD palNumEntries;
00842 PALETTEENTRY palPalEntry[2];
00843 } logpal;
00844 static HPALETTE hpal = NULL;
00845
00846 if (hpal == NULL) {
00847
00848 logpal.palVersion = 0x300;
00849 logpal.palNumEntries = 2;
00850 logpal.palPalEntry[0].peRed =
00851 logpal.palPalEntry[0].peGreen =
00852 logpal.palPalEntry[0].peBlue = 0x00;
00853 logpal.palPalEntry[0].peFlags = 0x00;
00854 logpal.palPalEntry[1].peRed =
00855 logpal.palPalEntry[1].peGreen =
00856 logpal.palPalEntry[1].peBlue = 0xFF;
00857 logpal.palPalEntry[1].peFlags = 0x00;
00858 if ((hpal = CreatePalette((LOGPALETTE *) & logpal)) == NULL)
00859 WIN32_GDI_FAILED("CreatePalette");
00860 }
00861 SelectPalette(data->xgc, hpal, FALSE);
00862 RealizePalette(data->xgc);
00863 fg = PALETTEINDEX(data->foreground);
00864 } else if (colormap_private->xcolormap->rc_palette) {
00865 int k;
00866 if (SelectPalette(data->xgc, colormap_private->xcolormap->palette,
00867 FALSE) == NULL)
00868 WIN32_GDI_FAILED("SelectPalette");
00869 if (TRUE || colormap_private->xcolormap->stale) {
00870 if ((k = RealizePalette(data->xgc)) == GDI_ERROR)
00871 WIN32_GDI_FAILED("RealizePalette");
00872 colormap_private->xcolormap->stale = FALSE;
00873 }
00874 #if 0
00875 g_print("Selected palette %#x for gc %#x, realized %d colors\n",
00876 colormap_private->xcolormap->palette, data->xgc, k);
00877 #endif
00878 }
00879
00880 fg = gdk_colormap_color(colormap_private, data->foreground);
00881
00882 if (SetTextColor(data->xgc, fg) == CLR_INVALID)
00883 WIN32_GDI_FAILED("SetTextColor");
00884
00885
00886
00887 logbrush.lbStyle = BS_SOLID;
00888 logbrush.lbColor = fg;
00889 logbrush.lbHatch = 0;
00890
00891
00892 if (data->pen_width <= 1) {
00893 data->pen_width = 1;
00894
00895 if (IS_WIN_NT(windows_version)) {
00896 if ((data->pen_style & PS_STYLE_MASK) == PS_SOLID) {
00897 data->pen_style = PS_COSMETIC;
00898 }
00899 }
00900
00901 } else {
00902 data->pen_style |= PS_GEOMETRIC;
00903 }
00904
00905
00906 if (IS_WIN_NT(windows_version) && (data->pen_style & PS_USERSTYLE)) {
00907 if ((hpen = ExtCreatePen(data->pen_style, data->pen_width,
00908 &logbrush, data->luser_dash,
00909 (CONST DWORD *) data->user_dash)) == NULL)
00910 WIN32_GDI_FAILED("ExtCreatePen");
00911 } else {
00912 if ((hpen = ExtCreatePen(data->pen_style, data->pen_width,
00913 &logbrush, 0, NULL)) == NULL)
00914 WIN32_GDI_FAILED("ExtCreatePen");
00915 if (SetBkMode(data->xgc, TRANSPARENT) == 0)
00916 WIN32_GDI_FAILED("SetBkMode");
00917 }
00918 if (SelectObject(data->xgc, hpen) == NULL)
00919 WIN32_GDI_FAILED("SelectObject");
00920
00921 switch (data->fill_style) {
00922 case GDK_OPAQUE_STIPPLED:
00923 if ((hbr =
00924 CreatePatternBrush(GDK_DRAWABLE_XID(data->stipple))) == NULL)
00925 WIN32_GDI_FAILED("CreatePatternBrush");
00926
00927 SetBrushOrgEx(data->xgc, data->ts_x_origin, data->ts_y_origin, NULL);
00928
00929 break;
00930
00931 case GDK_STIPPLED:
00932 if ((hbr =
00933 CreatePatternBrush(GDK_DRAWABLE_XID(data->stipple))) == NULL)
00934 WIN32_GDI_FAILED("CreatePatternBrush");
00935
00936 SetBrushOrgEx(data->xgc, data->ts_x_origin, data->ts_y_origin, NULL);
00937
00938 break;
00939
00940 case GDK_SOLID:
00941 default:
00942 if ((hbr = CreateSolidBrush(fg)) == NULL)
00943 WIN32_GDI_FAILED("CreateSolidBrush");
00944 break;
00945 }
00946 if (SelectObject(data->xgc, hbr) == NULL)
00947 WIN32_GDI_FAILED("SelectObject");
00948 }
00949
00950 void
00951 predraw_set_background(GdkGCWin32Data * data,
00952 GdkColormapPrivateWin32 * colormap_private)
00953 {
00954 COLORREF bg = gdk_colormap_color(colormap_private, data->background);
00955
00956 if (SetBkColor(data->xgc, bg) == CLR_INVALID)
00957 WIN32_GDI_FAILED("SetBkColor");
00958 }
00959
00960 HDC
00961 gdk_gc_predraw(GdkDrawable * drawable,
00962 GdkGCPrivate * gc_private, GdkGCValuesMask usage)
00963 {
00964 GdkDrawablePrivate *drawable_private = (GdkDrawablePrivate *) drawable;
00965 GdkColormapPrivateWin32 *colormap_private =
00966 (GdkColormapPrivateWin32 *) drawable_private->colormap;
00967 GdkGCWin32Data *data = GDK_GC_WIN32DATA(gc_private);
00968
00969 g_assert(data->xgc == NULL);
00970
00971 data->hwnd = GDK_DRAWABLE_XID(drawable);
00972
00973 if (GDK_DRAWABLE_TYPE(drawable) == GDK_DRAWABLE_PIXMAP) {
00974 if ((data->xgc = CreateCompatibleDC(NULL)) == NULL)
00975 WIN32_GDI_FAILED("CreateCompatibleDC");
00976
00977 if ((data->saved_dc = SaveDC(data->xgc)) == 0)
00978 WIN32_GDI_FAILED("SaveDC");
00979
00980 if (SelectObject(data->xgc, data->hwnd) == NULL)
00981 WIN32_GDI_FAILED("SelectObject");
00982 } else {
00983 if ((data->xgc = GetDC(data->hwnd)) == NULL)
00984 WIN32_GDI_FAILED("GetDC");
00985
00986 if ((data->saved_dc = SaveDC(data->xgc)) == 0)
00987 WIN32_GDI_FAILED("SaveDC");
00988 }
00989
00990 if (usage & GDK_GC_FOREGROUND)
00991 predraw_set_foreground(data, colormap_private);
00992
00993 if ((usage & GDK_GC_BACKGROUND)
00994 && (data->values_mask & GDK_GC_BACKGROUND))
00995 predraw_set_background(data, colormap_private);
00996
00997
00998 if (!IS_WIN_NT(windows_version)) {
00999 if (SetBkMode(data->xgc, TRANSPARENT) == 0)
01000 WIN32_GDI_FAILED("SetBkMode");
01001 }
01002
01003 if (usage & GDK_GC_FONT) {
01004 if (SetBkMode(data->xgc, TRANSPARENT) == 0)
01005 WIN32_GDI_FAILED("SetBkMode");
01006
01007
01008 if (SetTextAlign(data->xgc, text_align) == GDI_ERROR)
01009 WIN32_GDI_FAILED("SetTextAlign");
01010 }
01011
01012 if (data->rop2 != R2_COPYPEN)
01013 if (SetROP2(data->xgc, data->rop2) == 0)
01014 WIN32_GDI_FAILED("SetROP2");
01015
01016 if ((data->values_mask & GDK_GC_CLIP_MASK)
01017 && data->clip_region != NULL) {
01018 if (data->
01019 values_mask & (GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN))
01020 OffsetRgn(data->clip_region, data->clip_x_origin,
01021 data->clip_y_origin);
01022 SelectClipRgn(data->xgc, data->clip_region);
01023 }
01024
01025 return data->xgc;
01026 }
01027
01028 void
01029 gdk_gc_postdraw(GdkDrawable * drawable,
01030 GdkGCPrivate * gc_private, GdkGCValuesMask usage)
01031 {
01032 GdkDrawablePrivate *drawable_private = (GdkDrawablePrivate *) drawable;
01033 GdkColormapPrivateWin32 *colormap_private =
01034 (GdkColormapPrivateWin32 *) drawable_private->colormap;
01035 GdkGCWin32Data *data = GDK_GC_WIN32DATA(gc_private);
01036 HGDIOBJ hpen = NULL;
01037 HGDIOBJ hbr = NULL;
01038
01039 if (usage & GDK_GC_FOREGROUND) {
01040 if ((hpen = GetCurrentObject(data->xgc, OBJ_PEN)) == NULL)
01041 WIN32_GDI_FAILED("GetCurrentObject");
01042
01043 if ((hbr = GetCurrentObject(data->xgc, OBJ_BRUSH)) == NULL)
01044 WIN32_GDI_FAILED("GetCurrentObject");
01045 }
01046
01047 if (!RestoreDC(data->xgc, data->saved_dc))
01048 WIN32_GDI_FAILED("RestoreDC");
01049 #if 0
01050 if (colormap_private != NULL
01051 && colormap_private->xcolormap->rc_palette
01052 && colormap_private->xcolormap->stale) {
01053 SelectPalette(data->xgc, GetStockObject(DEFAULT_PALETTE), FALSE);
01054 if (!UnrealizeObject(colormap_private->xcolormap->palette))
01055 WIN32_GDI_FAILED("UnrealizeObject");
01056 }
01057 #endif
01058 if (GDK_DRAWABLE_TYPE(drawable) == GDK_DRAWABLE_PIXMAP) {
01059 if (!DeleteDC(data->xgc))
01060 WIN32_GDI_FAILED("DeleteDC");
01061 } else {
01062 ReleaseDC(data->hwnd, data->xgc);
01063 }
01064
01065 if (hpen != NULL)
01066 if (!DeleteObject(hpen))
01067 WIN32_GDI_FAILED("DeleteObject");
01068
01069 if (hbr != NULL)
01070 if (!DeleteObject(hbr))
01071 WIN32_GDI_FAILED("DeleteObject");
01072
01073 if ((data->values_mask & GDK_GC_CLIP_MASK)
01074 && data->clip_region != NULL
01075 && (data->
01076 values_mask & (GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN)))
01077 OffsetRgn(data->clip_region, -data->clip_x_origin,
01078 -data->clip_y_origin);
01079 data->xgc = NULL;
01080 }
01081
01082 HDC
01083 gdk_win32_hdc_get(GdkDrawable * drawable,
01084 GdkGC * gc, GdkGCValuesMask usage)
01085 {
01086 return gdk_gc_predraw(drawable, (GdkGCPrivate *) gc, usage);
01087 }
01088
01089 void
01090 gdk_win32_hdc_release(GdkDrawable * drawable,
01091 GdkGC * gc, GdkGCValuesMask usage)
01092 {
01093 gdk_gc_postdraw(drawable, (GdkGCPrivate *) gc, usage);
01094 }
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110 HRGN BitmapToRegion(HBITMAP hBmp)
01111 {
01112 HRGN hRgn = NULL;
01113 HDC hMemDC;
01114 BITMAP bm;
01115
01116 struct {
01117 BITMAPINFOHEADER bmiHeader;
01118 #if 1
01119 WORD bmiColors[2];
01120 #else
01121 RGBQUAD bmiColors[2];
01122 #endif
01123 } bmi;
01124 VOID *pbits8;
01125 HBITMAP hbm8;
01126 struct {
01127 WORD palVersion;
01128 WORD palNumEntries;
01129 PALETTEENTRY palPalEntry[2];
01130 } logpal;
01131 static HPALETTE bwPalette = NULL;
01132
01133 HBITMAP holdBmp;
01134 HDC hDC;
01135
01136 BITMAP bm8;
01137 HBITMAP holdBmp2;
01138 DWORD maxRects;
01139 RGNDATA *pData;
01140 BYTE *p8;
01141 int x, y;
01142 HRGN h;
01143
01144
01145 if (bwPalette == NULL) {
01146
01147 logpal.palVersion = 0x300;
01148 logpal.palNumEntries = 2;
01149 logpal.palPalEntry[0].peRed =
01150 logpal.palPalEntry[0].peGreen = logpal.palPalEntry[0].peBlue = 0;
01151 logpal.palPalEntry[0].peFlags = 0;
01152 logpal.palPalEntry[1].peRed =
01153 logpal.palPalEntry[1].peGreen =
01154 logpal.palPalEntry[1].peBlue = 0xFF;
01155 logpal.palPalEntry[1].peFlags = 0;
01156 if ((bwPalette = CreatePalette((LOGPALETTE *) & logpal)) == NULL)
01157 WIN32_GDI_FAILED("CreatePalette");
01158 }
01159
01160
01161 hMemDC = CreateCompatibleDC(NULL);
01162 if (!hMemDC) {
01163 WIN32_GDI_FAILED("CreateCompatibleDC");
01164 return NULL;
01165 }
01166
01167 SelectPalette(hMemDC, bwPalette, FALSE);
01168 RealizePalette(hMemDC);
01169
01170
01171 GetObject(hBmp, sizeof(bm), &bm);
01172
01173
01174 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
01175 bmi.bmiHeader.biWidth = bm.bmWidth;
01176 bmi.bmiHeader.biHeight = bm.bmHeight;
01177 bmi.bmiHeader.biPlanes = 1;
01178 bmi.bmiHeader.biBitCount = 8;
01179 bmi.bmiHeader.biCompression = BI_RGB;
01180 bmi.bmiHeader.biSizeImage = 0;
01181 bmi.bmiHeader.biXPelsPerMeter = 0;
01182 bmi.bmiHeader.biYPelsPerMeter = 0;
01183 bmi.bmiHeader.biClrUsed = 2;
01184 bmi.bmiHeader.biClrImportant = 2;
01185 #if 1
01186 bmi.bmiColors[0] = 0;
01187 bmi.bmiColors[1] = 1;
01188 hbm8 = CreateDIBSection(hMemDC, (BITMAPINFO *) & bmi,
01189 DIB_PAL_COLORS, &pbits8, NULL, 0);
01190 #else
01191 bmi.bmiColors[0].rgbBlue =
01192 bmi.bmiColors[0].rgbGreen = bmi.bmiColors[0].rgbRed = 0x00;
01193 bmi.bmiColors[0].rgbReserved = 0x00;
01194
01195 bmi.bmiColors[1].rgbBlue =
01196 bmi.bmiColors[1].rgbGreen = bmi.bmiColors[1].rgbRed = 0xFF;
01197 bmi.bmiColors[0].rgbReserved = 0x00;
01198
01199 hbm8 = CreateDIBSection(hMemDC, (BITMAPINFO *) & bmi,
01200 DIB_RGB_COLORS, &pbits8, NULL, 0);
01201 #endif
01202 if (!hbm8) {
01203 WIN32_GDI_FAILED("CreateDIBSection");
01204 DeleteDC(hMemDC);
01205 return NULL;
01206 }
01207
01208 holdBmp = (HBITMAP) SelectObject(hMemDC, hbm8);
01209
01210
01211 hDC = CreateCompatibleDC(hMemDC);
01212 if (!hDC) {
01213 WIN32_GDI_FAILED("CreateCompatibleDC #2");
01214 SelectObject(hMemDC, holdBmp);
01215 DeleteObject(hbm8);
01216 DeleteDC(hMemDC);
01217 return NULL;
01218 }
01219
01220
01221 GetObject(hbm8, sizeof(bm8), &bm8);
01222
01223
01224
01225
01226
01227
01228
01229
01230 bm8.bmWidthBytes = (((bm8.bmWidthBytes - 1) / 4) + 1) * 4;
01231
01232
01233 holdBmp2 = (HBITMAP) SelectObject(hDC, hBmp);
01234
01235 if (!BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY)) {
01236 WIN32_GDI_FAILED("BitBlt");
01237 SelectObject(hDC, holdBmp2);
01238 SelectObject(hMemDC, holdBmp);
01239 DeleteObject(hbm8);
01240 DeleteDC(hMemDC);
01241 return NULL;
01242 }
01243 SelectObject(hDC, holdBmp2);
01244 DeleteDC(hDC);
01245
01246
01247
01248
01249
01250
01251 #define ALLOC_UNIT 200
01252 maxRects = ALLOC_UNIT;
01253
01254 pData = g_malloc(sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
01255 memset(pData, 0, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
01256 pData->rdh.dwSize = sizeof(RGNDATAHEADER);
01257 pData->rdh.iType = RDH_RECTANGLES;
01258 pData->rdh.nCount = pData->rdh.nRgnSize = 0;
01259 SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
01260
01261
01262 p8 = (BYTE *) pbits8 + (bm8.bmHeight - 1) * bm8.bmWidthBytes;
01263 for (y = 0; y < bm.bmHeight; y++) {
01264
01265 for (x = 0; x < bm.bmWidth; x++) {
01266
01267 int x0 = x;
01268 BYTE *p = p8 + x;
01269 while (x < bm.bmWidth) {
01270 if (*p == 0)
01271
01272 break;
01273 p++;
01274 x++;
01275 }
01276
01277 if (x > x0) {
01278 RECT *pr;
01279
01280
01281
01282 if (pData->rdh.nCount >= maxRects) {
01283 maxRects += ALLOC_UNIT;
01284 pData = g_realloc(pData, sizeof(RGNDATAHEADER)
01285 + (sizeof(RECT) * maxRects));
01286 }
01287 pr = (RECT *) & pData->Buffer;
01288 SetRect(&pr[pData->rdh.nCount], x0, y, x, y + 1);
01289 if (x0 < pData->rdh.rcBound.left)
01290 pData->rdh.rcBound.left = x0;
01291 if (y < pData->rdh.rcBound.top)
01292 pData->rdh.rcBound.top = y;
01293 if (x > pData->rdh.rcBound.right)
01294 pData->rdh.rcBound.right = x;
01295 if (y + 1 > pData->rdh.rcBound.bottom)
01296 pData->rdh.rcBound.bottom = y + 1;
01297 pData->rdh.nCount++;
01298
01299
01300
01301
01302
01303
01304 if (pData->rdh.nCount == 2000) {
01305 HRGN h = ExtCreateRegion(NULL,
01306 sizeof(RGNDATAHEADER) +
01307 (sizeof(RECT) * maxRects), pData);
01308 if (hRgn) {
01309 CombineRgn(hRgn, hRgn, h, RGN_OR);
01310 DeleteObject(h);
01311 } else
01312 hRgn = h;
01313 pData->rdh.nCount = 0;
01314 SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
01315 }
01316 }
01317 }
01318
01319
01320 p8 -= bm8.bmWidthBytes;
01321 }
01322
01323
01324 h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER)
01325 + (sizeof(RECT) * maxRects), pData);
01326 if (hRgn) {
01327 CombineRgn(hRgn, hRgn, h, RGN_OR);
01328 DeleteObject(h);
01329 } else
01330 hRgn = h;
01331
01332
01333 g_free(pData);
01334 SelectObject(hMemDC, holdBmp);
01335 DeleteObject(hbm8);
01336 DeleteDC(hMemDC);
01337
01338 return hRgn;
01339 }
01340
01341 #ifdef G_ENABLE_DEBUG
01342
01343 gchar *gdk_win32_cap_style_to_string(GdkCapStyle cap_style)
01344 {
01345 switch (cap_style) {
01346 #define CASE(x) case x: return #x + strlen ("GDK_CAP_")
01347 CASE(GDK_CAP_NOT_LAST);
01348 CASE(GDK_CAP_BUTT);
01349 CASE(GDK_CAP_ROUND);
01350 CASE(GDK_CAP_PROJECTING);
01351 #undef CASE
01352 default:
01353 return ("illegal GdkCapStyle value");
01354 }
01355
01356 return NULL;
01357 }
01358
01359 gchar *gdk_win32_fill_style_to_string(GdkFill fill)
01360 {
01361 switch (fill) {
01362 #define CASE(x) case x: return #x + strlen ("GDK_")
01363 CASE(GDK_SOLID);
01364 CASE(GDK_TILED);
01365 CASE(GDK_STIPPLED);
01366 CASE(GDK_OPAQUE_STIPPLED);
01367 #undef CASE
01368 default:
01369 return ("illegal GdkFill value");
01370 }
01371
01372 return NULL;
01373 }
01374
01375 gchar *gdk_win32_function_to_string(GdkFunction function)
01376 {
01377 switch (function) {
01378 #define CASE(x) case x: return #x + strlen ("GDK_")
01379 CASE(GDK_COPY);
01380 CASE(GDK_INVERT);
01381 CASE(GDK_XOR);
01382 CASE(GDK_CLEAR);
01383 CASE(GDK_AND);
01384 CASE(GDK_AND_REVERSE);
01385 CASE(GDK_AND_INVERT);
01386 CASE(GDK_NOOP);
01387 CASE(GDK_OR);
01388 CASE(GDK_EQUIV);
01389 CASE(GDK_OR_REVERSE);
01390 CASE(GDK_COPY_INVERT);
01391 CASE(GDK_OR_INVERT);
01392 CASE(GDK_NAND);
01393 CASE(GDK_SET);
01394 #undef CASE
01395 default:
01396 return ("illegal GdkFunction value");
01397 }
01398
01399 return NULL;
01400 }
01401
01402 gchar *gdk_win32_join_style_to_string(GdkJoinStyle join_style)
01403 {
01404 switch (join_style) {
01405 #define CASE(x) case x: return #x + strlen ("GDK_JOIN_")
01406 CASE(GDK_JOIN_MITER);
01407 CASE(GDK_JOIN_ROUND);
01408 CASE(GDK_JOIN_BEVEL);
01409 #undef CASE
01410 default:
01411 return ("illegal GdkJoinStyle value");
01412 }
01413
01414 return NULL;
01415 }
01416
01417 gchar *gdk_win32_line_style_to_string(GdkLineStyle line_style)
01418 {
01419 switch (line_style) {
01420 #define CASE(x) case x: return #x + strlen ("GDK_LINE_")
01421 CASE(GDK_LINE_SOLID);
01422 CASE(GDK_LINE_ON_OFF_DASH);
01423 CASE(GDK_LINE_DOUBLE_DASH);
01424 #undef CASE
01425 default:
01426 return ("illegal GdkLineStyle value");
01427 }
01428
01429 return NULL;
01430 }
01431 #endif