Modifications to fix crashes on Window with alphaBlend = true on 16 bit display
authorJerome St-Louis <jerome@ecere.com>
Fri, 27 May 2011 00:20:34 +0000 (20:20 -0400)
committerJerome St-Louis <jerome@ecere.com>
Fri, 27 May 2011 00:20:34 +0000 (20:20 -0400)
ecere/src/gfx/Display.ec
ecere/src/gfx/drivers/GDIDisplayDriver.ec
ecere/src/gfx/drivers/LFBDisplayDriver.ec
ecere/src/gui/drivers/Win32Interface.ec

index 103c0d0..560f4ed 100644 (file)
@@ -1087,7 +1087,7 @@ public:
    property bool pickingPlanes { set { display3D.pickingPlanes = value; } };
 #endif
    property DisplayFlags flags { get { return displaySystem.flags; } }
-   property PixelFormat pixelFormat { get { return displaySystem.pixelFormat; } }
+   property PixelFormat pixelFormat { get { return /*alphaBlend ? pixelFormat888 : */displaySystem.pixelFormat; } }
    property bool alphaBlend { set { alphaBlend = value; } get { return alphaBlend; } };
    property bool useSharedMemory { set { useSharedMemory = value; } get { return useSharedMemory; } };
    property void * systemWindow { get { return window; } };
index ccebbc9..1c77b37 100644 (file)
@@ -230,7 +230,7 @@ class GDIDisplayDriver : DisplayDriver
          if((gdiDisplay.logPalette = (LOGPALETTE *)new0 byte[sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*256]) &&
             ((subclass(DisplayDriver))class(LFBDisplayDriver)).CreateDisplay(display))
          {
-            gdiDisplay.bitmap.pixelFormat = display.displaySystem.pixelFormat;
+            gdiDisplay.bitmap.pixelFormat = /*display.alphaBlend ? pixelFormat888 : */display.displaySystem.pixelFormat;
             result = true;
          }
       }
@@ -262,7 +262,7 @@ class GDIDisplayDriver : DisplayDriver
             gdiDisplay.memDC = CreateCompatibleDC(hdc);
             SetMapMode(gdiDisplay.memDC, MM_TEXT);
 
