aboutsummaryrefslogtreecommitdiffhomepage
path: root/gtk/PlatGTK.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'gtk/PlatGTK.cxx')
-rw-r--r--gtk/PlatGTK.cxx84
1 files changed, 84 insertions, 0 deletions
diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx
index f776a2c19..20c518fdb 100644
--- a/gtk/PlatGTK.cxx
+++ b/gtk/PlatGTK.cxx
@@ -713,6 +713,8 @@ public:
void FillRectangle(PRectangle rc, ColourAllocated back);
void FillRectangle(PRectangle rc, Surface &surfacePattern);
void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
+ void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
+ ColourAllocated outline, int alphaOutline, int flags);
void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
void Copy(PRectangle rc, Point from, Surface &surfaceSource);
@@ -1014,6 +1016,88 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAl
}
}
+// Plot a point into a guint32 buffer symetrically to all 4 qudrants
+static void AllFour(guint32 *pixels, int stride, int width, int height, int x, int y, guint32 val) {
+ pixels[y*stride+x] = val;
+ pixels[y*stride+width-1-x] = val;
+ pixels[(height-1-y)*stride+x] = val;
+ pixels[(height-1-y)*stride+width-1-x] = val;
+}
+
+static unsigned int GetRValue(unsigned int co) {
+ return (co >> 16) & 0xff;
+}
+
+static unsigned int GetGValue(unsigned int co) {
+ return (co >> 8) & 0xff;
+}
+
+static unsigned int GetBValue(unsigned int co) {
+ return co & 0xff;
+}
+
+#if GTK_MAJOR_VERSION < 2
+void SurfaceImpl::AlphaRectangle(PRectangle rc, int , ColourAllocated , int , ColourAllocated outline, int , int ) {
+ if (gc && drawable) {
+ // Can't use GdkPixbuf on GTK+ 1.x, so draw an outline rather than use alpha.
+ PenColour(outline);
+ gdk_draw_rectangle(drawable, gc, 0,
+ rc.left, rc.top,
+ rc.right - rc.left - 1, rc.bottom - rc.top - 1);
+ }
+}
+#else
+void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
+ ColourAllocated outline, int alphaOutline, int flags) {
+ if (gc && drawable) {
+ int width = rc.Width();
+ int height = rc.Height();
+ // Ensure not distorted too much by corners when small
+ cornerSize = Platform::Minimum(cornerSize, (Platform::Minimum(width, height) / 2) - 2);
+ // Make a 32 bit deep pixbuf with alpha
+ GdkPixbuf *pixalpha = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
+
+ guint8 pixVal[4] = {0};
+ guint32 valEmpty = *(reinterpret_cast<guint32 *>(pixVal));
+ pixVal[0] = GetRValue(fill.AsLong());
+ pixVal[1] = GetGValue(fill.AsLong());
+ pixVal[2] = GetBValue(fill.AsLong());
+ pixVal[3] = alphaFill;
+ guint32 valFill = *(reinterpret_cast<guint32 *>(pixVal));
+ pixVal[0] = GetRValue(outline.AsLong());
+ pixVal[1] = GetGValue(outline.AsLong());
+ pixVal[2] = GetBValue(outline.AsLong());
+ pixVal[3] = alphaOutline;
+ guint32 valOutline = *(reinterpret_cast<guint32 *>(pixVal));
+ guint32 *pixels = reinterpret_cast<guint32 *>(gdk_pixbuf_get_pixels(pixalpha));
+ int stride = gdk_pixbuf_get_rowstride(pixalpha) / 4;
+ for (int y=0; y<height; y++) {
+ for (int x=0; x<width; x++) {
+ if ((x==0) || (x==width-1) || (y == 0) || (y == height-1)) {
+ pixels[y*stride+x] = valOutline;
+ } else {
+ pixels[y*stride+x] = valFill;
+ }
+ }
+ }
+ for (int c=0;c<cornerSize; c++) {
+ for (int x=0;x<c+1; x++) {
+ AllFour(pixels, stride, width, height, x, c-x, valEmpty);
+ }
+ }
+ for (int x=1;x<cornerSize; x++) {
+ AllFour(pixels, stride, width, height, x, cornerSize-x, valOutline);
+ }
+
+ // Draw with alpha
+ gdk_draw_pixbuf(drawable, gc, pixalpha,
+ 0,0, rc.left,rc.top, width,height, GDK_RGB_DITHER_NORMAL, 0, 0);
+
+ g_object_unref(pixalpha);
+ }
+}
+#endif
+
void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
PenColour(back);
gdk_draw_arc(drawable, gc, 1,