From 41e7d8b25c6a606c5b562b6733ae62f79f876316 Mon Sep 17 00:00:00 2001 From: Anatoly Spektor Date: Wed, 10 Oct 2012 17:21:12 -0400 Subject: Use Cairo instead of gdk_draw_drawable and gdk_gc_set_exposures --- .../Eclipse SWT PI/cairo/library/cairo.c | 25 +++ .../Eclipse SWT PI/cairo/library/cairo_stats.c | 5 + .../Eclipse SWT PI/cairo/library/cairo_stats.h | 5 + .../org/eclipse/swt/internal/cairo/Cairo.java | 7 + .../Eclipse SWT PI/gtk/library/os.c | 18 ++ .../Eclipse SWT PI/gtk/library/os_custom.h | 1 + .../Eclipse SWT PI/gtk/library/os_stats.c | 1 + .../Eclipse SWT PI/gtk/library/os_stats.h | 1 + .../gtk/org/eclipse/swt/internal/gtk/OS.java | 13 ++ .../gtk/org/eclipse/swt/graphics/GC.java | 152 +++++++++++----- .../gtk/org/eclipse/swt/graphics/Region.java | 54 ++++-- .../gtk/org/eclipse/swt/graphics/TextLayout.java | 114 ++++++++---- .../gtk/org/eclipse/swt/widgets/Canvas.java | 199 ++++++++++++++------- .../gtk/org/eclipse/swt/widgets/Composite.java | 59 ++++-- .../gtk/org/eclipse/swt/widgets/Control.java | 73 +++++--- 15 files changed, 528 insertions(+), 199 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c index 197cfddc0c..8d6cf50d15 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo.c @@ -2313,6 +2313,31 @@ fail: } #endif +#if (!defined(NO_memmove__Lorg_eclipse_swt_internal_cairo_cairo_1rectangle_1int_1t_2II) && !defined(JNI64)) || (!defined(NO_memmove__Lorg_eclipse_swt_internal_cairo_cairo_1rectangle_1int_1t_2JI) && defined(JNI64)) +#ifndef JNI64 +JNIEXPORT void JNICALL Cairo_NATIVE(memmove__Lorg_eclipse_swt_internal_cairo_cairo_1rectangle_1int_1t_2II)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jint arg2) +#else +JNIEXPORT void JNICALL Cairo_NATIVE(memmove__Lorg_eclipse_swt_internal_cairo_cairo_1rectangle_1int_1t_2JI)(JNIEnv *env, jclass that, jobject arg0, jintLong arg1, jint arg2) +#endif +{ + cairo_rectangle_int_t _arg0, *lparg0=NULL; +#ifndef JNI64 + Cairo_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_cairo_cairo_1rectangle_1int_1t_2II_FUNC); +#else + Cairo_NATIVE_ENTER(env, that, memmove__Lorg_eclipse_swt_internal_cairo_cairo_1rectangle_1int_1t_2JI_FUNC); +#endif + if (arg0) if ((lparg0 = getcairo_rectangle_int_tFields(env, arg0, &_arg0)) == NULL) goto fail; + memmove((void *)lparg0, (const void *)arg1, (size_t)arg2); +fail: + if (arg0 && lparg0) setcairo_rectangle_int_tFields(env, arg0, lparg0); +#ifndef JNI64 + Cairo_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_cairo_cairo_1rectangle_1int_1t_2II_FUNC); +#else + Cairo_NATIVE_EXIT(env, that, memmove__Lorg_eclipse_swt_internal_cairo_cairo_1rectangle_1int_1t_2JI_FUNC); +#endif +} +#endif + #if (!defined(NO_memmove___3DII) && !defined(JNI64)) || (!defined(NO_memmove___3DJJ) && defined(JNI64)) #ifndef JNI64 JNIEXPORT void JNICALL Cairo_NATIVE(memmove___3DII)(JNIEnv *env, jclass that, jdoubleArray arg0, jintLong arg1, jintLong arg2) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c index 80f3a34d89..cf7191b2a9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.c @@ -204,6 +204,11 @@ char * Cairo_nativeFunctionNames[] = { #else "memmove__Lorg_eclipse_swt_internal_cairo_cairo_1path_1t_2JJ", #endif +#ifndef JNI64 + "memmove__Lorg_eclipse_swt_internal_cairo_cairo_1rectangle_1int_1t_2II", +#else + "memmove__Lorg_eclipse_swt_internal_cairo_cairo_1rectangle_1int_1t_2JI", +#endif #ifndef JNI64 "memmove___3DII", #else diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h index 223fd7a317..bb31882671 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library/cairo_stats.h @@ -214,6 +214,11 @@ typedef enum { #else memmove__Lorg_eclipse_swt_internal_cairo_cairo_1path_1t_2JJ_FUNC, #endif +#ifndef JNI64 + memmove__Lorg_eclipse_swt_internal_cairo_cairo_1rectangle_1int_1t_2II_FUNC, +#else + memmove__Lorg_eclipse_swt_internal_cairo_cairo_1rectangle_1int_1t_2JI_FUNC, +#endif #ifndef JNI64 memmove___3DII_FUNC, #else diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java index 54db145951..d9d0535e84 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cairo/org/eclipse/swt/internal/cairo/Cairo.java @@ -21,6 +21,7 @@ package org.eclipse.swt.internal.cairo; import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.gtk.GInterfaceInfo; public class Cairo extends Platform { static { @@ -1846,6 +1847,12 @@ public static final void cairo_region_get_rectangle(long /*int*/ region, int nth * @param size cast=(size_t) */ public static final native void memmove(cairo_path_t dest, long /*int*/ src, long /*int*/ size); +/** + * @param dest cast=(void *) + * @param src cast=(const void *) + * @param size cast=(size_t) + */ +public static final native void memmove(cairo_rectangle_int_t dest, long /*int*/ src, int size); /** * @param dest cast=(void *) * @param src cast=(const void *) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c index c7b9dd4e4b..39bb31c337 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c @@ -6970,6 +6970,24 @@ fail: } #endif +#ifndef NO__1gdk_1window_1begin_1paint_1region +JNIEXPORT void JNICALL OS_NATIVE(_1gdk_1window_1begin_1paint_1region) + (JNIEnv *env, jclass that, jintLong arg0, jintLong arg1) +{ + OS_NATIVE_ENTER(env, that, _1gdk_1window_1begin_1paint_1region_FUNC); +/* + gdk_window_begin_paint_region((GdkWindow *)arg0, arg1); +*/ + { + OS_LOAD_FUNCTION(fp, gdk_window_begin_paint_region) + if (fp) { + ((void (CALLING_CONVENTION*)(GdkWindow *, jintLong))fp)((GdkWindow *)arg0, arg1); + } + } + OS_NATIVE_EXIT(env, that, _1gdk_1window_1begin_1paint_1region_FUNC); +} +#endif + #ifndef NO__1gdk_1window_1create_1similar_1surface JNIEXPORT jintLong JNICALL OS_NATIVE(_1gdk_1window_1create_1similar_1surface) (JNIEnv *env, jclass that, jintLong arg0, jint arg1, jint arg2, jint arg3) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h index c585c1a454..9908e79ed5 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h @@ -261,6 +261,7 @@ #define gdk_window_get_pointer_LIB LIB_GDK #define gdk_window_at_pointer_LIB LIB_GDK #define gdk_window_get_height_LIB LIB_GDK +#define gdk_window_begin_paint_region_LIB LIB_GDK #define gdk_window_get_width_LIB LIB_GDK #define gdk_pixmap_get_size_LIB LIB_GDK #define gdk_window_get_display_LIB LIB_GDK diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c index 37ddef0dec..db705dc9b9 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c @@ -539,6 +539,7 @@ char * OS_nativeFunctionNames[] = { "_1gdk_1window_1add_1filter", "_1gdk_1window_1at_1pointer", "_1gdk_1window_1begin_1paint_1rect", + "_1gdk_1window_1begin_1paint_1region", "_1gdk_1window_1create_1similar_1surface", "_1gdk_1window_1destroy", "_1gdk_1window_1end_1paint", diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h index fdfc8d9b62..c0edc5908a 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h @@ -549,6 +549,7 @@ typedef enum { _1gdk_1window_1add_1filter_FUNC, _1gdk_1window_1at_1pointer_FUNC, _1gdk_1window_1begin_1paint_1rect_FUNC, + _1gdk_1window_1begin_1paint_1region_FUNC, _1gdk_1window_1create_1similar_1surface_FUNC, _1gdk_1window_1destroy_FUNC, _1gdk_1window_1end_1paint_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java index 356763790e..3760d0ec97 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java @@ -5220,6 +5220,19 @@ public static final void gdk_window_begin_paint_rect(long /*int*/ window, GdkRec lock.unlock(); } } +/** + * @method flags=dynamic + * @param window cast=(GdkWindow *) + */ +public static final native void _gdk_window_begin_paint_region(long /*int*/ window, long /*int*/ region); +public static final void gdk_window_begin_paint_region(long /*int*/ window, long /*int*/ region) { + lock.lock(); + try { + _gdk_window_begin_paint_region(window, region); + } finally { + lock.unlock(); + } +} /** * @method flags=dynamic * @param window cast=(GdkWindow *) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java index 35099e42bc..bdc8a4d524 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java @@ -2424,41 +2424,80 @@ public Rectangle getClipping() { long /*int*/ cairo = data.cairo; long /*int*/ clipRgn = data.clipRgn; long /*int*/ damageRgn = data.damageRgn; + long /*int*/ rgn = 0; if (clipRgn != 0 || damageRgn != 0 || cairo != 0) { - long /*int*/ rgn = cairo_region_create (); - GdkRectangle rect = new GdkRectangle(); - rect.width = width; - rect.height = height; - OS.gdk_region_union_with_rect(rgn, rect); - if (damageRgn != 0) { - cairo_region_intersect (rgn, damageRgn); - } - /* Intersect visible bounds with clipping */ - if (clipRgn != 0) { - /* Convert clipping to device space if needed */ - if (data.clippingTransform != null) { - clipRgn = convertRgn(clipRgn, data.clippingTransform); - cairo_region_intersect (rgn, clipRgn); - cairo_region_destroy (clipRgn); - } else { - cairo_region_intersect (rgn, clipRgn); + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + rgn = Cairo.cairo_region_create (); + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + rect.width = width; + rect.height = height; + Cairo.cairo_region_union_rectangle (rgn, rect); + if (damageRgn != 0) { + Cairo.cairo_region_intersect (rgn, damageRgn); } - } - /* Convert to user space */ - if (cairo != 0) { - double[] matrix = new double[6]; - Cairo.cairo_get_matrix(cairo, matrix); - Cairo.cairo_matrix_invert(matrix); - clipRgn = convertRgn(rgn, matrix); + /* Intersect visible bounds with clipping */ + if (clipRgn != 0) { + /* Convert clipping to device space if needed */ + if (data.clippingTransform != null) { + clipRgn = convertRgn(clipRgn, data.clippingTransform); + Cairo.cairo_region_intersect (rgn, clipRgn); + Cairo.cairo_region_destroy (clipRgn); + } else { + Cairo.cairo_region_intersect (rgn, clipRgn); + } + } + /* Convert to user space */ + if (cairo != 0) { + double[] matrix = new double[6]; + Cairo.cairo_get_matrix(cairo, matrix); + Cairo.cairo_matrix_invert(matrix); + clipRgn = convertRgn(rgn, matrix); + cairo_region_destroy (rgn); + rgn = clipRgn; + } + Cairo.cairo_region_get_extents (rgn, rect); cairo_region_destroy (rgn); - rgn = clipRgn; + x = rect.x; + y = rect.y; + width = rect.width; + height = rect.height; + } else { + rgn = OS.gdk_region_new (); + GdkRectangle rect = new GdkRectangle(); + rect.width = width; + rect.height = height; + OS.gdk_region_union_with_rect(rgn, rect); + if (damageRgn != 0) { + OS.gdk_region_intersect (rgn, damageRgn); + } + /* Intersect visible bounds with clipping */ + if (clipRgn != 0) { + /* Convert clipping to device space if needed */ + if (data.clippingTransform != null) { + clipRgn = convertRgn(clipRgn, data.clippingTransform); + OS.gdk_region_intersect (rgn, clipRgn); + OS.gdk_region_destroy (clipRgn); + } else { + OS.gdk_region_intersect (rgn, clipRgn); + } + } + /* Convert to user space */ + if (cairo != 0) { + double[] matrix = new double[6]; + Cairo.cairo_get_matrix(cairo, matrix); + Cairo.cairo_matrix_invert(matrix); + clipRgn = convertRgn(rgn, matrix); + cairo_region_destroy (rgn); + rgn = clipRgn; + } + OS.gdk_region_get_clipbox(rgn, rect); + OS.gdk_region_destroy (rgn); + x = rect.x; + y = rect.y; + width = rect.width; + height = rect.height; } - OS.gdk_region_get_clipbox(rgn, rect); - cairo_region_destroy (rgn); - x = rect.x; - y = rect.y; - width = rect.width; - height = rect.height; + } return new Rectangle(x, y, width, height); } @@ -2486,12 +2525,21 @@ public void getClipping(Region region) { long /*int*/ cairo = data.cairo; long /*int*/ clipRgn = data.clipRgn; if (clipRgn == 0) { - GdkRectangle rect = new GdkRectangle(); - int[] width = new int[1], height = new int[1]; - getSize(width, height); - rect.width = width[0]; - rect.height = height[0]; - OS.gdk_region_union_with_rect(clipping, rect); + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + int[] width = new int[1], height = new int[1]; + getSize(width, height); + rect.width = width[0]; + rect.height = height[0]; + Cairo.cairo_region_union_rectangle (clipping, rect); + } else { + GdkRectangle rect = new GdkRectangle(); + int[] width = new int[1], height = new int[1]; + getSize(width, height); + rect.width = width[0]; + rect.height = height[0]; + OS.gdk_region_union_with_rect(clipping, rect); + } } else { /* Convert clipping to device space if needed */ if (data.clippingTransform != null) { @@ -3410,15 +3458,27 @@ public void setClipping(int x, int y, int width, int height) { y = y + height; height = -height; } - GdkRectangle rect = new GdkRectangle(); - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - long /*int*/ clipRgn = cairo_region_create (); - OS.gdk_region_union_with_rect(clipRgn, rect); - setClipping(clipRgn); - cairo_region_destroy (clipRgn); + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + long /*int*/ clipRgn = cairo_region_create (); + Cairo.cairo_region_union_rectangle (clipRgn, rect); + setClipping(clipRgn); + Cairo.cairo_region_destroy (clipRgn); + } else { + GdkRectangle rect = new GdkRectangle(); + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + long /*int*/ clipRgn = cairo_region_create (); + OS.gdk_region_union_with_rect(clipRgn, rect); + setClipping(clipRgn); + OS.gdk_region_destroy (clipRgn); + } } /** diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Region.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Region.java index 46941170a6..7069896083 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Region.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Region.java @@ -157,12 +157,21 @@ public void add(Rectangle rect) { public void add(int x, int y, int width, int height) { if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); if (width < 0 || height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - GdkRectangle gdkRect = new GdkRectangle(); - gdkRect.x = x; - gdkRect.y = y; - gdkRect.width = width; - gdkRect.height = height; - OS.gdk_region_union_with_rect(handle, gdkRect); + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t cairoRect = new cairo_rectangle_int_t(); + cairoRect.x = x; + cairoRect.y = y; + cairoRect.width = width; + cairoRect.height = height; + Cairo.cairo_region_union_rectangle (handle, cairoRect); + } else { + GdkRectangle gdkRect = new GdkRectangle(); + gdkRect.x = x; + gdkRect.y = y; + gdkRect.width = width; + gdkRect.height = height; + OS.gdk_region_union_with_rect(handle, gdkRect); + } } /** @@ -262,9 +271,15 @@ public boolean equals(Object object) { */ public Rectangle getBounds() { if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - GdkRectangle gdkRect = new GdkRectangle(); - OS.gdk_region_get_clipbox(handle, gdkRect); - return new Rectangle(gdkRect.x, gdkRect.y, gdkRect.width, gdkRect.height); + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t cairoRect = new cairo_rectangle_int_t (); + Cairo.cairo_region_get_extents (handle, cairoRect); + return new Rectangle(cairoRect.x, cairoRect.y, cairoRect.width, cairoRect.height); + } else { + GdkRectangle gdkRect = new GdkRectangle(); + OS.gdk_region_get_clipbox(handle, gdkRect); + return new Rectangle(gdkRect.x, gdkRect.y, gdkRect.width, gdkRect.height); + } } /** @@ -408,12 +423,21 @@ public void intersect(Region region) { */ public boolean intersects (int x, int y, int width, int height) { if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - GdkRectangle gdkRect = new GdkRectangle(); - gdkRect.x = x; - gdkRect.y = y; - gdkRect.width = width; - gdkRect.height = height; - return OS.gdk_region_rect_in(handle, gdkRect) != OS.GDK_OVERLAP_RECTANGLE_OUT; + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t cairoRect = new cairo_rectangle_int_t (); + cairoRect.x = x; + cairoRect.y = y; + cairoRect.width = width; + cairoRect.height = height; + return Cairo.cairo_region_contains_rectangle (handle, cairoRect) != OS.GDK_OVERLAP_RECTANGLE_OUT; + } else { + GdkRectangle gdkRect = new GdkRectangle(); + gdkRect.x = x; + gdkRect.y = y; + gdkRect.width = width; + gdkRect.height = height; + return OS.gdk_region_rect_in(handle, gdkRect) != OS.GDK_OVERLAP_RECTANGLE_OUT; + } } /** * Returns true if the given rectangle intersects diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java index 657ba4e705..97016231c8 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/TextLayout.java @@ -827,44 +827,86 @@ public Rectangle getBounds(int start, int end) { int[] ranges = new int[]{byteStart, byteEnd}; long /*int*/ clipRegion = OS.gdk_pango_layout_get_clip_region(layout, 0, 0, ranges, 1); if (clipRegion == 0) return new Rectangle(0, 0, 0, 0); - GdkRectangle rect = new GdkRectangle(); - - /* - * Bug in Pango. The region returned by gdk_pango_layout_get_clip_region() - * includes areas from lines outside of the requested range. The fix - * is to subtract these areas from the clip region. - */ - PangoRectangle pangoRect = new PangoRectangle(); - long /*int*/ iter = OS.pango_layout_get_iter(layout); - if (iter == 0) SWT.error(SWT.ERROR_NO_HANDLES); - long /*int*/ linesRegion = cairo_region_create (); - if (linesRegion == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int lineEnd = 0; - do { - OS.pango_layout_iter_get_line_extents(iter, null, pangoRect); - if (OS.pango_layout_iter_next_line(iter)) { - lineEnd = OS.pango_layout_iter_get_index(iter) - 1; - } else { - lineEnd = strlen; + if (OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t(); + /* + * Bug in Pango. The region returned by gdk_pango_layout_get_clip_region() + * includes areas from lines outside of the requested range. The fix + * is to subtract these areas from the clip region. + */ + PangoRectangle pangoRect = new PangoRectangle(); + long /*int*/ iter = OS.pango_layout_get_iter(layout); + if (iter == 0) SWT.error(SWT.ERROR_NO_HANDLES); + long /*int*/ linesRegion = cairo_region_create (); + if (linesRegion == 0) SWT.error(SWT.ERROR_NO_HANDLES); + int lineEnd = 0; + do { + OS.pango_layout_iter_get_line_extents(iter, null, pangoRect); + if (OS.pango_layout_iter_next_line(iter)) { + lineEnd = OS.pango_layout_iter_get_index(iter) - 1; + } else { + lineEnd = strlen; + } + if (byteStart > lineEnd) continue; + rect.x = OS.PANGO_PIXELS(pangoRect.x); + rect.y = OS.PANGO_PIXELS(pangoRect.y); + rect.width = OS.PANGO_PIXELS(pangoRect.width); + rect.height = OS.PANGO_PIXELS(pangoRect.height); + Cairo.cairo_region_union_rectangle (linesRegion, rect); + } while (lineEnd + 1 <= byteEnd); + Cairo.cairo_region_intersect (clipRegion, linesRegion); + Cairo.cairo_region_destroy (linesRegion); + OS.pango_layout_iter_free(iter); + + Cairo.cairo_region_get_extents (clipRegion, rect); + Cairo.cairo_region_destroy (clipRegion); + if (OS.pango_context_get_base_dir(context) == OS.PANGO_DIRECTION_RTL) { + rect.x = width() - rect.x - rect.width; } - if (byteStart > lineEnd) continue; - rect.x = OS.PANGO_PIXELS(pangoRect.x); - rect.y = OS.PANGO_PIXELS(pangoRect.y); - rect.width = OS.PANGO_PIXELS(pangoRect.width); - rect.height = OS.PANGO_PIXELS(pangoRect.height); - OS.gdk_region_union_with_rect(linesRegion, rect); - } while (lineEnd + 1 <= byteEnd); - cairo_region_intersect (clipRegion, linesRegion); - cairo_region_destroy (linesRegion); - OS.pango_layout_iter_free(iter); - - OS.gdk_region_get_clipbox(clipRegion, rect); - cairo_region_destroy (clipRegion); - if (OS.pango_context_get_base_dir(context) == OS.PANGO_DIRECTION_RTL) { - rect.x = width() - rect.x - rect.width; + rect.x += Math.min (indent, wrapIndent); + return new Rectangle(rect.x, rect.y, rect.width, rect.height); + } else { + GdkRectangle rect = new GdkRectangle(); + /* + * Bug in Pango. The region returned by gdk_pango_layout_get_clip_region() + * includes areas from lines outside of the requested range. The fix + * is to subtract these areas from the clip region. + */ + PangoRectangle pangoRect = new PangoRectangle(); + long /*int*/ iter = OS.pango_layout_get_iter(layout); + if (iter == 0) SWT.error(SWT.ERROR_NO_HANDLES); + long /*int*/ linesRegion = cairo_region_create (); + if (linesRegion == 0) SWT.error(SWT.ERROR_NO_HANDLES); + int lineEnd = 0; + do { + OS.pango_layout_iter_get_line_extents(iter, null, pangoRect); + if (OS.pango_layout_iter_next_line(iter)) { + lineEnd = OS.pango_layout_iter_get_index(iter) - 1; + } else { + lineEnd = strlen; + } + if (byteStart > lineEnd) continue; + rect.x = OS.PANGO_PIXELS(pangoRect.x); + rect.y = OS.PANGO_PIXELS(pangoRect.y); + rect.width = OS.PANGO_PIXELS(pangoRect.width); + rect.height = OS.PANGO_PIXELS(pangoRect.height); + OS.gdk_region_union_with_rect(linesRegion, rect); + } while (lineEnd + 1 <= byteEnd); + OS.gdk_region_intersect (clipRegion, linesRegion); + OS.gdk_region_destroy (linesRegion); + OS.pango_layout_iter_free(iter); + + OS.gdk_region_get_clipbox(clipRegion, rect); + OS.gdk_region_destroy (clipRegion); + if (OS.pango_context_get_base_dir(context) == OS.PANGO_DIRECTION_RTL) { + rect.x = width() - rect.x - rect.width; + } + rect.x += Math.min (indent, wrapIndent); + return new Rectangle(rect.x, rect.y, rect.width, rect.height); } - rect.x += Math.min (indent, wrapIndent); - return new Rectangle(rect.x, rect.y, rect.width, rect.height); + + + } /** diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java index d0602e5e97..6d7f448b10 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Canvas.java @@ -13,6 +13,7 @@ package org.eclipse.swt.widgets; import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.cairo.Cairo; +import org.eclipse.swt.internal.cairo.cairo_rectangle_int_t; import org.eclipse.swt.internal.gtk.*; import org.eclipse.swt.*; @@ -252,76 +253,150 @@ public void scroll (int destX, int destY, int x, int y, int width, int height, b if (isFocus) caret.killFocus (); long /*int*/ window = paintWindow (); long /*int*/ visibleRegion = OS.gdk_drawable_get_visible_region (window); - GdkRectangle srcRect = new GdkRectangle (); - srcRect.x = x; - srcRect.y = y; - srcRect.width = width; - srcRect.height = height; - long /*int*/ copyRegion = OS.gdk_region_rectangle (srcRect); - cairo_region_intersect (copyRegion, visibleRegion); - long /*int*/ invalidateRegion = OS.gdk_region_rectangle (srcRect); - cairo_region_subtract (invalidateRegion, visibleRegion); - cairo_region_translate (invalidateRegion, deltaX, deltaY); - GdkRectangle copyRect = new GdkRectangle(); - OS.gdk_region_get_clipbox (copyRegion, copyRect); - if (copyRect.width != 0 && copyRect.height != 0) { - update (); - } - Control control = findBackgroundControl (); - if (control == null) control = this; - if (control.backgroundImage != null) { - redrawWidget (x, y, width, height, false, false, false); - redrawWidget (destX, destY, width, height, false, false, false); - } else { -// GC gc = new GC (this); -// gc.copyArea (x, y, width, height, destX, destY); -// gc.dispose (); - if (OS.USE_CAIRO) { - OS.gdk_window_invalidate_rect(window, copyRect, true); - long /*int*/ cairo = OS.gdk_cairo_create (window); - OS.gdk_cairo_set_source_window (cairo, window, 0, 0); - Cairo.cairo_rectangle(cairo, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height); - Cairo.cairo_fill (cairo); - Cairo.cairo_destroy (cairo); - }else{ - long /*int*/ gdkGC = OS.gdk_gc_new (window); - OS.gdk_gc_set_exposures (gdkGC, true); - OS.gdk_draw_drawable (window, gdkGC, window, copyRect.x, copyRect.y, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height); - OS.g_object_unref (gdkGC); + if(OS.GTK_VERSION >= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t srcRect = new cairo_rectangle_int_t(); + srcRect.x = x; + srcRect.y = y; + srcRect.width = width; + srcRect.height = height; + long /*int*/ copyRegion = Cairo.cairo_region_create_rectangle (srcRect); + Cairo.cairo_region_intersect (copyRegion, visibleRegion); + long /*int*/ invalidateRegion = Cairo.cairo_region_create_rectangle (srcRect); + Cairo.cairo_region_subtract (invalidateRegion, visibleRegion); + Cairo.cairo_region_translate (invalidateRegion, deltaX, deltaY); + cairo_rectangle_int_t copyRect = new cairo_rectangle_int_t (); + Cairo.cairo_region_get_extents (copyRegion, copyRect); + if (copyRect.width != 0 && copyRect.height != 0) { + update (); } - boolean disjoint = (destX + width < x) || (x + width < destX) || (destY + height < y) || (y + height < destY); - if (disjoint) { - GdkRectangle rect = new GdkRectangle (); - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - OS.gdk_region_union_with_rect (invalidateRegion, rect); + Control control = findBackgroundControl (); + if (control == null) control = this; + if (control.backgroundImage != null) { + redrawWidget (x, y, width, height, false, false, false); + redrawWidget (destX, destY, width, height, false, false, false); } else { - GdkRectangle rect = new GdkRectangle (); - if (deltaX != 0) { - int newX = destX - deltaX; - if (deltaX < 0) newX = destX + width; - rect.x = newX; +// GC gc = new GC (this); +// gc.copyArea (x, y, width, height, destX, destY); +// gc.dispose (); + if (OS.USE_CAIRO) { + OS.gdk_window_invalidate_region (window, copyRegion, true); + long /*int*/ cairo = OS.gdk_cairo_create (window); + OS.gdk_cairo_set_source_window (cairo, window, 0, 0); + Cairo.cairo_rectangle (cairo, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height); + Cairo.cairo_fill (cairo); + Cairo.cairo_destroy (cairo); + } else { + long /*int*/ gdkGC = OS.gdk_gc_new (window); + OS.gdk_gc_set_exposures (gdkGC, true); + OS.gdk_draw_drawable (window, gdkGC, window, copyRect.x, copyRect.y, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height); + OS.g_object_unref (gdkGC); + } + boolean disjoint = (destX + width < x) || (x + width < destX) || (destY + height < y) || (y + height < destY); + if (disjoint) { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + rect.x = x; rect.y = y; - rect.width = Math.abs(deltaX); + rect.width = width; rect.height = height; - OS.gdk_region_union_with_rect (invalidateRegion, rect); + Cairo.cairo_region_union_rectangle (invalidateRegion, rect); + } else { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + if (deltaX != 0) { + int newX = destX - deltaX; + if (deltaX < 0) newX = destX + width; + rect.x = newX; + rect.y = y; + rect.width = Math.abs(deltaX); + rect.height = height; + Cairo.cairo_region_union_rectangle (invalidateRegion, rect); + } + if (deltaY != 0) { + int newY = destY - deltaY; + if (deltaY < 0) newY = destY + height; + rect.x = x; + rect.y = newY; + rect.width = width; + rect.height = Math.abs(deltaY); + Cairo.cairo_region_union_rectangle (invalidateRegion, rect); + } + } + OS.gdk_window_invalidate_region(window, invalidateRegion, all); + Cairo.cairo_region_destroy (visibleRegion); + Cairo.cairo_region_destroy (copyRegion); + Cairo.cairo_region_destroy (invalidateRegion); + } + } else { + GdkRectangle srcRect = new GdkRectangle (); + srcRect.x = x; + srcRect.y = y; + srcRect.width = width; + srcRect.height = height; + long /*int*/ copyRegion = OS.gdk_region_rectangle (srcRect); + OS.gdk_region_intersect(copyRegion, visibleRegion); + long /*int*/ invalidateRegion = OS.gdk_region_rectangle (srcRect); + OS.gdk_region_subtract (invalidateRegion, visibleRegion); + OS.gdk_region_offset (invalidateRegion, deltaX, deltaY); + GdkRectangle copyRect = new GdkRectangle(); + OS.gdk_region_get_clipbox (copyRegion, copyRect); + if (copyRect.width != 0 && copyRect.height != 0) { + update (); + } + Control control = findBackgroundControl (); + if (control == null) control = this; + if (control.backgroundImage != null) { + redrawWidget (x, y, width, height, false, false, false); + redrawWidget (destX, destY, width, height, false, false, false); + } else { +// GC gc = new GC (this); +// gc.copyArea (x, y, width, height, destX, destY); +// gc.dispose (); + if (OS.USE_CAIRO) { + OS.gdk_window_invalidate_region (window, copyRegion, true); + long /*int*/ cairo = OS.gdk_cairo_create (window); + OS.gdk_cairo_set_source_window (cairo, window, 0, 0); + Cairo.cairo_rectangle (cairo, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height); + Cairo.cairo_fill (cairo); + Cairo.cairo_destroy (cairo); + } else { + long /*int*/ gdkGC = OS.gdk_gc_new (window); + OS.gdk_gc_set_exposures (gdkGC, true); + OS.gdk_draw_drawable (window, gdkGC, window, copyRect.x, copyRect.y, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height); + OS.g_object_unref (gdkGC); } - if (deltaY != 0) { - int newY = destY - deltaY; - if (deltaY < 0) newY = destY + height; + boolean disjoint = (destX + width < x) || (x + width < destX) || (destY + height < y) || (y + height < destY); + if (disjoint) { + GdkRectangle rect = new GdkRectangle (); rect.x = x; - rect.y = newY; + rect.y = y; rect.width = width; - rect.height = Math.abs(deltaY); + rect.height = height; OS.gdk_region_union_with_rect (invalidateRegion, rect); - } - } - OS.gdk_window_invalidate_region(window, invalidateRegion, all); - cairo_region_destroy (visibleRegion); - cairo_region_destroy (copyRegion); - cairo_region_destroy (invalidateRegion); + } else { + GdkRectangle rect = new GdkRectangle (); + if (deltaX != 0) { + int newX = destX - deltaX; + if (deltaX < 0) newX = destX + width; + rect.x = newX; + rect.y = y; + rect.width = Math.abs(deltaX); + rect.height = height; + OS.gdk_region_union_with_rect (invalidateRegion, rect); + } + if (deltaY != 0) { + int newY = destY - deltaY; + if (deltaY < 0) newY = destY + height; + rect.x = x; + rect.y = newY; + rect.width = width; + rect.height = Math.abs(deltaY); + OS.gdk_region_union_with_rect (invalidateRegion, rect); + } + } + OS.gdk_window_invalidate_region(window, invalidateRegion, all); + OS.gdk_region_destroy (visibleRegion); + OS.gdk_region_destroy (copyRegion); + OS.gdk_region_destroy (invalidateRegion); + } } if (all) { Control [] children = _getChildren (); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java index b63026b264..e5de893029 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Composite.java @@ -731,25 +731,48 @@ long /*int*/ gtk_expose_event (long /*int*/ widget, long /*int*/ eventPtr) { long /*int*/ [] rectangles = new long /*int*/ [1]; int [] n_rectangles = new int [1]; OS.gdk_region_get_rectangles (gdkEvent.region, rectangles, n_rectangles); - GdkRectangle rect = new GdkRectangle (); - for (int i=0; i= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + for (int i=0; i= OS.VERSION(3, 0, 0)) { + cairo_rectangle_int_t rect = new cairo_rectangle_int_t (); + gdk_window_get_size (window, width, height); + rect.width = width [0]; + rect.height = height [0]; + long /*int*/ cr = Cairo.cairo_region_create_rectangle (rect); + OS.gdk_window_begin_paint_region(window, cr); + OS.gdk_window_get_internal_paint_info (window, real_drawable, x_offset, y_offset); + long /*int*/ [] userData = new long /*int*/ [1]; + OS.gdk_window_get_user_data (window, userData); + if (userData [0] != 0) { + long /*int*/ eventPtr = OS.gdk_event_new (OS.GDK_EXPOSE); + GdkEventExpose event = new GdkEventExpose (); + event.type = OS.GDK_EXPOSE; + event.window = OS.g_object_ref (window); + event.area_width = rect.width; + event.area_height = rect.height; + event.region = Cairo.cairo_region_create_rectangle (rect); + OS.memmove (eventPtr, event, GdkEventExpose.sizeof); + OS.gtk_widget_send_expose (userData [0], eventPtr); + OS.gdk_event_free (eventPtr); + } + } else { + GdkRectangle rect = new GdkRectangle (); + gdk_window_get_size (window, width, height); + rect.width = width [0]; + rect.height = height [0]; + OS.gdk_window_begin_paint_rect (window, rect); + OS.gdk_window_get_internal_paint_info (window, real_drawable, x_offset, y_offset); + long /*int*/ [] userData = new long /*int*/ [1]; + OS.gdk_window_get_user_data (window, userData); + if (userData [0] != 0) { + long /*int*/ eventPtr = OS.gdk_event_new (OS.GDK_EXPOSE); + GdkEventExpose event = new GdkEventExpose (); + event.type = OS.GDK_EXPOSE; + event.window = OS.g_object_ref (window); + event.area_width = rect.width; + event.area_height = rect.height; + event.region = OS.gdk_region_rectangle (rect); + OS.memmove (eventPtr, event, GdkEventExpose.sizeof); + OS.gtk_widget_send_expose (userData [0], eventPtr); + OS.gdk_event_free (eventPtr); + } } - int srcX = x_offset [0], srcY = y_offset [0]; - int destX = x, destY = y, destWidth = width [0], destHeight = height [0]; + srcX = x_offset [0]; + srcY = y_offset [0]; + destX = x; + destY = y; + destWidth = width [0]; + destHeight = height [0]; if (!first) { int [] cX = new int [1], cY = new int [1]; OS.gdk_window_get_position (window, cX, cY); -- cgit