-            gdiDisplay.bitmap.pixelFormat = display.displaySystem.pixelFormat;
+            gdiDisplay.bitmap.pixelFormat = /*display.alphaBlend ? pixelFormat888 : */display.displaySystem.pixelFormat;
 
             switch(GetColorDepthShifts(gdiDisplay.bitmap.pixelFormat))
             {
@@ -334,7 +334,7 @@ class GDIDisplayDriver : DisplayDriver
    void StartUpdate(Display display)
    {
       GDIDisplay gdiDisplay = display.driverData;
-      if(!display.alphaBlend)
+      if(!display.alphaBlend || display.pixelFormat != pixelFormat888)
       {
          GdiSetBatchLimit(1000);
          gdiDisplay.hdc = GetDC(display.window);
@@ -355,7 +355,7 @@ class GDIDisplayDriver : DisplayDriver
       box.right += 1;
       box.bottom += 1;
 
-      if(!display.alphaBlend)
+      if(!display.alphaBlend || display.pixelFormat != pixelFormat888)
       {
          // printf("Box: %d, %d, %d, %d\n", box.left, box.top, box.right, box.bottom);
          ScrollDC(gdiDisplay.hdc, -x, -y, (RECT *)&box, (RECT *)&box, gdiDisplay.rgn, null);
@@ -395,7 +395,7 @@ class GDIDisplayDriver : DisplayDriver
    {
       GDIDisplay gdiDisplay = display.driverData;
       int returnValue;
-      if(display.alphaBlend)
+      if(display.alphaBlend && display.pixelFormat == pixelFormat888)
       {
          HDC hdc = GetDC(0);
          POINT point = { gdiDisplay.offset.x, gdiDisplay.offset.y};
@@ -424,7 +424,7 @@ class GDIDisplayDriver : DisplayDriver
    {
       GDIDisplay gdiDisplay = display.driverData;
       DeleteObject(gdiDisplay.rgn);
-      if(!display.alphaBlend)
+      if(!display.alphaBlend || display.pixelFormat != pixelFormat888)
          ReleaseDC(display.window,gdiDisplay.hdc);
 
       // delete gdiDisplay.data;
@@ -647,7 +647,7 @@ class GDIDisplayDriver : DisplayDriver
    {
       ((subclass(DisplayDriver))class(LFBDisplayDriver)).SetBackground(display, surface, color);
 
-      if(display && !display.alphaBlend)
+      if(display && (!display.alphaBlend || display.pixelFormat != pixelFormat888))
       { 
          GDISurface gdiSurface = surface.driverData;
          GDIDisplay gdiDisplay = display ? display.driverData : null;
@@ -886,7 +886,7 @@ class GDIDisplayDriver : DisplayDriver
    void TextFont(Display display, Surface surface, Font font)
    {
       GDIFont gdiFont = (GDIFont) font;
-      if(display.alphaBlend)
+      if(display.alphaBlend && display.pixelFormat == pixelFormat888)
       {
          if(!gdiFont.font)
          {
@@ -905,7 +905,7 @@ class GDIDisplayDriver : DisplayDriver
    void TextOpacity(Display display, Surface surface, bool opaque)
    {
       ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextOpacity(display, surface, opaque);
-      if(display && !display.alphaBlend)      
+      if(display && (!display.alphaBlend || display.pixelFormat != pixelFormat888))
       {
          GDISurface gdiSurface = surface.driverData;
          SetBkMode(gdiSurface.hdc, opaque ? OPAQUE : TRANSPARENT);
@@ -914,7 +914,7 @@ class GDIDisplayDriver : DisplayDriver
 
    void WriteText(Display display, Surface surface, int x, int y, char * text, int len)
    {
-      if(display.alphaBlend)
+      if(display.alphaBlend && display.pixelFormat == pixelFormat888)
       {
          GDIFont gdiFont = (GDIFont)surface.font;
          if(!gdiFont.font)
@@ -937,7 +937,7 @@ class GDIDisplayDriver : DisplayDriver
          uint16 * u16text = UTF8toUTF16Len(text, len, &wordCount);
 
          TextOut(gdiSurface.hdc, x + surface.offset.x, y + surface.offset.y, u16text, wordCount);
-         if(display.alphaBlend)
+         if(display.alphaBlend && display.pixelFormat == pixelFormat888)
          {
             int w, h;
             FontExtent(display.displaySystem, surface.font, text, len, &w, &h);
@@ -953,7 +953,7 @@ class GDIDisplayDriver : DisplayDriver
 
    void TextExtent(Display display, Surface surface, char * text, int len, int * width, int * height)
    {
-      if(display && display.alphaBlend)
+      if(display && display.alphaBlend && display.pixelFormat == pixelFormat888)
          ((subclass(DisplayDriver))class(LFBDisplayDriver)).TextExtent(display, surface, text, len, width, height);
       else
       {
index 277fa02..30af1b1 100644 (file)
@@ -1023,7 +1023,7 @@ public class LFBDisplayDriver : DisplayDriver
    {
       if(bitmap.pixelFormat != pixelFormatAlpha)
       {
-         if(!ConvertBitmap(displaySystem, bitmap, bitmap.alphaBlend ? pixelFormat888 : displaySystem.pixelFormat, null))
+         if(!ConvertBitmap(displaySystem, bitmap, /*bitmap.alphaBlend ? pixelFormat888 : */displaySystem.pixelFormat, null))
          {
             FreeBitmap(displaySystem, bitmap);
             return false;
@@ -2079,39 +2079,88 @@ public class LFBDisplayDriver : DisplayDriver
             int x, y;
             if(src.pixelFormat == pixelFormatAlpha)
             {
-               ColorAlpha * picture = ((ColorAlpha *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
-               byte * source = ((byte *)src.picture) + (src.stride * sy) + sx;
-               ColorAlpha color = lfbSurface.writingText ? surface.foreground : surface.blitTint;
-               for(y = 0; y < h; y++)
+               if(lfbSurface.bitmap.pixelFormat == pixelFormat888)
                {
-                  for(x = 0; x < w; x++, picture++, source++)
+                  ColorAlpha * picture = ((ColorAlpha *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
+                  byte * source = ((byte *)src.picture) + (src.stride * sy) + sx;
+                  ColorAlpha color = lfbSurface.writingText ? surface.foreground : surface.blitTint;
+                  for(y = 0; y < h; y++)
                   {
-                     int a = *source * color.a;
-                     ColorAlpha dest = *picture;
-                     int r = (a * color.color.r + ((255 * 255 - a) * dest.color.r)) / (255 * 255);
-                     int g = (a * color.color.g + ((255 * 255 - a) * dest.color.g)) / (255 * 255);
-                     int b = (a * color.color.b + ((255 * 255 - a) * dest.color.b)) / (255 * 255);
-                     if(r > 255) r = 255;
-                     if(g > 255) g = 255;
-                     if(b > 255) b = 255;
-                     picture->color = { (byte)r, (byte)g, (byte)b };
-                     if(alphaWrite == blend)
+                     for(x = 0; x < w; x++, picture++, source++)
                      {
-                        int ca = (a * 255 + (255 * 255 - a) * dest.a) / (255 * 255);
-                        if(ca > 255) ca = 255;
-                        picture->a = (byte)ca;
+                        int a = *source * color.a;
+                        ColorAlpha dest = *picture;
+                        int r = (a * color.color.r + ((255 * 255 - a) * dest.color.r)) / (255 * 255);
+                        int g = (a * color.color.g + ((255 * 255 - a) * dest.color.g)) / (255 * 255);
+                        int b = (a * color.color.b + ((255 * 255 - a) * dest.color.b)) / (255 * 255);
+                        if(r > 255) r = 255;
+                        if(g > 255) g = 255;
+                        if(b > 255) b = 255;
+                        picture->color = { (byte)r, (byte)g, (byte)b };
+                        if(alphaWrite == blend)
+                        {
+                           int ca = (a * 255 + (255 * 255 - a) * dest.a) / (255 * 255);
+                           if(ca > 255) ca = 255;
+                           picture->a = (byte)ca;
+                        }
+                        else if(alphaWrite)
+                           picture->a = (byte)(a / 255);
                      }
-                     else if(alphaWrite)
-                        picture->a = (byte)(a / 255);
+                     picture += lfbSurface.bitmap.stride - w;
+                     source += src.stride - w;
+                  }
+               }
+               else if(lfbSurface.bitmap.pixelFormat == pixelFormat555)
+               {
+                  Color555 * picture = ((Color555 *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
+                  byte * source = ((byte *)src.picture) + (src.stride * sy) + sx;
+                  ColorAlpha color = lfbSurface.writingText ? surface.foreground : surface.blitTint;
+                  for(y = 0; y < h; y++)
+                  {
+                     for(x = 0; x < w; x++, picture++, source++)
+                     {
+                        int a = *source * color.a;
+                        Color dest = *picture;
+                        int r = (a * color.color.r + ((255 * 255 - a) * dest.r)) / (255 * 255);
+                        int g = (a * color.color.g + ((255 * 255 - a) * dest.g)) / (255 * 255);
+                        int b = (a * color.color.b + ((255 * 255 - a) * dest.b)) / (255 * 255);
+                        if(r > 255) r = 255;
+                        if(g > 255) g = 255;
+                        if(b > 255) b = 255;
+                        *picture = Color { (byte)r, (byte)g, (byte)b };
+                     }
+                     picture += lfbSurface.bitmap.stride - w;
+                     source += src.stride - w;
+                  }
+               }
+               else if(lfbSurface.bitmap.pixelFormat == pixelFormat565)
+               {
+                  Color565 * picture = ((Color565 *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
+                  byte * source = ((byte *)src.picture) + (src.stride * sy) + sx;
+                  ColorAlpha color = lfbSurface.writingText ? surface.foreground : surface.blitTint;
+                  for(y = 0; y < h; y++)
+                  {
+                     for(x = 0; x < w; x++, picture++, source++)
+                     {
+                        int a = *source * color.a;
+                        Color dest = *picture;
+                        int r = (a * color.color.r + ((255 * 255 - a) * dest.r)) / (255 * 255);
+                        int g = (a * color.color.g + ((255 * 255 - a) * dest.g)) / (255 * 255);
+                        int b = (a * color.color.b + ((255 * 255 - a) * dest.b)) / (255 * 255);
+                        if(r > 255) r = 255;
+                        if(g > 255) g = 255;
+                        if(b > 255) b = 255;
+                        *picture = Color { (byte)r, (byte)g, (byte)b };
+                     }
+                     picture += lfbSurface.bitmap.stride - w;
+                     source += src.stride - w;
                   }
-                  picture += lfbSurface.bitmap.stride - w;
-                  source += src.stride - w;
                }
             }
             else
             {
                ColorAlpha * source = ((ColorAlpha *)src.picture) + (src.stride * sy) + sx;
-               if(lfbSurface.bitmap.pixelFormat == pixelFormat888)               
+               if(lfbSurface.bitmap.pixelFormat == pixelFormat888)
                {
                   ColorAlpha * picture = ((ColorAlpha *)lfbSurface.bitmap.picture) + (lfbSurface.bitmap.stride * dy) + dx;
                   for(y = 0; y < h; y++)
@@ -2168,11 +2217,11 @@ public class LFBDisplayDriver : DisplayDriver
                   {
                      for(x = 0; x < w; x++, picture++, source++)
                      {
-                        ColorAlpha src = *source;
+                        ColorAlpha psrc = *source;
                         Color555 dest = *picture;
-                        int r = src.a * src.color.r * 31 / 255 + ((255 - src.a) * dest.r);
-                        int g = src.a * src.color.g * 31 / 255 + ((255 - src.a) * dest.g);
-                        int b = src.a * src.color.b * 31 / 255 + ((255 - src.a) * dest.b);
+                        int r = psrc.a * psrc.color.r * 31 / 255 + ((255 - psrc.a) * dest.r);
+                        int g = psrc.a * psrc.color.g * 31 / 255 + ((255 - psrc.a) * dest.g);
+                        int b = psrc.a * psrc.color.b * 31 / 255 + ((255 - psrc.a) * dest.b);
                         if(r > 255 * 31) r = 255 * 31;
                         if(g > 255 * 31) g = 255 * 31;
                         if(b > 255 * 31) b = 255 * 31;
index 29fcb7e..5225ddc 100644 (file)
@@ -495,7 +495,7 @@ class Win32Interface : Interface
                break;
             case WM_PAINT:
             {
-               if(!window.alphaBlend)
+               if(!window.alphaBlend || window.display.pixelFormat != pixelFormat888)
                {
                   PAINTSTRUCT ps;
 
@@ -1307,7 +1307,7 @@ class Win32Interface : Interface
    void SetRootWindowColor(Window window)
    {
       DWORD style = GetWindowLong(window.windowHandle, GWL_EXSTYLE);
-      if(window.alphaBlend)
+      if(window.alphaBlend && window.display.pixelFormat == pixelFormat888)
       {
          /*if(A(window.background) == 255)
          {
@@ -1701,6 +1701,20 @@ class Win32Interface : Interface
    {
       HICON icon = null;
       HICON oldIcon = (HICON)SendMessage(window.windowHandle, WM_GETICON, ICON_BIG, 0);
+
+      // WARNING -- putting this here as it is right after CreateRootWindow
+      // Take out Layered flag if we're not in 24 bit
+      {
+         if(window.alphaBlend && window.display.pixelFormat != pixelFormat888)
+         {
+#ifndef ECERE_NOBLENDING
+            DWORD style = GetWindowLong(window.windowHandle, GWL_EXSTYLE);
+            style &= ~WS_EX_LAYERED;
+            SetWindowLong(window.windowHandle, GWL_EXSTYLE, style);
+#endif
+         }
+      }
+
       if(oldIcon && oldIcon != (HICON)GetClassLong(window.windowHandle, GCL_HICON))
       {
          DestroyIcon(oldIcon);