FLTK logo

[master] b3e1df3 - STR 3489: fix alpha blending for X11

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] b3e1df3 - STR 3489: fix alpha blending for X11 "Matthias Melcher" 12:32 Mar 15  
 
commit b3e1df35848003952369f8cbf05cdd41ae62d839
Author:     Matthias Melcher <github@matthiasm.com>
AuthorDate: Fri Mar 15 20:18:02 2024 +0100
Commit:     Matthias Melcher <github@matthiasm.com>
CommitDate: Fri Mar 15 20:18:35 2024 +0100

    STR 3489: fix alpha blending for X11

 src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx | 60 +++++++++++++---------
 1 file changed, 37 insertions(+), 23 deletions(-)

diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx
index 78c08af..5dafe50 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx
@@ -1,7 +1,7 @@
 //
 // Image drawing routines for the Fast Light Tool Kit (FLTK).
 //
-// Copyright 1998-2020 by Bill Spitzak and others.
+// Copyright 1998-2024 by Bill Spitzak and others.
 //
 // This library is free software. Distribution and use rights are outlined in
 // the file "COPYING" which should have been included with this file.  If this
@@ -640,7 +640,6 @@ void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_Bitmap *bm, int X, int Y, int W, int
   XSetFillStyle(fl_display, gc_, FillSolid);
 }
 
-
 // Composite an image with alpha on systems that don't have accelerated
 // alpha compositing...
 static void alpha_blend(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) {
@@ -671,8 +670,9 @@ static void alpha_blend(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, i
   int srcskip = ld - img->d() * W;
   uchar *dstptr = dst;
 
-  uchar srcr, srcg, srcb, srca;
-  uchar dstr, dstg, dstb, dsta;
+  uchar srcr, srcg, srcb;  // source color components
+  uchar dstr, dstg, dstb;  // destination color components
+  unsigned int srca, dsta; // source alpha and inverse source alpha
 
   if (img->d() == 2) {
     // Composite grayscale + alpha over RGB...
@@ -680,15 +680,23 @@ static void alpha_blend(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, i
       for (int x = W; x > 0; x--) {
         srcg = *srcptr++;
         srca = *srcptr++;
-
-        dstr = dstptr[0];
-        dstg = dstptr[1];
-        dstb = dstptr[2];
-        dsta = 255 - srca;
-
-        *dstptr++ = (srcg * srca + dstr * dsta) >> 8;
-        *dstptr++ = (srcg * srca + dstg * dsta) >> 8;
-        *dstptr++ = (srcg * srca + dstb * dsta) >> 8;
+        if (srca == 255) { // special case "copy"
+          *dstptr++ = srcg;
+          *dstptr++ = srcg;
+          *dstptr++ = srcg;
+        } else if (srca == 0) { // special case "ignore"
+          dstptr += 3;
+        } else { // common case "blend"
+          srca += srca>>7; // multiply by 1.004 to compensate integer rounding error
+          dstr = dstptr[0];
+          dstg = dstptr[1];
+          dstb = dstptr[2];
+          dsta = 256 - srca;
+          unsigned int srcg_pm = srcg * srca; // premultiply once
+          *dstptr++ = (srcg_pm + dstr * dsta) >> 8;
+          *dstptr++ = (srcg_pm + dstg * dsta) >> 8;
+          *dstptr++ = (srcg_pm + dstb * dsta) >> 8;
+        }
       }
   } else {
     // Composite RGBA over RGB...
@@ -698,18 +706,24 @@ static void alpha_blend(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, i
         srcg = *srcptr++;
         srcb = *srcptr++;
         srca = *srcptr++;
-
-        dstr = dstptr[0];
-        dstg = dstptr[1];
-        dstb = dstptr[2];
-        dsta = 255 - srca;
-
-        *dstptr++ = (srcr * srca + dstr * dsta) >> 8;
-        *dstptr++ = (srcg * srca + dstg * dsta) >> 8;
-        *dstptr++ = (srcb * srca + dstb * dsta) >> 8;
+        if (srca == 255) { // special case "copy"
+          *dstptr++ = srcr;
+          *dstptr++ = srcg;
+          *dstptr++ = srcb;
+        } else if (srca == 0) { // special case "ignore"
+          dstptr += 3;
+        } else { // common case "blend"
+          srca += srca>>7; // multiply by 1.004 to compensate integer rounding error
+          dstr = dstptr[0];
+          dstg = dstptr[1];
+          dstb = dstptr[2];
+          dsta = 256 - srca;
+          *dstptr++ = (srcr * srca + dstr * dsta) >> 8;
+          *dstptr++ = (srcg * srca + dstg * dsta) >> 8;
+          *dstptr++ = (srcb * srca + dstb * dsta) >> 8;
+        }
       }
   }
-
   fl_draw_image(dst, X, Y, W, H, 3, 0);
 
   delete[] dst;
Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.