Mercurial > projects > dwt-linux
diff 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 |
line wrap: on
line diff
--- a/dwt/graphics/GC.d Mon May 12 15:36:37 2008 +0200 +++ b/dwt/graphics/GC.d Mon May 12 19:13:01 2008 +0200 @@ -78,6 +78,9 @@ * @see dwt.events.PaintEvent */ public final class GC : Resource { + + alias Resource.init_ init_; + /** * the handle to the OS device context * (Warning: This field is platform dependent) @@ -180,8 +183,8 @@ if (device is null) device = Device.getDevice(); if (device is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); this.device = data.device = device; - init(drawable, data, gdkGC); - if (device.tracking) device.new_Object(this); + init_(drawable, data, gdkGC); + init_(); } static void addCairoString(cairo_t* cairo, String str, float x, float y, Font font) { @@ -191,7 +194,11 @@ if (layout is null) DWT.error(DWT.ERROR_NO_HANDLES); OS.pango_layout_set_text(layout, buffer, -1); OS.pango_layout_set_font_description(layout, font.handle); - Cairo.cairo_move_to(cairo, x, y); + double currentX, currentY; + Cairo.cairo_get_current_point(cairo, ¤tX, ¤tY); + if (currentX !is x || currentY !is y) { + Cairo.cairo_move_to(cairo, x, y); + } OS.pango_cairo_layout_path(cairo, layout); OS.g_object_unref(layout); } else { @@ -209,11 +216,18 @@ return style & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT); } +public static GC gtk_new(GdkGC* handle, GCData data) { + GC gc = new GC(); + gc.device = data.device; + gc.init_(null, data, handle); + return gc; +} + public static GC gtk_new(Drawable drawable, GCData data) { GC gc = new GC(); auto gdkGC = drawable.internal_new_GC(data); gc.device = data.device; - gc.init(drawable, data, gdkGC); + gc.init_(drawable, data, gdkGC); return gc; } @@ -237,14 +251,25 @@ data.state &= ~FOREGROUND; } if (pattern !is null) { - Cairo.cairo_set_source(cairo, pattern.handle); + if ((data.style & DWT.MIRRORED) !is 0 && pattern.surface !is null) { + auto newPattern = Cairo.cairo_pattern_create_for_surface(pattern.surface); + if (newPattern is null) DWT.error(DWT.ERROR_NO_HANDLES); + Cairo.cairo_pattern_set_extend(newPattern, Cairo.CAIRO_EXTEND_REPEAT); + double[6] matrix; matrix[0] = -1; matrix[1] = 0; matrix[2] = 0; matrix[3] = 1; matrix[4] = 0; matrix[5] = 0; + Cairo.cairo_pattern_set_matrix(newPattern, cast(cairo_matrix_t*) matrix.ptr); + Cairo.cairo_set_source(cairo, newPattern); + Cairo.cairo_pattern_destroy(newPattern); + } else { + Cairo.cairo_set_source(cairo, pattern.handle); + } } else { 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); } } if ((state & FONT) !is 0) { if (data.layout !is null) { - OS.pango_layout_set_font_description(data.layout, data.font); + Font font = data.font; + OS.pango_layout_set_font_description(data.layout, font.handle); } if (OS.GTK_VERSION < OS.buildVERSION(2, 8, 0)) { setCairoFont(cairo, data.font); @@ -312,13 +337,16 @@ data.cairoXoffset = data.cairoYoffset = 0; double[] matrix = new double[6]; Cairo.cairo_get_matrix(cairo,cast(cairo_matrix_t*) matrix.ptr); - double scaling = matrix[0]; + double dx = 1; + double dy = 1; + Cairo.cairo_user_to_device_distance(cairo, &dx, &dy); + double scaling = dx; if (scaling < 0) scaling = -scaling; double strokeWidth = data.lineWidth * scaling; if (strokeWidth is 0 || (cast(int)strokeWidth % 2) is 1) { data.cairoXoffset = 0.5 / scaling; } - scaling = matrix[3]; + scaling = dy; if (scaling < 0) scaling = -scaling; strokeWidth = data.lineWidth * scaling; if (strokeWidth is 0 || (cast(int)strokeWidth % 2) is 1) { @@ -344,7 +372,8 @@ } if ((state & FONT) !is 0) { if (data.layout !is null) { - OS.pango_layout_set_font_description(data.layout, data.font); + Font font = data.font; + OS.pango_layout_set_font_description(data.layout, font.handle); } } if ((state & (LINE_CAP | LINE_JOIN | LINE_STYLE | LINE_WIDTH)) !is 0) { @@ -544,7 +573,7 @@ if (layout is null) DWT.error(DWT.ERROR_NO_HANDLES); data.layout = layout; OS.pango_context_set_language(context, OS.gtk_get_default_language()); - OS.pango_context_set_base_dir(context, OS.PANGO_DIRECTION_LTR); + OS.pango_context_set_base_dir(context, (data.style & DWT.MIRRORED) !is 0 ? OS.PANGO_DIRECTION_RTL : OS.PANGO_DIRECTION_LTR); OS.gdk_pango_context_set_colormap(context, OS.gdk_colormap_get_system()); if (OS.GTK_VERSION >= OS.buildVERSION(2, 4, 0)) { OS.pango_layout_set_auto_dir(layout, false); @@ -559,19 +588,7 @@ data.context = null; } -/** - * Disposes of the operating system resources associated with - * the graphics context. Applications must dispose of all GCs - * which they allocate. - * - * @exception DWTError <ul> - * <li>ERROR_THREAD_INVALID_ACCESS if not called from the thread that created the drawable</li> - * </ul> - */ -public override void dispose() { - if (handle is null) return; - if (data.device.isDisposed()) return; - +void destroy() { if (data.disposeCairo) { auto cairo = data.cairo; if (cairo !is null) Cairo.cairo_destroy(cairo); @@ -590,17 +607,15 @@ disposeLayout(); /* Dispose the GC */ - Device device = data.device; - drawable.internal_dispose_GC(handle, data); - + if (drawable !is null) { + drawable.internal_dispose_GC(handle, data); + } data.drawable = null; data.clipRgn = null; drawable = null; handle = null; data.image = null; data.str = null; - if (device.tracking) device.dispose_Object(this); - data.device = null; data = null; } @@ -808,6 +823,10 @@ if (data.alpha !is 0) { srcImage.createSurface(); Cairo.cairo_save(cairo); + if ((data.style & DWT.MIRRORED) !is 0) { + Cairo.cairo_scale(cairo, -1f, 1); + Cairo.cairo_translate(cairo, - 2 * destX - destWidth, 0); + } Cairo.cairo_rectangle(cairo, destX , destY, destWidth, destHeight); Cairo.cairo_clip(cairo); Cairo.cairo_translate(cairo, destX - srcX, destY - srcY); @@ -1054,7 +1073,7 @@ 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) { int translateX = 0, translateY = 0; auto drawable = data.drawable; - if (data.image is null) { + if (data.image is null && !data.realDrawable) { int x, y; GdkDrawable* real_drawable; OS.gdk_window_get_internal_paint_info(cast(GdkWindow*)drawable, &real_drawable, &x, &y); @@ -1448,21 +1467,25 @@ if (nah < 0) nah = 0 - nah; auto cairo = data.cairo; if (cairo !is null) { - float naw2 = naw / 2f; - float nah2 = nah / 2f; - float fw = nw / naw2; - float fh = nh / nah2; - Cairo.cairo_save(cairo); double xOffset = data.cairoXoffset, yOffset = data.cairoYoffset; - Cairo.cairo_translate(cairo, nx + xOffset, ny + yOffset); - Cairo.cairo_scale(cairo, naw2, nah2); - Cairo.cairo_move_to(cairo, fw - 1, 0); - Cairo.cairo_arc(cairo, fw - 1, 1, 1, Compatibility.PI + Compatibility.PI/2.0, Compatibility.PI*2.0); - Cairo.cairo_arc(cairo, fw - 1, fh - 1, 1, 0, Compatibility.PI/2.0); - Cairo.cairo_arc(cairo, 1, fh - 1, 1, Compatibility.PI/2, Compatibility.PI); - Cairo.cairo_arc(cairo, 1, 1, 1, Compatibility.PI, 270.0*Compatibility.PI/180.0); - Cairo.cairo_close_path(cairo); - Cairo.cairo_restore(cairo); + if (naw is 0 || nah is 0) { + Cairo.cairo_rectangle(cairo, x + xOffset, y + yOffset, width, height); + } else { + float naw2 = naw / 2f; + float nah2 = nah / 2f; + float fw = nw / naw2; + float fh = nh / nah2; + Cairo.cairo_save(cairo); + Cairo.cairo_translate(cairo, nx + xOffset, ny + yOffset); + Cairo.cairo_scale(cairo, naw2, nah2); + Cairo.cairo_move_to(cairo, fw - 1, 0); + Cairo.cairo_arc(cairo, fw - 1, 1, 1, Compatibility.PI + Compatibility.PI/2.0, Compatibility.PI*2.0); + Cairo.cairo_arc(cairo, fw - 1, fh - 1, 1, 0, Compatibility.PI/2.0); + Cairo.cairo_arc(cairo, 1, fh - 1, 1, Compatibility.PI/2, Compatibility.PI); + Cairo.cairo_arc(cairo, 1, 1, 1, Compatibility.PI, 270.0*Compatibility.PI/180.0); + Cairo.cairo_close_path(cairo); + Cairo.cairo_restore(cairo); + } Cairo.cairo_stroke(cairo); return; } @@ -1653,8 +1676,19 @@ Cairo.cairo_fill(cairo); } checkGC(FOREGROUND | FONT); + if ((data.style & DWT.MIRRORED) !is 0) { + Cairo.cairo_save(cairo); + int width, height; + OS.pango_layout_get_size(data.layout, &width, &height); + Cairo.cairo_scale(cairo, -1f, 1); + Cairo.cairo_translate(cairo, -2 * x - OS.PANGO_PIXELS(width), 0); + } Cairo.cairo_move_to(cairo, x, y); OS.pango_cairo_show_layout(cairo, data.layout); + if ((data.style & DWT.MIRRORED) !is 0) { + Cairo.cairo_restore(cairo); + } + Cairo.cairo_new_path(cairo); return; } checkGC(FOREGROUND | FONT | BACKGROUND_BG); @@ -2055,20 +2089,24 @@ if (nah < 0) nah = 0 - nah; auto cairo = data.cairo; if (cairo !is null) { - float naw2 = naw / 2f; - float nah2 = nah / 2f; - float fw = nw / naw2; - float fh = nh / nah2; - Cairo.cairo_save(cairo); - Cairo.cairo_translate(cairo, nx, ny); - Cairo.cairo_scale(cairo, naw2, nah2); - Cairo.cairo_move_to(cairo, fw - 1, 0); - Cairo.cairo_arc(cairo, fw - 1, 1, 1, Compatibility.PI + Compatibility.PI/2.0, Compatibility.PI*2.0); - Cairo.cairo_arc(cairo, fw - 1, fh - 1, 1, 0, Compatibility.PI/2.0); - Cairo.cairo_arc(cairo, 1, fh - 1, 1, Compatibility.PI/2, Compatibility.PI); - Cairo.cairo_arc(cairo, 1, 1, 1, Compatibility.PI, 270.0*Compatibility.PI/180.0); - Cairo.cairo_close_path(cairo); - Cairo.cairo_restore(cairo); + if (naw is 0 || nah is 0) { + Cairo.cairo_rectangle(cairo, x, y, width, height); + } else { + float naw2 = naw / 2f; + float nah2 = nah / 2f; + float fw = nw / naw2; + float fh = nh / nah2; + Cairo.cairo_save(cairo); + Cairo.cairo_translate(cairo, nx, ny); + Cairo.cairo_scale(cairo, naw2, nah2); + Cairo.cairo_move_to(cairo, fw - 1, 0); + Cairo.cairo_arc(cairo, fw - 1, 1, 1, Compatibility.PI + Compatibility.PI/2.0, Compatibility.PI*2.0); + Cairo.cairo_arc(cairo, fw - 1, fh - 1, 1, 0, Compatibility.PI/2.0); + Cairo.cairo_arc(cairo, 1, fh - 1, 1, Compatibility.PI/2, Compatibility.PI); + Cairo.cairo_arc(cairo, 1, 1, 1, Compatibility.PI, 270.0*Compatibility.PI/180.0); + Cairo.cairo_close_path(cairo); + Cairo.cairo_restore(cairo); + } Cairo.cairo_fill(cairo); return; } @@ -2283,10 +2321,15 @@ if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); /* Calculate visible bounds in device space */ int x = 0, y = 0, width = 0, height = 0; - int w, h; - OS.gdk_drawable_get_size(data.drawable, &w, &h); - width = w; - height = h; + if (data.width !is -1 && data.height !is -1) { + width = data.width; + height = data.height; + } else { + int w, h; + OS.gdk_drawable_get_size(data.drawable, &w, &h); + width = w; + height = h; + } /* Intersect visible bounds with clipping in device space and then convert then to user space */ auto cairo = data.cairo; auto clipRgn = data.clipRgn; @@ -2353,11 +2396,16 @@ auto cairo = data.cairo; auto clipRgn = data.clipRgn; if (clipRgn is null) { - int width,height; - OS.gdk_drawable_get_size(data.drawable, &width, &height); GdkRectangle rect; - rect.width = width; - rect.height = height; + if (data.width !is -1 && data.height !is -1) { + rect.width = data.width; + rect.height = data.height; + } else { + int width, height; + OS.gdk_drawable_get_size(data.drawable, &width, &height); + rect.width = width; + rect.height = height; + } OS.gdk_region_union_with_rect(clipping, &rect); } else { /* Convert clipping to device space if needed */ @@ -2415,7 +2463,7 @@ */ public Font getFont() { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - return Font.gtk_new(data.device, data.font); + return data.font; } /** @@ -2433,9 +2481,10 @@ if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); if (data.context is null) createLayout(); checkGC(FONT); + Font font = data.font; auto context = data.context; auto lang = OS.pango_context_get_language(context); - auto metrics = OS.pango_context_get_metrics(context, data.font, lang); + auto metrics = OS.pango_context_get_metrics(context, font.handle, lang); FontMetrics fm = new FontMetrics(); fm.ascent = OS.PANGO_PIXELS(OS.pango_font_metrics_get_ascent(metrics)); fm.descent = OS.PANGO_PIXELS(OS.pango_font_metrics_get_descent(metrics)); @@ -2723,6 +2772,9 @@ auto cairo = data.cairo; if (cairo !is null) { Cairo.cairo_get_matrix(cairo, cast(cairo_matrix_t*)transform.handle.ptr); + double[] identity = identity(); + Cairo.cairo_matrix_invert(cast(cairo_matrix_t*)identity.ptr); + Cairo.cairo_matrix_multiply(cast(cairo_matrix_t*)transform.handle.ptr, cast(cairo_matrix_t*)transform.handle.ptr, cast(cairo_matrix_t*)identity.ptr); } else { transform.setElements(1, 0, 0, 1, 0, 0); } @@ -2765,7 +2817,19 @@ return cast(hash_t)/*64*/handle; } -void init(Drawable drawable, GCData data, GdkGC* gdkGC) { +double[] identity() { + double[] identity = new double[6]; + if ((data.style & DWT.MIRRORED) !is 0) { + int w, h; + OS.gdk_drawable_get_size(data.drawable, &w, &h); + Cairo.cairo_matrix_init(cast(cairo_matrix_t*)identity.ptr, -1, 0, 0, 1, w, 0); + } else { + Cairo.cairo_matrix_init_identity(cast(cairo_matrix_t*)identity.ptr); + } + return identity; +} + +void init_(Drawable drawable, GCData data, GdkGC* gdkGC) { if (data.foreground !is null) data.state &= ~FOREGROUND; if (data.background !is null) data.state &= ~(BACKGROUND | BACKGROUND_BG); if (data.font !is null) data.state &= ~FONT; @@ -2783,6 +2847,11 @@ this.drawable = drawable; this.data = data; handle = gdkGC; + if ((data.style & DWT.MIRRORED) !is 0) { + initCairo(); + auto cairo = data.cairo; + Cairo.cairo_set_matrix(cairo, cast(cairo_matrix_t*) identity().ptr); + } } void initCairo() { @@ -2797,12 +2866,14 @@ if (data.image !is null) { xDrawable = OS.GDK_PIXMAP_XID(drawable); } else { - int x, y; - GdkDrawable* real_drawable; - OS.gdk_window_get_internal_paint_info(cast(GdkWindow*)drawable, &real_drawable, &x, &y); - xDrawable = OS.gdk_x11_drawable_get_xid(real_drawable); - translateX = -x; - translateY = -y; + if (!data.realDrawable) { + int x, y; + GdkDrawable* real_drawable; + OS.gdk_window_get_internal_paint_info(cast(GdkWindow*)drawable, &real_drawable, &x, &y); + xDrawable = OS.gdk_x11_drawable_get_xid(real_drawable); + translateX = -x; + translateY = -y; + } } int w, h; OS.gdk_drawable_get_size(drawable, &w, &h); @@ -2901,6 +2972,19 @@ */ public void setAdvanced(bool advanced) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if ((data.style & DWT.MIRRORED) !is 0) { + if (!advanced) { + setAlpha(0xFF); + setAntialias(DWT.DEFAULT); + setBackgroundPattern(null); + setClipping(cast(GdkRegion*)null); + setForegroundPattern(null); + setInterpolation(DWT.DEFAULT); + setTextAntialias(DWT.DEFAULT); + setTransform(null); + } + return; + } if (advanced && data.cairo !is null) return; if (advanced) { try { @@ -3268,9 +3352,8 @@ */ public void setFont(Font font) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - if (font is null) font = data.device.systemFont; - if (font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); - data.font = font.handle; + if (font !is null && font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); + data.font = font !is null ? font : data.device.systemFont; data.state &= ~FONT; data.stringWidth = data.stringHeight = -1; } @@ -3469,7 +3552,7 @@ DWT.error(DWT.ERROR_INVALID_ARGUMENT); } } - int cap = attributes.join; + int cap = attributes.cap; if (cap !is data.lineCap) { mask |= LINE_CAP; switch (cap) { @@ -3810,11 +3893,11 @@ if (data.cairo is null && transform is null) return; initCairo(); auto cairo = data.cairo; + double[] identity = identity(); if (transform !is null) { - Cairo.cairo_set_matrix(cairo,cast(cairo_matrix_t*) transform.handle.ptr); - } else { - Cairo.cairo_identity_matrix(cairo); + Cairo.cairo_matrix_multiply(cast(cairo_matrix_t*)identity.ptr, cast(cairo_matrix_t*)transform.handle.ptr, cast(cairo_matrix_t*)identity.ptr); } + Cairo.cairo_set_matrix(cairo, cast(cairo_matrix_t*)identity.ptr); data.state &= ~DRAW_OFFSET; }