Mercurial > projects > dwt-linux
comparison dwt/graphics/GC.d @ 240:ce446666f5a2
Update to SWT 3.4M7
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 12 May 2008 19:13:01 +0200 |
parents | 380bad9f6852 |
children | 448eacc3a526 |
comparison
equal
deleted
inserted
replaced
239:06a1f6829310 | 240:ce446666f5a2 |
---|---|
76 * </p> | 76 * </p> |
77 * | 77 * |
78 * @see dwt.events.PaintEvent | 78 * @see dwt.events.PaintEvent |
79 */ | 79 */ |
80 public final class GC : Resource { | 80 public final class GC : Resource { |
81 | |
82 alias Resource.init_ init_; | |
83 | |
81 /** | 84 /** |
82 * the handle to the OS device context | 85 * the handle to the OS device context |
83 * (Warning: This field is platform dependent) | 86 * (Warning: This field is platform dependent) |
84 * <p> | 87 * <p> |
85 * <b>IMPORTANT:</b> This field is <em>not</em> part of the DWT | 88 * <b>IMPORTANT:</b> This field is <em>not</em> part of the DWT |
178 auto gdkGC = drawable.internal_new_GC(data); | 181 auto gdkGC = drawable.internal_new_GC(data); |
179 Device device = data.device; | 182 Device device = data.device; |
180 if (device is null) device = Device.getDevice(); | 183 if (device is null) device = Device.getDevice(); |
181 if (device is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | 184 if (device is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); |
182 this.device = data.device = device; | 185 this.device = data.device = device; |
183 init(drawable, data, gdkGC); | 186 init_(drawable, data, gdkGC); |
184 if (device.tracking) device.new_Object(this); | 187 init_(); |
185 } | 188 } |
186 | 189 |
187 static void addCairoString(cairo_t* cairo, String str, float x, float y, Font font) { | 190 static void addCairoString(cairo_t* cairo, String str, float x, float y, Font font) { |
188 char* buffer = toStringz( str ); | 191 char* buffer = toStringz( str ); |
189 if (OS.GTK_VERSION >= OS.buildVERSION(2, 8, 0)) { | 192 if (OS.GTK_VERSION >= OS.buildVERSION(2, 8, 0)) { |
190 auto layout = OS.pango_cairo_create_layout(cairo); | 193 auto layout = OS.pango_cairo_create_layout(cairo); |
191 if (layout is null) DWT.error(DWT.ERROR_NO_HANDLES); | 194 if (layout is null) DWT.error(DWT.ERROR_NO_HANDLES); |
192 OS.pango_layout_set_text(layout, buffer, -1); | 195 OS.pango_layout_set_text(layout, buffer, -1); |
193 OS.pango_layout_set_font_description(layout, font.handle); | 196 OS.pango_layout_set_font_description(layout, font.handle); |
194 Cairo.cairo_move_to(cairo, x, y); | 197 double currentX, currentY; |
198 Cairo.cairo_get_current_point(cairo, ¤tX, ¤tY); | |
199 if (currentX !is x || currentY !is y) { | |
200 Cairo.cairo_move_to(cairo, x, y); | |
201 } | |
195 OS.pango_cairo_layout_path(cairo, layout); | 202 OS.pango_cairo_layout_path(cairo, layout); |
196 OS.g_object_unref(layout); | 203 OS.g_object_unref(layout); |
197 } else { | 204 } else { |
198 GC.setCairoFont(cairo, font); | 205 GC.setCairoFont(cairo, font); |
199 cairo_font_extents_t* extents = new cairo_font_extents_t(); | 206 cairo_font_extents_t* extents = new cairo_font_extents_t(); |
207 static int checkStyle (int style) { | 214 static int checkStyle (int style) { |
208 if ((style & DWT.LEFT_TO_RIGHT) !is 0) style &= ~DWT.RIGHT_TO_LEFT; | 215 if ((style & DWT.LEFT_TO_RIGHT) !is 0) style &= ~DWT.RIGHT_TO_LEFT; |
209 return style & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT); | 216 return style & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT); |
210 } | 217 } |
211 | 218 |
219 public static GC gtk_new(GdkGC* handle, GCData data) { | |
220 GC gc = new GC(); | |
221 gc.device = data.device; | |
222 gc.init_(null, data, handle); | |
223 return gc; | |
224 } | |
225 | |
212 public static GC gtk_new(Drawable drawable, GCData data) { | 226 public static GC gtk_new(Drawable drawable, GCData data) { |
213 GC gc = new GC(); | 227 GC gc = new GC(); |
214 auto gdkGC = drawable.internal_new_GC(data); | 228 auto gdkGC = drawable.internal_new_GC(data); |
215 gc.device = data.device; | 229 gc.device = data.device; |
216 gc.init(drawable, data, gdkGC); | 230 gc.init_(drawable, data, gdkGC); |
217 return gc; | 231 return gc; |
218 } | 232 } |
219 | 233 |
220 void checkGC (int mask) { | 234 void checkGC (int mask) { |
221 int state = data.state; | 235 int state = data.state; |
235 color = data.background; | 249 color = data.background; |
236 pattern = data.backgroundPattern; | 250 pattern = data.backgroundPattern; |
237 data.state &= ~FOREGROUND; | 251 data.state &= ~FOREGROUND; |
238 } | 252 } |
239 if (pattern !is null) { | 253 if (pattern !is null) { |
240 Cairo.cairo_set_source(cairo, pattern.handle); | 254 if ((data.style & DWT.MIRRORED) !is 0 && pattern.surface !is null) { |
255 auto newPattern = Cairo.cairo_pattern_create_for_surface(pattern.surface); | |
256 if (newPattern is null) DWT.error(DWT.ERROR_NO_HANDLES); | |
257 Cairo.cairo_pattern_set_extend(newPattern, Cairo.CAIRO_EXTEND_REPEAT); | |
258 double[6] matrix; matrix[0] = -1; matrix[1] = 0; matrix[2] = 0; matrix[3] = 1; matrix[4] = 0; matrix[5] = 0; | |
259 Cairo.cairo_pattern_set_matrix(newPattern, cast(cairo_matrix_t*) matrix.ptr); | |
260 Cairo.cairo_set_source(cairo, newPattern); | |
261 Cairo.cairo_pattern_destroy(newPattern); | |
262 } else { | |
263 Cairo.cairo_set_source(cairo, pattern.handle); | |
264 } | |
241 } else { | 265 } else { |
242 Cairo.cairo_set_source_rgba(cairo, (color.red & 0xFFFF) / cast(float)0xFFFF, (color.green & 0xFFFF) / cast(float)0xFFFF, (color.blue & 0xFFFF) / cast(float)0xFFFF, data.alpha / cast(float)0xFF); | 266 Cairo.cairo_set_source_rgba(cairo, (color.red & 0xFFFF) / cast(float)0xFFFF, (color.green & 0xFFFF) / cast(float)0xFFFF, (color.blue & 0xFFFF) / cast(float)0xFFFF, data.alpha / cast(float)0xFF); |
243 } | 267 } |
244 } | 268 } |
245 if ((state & FONT) !is 0) { | 269 if ((state & FONT) !is 0) { |
246 if (data.layout !is null) { | 270 if (data.layout !is null) { |
247 OS.pango_layout_set_font_description(data.layout, data.font); | 271 Font font = data.font; |
272 OS.pango_layout_set_font_description(data.layout, font.handle); | |
248 } | 273 } |
249 if (OS.GTK_VERSION < OS.buildVERSION(2, 8, 0)) { | 274 if (OS.GTK_VERSION < OS.buildVERSION(2, 8, 0)) { |
250 setCairoFont(cairo, data.font); | 275 setCairoFont(cairo, data.font); |
251 } | 276 } |
252 } | 277 } |
310 } | 335 } |
311 if ((state & DRAW_OFFSET) !is 0) { | 336 if ((state & DRAW_OFFSET) !is 0) { |
312 data.cairoXoffset = data.cairoYoffset = 0; | 337 data.cairoXoffset = data.cairoYoffset = 0; |
313 double[] matrix = new double[6]; | 338 double[] matrix = new double[6]; |
314 Cairo.cairo_get_matrix(cairo,cast(cairo_matrix_t*) matrix.ptr); | 339 Cairo.cairo_get_matrix(cairo,cast(cairo_matrix_t*) matrix.ptr); |
315 double scaling = matrix[0]; | 340 double dx = 1; |
341 double dy = 1; | |
342 Cairo.cairo_user_to_device_distance(cairo, &dx, &dy); | |
343 double scaling = dx; | |
316 if (scaling < 0) scaling = -scaling; | 344 if (scaling < 0) scaling = -scaling; |
317 double strokeWidth = data.lineWidth * scaling; | 345 double strokeWidth = data.lineWidth * scaling; |
318 if (strokeWidth is 0 || (cast(int)strokeWidth % 2) is 1) { | 346 if (strokeWidth is 0 || (cast(int)strokeWidth % 2) is 1) { |
319 data.cairoXoffset = 0.5 / scaling; | 347 data.cairoXoffset = 0.5 / scaling; |
320 } | 348 } |
321 scaling = matrix[3]; | 349 scaling = dy; |
322 if (scaling < 0) scaling = -scaling; | 350 if (scaling < 0) scaling = -scaling; |
323 strokeWidth = data.lineWidth * scaling; | 351 strokeWidth = data.lineWidth * scaling; |
324 if (strokeWidth is 0 || (cast(int)strokeWidth % 2) is 1) { | 352 if (strokeWidth is 0 || (cast(int)strokeWidth % 2) is 1) { |
325 data.cairoYoffset = 0.5 / scaling; | 353 data.cairoYoffset = 0.5 / scaling; |
326 } | 354 } |
342 GdkColor* background = data.background; | 370 GdkColor* background = data.background; |
343 OS.gdk_gc_set_background(handle, background); | 371 OS.gdk_gc_set_background(handle, background); |
344 } | 372 } |
345 if ((state & FONT) !is 0) { | 373 if ((state & FONT) !is 0) { |
346 if (data.layout !is null) { | 374 if (data.layout !is null) { |
347 OS.pango_layout_set_font_description(data.layout, data.font); | 375 Font font = data.font; |
376 OS.pango_layout_set_font_description(data.layout, font.handle); | |
348 } | 377 } |
349 } | 378 } |
350 if ((state & (LINE_CAP | LINE_JOIN | LINE_STYLE | LINE_WIDTH)) !is 0) { | 379 if ((state & (LINE_CAP | LINE_JOIN | LINE_STYLE | LINE_WIDTH)) !is 0) { |
351 int cap_style = 0; | 380 int cap_style = 0; |
352 int join_style = 0; | 381 int join_style = 0; |
542 data.context = context; | 571 data.context = context; |
543 auto layout = OS.pango_layout_new(context); | 572 auto layout = OS.pango_layout_new(context); |
544 if (layout is null) DWT.error(DWT.ERROR_NO_HANDLES); | 573 if (layout is null) DWT.error(DWT.ERROR_NO_HANDLES); |
545 data.layout = layout; | 574 data.layout = layout; |
546 OS.pango_context_set_language(context, OS.gtk_get_default_language()); | 575 OS.pango_context_set_language(context, OS.gtk_get_default_language()); |
547 OS.pango_context_set_base_dir(context, OS.PANGO_DIRECTION_LTR); | 576 OS.pango_context_set_base_dir(context, (data.style & DWT.MIRRORED) !is 0 ? OS.PANGO_DIRECTION_RTL : OS.PANGO_DIRECTION_LTR); |
548 OS.gdk_pango_context_set_colormap(context, OS.gdk_colormap_get_system()); | 577 OS.gdk_pango_context_set_colormap(context, OS.gdk_colormap_get_system()); |
549 if (OS.GTK_VERSION >= OS.buildVERSION(2, 4, 0)) { | 578 if (OS.GTK_VERSION >= OS.buildVERSION(2, 4, 0)) { |
550 OS.pango_layout_set_auto_dir(layout, false); | 579 OS.pango_layout_set_auto_dir(layout, false); |
551 } | 580 } |
552 } | 581 } |
557 if (data.layout !is null) OS.g_object_unref(data.layout); | 586 if (data.layout !is null) OS.g_object_unref(data.layout); |
558 data.layout = null; | 587 data.layout = null; |
559 data.context = null; | 588 data.context = null; |
560 } | 589 } |
561 | 590 |
562 /** | 591 void destroy() { |
563 * Disposes of the operating system resources associated with | |
564 * the graphics context. Applications must dispose of all GCs | |
565 * which they allocate. | |
566 * | |
567 * @exception DWTError <ul> | |
568 * <li>ERROR_THREAD_INVALID_ACCESS if not called from the thread that created the drawable</li> | |
569 * </ul> | |
570 */ | |
571 public override void dispose() { | |
572 if (handle is null) return; | |
573 if (data.device.isDisposed()) return; | |
574 | |
575 if (data.disposeCairo) { | 592 if (data.disposeCairo) { |
576 auto cairo = data.cairo; | 593 auto cairo = data.cairo; |
577 if (cairo !is null) Cairo.cairo_destroy(cairo); | 594 if (cairo !is null) Cairo.cairo_destroy(cairo); |
578 data.cairo = null; | 595 data.cairo = null; |
579 } | 596 } |
588 } | 605 } |
589 | 606 |
590 disposeLayout(); | 607 disposeLayout(); |
591 | 608 |
592 /* Dispose the GC */ | 609 /* Dispose the GC */ |
593 Device device = data.device; | 610 if (drawable !is null) { |
594 drawable.internal_dispose_GC(handle, data); | 611 drawable.internal_dispose_GC(handle, data); |
595 | 612 } |
596 data.drawable = null; | 613 data.drawable = null; |
597 data.clipRgn = null; | 614 data.clipRgn = null; |
598 drawable = null; | 615 drawable = null; |
599 handle = null; | 616 handle = null; |
600 data.image = null; | 617 data.image = null; |
601 data.str = null; | 618 data.str = null; |
602 if (device.tracking) device.dispose_Object(this); | |
603 data.device = null; | |
604 data = null; | 619 data = null; |
605 } | 620 } |
606 | 621 |
607 /** | 622 /** |
608 * Draws the outline of a circular or elliptical arc | 623 * Draws the outline of a circular or elliptical arc |
806 auto cairo = data.cairo; | 821 auto cairo = data.cairo; |
807 if (cairo !is null) { | 822 if (cairo !is null) { |
808 if (data.alpha !is 0) { | 823 if (data.alpha !is 0) { |
809 srcImage.createSurface(); | 824 srcImage.createSurface(); |
810 Cairo.cairo_save(cairo); | 825 Cairo.cairo_save(cairo); |
826 if ((data.style & DWT.MIRRORED) !is 0) { | |
827 Cairo.cairo_scale(cairo, -1f, 1); | |
828 Cairo.cairo_translate(cairo, - 2 * destX - destWidth, 0); | |
829 } | |
811 Cairo.cairo_rectangle(cairo, destX , destY, destWidth, destHeight); | 830 Cairo.cairo_rectangle(cairo, destX , destY, destWidth, destHeight); |
812 Cairo.cairo_clip(cairo); | 831 Cairo.cairo_clip(cairo); |
813 Cairo.cairo_translate(cairo, destX - srcX, destY - srcY); | 832 Cairo.cairo_translate(cairo, destX - srcX, destY - srcY); |
814 if (srcWidth !is destWidth || srcHeight !is destHeight) { | 833 if (srcWidth !is destWidth || srcHeight !is destHeight) { |
815 Cairo.cairo_scale(cairo, destWidth / cast(float)srcWidth, destHeight / cast(float)srcHeight); | 834 Cairo.cairo_scale(cairo, destWidth / cast(float)srcWidth, destHeight / cast(float)srcHeight); |
1052 if (srcImage.transparentPixel !is -1 && srcImage.memGC !is null) srcImage.destroyMask(); | 1071 if (srcImage.transparentPixel !is -1 && srcImage.memGC !is null) srcImage.destroyMask(); |
1053 } | 1072 } |
1054 void drawImageXRender(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, bool simple, int imgWidth, int imgHeight, GdkDrawable* maskPixmap, int maskType) { | 1073 void drawImageXRender(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, bool simple, int imgWidth, int imgHeight, GdkDrawable* maskPixmap, int maskType) { |
1055 int translateX = 0, translateY = 0; | 1074 int translateX = 0, translateY = 0; |
1056 auto drawable = data.drawable; | 1075 auto drawable = data.drawable; |
1057 if (data.image is null) { | 1076 if (data.image is null && !data.realDrawable) { |
1058 int x, y; | 1077 int x, y; |
1059 GdkDrawable* real_drawable; | 1078 GdkDrawable* real_drawable; |
1060 OS.gdk_window_get_internal_paint_info(cast(GdkWindow*)drawable, &real_drawable, &x, &y); | 1079 OS.gdk_window_get_internal_paint_info(cast(GdkWindow*)drawable, &real_drawable, &x, &y); |
1061 drawable = real_drawable; | 1080 drawable = real_drawable; |
1062 translateX = -x; | 1081 translateX = -x; |
1446 } | 1465 } |
1447 if (naw < 0) naw = 0 - naw; | 1466 if (naw < 0) naw = 0 - naw; |
1448 if (nah < 0) nah = 0 - nah; | 1467 if (nah < 0) nah = 0 - nah; |
1449 auto cairo = data.cairo; | 1468 auto cairo = data.cairo; |
1450 if (cairo !is null) { | 1469 if (cairo !is null) { |
1451 float naw2 = naw / 2f; | |
1452 float nah2 = nah / 2f; | |
1453 float fw = nw / naw2; | |
1454 float fh = nh / nah2; | |
1455 Cairo.cairo_save(cairo); | |
1456 double xOffset = data.cairoXoffset, yOffset = data.cairoYoffset; | 1470 double xOffset = data.cairoXoffset, yOffset = data.cairoYoffset; |
1457 Cairo.cairo_translate(cairo, nx + xOffset, ny + yOffset); | 1471 if (naw is 0 || nah is 0) { |
1458 Cairo.cairo_scale(cairo, naw2, nah2); | 1472 Cairo.cairo_rectangle(cairo, x + xOffset, y + yOffset, width, height); |
1459 Cairo.cairo_move_to(cairo, fw - 1, 0); | 1473 } else { |
1460 Cairo.cairo_arc(cairo, fw - 1, 1, 1, Compatibility.PI + Compatibility.PI/2.0, Compatibility.PI*2.0); | 1474 float naw2 = naw / 2f; |
1461 Cairo.cairo_arc(cairo, fw - 1, fh - 1, 1, 0, Compatibility.PI/2.0); | 1475 float nah2 = nah / 2f; |
1462 Cairo.cairo_arc(cairo, 1, fh - 1, 1, Compatibility.PI/2, Compatibility.PI); | 1476 float fw = nw / naw2; |
1463 Cairo.cairo_arc(cairo, 1, 1, 1, Compatibility.PI, 270.0*Compatibility.PI/180.0); | 1477 float fh = nh / nah2; |
1464 Cairo.cairo_close_path(cairo); | 1478 Cairo.cairo_save(cairo); |
1465 Cairo.cairo_restore(cairo); | 1479 Cairo.cairo_translate(cairo, nx + xOffset, ny + yOffset); |
1480 Cairo.cairo_scale(cairo, naw2, nah2); | |
1481 Cairo.cairo_move_to(cairo, fw - 1, 0); | |
1482 Cairo.cairo_arc(cairo, fw - 1, 1, 1, Compatibility.PI + Compatibility.PI/2.0, Compatibility.PI*2.0); | |
1483 Cairo.cairo_arc(cairo, fw - 1, fh - 1, 1, 0, Compatibility.PI/2.0); | |
1484 Cairo.cairo_arc(cairo, 1, fh - 1, 1, Compatibility.PI/2, Compatibility.PI); | |
1485 Cairo.cairo_arc(cairo, 1, 1, 1, Compatibility.PI, 270.0*Compatibility.PI/180.0); | |
1486 Cairo.cairo_close_path(cairo); | |
1487 Cairo.cairo_restore(cairo); | |
1488 } | |
1466 Cairo.cairo_stroke(cairo); | 1489 Cairo.cairo_stroke(cairo); |
1467 return; | 1490 return; |
1468 } | 1491 } |
1469 int naw2 = naw / 2; | 1492 int naw2 = naw / 2; |
1470 int nah2 = nah / 2; | 1493 int nah2 = nah / 2; |
1651 OS.pango_layout_get_size(data.layout, &width, &height); | 1674 OS.pango_layout_get_size(data.layout, &width, &height); |
1652 Cairo.cairo_rectangle(cairo, x, y, OS.PANGO_PIXELS(width), OS.PANGO_PIXELS(height)); | 1675 Cairo.cairo_rectangle(cairo, x, y, OS.PANGO_PIXELS(width), OS.PANGO_PIXELS(height)); |
1653 Cairo.cairo_fill(cairo); | 1676 Cairo.cairo_fill(cairo); |
1654 } | 1677 } |
1655 checkGC(FOREGROUND | FONT); | 1678 checkGC(FOREGROUND | FONT); |
1679 if ((data.style & DWT.MIRRORED) !is 0) { | |
1680 Cairo.cairo_save(cairo); | |
1681 int width, height; | |
1682 OS.pango_layout_get_size(data.layout, &width, &height); | |
1683 Cairo.cairo_scale(cairo, -1f, 1); | |
1684 Cairo.cairo_translate(cairo, -2 * x - OS.PANGO_PIXELS(width), 0); | |
1685 } | |
1656 Cairo.cairo_move_to(cairo, x, y); | 1686 Cairo.cairo_move_to(cairo, x, y); |
1657 OS.pango_cairo_show_layout(cairo, data.layout); | 1687 OS.pango_cairo_show_layout(cairo, data.layout); |
1688 if ((data.style & DWT.MIRRORED) !is 0) { | |
1689 Cairo.cairo_restore(cairo); | |
1690 } | |
1691 Cairo.cairo_new_path(cairo); | |
1658 return; | 1692 return; |
1659 } | 1693 } |
1660 checkGC(FOREGROUND | FONT | BACKGROUND_BG); | 1694 checkGC(FOREGROUND | FONT | BACKGROUND_BG); |
1661 GdkColor* background = null; | 1695 GdkColor* background = null; |
1662 if ((flags & DWT.DRAW_TRANSPARENT) is 0) background = data.background; | 1696 if ((flags & DWT.DRAW_TRANSPARENT) is 0) background = data.background; |
2053 } | 2087 } |
2054 if (naw < 0) naw = 0 - naw; | 2088 if (naw < 0) naw = 0 - naw; |
2055 if (nah < 0) nah = 0 - nah; | 2089 if (nah < 0) nah = 0 - nah; |
2056 auto cairo = data.cairo; | 2090 auto cairo = data.cairo; |
2057 if (cairo !is null) { | 2091 if (cairo !is null) { |
2058 float naw2 = naw / 2f; | 2092 if (naw is 0 || nah is 0) { |
2059 float nah2 = nah / 2f; | 2093 Cairo.cairo_rectangle(cairo, x, y, width, height); |
2060 float fw = nw / naw2; | 2094 } else { |
2061 float fh = nh / nah2; | 2095 float naw2 = naw / 2f; |
2062 Cairo.cairo_save(cairo); | 2096 float nah2 = nah / 2f; |
2063 Cairo.cairo_translate(cairo, nx, ny); | 2097 float fw = nw / naw2; |
2064 Cairo.cairo_scale(cairo, naw2, nah2); | 2098 float fh = nh / nah2; |
2065 Cairo.cairo_move_to(cairo, fw - 1, 0); | 2099 Cairo.cairo_save(cairo); |
2066 Cairo.cairo_arc(cairo, fw - 1, 1, 1, Compatibility.PI + Compatibility.PI/2.0, Compatibility.PI*2.0); | 2100 Cairo.cairo_translate(cairo, nx, ny); |
2067 Cairo.cairo_arc(cairo, fw - 1, fh - 1, 1, 0, Compatibility.PI/2.0); | 2101 Cairo.cairo_scale(cairo, naw2, nah2); |
2068 Cairo.cairo_arc(cairo, 1, fh - 1, 1, Compatibility.PI/2, Compatibility.PI); | 2102 Cairo.cairo_move_to(cairo, fw - 1, 0); |
2069 Cairo.cairo_arc(cairo, 1, 1, 1, Compatibility.PI, 270.0*Compatibility.PI/180.0); | 2103 Cairo.cairo_arc(cairo, fw - 1, 1, 1, Compatibility.PI + Compatibility.PI/2.0, Compatibility.PI*2.0); |
2070 Cairo.cairo_close_path(cairo); | 2104 Cairo.cairo_arc(cairo, fw - 1, fh - 1, 1, 0, Compatibility.PI/2.0); |
2071 Cairo.cairo_restore(cairo); | 2105 Cairo.cairo_arc(cairo, 1, fh - 1, 1, Compatibility.PI/2, Compatibility.PI); |
2106 Cairo.cairo_arc(cairo, 1, 1, 1, Compatibility.PI, 270.0*Compatibility.PI/180.0); | |
2107 Cairo.cairo_close_path(cairo); | |
2108 Cairo.cairo_restore(cairo); | |
2109 } | |
2072 Cairo.cairo_fill(cairo); | 2110 Cairo.cairo_fill(cairo); |
2073 return; | 2111 return; |
2074 } | 2112 } |
2075 int naw2 = naw / 2; | 2113 int naw2 = naw / 2; |
2076 int nah2 = nah / 2; | 2114 int nah2 = nah / 2; |
2281 */ | 2319 */ |
2282 public Rectangle getClipping() { | 2320 public Rectangle getClipping() { |
2283 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | 2321 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); |
2284 /* Calculate visible bounds in device space */ | 2322 /* Calculate visible bounds in device space */ |
2285 int x = 0, y = 0, width = 0, height = 0; | 2323 int x = 0, y = 0, width = 0, height = 0; |
2286 int w, h; | 2324 if (data.width !is -1 && data.height !is -1) { |
2287 OS.gdk_drawable_get_size(data.drawable, &w, &h); | 2325 width = data.width; |
2288 width = w; | 2326 height = data.height; |
2289 height = h; | 2327 } else { |
2328 int w, h; | |
2329 OS.gdk_drawable_get_size(data.drawable, &w, &h); | |
2330 width = w; | |
2331 height = h; | |
2332 } | |
2290 /* Intersect visible bounds with clipping in device space and then convert then to user space */ | 2333 /* Intersect visible bounds with clipping in device space and then convert then to user space */ |
2291 auto cairo = data.cairo; | 2334 auto cairo = data.cairo; |
2292 auto clipRgn = data.clipRgn; | 2335 auto clipRgn = data.clipRgn; |
2293 auto damageRgn = data.damageRgn; | 2336 auto damageRgn = data.damageRgn; |
2294 if (clipRgn !is null || damageRgn !is null || cairo !is null) { | 2337 if (clipRgn !is null || damageRgn !is null || cairo !is null) { |
2351 auto clipping = region.handle; | 2394 auto clipping = region.handle; |
2352 OS.gdk_region_subtract(clipping, clipping); | 2395 OS.gdk_region_subtract(clipping, clipping); |
2353 auto cairo = data.cairo; | 2396 auto cairo = data.cairo; |
2354 auto clipRgn = data.clipRgn; | 2397 auto clipRgn = data.clipRgn; |
2355 if (clipRgn is null) { | 2398 if (clipRgn is null) { |
2356 int width,height; | |
2357 OS.gdk_drawable_get_size(data.drawable, &width, &height); | |
2358 GdkRectangle rect; | 2399 GdkRectangle rect; |
2359 rect.width = width; | 2400 if (data.width !is -1 && data.height !is -1) { |
2360 rect.height = height; | 2401 rect.width = data.width; |
2402 rect.height = data.height; | |
2403 } else { | |
2404 int width, height; | |
2405 OS.gdk_drawable_get_size(data.drawable, &width, &height); | |
2406 rect.width = width; | |
2407 rect.height = height; | |
2408 } | |
2361 OS.gdk_region_union_with_rect(clipping, &rect); | 2409 OS.gdk_region_union_with_rect(clipping, &rect); |
2362 } else { | 2410 } else { |
2363 /* Convert clipping to device space if needed */ | 2411 /* Convert clipping to device space if needed */ |
2364 if (data.clippingTransform !is null) { | 2412 if (data.clippingTransform !is null) { |
2365 auto rgn = convertRgn(clipRgn, data.clippingTransform); | 2413 auto rgn = convertRgn(clipRgn, data.clippingTransform); |
2413 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | 2461 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> |
2414 * </ul> | 2462 * </ul> |
2415 */ | 2463 */ |
2416 public Font getFont() { | 2464 public Font getFont() { |
2417 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | 2465 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); |
2418 return Font.gtk_new(data.device, data.font); | 2466 return data.font; |
2419 } | 2467 } |
2420 | 2468 |
2421 /** | 2469 /** |
2422 * Returns a FontMetrics which contains information | 2470 * Returns a FontMetrics which contains information |
2423 * about the font currently being used by the receiver | 2471 * about the font currently being used by the receiver |
2431 */ | 2479 */ |
2432 public FontMetrics getFontMetrics() { | 2480 public FontMetrics getFontMetrics() { |
2433 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | 2481 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); |
2434 if (data.context is null) createLayout(); | 2482 if (data.context is null) createLayout(); |
2435 checkGC(FONT); | 2483 checkGC(FONT); |
2484 Font font = data.font; | |
2436 auto context = data.context; | 2485 auto context = data.context; |
2437 auto lang = OS.pango_context_get_language(context); | 2486 auto lang = OS.pango_context_get_language(context); |
2438 auto metrics = OS.pango_context_get_metrics(context, data.font, lang); | 2487 auto metrics = OS.pango_context_get_metrics(context, font.handle, lang); |
2439 FontMetrics fm = new FontMetrics(); | 2488 FontMetrics fm = new FontMetrics(); |
2440 fm.ascent = OS.PANGO_PIXELS(OS.pango_font_metrics_get_ascent(metrics)); | 2489 fm.ascent = OS.PANGO_PIXELS(OS.pango_font_metrics_get_ascent(metrics)); |
2441 fm.descent = OS.PANGO_PIXELS(OS.pango_font_metrics_get_descent(metrics)); | 2490 fm.descent = OS.PANGO_PIXELS(OS.pango_font_metrics_get_descent(metrics)); |
2442 fm.averageCharWidth = OS.PANGO_PIXELS(OS.pango_font_metrics_get_approximate_char_width(metrics)); | 2491 fm.averageCharWidth = OS.PANGO_PIXELS(OS.pango_font_metrics_get_approximate_char_width(metrics)); |
2443 fm.height = fm.ascent + fm.descent; | 2492 fm.height = fm.ascent + fm.descent; |
2721 if (transform is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | 2770 if (transform is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); |
2722 if (transform.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | 2771 if (transform.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); |
2723 auto cairo = data.cairo; | 2772 auto cairo = data.cairo; |
2724 if (cairo !is null) { | 2773 if (cairo !is null) { |
2725 Cairo.cairo_get_matrix(cairo, cast(cairo_matrix_t*)transform.handle.ptr); | 2774 Cairo.cairo_get_matrix(cairo, cast(cairo_matrix_t*)transform.handle.ptr); |
2775 double[] identity = identity(); | |
2776 Cairo.cairo_matrix_invert(cast(cairo_matrix_t*)identity.ptr); | |
2777 Cairo.cairo_matrix_multiply(cast(cairo_matrix_t*)transform.handle.ptr, cast(cairo_matrix_t*)transform.handle.ptr, cast(cairo_matrix_t*)identity.ptr); | |
2726 } else { | 2778 } else { |
2727 transform.setElements(1, 0, 0, 1, 0, 0); | 2779 transform.setElements(1, 0, 0, 1, 0, 0); |
2728 } | 2780 } |
2729 } | 2781 } |
2730 | 2782 |
2763 */ | 2815 */ |
2764 public override hash_t toHash() { | 2816 public override hash_t toHash() { |
2765 return cast(hash_t)/*64*/handle; | 2817 return cast(hash_t)/*64*/handle; |
2766 } | 2818 } |
2767 | 2819 |
2768 void init(Drawable drawable, GCData data, GdkGC* gdkGC) { | 2820 double[] identity() { |
2821 double[] identity = new double[6]; | |
2822 if ((data.style & DWT.MIRRORED) !is 0) { | |
2823 int w, h; | |
2824 OS.gdk_drawable_get_size(data.drawable, &w, &h); | |
2825 Cairo.cairo_matrix_init(cast(cairo_matrix_t*)identity.ptr, -1, 0, 0, 1, w, 0); | |
2826 } else { | |
2827 Cairo.cairo_matrix_init_identity(cast(cairo_matrix_t*)identity.ptr); | |
2828 } | |
2829 return identity; | |
2830 } | |
2831 | |
2832 void init_(Drawable drawable, GCData data, GdkGC* gdkGC) { | |
2769 if (data.foreground !is null) data.state &= ~FOREGROUND; | 2833 if (data.foreground !is null) data.state &= ~FOREGROUND; |
2770 if (data.background !is null) data.state &= ~(BACKGROUND | BACKGROUND_BG); | 2834 if (data.background !is null) data.state &= ~(BACKGROUND | BACKGROUND_BG); |
2771 if (data.font !is null) data.state &= ~FONT; | 2835 if (data.font !is null) data.state &= ~FONT; |
2772 | 2836 |
2773 Image image = data.image; | 2837 Image image = data.image; |
2781 if (image.transparentPixel !is -1) image.destroyMask(); | 2845 if (image.transparentPixel !is -1) image.destroyMask(); |
2782 } | 2846 } |
2783 this.drawable = drawable; | 2847 this.drawable = drawable; |
2784 this.data = data; | 2848 this.data = data; |
2785 handle = gdkGC; | 2849 handle = gdkGC; |
2850 if ((data.style & DWT.MIRRORED) !is 0) { | |
2851 initCairo(); | |
2852 auto cairo = data.cairo; | |
2853 Cairo.cairo_set_matrix(cairo, cast(cairo_matrix_t*) identity().ptr); | |
2854 } | |
2786 } | 2855 } |
2787 | 2856 |
2788 void initCairo() { | 2857 void initCairo() { |
2789 data.device.checkCairo(); | 2858 data.device.checkCairo(); |
2790 auto cairo = data.cairo; | 2859 auto cairo = data.cairo; |
2795 int translateX = 0, translateY = 0; | 2864 int translateX = 0, translateY = 0; |
2796 auto drawable = data.drawable; | 2865 auto drawable = data.drawable; |
2797 if (data.image !is null) { | 2866 if (data.image !is null) { |
2798 xDrawable = OS.GDK_PIXMAP_XID(drawable); | 2867 xDrawable = OS.GDK_PIXMAP_XID(drawable); |
2799 } else { | 2868 } else { |
2800 int x, y; | 2869 if (!data.realDrawable) { |
2801 GdkDrawable* real_drawable; | 2870 int x, y; |
2802 OS.gdk_window_get_internal_paint_info(cast(GdkWindow*)drawable, &real_drawable, &x, &y); | 2871 GdkDrawable* real_drawable; |
2803 xDrawable = OS.gdk_x11_drawable_get_xid(real_drawable); | 2872 OS.gdk_window_get_internal_paint_info(cast(GdkWindow*)drawable, &real_drawable, &x, &y); |
2804 translateX = -x; | 2873 xDrawable = OS.gdk_x11_drawable_get_xid(real_drawable); |
2805 translateY = -y; | 2874 translateX = -x; |
2875 translateY = -y; | |
2876 } | |
2806 } | 2877 } |
2807 int w, h; | 2878 int w, h; |
2808 OS.gdk_drawable_get_size(drawable, &w, &h); | 2879 OS.gdk_drawable_get_size(drawable, &w, &h); |
2809 int width = w, height = h; | 2880 int width = w, height = h; |
2810 auto surface = Cairo.cairo_xlib_surface_create(cast(void*)xDisplay, xDrawable, xVisual, width, height); | 2881 auto surface = Cairo.cairo_xlib_surface_create(cast(void*)xDisplay, xDrawable, xVisual, width, height); |
2899 * | 2970 * |
2900 * @since 3.1 | 2971 * @since 3.1 |
2901 */ | 2972 */ |
2902 public void setAdvanced(bool advanced) { | 2973 public void setAdvanced(bool advanced) { |
2903 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | 2974 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); |
2975 if ((data.style & DWT.MIRRORED) !is 0) { | |
2976 if (!advanced) { | |
2977 setAlpha(0xFF); | |
2978 setAntialias(DWT.DEFAULT); | |
2979 setBackgroundPattern(null); | |
2980 setClipping(cast(GdkRegion*)null); | |
2981 setForegroundPattern(null); | |
2982 setInterpolation(DWT.DEFAULT); | |
2983 setTextAntialias(DWT.DEFAULT); | |
2984 setTransform(null); | |
2985 } | |
2986 return; | |
2987 } | |
2904 if (advanced && data.cairo !is null) return; | 2988 if (advanced && data.cairo !is null) return; |
2905 if (advanced) { | 2989 if (advanced) { |
2906 try { | 2990 try { |
2907 initCairo(); | 2991 initCairo(); |
2908 } catch (DWTException e) {} | 2992 } catch (DWTException e) {} |
3266 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | 3350 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> |
3267 * </ul> | 3351 * </ul> |
3268 */ | 3352 */ |
3269 public void setFont(Font font) { | 3353 public void setFont(Font font) { |
3270 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | 3354 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); |
3271 if (font is null) font = data.device.systemFont; | 3355 if (font !is null && font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); |
3272 if (font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | 3356 data.font = font !is null ? font : data.device.systemFont; |
3273 data.font = font.handle; | |
3274 data.state &= ~FONT; | 3357 data.state &= ~FONT; |
3275 data.stringWidth = data.stringHeight = -1; | 3358 data.stringWidth = data.stringHeight = -1; |
3276 } | 3359 } |
3277 | 3360 |
3278 /** | 3361 /** |
3467 break; | 3550 break; |
3468 default: | 3551 default: |
3469 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | 3552 DWT.error(DWT.ERROR_INVALID_ARGUMENT); |
3470 } | 3553 } |
3471 } | 3554 } |
3472 int cap = attributes.join; | 3555 int cap = attributes.cap; |
3473 if (cap !is data.lineCap) { | 3556 if (cap !is data.lineCap) { |
3474 mask |= LINE_CAP; | 3557 mask |= LINE_CAP; |
3475 switch (cap) { | 3558 switch (cap) { |
3476 case DWT.JOIN_MITER: | 3559 case DWT.JOIN_MITER: |
3477 case DWT.JOIN_ROUND: | 3560 case DWT.JOIN_ROUND: |
3808 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | 3891 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); |
3809 if (transform !is null && transform.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | 3892 if (transform !is null && transform.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); |
3810 if (data.cairo is null && transform is null) return; | 3893 if (data.cairo is null && transform is null) return; |
3811 initCairo(); | 3894 initCairo(); |
3812 auto cairo = data.cairo; | 3895 auto cairo = data.cairo; |
3896 double[] identity = identity(); | |
3813 if (transform !is null) { | 3897 if (transform !is null) { |
3814 Cairo.cairo_set_matrix(cairo,cast(cairo_matrix_t*) transform.handle.ptr); | 3898 Cairo.cairo_matrix_multiply(cast(cairo_matrix_t*)identity.ptr, cast(cairo_matrix_t*)transform.handle.ptr, cast(cairo_matrix_t*)identity.ptr); |
3815 } else { | 3899 } |
3816 Cairo.cairo_identity_matrix(cairo); | 3900 Cairo.cairo_set_matrix(cairo, cast(cairo_matrix_t*)identity.ptr); |
3817 } | |
3818 data.state &= ~DRAW_OFFSET; | 3901 data.state &= ~DRAW_OFFSET; |
3819 } | 3902 } |
3820 | 3903 |
3821 /** | 3904 /** |
3822 * If the argument is <code>true</code>, puts the receiver | 3905 * If the argument is <code>true</code>, puts the receiver |