summaryrefslogtreecommitdiffstats
path: root/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt
diff options
context:
space:
mode:
authorSilenio Quarti <silenio>2005-02-12 00:18:39 +0000
committerSilenio Quarti <silenio>2005-02-12 00:18:39 +0000
commit85b8baf1efb6a545680cc9553a80da0d7364e4a0 (patch)
treedff960bcaaffb0a39060a1ce0e0d552d17f88c48 /bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt
parent592fd31261f874251936ca94343b0a4b4e33ed56 (diff)
downloadeclipse.platform.swt-85b8baf1efb6a545680cc9553a80da0d7364e4a0.tar.gz
eclipse.platform.swt-85b8baf1efb6a545680cc9553a80da0d7364e4a0.tar.xz
eclipse.platform.swt-85b8baf1efb6a545680cc9553a80da0d7364e4a0.zip
advanced graphics API (initial)
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java8
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java530
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java3
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java6
4 files changed, 526 insertions, 21 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java
index 1b6d502d3b..9166b17fb1 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java
@@ -128,6 +128,14 @@ public Device(DeviceData data) {
systemFont = getSystemFont ();
}
+void checkCairo() {
+ try {
+ Class.forName("org.eclipse.swt.internal.cairo.Cairo");
+ } catch (Throwable t) {
+ SWT.error(SWT.ERROR_NO_GRAPHICS_LIBRARY, t);
+ }
+}
+
/**
* Throws an <code>SWTException</code> if the receiver can not
* be accessed by the caller. This may include both checks on
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 7bbde348f4..6a9062e45c 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
@@ -11,6 +11,7 @@
package org.eclipse.swt.graphics;
+import org.eclipse.swt.internal.cairo.*;
import org.eclipse.swt.internal.gtk.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.*;
@@ -234,6 +235,14 @@ public void dispose() {
if (handle == 0) return;
if (data.device.isDisposed()) return;
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) Cairo.cairo_destroy(cairo);
+ int /*long*/ matrix = data.matrix;
+ if (matrix != 0) Cairo.cairo_matrix_destroy(matrix);
+ int /*long*/ inverseMatrix = data.inverseMatrix;
+ if (inverseMatrix != 0) Cairo.cairo_matrix_destroy(inverseMatrix);
+ data.cairo = data.matrix = data.inverseMatrix = 0;
+
/* Free resources */
int /*long*/ clipRgn = data.clipRgn;
if (clipRgn != 0) OS.gdk_region_destroy(clipRgn);
@@ -302,6 +311,17 @@ public void drawArc(int x, int y, int width, int height, int startAngle, int arc
height = -height;
}
if (width == 0 || height == 0 || arcAngle == 0) return;
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ Cairo.cairo_save(cairo);
+ Cairo.cairo_translate(cairo, x + width / 2f, y + height / 2f);
+ Cairo.cairo_scale(cairo, width / 2f, height / 2f);
+ Cairo.cairo_set_line_width(cairo, Cairo.cairo_current_line_width(cairo) / (width / 2f));
+ Cairo.cairo_arc_negative(cairo, 0, 0, 1, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+ Cairo.cairo_stroke(cairo);
+ Cairo.cairo_restore(cairo);
+ return;
+ }
OS.gdk_draw_arc(data.drawable, handle, 0, x, y, width, height, startAngle * 64, arcAngle * 64);
}
@@ -429,6 +449,34 @@ void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight,
}
}
void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, int imgWidth, int imgHeight) {
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ if (srcImage.surface == 0) {
+ int /*long*/ xDisplay = OS.GDK_DISPLAY();
+ int /*long*/ xDrawable = OS.GDK_PIXMAP_XID(srcImage.pixmap);
+ int /*long*/ xVisual = OS.gdk_x11_visual_get_xvisual(OS.gdk_visual_get_system());
+ int /*long*/ xColormap = OS.gdk_x11_colormap_get_xcolormap(OS.gdk_colormap_get_system());
+ srcImage.surface = Cairo.cairo_xlib_surface_create(xDisplay, xDrawable, xVisual, 0, xColormap);
+ }
+ Cairo.cairo_save(cairo);
+ //TODO - draw a piece of the image
+// if (srcX != 0 || srcY != 0) {
+// Cairo.cairo_rectangle(cairo, destX, destY, destWidth, destHeight);
+// Cairo.cairo_clip(cairo);
+// Cairo.cairo_new_path(cairo);
+// }
+ //TODO - need 0.5 to draw at 0,0 with no transformation ???
+ System.out.println("filter="+ Cairo.cairo_surface_get_filter(srcImage.surface));
+ Cairo.cairo_surface_set_filter(srcImage.surface, 5);
+ System.out.println("\tfilter="+ Cairo.cairo_surface_get_filter(srcImage.surface));
+ Cairo.cairo_translate(cairo, destX - srcX + 0.5, destY - srcY);
+ if (srcWidth != destWidth || srcHeight != destHeight) {
+ Cairo.cairo_scale(cairo, destWidth / (float)srcWidth, destHeight / (float)srcHeight);
+ }
+ Cairo.cairo_show_surface(cairo, srcImage.surface, imgWidth, imgHeight);
+ Cairo.cairo_restore(cairo);
+ return;
+ }
if (srcWidth == destWidth && srcHeight == destHeight) {
OS.gdk_draw_drawable(data.drawable, handle, srcImage.pixmap, srcX, srcY, destX, destY, destWidth, destHeight);
} else {
@@ -590,6 +638,13 @@ int /*long*/ scale(int /*long*/ src, int srcX, int srcY, int srcWidth, int srcHe
*/
public void drawLine(int x1, int y1, int x2, int y2) {
if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ Cairo.cairo_move_to(cairo, x1, y1);
+ Cairo.cairo_line_to(cairo, x2, y2);
+ Cairo.cairo_stroke(cairo);
+ return;
+ }
OS.gdk_draw_line (data.drawable, handle, x1, y1, x2, y2);
}
@@ -624,9 +679,28 @@ public void drawOval(int x, int y, int width, int height) {
y = y + height;
height = -height;
}
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ Cairo.cairo_save(cairo);
+ Cairo.cairo_translate(cairo, x + width / 2f, y + height / 2f);
+ Cairo.cairo_scale(cairo, width / 2f, height / 2f);
+ Cairo.cairo_set_line_width(cairo, Cairo.cairo_current_line_width(cairo) / (width / 2f));
+ Cairo.cairo_arc_negative(cairo, 0, 0, 1, 0, -2 * (float)Compatibility.PI);
+ Cairo.cairo_stroke(cairo);
+ Cairo.cairo_restore(cairo);
+ return;
+ }
OS.gdk_draw_arc(data.drawable, handle, 0, x, y, width, height, 0, 23040);
}
+public void drawPath(Path path) {
+ if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ if (path.handle == 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ initCairo();
+ Cairo.cairo_add_path(data.cairo, path.handle);
+ Cairo.cairo_stroke(data.cairo);
+}
+
/**
* Draws a pixel, using the foreground color, at the specified
* point (<code>x</code>, <code>y</code>).
@@ -646,6 +720,12 @@ public void drawOval(int x, int y, int width, int height) {
*/
public void drawPoint (int x, int y) {
if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ Cairo.cairo_rectangle(cairo, x, y, 1, 1);
+ Cairo.cairo_fill(cairo);
+ return;
+ }
OS.gdk_draw_point(data.drawable, handle, x, y);
}
@@ -669,6 +749,12 @@ public void drawPoint (int x, int y) {
public void drawPolygon(int[] pointArray) {
if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ drawPolyline(cairo, pointArray, true);
+ Cairo.cairo_stroke(cairo);
+ return;
+ }
OS.gdk_draw_polygon(data.drawable, handle, 0, pointArray, pointArray.length / 2);
}
@@ -692,9 +778,25 @@ public void drawPolygon(int[] pointArray) {
public void drawPolyline(int[] pointArray) {
if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ drawPolyline(cairo, pointArray, false);
+ Cairo.cairo_stroke(cairo);
+ return;
+ }
OS.gdk_draw_lines(data.drawable, handle, pointArray, pointArray.length / 2);
}
+void drawPolyline(int /*long*/ cairo, int[] pointArray, boolean close) {
+ int count = pointArray.length / 2;
+ if (count == 0) return;
+ Cairo.cairo_move_to(cairo, pointArray[0], pointArray[1]);
+ for (int i = 1, j=2; i < count; i++, j += 2) {
+ Cairo.cairo_line_to(cairo, pointArray[j], pointArray[j + 1]);
+ }
+ if (close) Cairo.cairo_close_path(cairo);
+}
+
/**
* Draws the outline of the rectangle specified by the arguments,
* using the receiver's foreground color. The left and right edges
@@ -720,6 +822,12 @@ public void drawRectangle(int x, int y, int width, int height) {
y = y + height;
height = -height;
}
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ Cairo.cairo_rectangle(cairo, x, y, width, height);
+ Cairo.cairo_stroke(cairo);
+ return;
+ }
OS.gdk_draw_rectangle(data.drawable, handle, 0, x, y, width, height);
}
@@ -770,7 +878,6 @@ public void drawRoundRectangle(int x, int y, int width, int height, int arcWidth
int nh = height;
int naw = arcWidth;
int nah = arcHeight;
-
if (nw < 0) {
nw = 0 - nw;
nx = nx - nw;
@@ -779,14 +886,29 @@ public void drawRoundRectangle(int x, int y, int width, int height, int arcWidth
nh = 0 - nh;
ny = ny -nh;
}
- if (naw < 0)
- naw = 0 - naw;
- if (nah < 0)
- nah = 0 - nah;
-
+ if (naw < 0) naw = 0 - naw;
+ if (nah < 0) nah = 0 - nah;
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ 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_to(cairo, 0, 0, 0, 1, 1);
+// Cairo.cairo_arc_to(cairo, 0, fh, 1, fh, 1);
+// Cairo.cairo_arc_to(cairo, fw, fh, fw, fh - 1, 1);
+// Cairo.cairo_arc_to(cairo, fw, 0, fw - 1, 0, 1);
+ Cairo.cairo_close_path(handle);
+ Cairo.cairo_stroke(cairo);
+ Cairo.cairo_restore(cairo);
+ return;
+ }
int naw2 = naw / 2;
int nah2 = nah / 2;
-
int /*long*/ drawable = data.drawable;
if (nw > naw) {
if (nh > nah) {
@@ -947,6 +1069,18 @@ public void drawText (String string, int x, int y, int flags) {
if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
if (string == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
if (string.length() == 0) return;
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ //TODO - honor flags
+ cairo_font_extents_t extents = new cairo_font_extents_t();
+ Cairo.cairo_current_font_extents(cairo, extents);
+ double baseline = y + extents.ascent;
+ Cairo.cairo_move_to(cairo, x, baseline);
+ byte[] buffer = Converter.wcsToMbcs(null, string, true);
+ Cairo.cairo_text_path(cairo, buffer);
+ Cairo.cairo_fill(cairo);
+ return;
+ }
setString(string, flags);
GdkColor background = null;
GdkGCValues values = null;
@@ -1049,6 +1183,20 @@ public void fillArc(int x, int y, int width, int height, int startAngle, int arc
OS.gdk_gc_get_values(handle, values);
GdkColor color = new GdkColor();
color.pixel = values.background_pixel;
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ int /*long*/ colormap = OS.gdk_colormap_get_system();
+ OS.gdk_colormap_query_color(colormap, color.pixel, color);
+ Cairo.cairo_save(cairo);
+ Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+ Cairo.cairo_translate(cairo, x + width / 2f, y + height / 2f);
+ Cairo.cairo_scale(cairo, width / 2f, height / 2f);
+ Cairo.cairo_arc_negative(cairo, 0, 0, 1, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+ Cairo.cairo_line_to(cairo, 0, 0);
+ Cairo.cairo_fill(cairo);
+ Cairo.cairo_restore(cairo);
+ return;
+ }
OS.gdk_gc_set_foreground(handle, color);
OS.gdk_draw_arc(data.drawable, handle, 1, x, y, width, height, startAngle * 64, arcAngle * 64);
color.pixel = values.foreground_pixel;
@@ -1108,6 +1256,26 @@ public void fillGradientRectangle(int x, int y, int width, int height, boolean v
fillRectangle(x, y, width, height);
return;
}
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ int /*long*/ pattern;
+ if (vertical) {
+ pattern = Cairo.cairo_pattern_create_linear (0.0, 0.0, 0.0, 1.0);
+ } else {
+ pattern = Cairo.cairo_pattern_create_linear (0.0, 0.0, 1.0, 0.0);
+ }
+ Cairo.cairo_pattern_add_color_stop (pattern, 0, fromRGB.red / 255f, fromRGB.green / 255f, fromRGB.blue / 255f, 1);
+ Cairo.cairo_pattern_add_color_stop (pattern, 1, toRGB.red / 255f, toRGB.green / 255f, toRGB.blue / 255f, 1);
+ Cairo.cairo_save(cairo);
+ Cairo.cairo_translate(cairo, x, y);
+ Cairo.cairo_scale(cairo, width, height);
+ Cairo.cairo_rectangle(cairo, 0, 0, 1, 1);
+ Cairo.cairo_set_pattern(cairo, pattern);
+ Cairo.cairo_fill(cairo);
+ Cairo.cairo_restore(cairo);
+ Cairo.cairo_pattern_destroy(pattern);
+ return;
+ }
ImageData.fillGradientRectangle(this, data.device,
x, y, width, height, vertical, fromRGB, toRGB,
8, 8, 8);
@@ -1143,12 +1311,43 @@ public void fillOval(int x, int y, int width, int height) {
OS.gdk_gc_get_values(handle, values);
GdkColor color = new GdkColor();
color.pixel = values.background_pixel;
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ int /*long*/ colormap = OS.gdk_colormap_get_system();
+ OS.gdk_colormap_query_color(colormap, color.pixel, color);
+ Cairo.cairo_save(cairo);
+ Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+ Cairo.cairo_translate(cairo, x + width / 2f, y + height / 2f);
+ Cairo.cairo_scale(cairo, width / 2f, height / 2f);
+ Cairo.cairo_arc_negative(cairo, 0, 0, 1, 0, 2 * (float)Compatibility.PI);
+ Cairo.cairo_fill(cairo);
+ Cairo.cairo_restore(cairo);
+ return;
+ }
OS.gdk_gc_set_foreground(handle, color);
OS.gdk_draw_arc(data.drawable, handle, 1, x, y, width, height, 0, 23040);
color.pixel = values.foreground_pixel;
OS.gdk_gc_set_foreground(handle, color);
}
+public void fillPath (Path path) {
+ if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ if (path.handle == 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ initCairo();
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ GdkColor color = new GdkColor();
+ color.pixel = values.background_pixel;
+ int /*long*/ cairo = data.cairo;
+ int /*long*/ colormap = OS.gdk_colormap_get_system();
+ OS.gdk_colormap_query_color(colormap, color.pixel, color);
+ Cairo.cairo_save(cairo);
+ Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+ Cairo.cairo_add_path(cairo, path.handle);
+ Cairo.cairo_fill(cairo);
+ Cairo.cairo_restore(cairo);
+}
+
/**
* Fills the interior of the closed polygon which is defined by the
* specified array of integer coordinates, using the receiver's
@@ -1175,6 +1374,17 @@ public void fillPolygon(int[] pointArray) {
OS.gdk_gc_get_values(handle, values);
GdkColor color = new GdkColor();
color.pixel = values.background_pixel;
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ int /*long*/ colormap = OS.gdk_colormap_get_system();
+ OS.gdk_colormap_query_color(colormap, color.pixel, color);
+ Cairo.cairo_save(cairo);
+ Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+ drawPolyline(cairo, pointArray, true);
+ Cairo.cairo_fill(cairo);
+ Cairo.cairo_restore(cairo);
+ return;
+ }
OS.gdk_gc_set_foreground(handle, color);
OS.gdk_draw_polygon(data.drawable, handle, 1, pointArray, pointArray.length / 2);
color.pixel = values.foreground_pixel;
@@ -1210,6 +1420,17 @@ public void fillRectangle(int x, int y, int width, int height) {
OS.gdk_gc_get_values(handle, values);
GdkColor color = new GdkColor();
color.pixel = values.background_pixel;
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ int /*long*/ colormap = OS.gdk_colormap_get_system();
+ OS.gdk_colormap_query_color(colormap, color.pixel, color);
+ Cairo.cairo_save(cairo);
+ Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+ Cairo.cairo_rectangle(cairo, x, y, width, height);
+ Cairo.cairo_fill(cairo);
+ Cairo.cairo_restore(cairo);
+ return;
+ }
OS.gdk_gc_set_foreground(handle, color);
OS.gdk_draw_rectangle(data.drawable, handle, 1, x, y, width, height);
color.pixel = values.foreground_pixel;
@@ -1262,7 +1483,6 @@ public void fillRoundRectangle(int x, int y, int width, int height, int arcWidth
int nh = height;
int naw = arcWidth;
int nah = arcHeight;
-
if (nw < 0) {
nw = 0 - nw;
nx = nx - nw;
@@ -1271,20 +1491,37 @@ public void fillRoundRectangle(int x, int y, int width, int height, int arcWidth
nh = 0 - nh;
ny = ny -nh;
}
- if (naw < 0)
- naw = 0 - naw;
- if (nah < 0)
- nah = 0 - nah;
-
- int naw2 = naw / 2;
- int nah2 = nah / 2;
-
+ if (naw < 0) naw = 0 - naw;
+ if (nah < 0) nah = 0 - nah;
GdkGCValues values = new GdkGCValues();
OS.gdk_gc_get_values(handle, values);
GdkColor color = new GdkColor();
color.pixel = values.background_pixel;
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ float naw2 = naw / 2f;
+ float nah2 = nah / 2f;
+ float fw = nw / naw2;
+ float fh = nh / nah2;
+ int /*long*/ colormap = OS.gdk_colormap_get_system();
+ OS.gdk_colormap_query_color(colormap, color.pixel, color);
+ Cairo.cairo_save(cairo);
+ Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+ Cairo.cairo_translate(cairo, nx, ny);
+ Cairo.cairo_scale(cairo, naw2, nah2);
+ Cairo.cairo_move_to(cairo, fw - 1, 0);
+// Cairo.cairo_arc_to(cairo, 0, 0, 0, 1, 1);
+// Cairo.cairo_arc_to(cairo, 0, fh, 1, fh, 1);
+// Cairo.cairo_arc_to(cairo, fw, fh, fw, fh - 1, 1);
+// Cairo.cairo_arc_to(cairo, fw, 0, fw - 1, 0, 1);
+ Cairo.cairo_close_path(handle);
+ Cairo.cairo_stroke(cairo);
+ Cairo.cairo_restore(cairo);
+ return;
+ }
+ int naw2 = naw / 2;
+ int nah2 = nah / 2;
OS.gdk_gc_set_foreground(handle, color);
-
int /*long*/ drawable = data.drawable;
if (nw > naw) {
if (nh > nah) {
@@ -1309,7 +1546,6 @@ public void fillRoundRectangle(int x, int y, int width, int height, int arcWidth
OS.gdk_draw_arc(drawable, handle, 1, nx, ny, nw, nh, 0, 23040);
}
}
-
color.pixel = values.foreground_pixel;
OS.gdk_gc_set_foreground(handle, color);
}
@@ -1350,6 +1586,12 @@ public int getAdvanceWidth(char ch) {
return stringExtent(new String(new char[]{ch})).x;
}
+public int getAlpha() {
+ if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ initCairo();
+ return (int)(Cairo.cairo_current_alpha(data.cairo) * 255);
+}
+
/**
* Returns the background color.
*
@@ -1444,6 +1686,7 @@ public void getClipping(Region region) {
OS.gdk_region_union_with_rect(hRegion, rect);
} else {
OS.gdk_region_union(hRegion, clipRgn);
+ if (!isIdentity(data.matrix)) return;
}
if (data.damageRgn != 0) {
OS.gdk_region_intersect(hRegion, data.damageRgn);
@@ -1605,6 +1848,14 @@ public int getStyle () {
return data.style;
}
+public void getTransform(Transform transform) {
+ if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ if (transform == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (transform.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ initCairo();
+ Cairo.cairo_matrix_copy(transform.handle, data.matrix);
+}
+
/**
* Returns <code>true</code> if this GC is drawing in the mode
* where the resulting color in the destination is the
@@ -1677,6 +1928,65 @@ void init(Drawable drawable, GCData data, int /*long*/ gdkGC) {
handle = gdkGC;
}
+void initCairo() {
+ data.device.checkCairo();
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) return;
+ data.cairo = cairo = Cairo.cairo_create();
+ if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+ data.matrix = Cairo.cairo_matrix_create();
+ if (data.matrix == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+ data.inverseMatrix = Cairo.cairo_matrix_create();
+ if (data.inverseMatrix == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+ int /*long*/ xDisplay = OS.GDK_DISPLAY();
+ int /*long*/ xDrawable = 0;
+ int translateX = 0, translateY = 0;
+ if (data.image != null) {
+ xDrawable = OS.GDK_PIXMAP_XID(data.drawable);
+ } else {
+ int[] x = new int[1], y = new int[1];
+ int /*long*/ [] real_drawable = new int /*long*/ [1];
+ OS.gdk_window_get_internal_paint_info(data.drawable, real_drawable, x, y);
+ xDrawable = OS.gdk_x11_drawable_get_xid(real_drawable[0]);
+ translateX = -x[0];
+ translateY = -y[0];
+ }
+ Cairo.cairo_set_target_drawable(cairo, xDisplay, xDrawable);
+ Cairo.cairo_translate(cairo, translateX, translateY);
+ Cairo.cairo_set_fill_rule(cairo, Cairo.CAIRO_FILL_RULE_EVEN_ODD);
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ GdkColor color = new GdkColor();
+ color.pixel = values.foreground_pixel;
+ int /*long*/ colormap = OS.gdk_colormap_get_system();
+ OS.gdk_colormap_query_color(colormap, color.pixel, color);
+ Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+ Cairo.cairo_set_line_width(cairo, Math.max(1, values.line_width));
+ int cap = Cairo.CAIRO_LINE_CAP_BUTT;
+ switch (values.cap_style) {
+ case OS.GDK_CAP_ROUND: cap = Cairo.CAIRO_LINE_CAP_ROUND; break;
+ case OS.GDK_CAP_BUTT: cap = Cairo.CAIRO_LINE_CAP_BUTT; break;
+ case OS.GDK_CAP_PROJECTING: cap = Cairo.CAIRO_LINE_CAP_SQUARE; break;
+ }
+ Cairo.cairo_set_line_cap(cairo, cap);
+ int join = Cairo.CAIRO_LINE_JOIN_MITER;
+ switch (values.join_style) {
+ case OS.GDK_JOIN_MITER: join = Cairo.CAIRO_LINE_JOIN_MITER; break;
+ case OS.GDK_JOIN_ROUND: join = Cairo.CAIRO_LINE_JOIN_ROUND; break;
+ case OS.GDK_JOIN_BEVEL: join = Cairo.CAIRO_LINE_JOIN_BEVEL; break;
+ }
+ Cairo.cairo_set_line_join(cairo, join);
+ if (data.dashes != null) {
+ double[] dashes = new double[data.dashes.length];
+ for (int i = 0; i < dashes.length; i++) {
+ dashes[i] = data.dashes[i];
+ }
+ Cairo.cairo_set_dash(cairo, dashes, dashes.length, 0);
+ }
+ setCairoFont(cairo, data.font);
+ setCairoClip(cairo, data.clipRgn);
+}
+
/**
* Returns <code>true</code> if the receiver has a clipping
* region set into it, and <code>false</code> otherwise.
@@ -1710,6 +2020,20 @@ public boolean isDisposed() {
return handle == 0;
}
+boolean isIdentity(int /*long*/ matrix) {
+ if (matrix == 0) return true;
+ double[] a = new double[1], b = new double[1], c = new double[1];
+ double[] d = new double[1], tx = new double[1], ty = new double[1];
+ Cairo.cairo_matrix_get_affine(matrix, a, b, c, d, tx, ty);
+ return a[0] == 1 && b[0] == 0 && c[0] == 0 && d[0] == 1 && tx[0] == 0 && ty[0] == 0;
+}
+
+public void setAlpha(int alpha) {
+ if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ initCairo();
+ Cairo.cairo_set_alpha(data.cairo, alpha / 255f);
+}
+
/**
* Sets the background color. The background color is used
* for fill operations and as the background color when text
@@ -1732,11 +2056,51 @@ public void setBackground(Color color) {
OS.gdk_gc_set_background(handle, color.handle);
}
+static void setCairoFont(int /*long*/ cairo, Font font) {
+ setCairoFont(cairo, font.handle);
+}
+
+static void setCairoFont(int /*long*/ cairo, int /*long*/ font) {
+ int /*long*/ family = OS.pango_font_description_get_family(font);
+ int length = OS.strlen(family);
+ byte[] buffer = new byte[length + 1];
+ OS.memmove(buffer, family, length);
+ //TODO - convert font height from pango to cairo
+ double height = OS.PANGO_PIXELS(OS.pango_font_description_get_size(font)) * 96 / 72;
+ int pangoStyle = OS.pango_font_description_get_style(font);
+ int pangoWeight = OS.pango_font_description_get_weight(font);
+ int slant = Cairo.CAIRO_FONT_SLANT_NORMAL;
+ if (pangoStyle == OS.PANGO_STYLE_ITALIC) slant = Cairo.CAIRO_FONT_SLANT_ITALIC;
+ if (pangoStyle == OS.PANGO_STYLE_OBLIQUE) slant = Cairo.CAIRO_FONT_SLANT_OBLIQUE;
+ int weight = Cairo.CAIRO_FONT_WEIGHT_NORMAL;
+ if (pangoWeight == OS.PANGO_WEIGHT_BOLD) weight = Cairo.CAIRO_FONT_WEIGHT_BOLD;
+ Cairo.cairo_select_font(cairo, buffer, slant, weight);
+ Cairo.cairo_scale_font(cairo, height);
+}
+
+static void setCairoClip(int /*long*/ cairo, int /*long*/ clipRgn) {
+ Cairo.cairo_init_clip(cairo);
+ if (clipRgn == 0) return;
+ int[] nRects = new int[1];
+ int /*long*/[] rects = new int /*long*/[1];
+ OS.gdk_region_get_rectangles(clipRgn, rects, nRects);
+ GdkRectangle rect = new GdkRectangle();
+ for (int i=0; i<nRects[0]; i++) {
+ OS.memmove(rect, rects[0] + (i * GdkRectangle.sizeof), GdkRectangle.sizeof);
+ Cairo.cairo_rectangle(cairo, rect.x, rect.y, rect.width, rect.height);
+ }
+ Cairo.cairo_clip(cairo);
+ Cairo.cairo_new_path(cairo);
+ if (rects[0] != 0) OS.g_free(rects[0]);
+}
+
void setClipping(int /*long*/ clipRgn) {
if (clipRgn == 0) {
if (data.clipRgn != 0) {
OS.gdk_region_destroy(data.clipRgn);
data.clipRgn = 0;
+ } else {
+ return;
}
int /*long*/ clipping = data.damageRgn != 0 ? data.damageRgn : 0;
OS.gdk_gc_set_clip_region(handle, clipping);
@@ -1753,6 +2117,10 @@ void setClipping(int /*long*/ clipRgn) {
OS.gdk_gc_set_clip_region(handle, clipping);
if (clipping != clipRgn) OS.gdk_region_destroy(clipping);
}
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ setCairoClip(cairo, clipRgn);
+ }
}
/**
@@ -1790,6 +2158,19 @@ public void setClipping(int x, int y, int width, int height) {
OS.gdk_region_destroy(clipRgn);
}
+public void setClipping(Path path) {
+ if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ if (path != null && path.isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ setClipping(0);
+ if (path != null) {
+ initCairo();
+ int /*long*/ cairo = data.cairo;
+ Cairo.cairo_add_path(cairo, path.handle);
+ Cairo.cairo_clip(cairo);
+ Cairo.cairo_new_path(cairo);
+ }
+}
+
/**
* Sets the area of the receiver which can be changed
* by drawing operations to the rectangular area specified
@@ -1816,6 +2197,9 @@ public void setClipping(Rectangle rect) {
*
* @param region the clipping region.
*
+ * * @exception IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if the region has been disposed</li>
+ * </ul>
* @exception SWTException <ul>
* <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
* </ul>
@@ -1848,6 +2232,10 @@ public void setFont(Font font) {
int /*long*/ fontHandle = data.font = font.handle;
OS.pango_layout_set_font_description(data.layout, fontHandle);
data.stringWidth = data.stringHeight = -1;
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ setCairoFont(cairo, fontHandle);
+ }
}
/**
@@ -1869,20 +2257,28 @@ public void setForeground(Color color) {
if (color == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
if (color.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
OS.gdk_gc_set_foreground(handle, color.handle);
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ GdkColor gdkColor = color.handle;
+ Cairo.cairo_set_rgb_color(cairo, (gdkColor.red & 0xFFFF) / (float)0xFFFF, (gdkColor.green & 0xFFFF) / (float)0xFFFF, (gdkColor.blue & 0xFFFF) / (float)0xFFFF);
+ }
}
public void setLineCap(int cap) {
if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
- int cap_style = 0;
+ int cap_style = 0, cairo_style = 0;
switch (cap) {
case SWT.CAP_ROUND:
cap_style = OS.GDK_CAP_ROUND;
+ cairo_style = Cairo.CAIRO_LINE_CAP_ROUND;
break;
case SWT.CAP_FLAT:
cap_style = OS.GDK_CAP_BUTT;
+ cairo_style = Cairo.CAIRO_LINE_CAP_BUTT;
break;
case SWT.CAP_SQUARE:
cap_style = OS.GDK_CAP_PROJECTING;
+ cairo_style = Cairo.CAIRO_LINE_CAP_SQUARE;
break;
default:
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
@@ -1891,6 +2287,10 @@ public void setLineCap(int cap) {
OS.gdk_gc_get_values(handle, values);
int line_style = data.lineStyle == SWT.LINE_SOLID ? OS.GDK_LINE_SOLID : OS.GDK_LINE_ON_OFF_DASH;
OS.gdk_gc_set_line_attributes(handle, values.line_width, line_style, cap_style, values.join_style);
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ Cairo.cairo_set_line_cap(cairo, cairo_style);
+ }
}
public void setLineDash(int[] dashes) {
@@ -1913,20 +2313,35 @@ public void setLineDash(int[] dashes) {
OS.gdk_gc_get_values(handle, values);
int line_style = data.lineStyle == SWT.LINE_SOLID ? OS.GDK_LINE_SOLID : OS.GDK_LINE_ON_OFF_DASH;
OS.gdk_gc_set_line_attributes(handle, values.line_width, line_style, values.cap_style, values.join_style);
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ if (data.dashes != null) {
+ double[] cairoDashes = new double[data.dashes.length];
+ for (int i = 0; i < dashes.length; i++) {
+ cairoDashes[i] = data.dashes[i];
+ }
+ Cairo.cairo_set_dash(cairo, cairoDashes, cairoDashes.length, 0);
+ } else {
+ Cairo.cairo_set_dash(cairo, null, 0, 0);
+ }
+ }
}
public void setLineJoin(int join) {
if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
- int join_style = 0;
+ int join_style = 0, cairo_style = 0;
switch (join) {
case SWT.JOIN_MITER:
join_style = OS.GDK_JOIN_MITER;
+ cairo_style = Cairo.CAIRO_LINE_JOIN_MITER;
break;
case SWT.JOIN_ROUND:
join_style = OS.GDK_JOIN_ROUND;
+ cairo_style = Cairo.CAIRO_LINE_JOIN_ROUND;
break;
case SWT.JOIN_BEVEL:
join_style = OS.GDK_JOIN_BEVEL;
+ cairo_style = Cairo.CAIRO_LINE_JOIN_BEVEL;
break;
default:
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
@@ -1935,6 +2350,10 @@ public void setLineJoin(int join) {
OS.gdk_gc_get_values(handle, values);
int line_style = data.lineStyle == SWT.LINE_SOLID ? OS.GDK_LINE_SOLID : OS.GDK_LINE_ON_OFF_DASH;
OS.gdk_gc_set_line_attributes(handle, values.line_width, line_style, values.cap_style, join_style);
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ Cairo.cairo_set_line_join(cairo, cairo_style);
+ }
}
/**
@@ -1951,28 +2370,42 @@ public void setLineJoin(int join) {
*/
public void setLineStyle(int lineStyle) {
if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ int /*long*/ cairo = data.cairo;
int line_style = OS.GDK_LINE_ON_OFF_DASH;
switch (lineStyle) {
case SWT.LINE_SOLID:
line_style = OS.GDK_LINE_SOLID;
+ if (cairo != 0) Cairo.cairo_set_dash(cairo, null, 0, 0);
break;
case SWT.LINE_DASH:
OS.gdk_gc_set_dashes(handle, 0, new byte[] {18, 6}, 2);
+ if (cairo != 0) Cairo.cairo_set_dash(cairo, new double[] {18, 6}, 2, 0);
break;
case SWT.LINE_DOT:
OS.gdk_gc_set_dashes(handle, 0, new byte[] {3, 3}, 2);
+ if (cairo != 0) Cairo.cairo_set_dash(cairo, new double[] {3, 3}, 2, 0);
break;
case SWT.LINE_DASHDOT:
OS.gdk_gc_set_dashes(handle, 0, new byte[] {9, 6, 3, 6}, 4);
+ if (cairo != 0) Cairo.cairo_set_dash(cairo, new double[] {9, 6, 3, 6}, 4, 0);
break;
case SWT.LINE_DASHDOTDOT:
OS.gdk_gc_set_dashes(handle, 0, new byte[] {9, 3, 3, 3, 3, 3}, 6);
+ if (cairo != 0) Cairo.cairo_set_dash(cairo, new double[] {9, 3, 3, 3, 3, 3}, 6, 0);
case SWT.LINE_CUSTOM:
byte[] dash_list = data.dashes;
if (dash_list != null) {
OS.gdk_gc_set_dashes(handle, 0, dash_list, dash_list.length);
+ if (cairo != 0) {
+ double[] dashes = new double[data.dashes.length];
+ for (int i = 0; i < dashes.length; i++) {
+ dashes[i] = data.dashes[i];
+ }
+ Cairo.cairo_set_dash(cairo, dashes, dashes.length, 0);
+ }
} else {
line_style = OS.GDK_LINE_SOLID;
+ if (cairo != 0) Cairo.cairo_set_dash(cairo, null, 0, 0);
}
break;
default:
@@ -2002,6 +2435,10 @@ public void setLineWidth(int width) {
OS.gdk_gc_get_values(handle, values);
int line_style = data.lineStyle == SWT.LINE_SOLID ? OS.GDK_LINE_SOLID : OS.GDK_LINE_ON_OFF_DASH;
OS.gdk_gc_set_line_attributes(handle, width, line_style, values.cap_style, values.join_style);
+ int /*long*/ cairo = data.cairo;
+ if (cairo != 0) {
+ Cairo.cairo_set_line_width(cairo, width);
+ }
}
void setString(String string, int flags) {
@@ -2045,6 +2482,59 @@ void setString(String string, int flags) {
data.drawFlags = flags;
}
+public void setTransform(Transform transform) {
+ if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ if (transform == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (transform.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ initCairo();
+ int /*long*/ cairo = data.cairo;
+ Cairo.cairo_concat_matrix(cairo, data.inverseMatrix);
+ Cairo.cairo_concat_matrix(cairo, transform.handle);
+ Cairo.cairo_matrix_copy(data.matrix, transform.handle);
+ Cairo.cairo_matrix_copy(data.inverseMatrix, transform.handle);
+ Cairo.cairo_matrix_invert(data.inverseMatrix);
+ //TODO - round off problems
+ int /*long*/ clipRgn = data.clipRgn;
+ if (clipRgn != 0) {
+ int /*long*/ matrix = data.inverseMatrix;
+ int /*long*/ newRgn = OS.gdk_region_new();
+ int[] nRects = new int[1];
+ int /*long*/[] rects = new int /*long*/[1];
+ OS.gdk_region_get_rectangles(clipRgn, rects, nRects);
+ GdkRectangle rect = new GdkRectangle();
+ int[] pointArray = new int[8];
+ double[] x = new double[1], y = new double[1];
+ for (int i=0; i<nRects[0]; i++) {
+ OS.memmove(rect, rects[0] + (i * GdkRectangle.sizeof), GdkRectangle.sizeof);
+ x[0] = rect.x;
+ y[0] = rect.y;
+ Cairo.cairo_matrix_transform_point(matrix, x, y);
+ pointArray[0] = (int)Math.round(x[0]);
+ pointArray[1] = (int)Math.round(y[0]);
+ x[0] = rect.x + rect.width;
+ y[0] = rect.y;
+ Cairo.cairo_matrix_transform_point(matrix, x, y);
+ pointArray[2] = (int)Math.round(x[0]);
+ pointArray[3] = (int)Math.round(y[0]);
+ x[0] = rect.x + rect.width;
+ y[0] = rect.y + rect.height;
+ Cairo.cairo_matrix_transform_point(matrix, x, y);
+ pointArray[4] = (int)Math.round(x[0]);
+ pointArray[5] = (int)Math.round(y[0]);
+ x[0] = rect.x;
+ y[0] = rect.y + rect.height;
+ Cairo.cairo_matrix_transform_point(matrix, x, y);
+ pointArray[6] = (int)Math.round(x[0]);
+ pointArray[7] = (int)Math.round(y[0]);
+ int /*long*/ polyRgn = OS.gdk_region_polygon(pointArray, pointArray.length / 2, OS.GDK_EVEN_ODD_RULE);
+ OS.gdk_region_union(newRgn, polyRgn);
+ OS.gdk_region_destroy(polyRgn);
+ }
+ OS.gdk_region_destroy(clipRgn);
+ data.clipRgn = newRgn;
+ }
+}
+
/**
* If the argument is <code>true</code>, puts the receiver
* in a drawing mode where the resulting color in the destination
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java
index 320d7fca34..7dd8743351 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java
@@ -39,6 +39,9 @@ public final class GCData {
public byte[] dashes;
public boolean xorMode;
+ public int /*long*/ cairo;
+ public int /*long*/ matrix, inverseMatrix;
+
public String string;
public int stringWidth = -1;
public int stringHeight = -1;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java
index 1847a02220..9da6e5816f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java
@@ -11,6 +11,7 @@
package org.eclipse.swt.graphics;
+import org.eclipse.swt.internal.cairo.*;
import org.eclipse.swt.internal.gtk.*;
import org.eclipse.swt.*;
import java.io.*;
@@ -94,6 +95,8 @@ public final class Image implements Drawable {
*/
public int /*long*/ mask;
+ int /*long*/ surface;
+
/**
* The device where this image was created.
*/
@@ -558,7 +561,8 @@ public void dispose () {
if (memGC != null) memGC.dispose();
if (pixmap != 0) OS.g_object_unref(pixmap);
if (mask != 0) OS.g_object_unref(mask);
- pixmap = mask = 0;
+ if (surface != 0) Cairo.cairo_surface_destroy(surface);
+ surface = pixmap = mask = 0;
memGC = null;
if (device.tracking) device.dispose_Object(this);
device = null;