diff --git a/include/wx/rawbmp.h b/include/wx/rawbmp.h index a8be3f8fd0..c7ae877a3f 100644 --- a/include/wx/rawbmp.h +++ b/include/wx/rawbmp.h @@ -146,12 +146,19 @@ struct wxPixelFormat // wxImage format is common to all platforms typedef wxPixelFormat wxImagePixelFormat; +// wxPIXEL_FORMAT_ALPHA is the offset of alpha (defined if the format has +// alpha). + +// wxHAS_PREMULTIPLIED_ALPHA is defined if R, G, and B are stored premultiplied +// (scaled) by alpha, otherwise they have full value ("straight alpha"). + // the (most common) native bitmap format without alpha support #if defined(__WXMSW__) // under MSW the RGB components are reversed, they're in BGR order typedef wxPixelFormat wxNativePixelFormat; #define wxPIXEL_FORMAT_ALPHA 3 + #define wxHAS_PREMULTIPLIED_ALPHA template<> struct wxPixelFormat @@ -170,12 +177,13 @@ typedef wxPixelFormat wxImagePixelFormat; enum { HasAlpha = false }; }; typedef wxPixelFormat wxMonoPixelFormat; -#elif defined(__WXMAC__) +#elif defined(__WXOSX__) // under Mac, first component is unused but still present, hence we use // 32bpp, not 24 typedef wxPixelFormat wxNativePixelFormat; #define wxPIXEL_FORMAT_ALPHA 0 + #define wxHAS_PREMULTIPLIED_ALPHA #elif defined(__WXGTK__) // Under GTK+ 2.X we use GdkPixbuf, which is standard RGB or RGBA typedef wxPixelFormat wxNativePixelFormat; @@ -190,6 +198,7 @@ typedef wxPixelFormat wxImagePixelFormat; typedef wxPixelFormat wxNativePixelFormat; #define wxPIXEL_FORMAT_ALPHA 3 + #define wxHAS_PREMULTIPLIED_ALPHA template<> struct wxPixelFormat diff --git a/samples/image/image.cpp b/samples/image/image.cpp index 61ea8004ab..27ee4975c8 100644 --- a/samples/image/image.cpp +++ b/samples/image/image.cpp @@ -675,12 +675,23 @@ public: for ( int x = 0; x < REAL_SIZE; ++x ) { - // note that RGB must be premultiplied by alpha unsigned a = (wxAlphaPixelData::Iterator::ChannelType)((x*255.)/REAL_SIZE); + p.Alpha() = a; +#ifdef wxHAS_PREMULTIPLIED_ALPHA + // RGB must be premultiplied by alpha on some platforms p.Red() = r * a / 256; p.Green() = g * a / 256; p.Blue() = b * a / 256; - p.Alpha() = a; +#else + if ( a ) + { + p.Red() = r; + p.Green() = g; + p.Blue() = b; + } + else + p.Red() = p.Green() = p.Blue() = 0; +#endif // wxHAS_PREMULTIPLIED_ALPHA ++p; // same as p.OffsetX(1) } diff --git a/src/generic/bmpsvg.cpp b/src/generic/bmpsvg.cpp index dd6672cad8..e480970453 100644 --- a/src/generic/bmpsvg.cpp +++ b/src/generic/bmpsvg.cpp @@ -189,14 +189,14 @@ wxBitmap wxBitmapBundleImplSVG::DoRasterize(const wxSize& size) for ( int x = 0; x < size.x; ++x ) { const unsigned char a = src[3]; -#if defined (__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) - // MSW, OSX, and Qt bitmaps require premultiplication by alpha. +#ifdef wxHAS_PREMULTIPLIED_ALPHA + // Some platforms require premultiplication by alpha. dst.Red() = src[0] * a / 255; dst.Green() = src[1] * a / 255; dst.Blue() = src[2] * a / 255; dst.Alpha() = a; #else - // Other platforms (esp. GTK) store bitmaps with straight alpha. + // Other platforms store bitmaps with straight alpha. dst.Alpha() = a; if ( a ) { @@ -205,7 +205,7 @@ wxBitmap wxBitmapBundleImplSVG::DoRasterize(const wxSize& size) dst.Blue() = src[2]; } else - // A more canonical form for completely transparent pixels + // A more canonical form for completely transparent pixels. dst.Red() = dst.Green() = dst.Blue() = 0; #endif ++dst; diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index a127987c6a..971b933e10 100644 --- a/src/generic/graphicc.cpp +++ b/src/generic/graphicc.cpp @@ -1659,11 +1659,11 @@ wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitm // with alpha in the upper 8 bits, then red, then green, then // blue. The 32-bit quantities are stored native-endian. // Pre-multiplied alpha is used. -#if defined (__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA unsigned char alpha = hasAlpha ? p.Alpha() : wxALPHA_OPAQUE; - // MSW, OSX and Qt bitmap pixel bits are already premultiplied. + // Bitmap pixel bits are already premultiplied. *data = (alpha << 24 | p.Red() << 16 | p.Green() << 8 | p.Blue()); -#else // !__WXMSW__ , !__WXOSX__ , !__WXQT__ +#else // !wxHAS_PREMULTIPLIED_ALPHA // We always have alpha, but we need to premultiply it. unsigned char alpha = p.Alpha(); if (alpha == wxALPHA_TRANSPARENT) @@ -1673,7 +1673,7 @@ wxCairoBitmapData::wxCairoBitmapData( wxGraphicsRenderer* renderer, const wxBitm | Premultiply(alpha, p.Red()) << 16 | Premultiply(alpha, p.Green()) << 8 | Premultiply(alpha, p.Blue())); -#endif // __WXMSW__, __WXOSX__, __WXQT__ / !__WXMSW__, !__WXOSX__, !__WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA / !wxHAS_PREMULTIPLIED_ALPHA ++data; ++p; } diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 9a256248d0..423fd55578 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -392,7 +392,7 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesi hdc->DrawRoundedRectangle(wxRectFromPRectangle(rc), 4); } -#if defined(__WXMSW__) || defined(__WXMAC__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA #define wxPy_premultiply(p, a) ((p) * (a) / 0xff) #else #define wxPy_premultiply(p, a) (p) diff --git a/tests/graphics/bitmap.cpp b/tests/graphics/bitmap.cpp index a8c7ecbf19..eeb4bf7b54 100644 --- a/tests/graphics/bitmap.cpp +++ b/tests/graphics/bitmap.cpp @@ -253,12 +253,12 @@ TEST_CASE("BitmapTestCase::ToImage", "[bitmap][image][convertto]") const wxColour clrBg(*wxGREEN); const unsigned char alpha = 92; -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // premultiplied values const wxColour clrFgAlpha(((clrFg.Red() * alpha) + 127) / 255, ((clrFg.Green() * alpha) + 127) / 255, ((clrFg.Blue() * alpha) + 127) / 255); #else const wxColour clrFgAlpha(clrFg); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA wxAlphaPixelData data(bmp); REQUIRE(data); @@ -306,13 +306,13 @@ TEST_CASE("BitmapTestCase::ToImage", "[bitmap][image][convertto]") { wxColour bmpc(iBmp.Red(), iBmp.Green(), iBmp.Blue(), iBmp.Alpha()); wxColour imgc(image.GetRed(x, y), image.GetGreen(x, y), image.GetBlue(x, y), image.GetAlpha(x,y)); -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // Premultiplied values unsigned char r = ((imgc.Red() * imgc.Alpha()) + 127) / 255; unsigned char g = ((imgc.Green() * imgc.Alpha()) + 127) / 255; unsigned char b = ((imgc.Blue() * imgc.Alpha()) + 127) / 255; imgc.Set(r, g, b, imgc.Alpha()); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA CHECK_EQUAL_COLOUR_RGBA(imgc, bmpc); } rowStartBmp.OffsetY(dataBmp, 1); @@ -330,12 +330,12 @@ TEST_CASE("BitmapTestCase::ToImage", "[bitmap][image][convertto]") const wxColour clrFg(*wxCYAN); const wxColour clrBg(*wxGREEN); const unsigned char alpha = 92; -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // premultiplied values const wxColour clrFgAlpha(((clrFg.Red() * alpha) + 127) / 255, ((clrFg.Green() * alpha) + 127) / 255, ((clrFg.Blue() * alpha) + 127) / 255); #else const wxColour clrFgAlpha(clrFg); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA wxAlphaPixelData data(bmp); REQUIRE(data); @@ -412,13 +412,13 @@ TEST_CASE("BitmapTestCase::ToImage", "[bitmap][image][convertto]") wxColour imgc(image.GetRed(x, y), image.GetGreen(x, y), image.GetBlue(x, y), image.GetAlpha(x,y)); if ( maskc == *wxWHITE ) { -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // Premultiplied values unsigned char r = ((imgc.Red() * imgc.Alpha()) + 127) / 255; unsigned char g = ((imgc.Green() * imgc.Alpha()) + 127) / 255; unsigned char b = ((imgc.Blue() * imgc.Alpha()) + 127) / 255; imgc.Set(r, g, b, imgc.Alpha()); -#endif // __WXMSW__ || __WXOSX || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA CHECK_EQUAL_COLOUR_RGBA(imgc, bmpc); unmaskedPixelsCount++; } @@ -545,13 +545,13 @@ TEST_CASE("BitmapTestCase::FromImage", "[bitmap][image][convertfrom]") { wxColour bmpc(iBmp.Red(), iBmp.Green(), iBmp.Blue(), iBmp.Alpha()); wxColour imgc(img.GetRed(x, y), img.GetGreen(x, y), img.GetBlue(x, y), img.GetAlpha(x, y)); -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // Premultiplied values unsigned char r = ((imgc.Red() * imgc.Alpha()) + 127) / 255; unsigned char g = ((imgc.Green() * imgc.Alpha()) + 127) / 255; unsigned char b = ((imgc.Blue() * imgc.Alpha()) + 127) / 255; imgc.Set(r, g, b, imgc.Alpha()); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA CHECK_EQUAL_COLOUR_RGBA(bmpc, imgc); } rowStartBmp.OffsetY(dataBmp, 1); @@ -596,23 +596,23 @@ TEST_CASE("BitmapTestCase::FromImage", "[bitmap][image][convertfrom]") wxColour bmpc(iBmp.Red(), iBmp.Green(), iBmp.Blue(), iBmp.Alpha()); wxColour maskc(iMask.Red(), iMask.Green(), iMask.Blue()); wxColour imgc(img.GetRed(x, y), img.GetGreen(x, y), img.GetBlue(x, y), img.GetAlpha(x, y)); -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // Premultiplied values unsigned char r = ((imgc.Red() * imgc.Alpha()) + 127) / 255; unsigned char g = ((imgc.Green() * imgc.Alpha()) + 127) / 255; unsigned char b = ((imgc.Blue() * imgc.Alpha()) + 127) / 255; imgc.Set(r, g, b, imgc.Alpha()); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA CHECK_EQUAL_COLOUR_RGBA(bmpc, imgc); wxColour c = maskc == *wxWHITE ? fillCol : maskCol; -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // Premultiplied values r = ((c.Red() * imgc.Alpha()) + 127) / 255; g = ((c.Green() * imgc.Alpha()) + 127) / 255; b = ((c.Blue() * imgc.Alpha()) + 127) / 255; c.Set(r, g, b); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA CHECK_EQUAL_COLOUR_RGB(bmpc, c); } rowStartBmp.OffsetY(dataBmp, 1); @@ -810,12 +810,12 @@ TEST_CASE("BitmapTestCase::DrawAlpha", "[bitmap][draw][alpha]") const wxColour clrBg(*wxGREEN); const unsigned char alpha = 92; -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // premultiplied values const wxColour clrFgAlpha(((clrFg.Red() * alpha) + 127) / 255, ((clrFg.Green() * alpha) + 127) / 255, ((clrFg.Blue() * alpha) + 127) / 255); #else const wxColour clrFgAlpha(clrFg); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA // Bitmap to be drawn wxBitmap bmp(w, h, 32); @@ -873,7 +873,7 @@ TEST_CASE("BitmapTestCase::DrawAlpha", "[bitmap][draw][alpha]") p1.OffsetX(data24, w / 4); // left side is opaque ASSERT_EQUAL_COLOUR_RGB(p1, clrFg); p1.OffsetX(data24, w / 2); // right side is with alpha -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // premultiplied values ASSERT_EQUAL_RGB(p1, clrFgAlpha.Red() + (clrBg.Red() * (255 - alpha) + 127) / 255, clrFgAlpha.Green() + (clrBg.Green() * (255 - alpha) + 127) / 255, @@ -882,7 +882,7 @@ TEST_CASE("BitmapTestCase::DrawAlpha", "[bitmap][draw][alpha]") ASSERT_EQUAL_RGB(p1, (clrFg.Red() * alpha + clrBg.Red() * (255 - alpha) + 127) / 255, (clrFg.Green() * alpha + clrBg.Green() * (255 - alpha) + 127) / 255, (clrFg.Blue() * alpha + clrBg.Blue() * (255 - alpha) + 127) / 255); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA #if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) // Drawing the bitmap on 32 bpp xRGB target @@ -906,10 +906,16 @@ TEST_CASE("BitmapTestCase::DrawAlpha", "[bitmap][draw][alpha]") p2.OffsetX(data32, w / 4); // left side is opaque ASSERT_EQUAL_COLOUR_RGB(p2, clrFg); p2.OffsetX(data32, w / 2); // right side is with alpha +#ifdef wxHAS_PREMULTIPLIED_ALPHA // premultiplied values ASSERT_EQUAL_RGB(p2, clrFgAlpha.Red() + (clrBg.Red() * (255 - alpha) + 127) / 255, clrFgAlpha.Green() + (clrBg.Green() * (255 - alpha) + 127) / 255, clrFgAlpha.Blue() + (clrBg.Blue() * (255 - alpha) + 127) / 255); +#else + ASSERT_EQUAL_RGB(p2, (clrFg.Red() * alpha + clrBg.Red() * (255 - alpha) + 127) / 255, + (clrFg.Green() * alpha + clrBg.Green() * (255 - alpha) + 127) / 255, + (clrFg.Blue() * alpha + clrBg.Blue() * (255 - alpha) + 127) / 255); +#endif // wxHAS_PREMULTIPLIED_ALPHA #endif // __WXMSW__ || __WXOSX__ || __WXQT__ } @@ -925,12 +931,12 @@ TEST_CASE("BitmapTestCase::DrawAlphaWithMask", "[bitmap][draw][alpha][withmask]" const wxColour clrBg(*wxGREEN); const unsigned char alpha = 92; -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // premultiplied values const wxColour clrFgAlpha(((clrFg.Red() * alpha) + 127) / 255, ((clrFg.Green() * alpha) + 127) / 255, ((clrFg.Blue() * alpha) + 127) / 255); #else const wxColour clrFgAlpha(clrFg); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA // Bitmap with mask to be drawn wxBitmap bmp(w, h, 32); @@ -993,7 +999,7 @@ TEST_CASE("BitmapTestCase::DrawAlphaWithMask", "[bitmap][draw][alpha][withmask]" p1.OffsetX(data24, w / 4); // drawn area - left side opaque ASSERT_EQUAL_COLOUR_RGB(p1, clrFg); p1.OffsetX(data24, w / 2); // drawn area - right side with alpha -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // premultiplied values ASSERT_EQUAL_RGB(p1, clrFgAlpha.Red() + (clrBg.Red() * (255 - alpha) + 127) / 255, clrFgAlpha.Green() + (clrBg.Green() * (255 - alpha) + 127) / 255, @@ -1002,7 +1008,7 @@ TEST_CASE("BitmapTestCase::DrawAlphaWithMask", "[bitmap][draw][alpha][withmask]" ASSERT_EQUAL_RGB(p1, (clrFg.Red() * alpha + clrBg.Red() * (255 - alpha) + 127) / 255, (clrFg.Green() * alpha + clrBg.Green() * (255 - alpha) + 127) / 255, (clrFg.Blue() * alpha + clrBg.Blue() * (255 - alpha) + 127) / 255); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA p1 = rowStart1; p1.OffsetY(data24, h / 2); p1.OffsetX(data24, w / 4); // masked area - left side @@ -1033,7 +1039,7 @@ TEST_CASE("BitmapTestCase::DrawAlphaWithMask", "[bitmap][draw][alpha][withmask]" p1.OffsetX(data24, w / 4); // left upper side opaque ASSERT_EQUAL_COLOUR_RGB(p1, clrFg); p1.OffsetX(data24, w / 2); // right upper side with alpha -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // premultiplied values ASSERT_EQUAL_RGB(p1, clrFgAlpha.Red() + (clrBg.Red() * (255 - alpha) + 127) / 255, clrFgAlpha.Green() + (clrBg.Green() * (255 - alpha) + 127) / 255, @@ -1042,13 +1048,13 @@ TEST_CASE("BitmapTestCase::DrawAlphaWithMask", "[bitmap][draw][alpha][withmask]" ASSERT_EQUAL_RGB(p1, (clrFg.Red() * alpha + clrBg.Red() * (255 - alpha) + 127) / 255, (clrFg.Green() * alpha + clrBg.Green() * (255 - alpha) + 127) / 255, (clrFg.Blue() * alpha + clrBg.Blue() * (255 - alpha) + 127) / 255); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA p1 = rowStart1; p1.OffsetY(data24, h / 2); p1.OffsetX(data24, w / 4); // left lower side - same colour as upper ASSERT_EQUAL_COLOUR_RGB(p1, clrFg); p1.OffsetX(data24, w / 2); // right lower side - same colour as upper -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // premultiplied values ASSERT_EQUAL_RGB(p1, clrFgAlpha.Red() + (clrBg.Red() * (255 - alpha) + 127) / 255, clrFgAlpha.Green() + (clrBg.Green() * (255 - alpha) + 127) / 255, @@ -1057,7 +1063,7 @@ TEST_CASE("BitmapTestCase::DrawAlphaWithMask", "[bitmap][draw][alpha][withmask]" ASSERT_EQUAL_RGB(p1, (clrFg.Red() * alpha + clrBg.Red() * (255 - alpha) + 127) / 255, (clrFg.Green() * alpha + clrBg.Green() * (255 - alpha) + 127) / 255, (clrFg.Blue() * alpha + clrBg.Blue() * (255 - alpha) + 127) / 255); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA } #if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) @@ -1084,10 +1090,16 @@ TEST_CASE("BitmapTestCase::DrawAlphaWithMask", "[bitmap][draw][alpha][withmask]" p2.OffsetX(data32, w / 4); // drawn area - left side opaque ASSERT_EQUAL_COLOUR_RGB(p2, clrFg); p2.OffsetX(data32, w / 2); // drawn area - right side with alpha +#ifdef wxHAS_PREMULTIPLIED_ALPHA // premultiplied values ASSERT_EQUAL_RGB(p2, clrFgAlpha.Red() + (clrBg.Red() * (255 - alpha) + 127) / 255, clrFgAlpha.Green() + (clrBg.Green() * (255 - alpha) + 127) / 255, clrFgAlpha.Blue() + (clrBg.Blue() * (255 - alpha) + 127) / 255); +#else + ASSERT_EQUAL_RGB(p2, (clrFg.Red() * alpha + clrBg.Red() * (255 - alpha) + 127) / 255, + (clrFg.Green() * alpha + clrBg.Green() * (255 - alpha) + 127) / 255, + (clrFg.Blue() * alpha + clrBg.Blue() * (255 - alpha) + 127) / 255); +#endif // wxHAS_PREMULTIPLIED_ALPHA p2 = rowStart2; p2.OffsetY(data32, h / 2); p2.OffsetX(data32, w / 4); // masked area - left side @@ -1119,19 +1131,31 @@ TEST_CASE("BitmapTestCase::DrawAlphaWithMask", "[bitmap][draw][alpha][withmask]" p2.OffsetX(data32, w / 4); // left upper side opaque ASSERT_EQUAL_COLOUR_RGB(p2, clrFg); p2.OffsetX(data32, w / 2); // right upper side with alpha +#ifdef wxHAS_PREMULTIPLIED_ALPHA // premultiplied values ASSERT_EQUAL_RGB(p2, clrFgAlpha.Red() + (clrBg.Red() * (255 - alpha) + 127) / 255, clrFgAlpha.Green() + (clrBg.Green() * (255 - alpha) + 127) / 255, clrFgAlpha.Blue() + (clrBg.Blue() * (255 - alpha) + 127) / 255); +#else + ASSERT_EQUAL_RGB(p2, (clrFg.Red() * alpha + clrBg.Red() * (255 - alpha) + 127) / 255, + (clrFg.Green() * alpha + clrBg.Green() * (255 - alpha) + 127) / 255, + (clrFg.Blue() * alpha + clrBg.Blue() * (255 - alpha) + 127) / 255); +#endif // wxHAS_PREMULTIPLIED_ALPHA p2 = rowStart2; p2.OffsetY(data32, h / 2); p2.OffsetX(data32, w / 4); // left lower side - same colour as upper ASSERT_EQUAL_COLOUR_RGB(p2, clrFg); p2.OffsetX(data32, w / 2); // right lower side - same colour as upper // premultiplied values +#ifdef wxHAS_PREMULTIPLIED_ALPHA ASSERT_EQUAL_RGB(p2, clrFgAlpha.Red() + (clrBg.Red() * (255 - alpha) + 127) / 255, clrFgAlpha.Green() + (clrBg.Green() * (255 - alpha) + 127) / 255, clrFgAlpha.Blue() + (clrBg.Blue() * (255 - alpha) + 127) / 255); +#else + ASSERT_EQUAL_RGB(p2, (clrFg.Red() * alpha + clrBg.Red() * (255 - alpha) + 127) / 255, + (clrFg.Green() * alpha + clrBg.Green() * (255 - alpha) + 127) / 255, + (clrFg.Blue() * alpha + clrBg.Blue() * (255 - alpha) + 127) / 255); +#endif // wxHAS_PREMULTIPLIED_ALPHA } #endif // __WXMSW__ || __WXOSX__ || __WXQT__ } @@ -1388,12 +1412,12 @@ TEST_CASE("BitmapTestCase::SubBitmapAlphaWithMask", "[bitmap][subbitmap][alpha][ const wxColour clrLeft(*wxCYAN); const unsigned char alpha = 92; -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // premultiplied values const wxColour clrRight(((clrLeft.Red() * alpha) + 127) / 255, ((clrLeft.Green() * alpha) + 127) / 255, ((clrLeft.Blue() * alpha) + 127) / 255, alpha); #else const wxColour clrRight(clrLeft.Red(), clrLeft.Green(), clrLeft.Blue(), alpha); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA wxBitmap bmp(w, h, 32); #if defined(__WXMSW__) || defined(__WXOSX__) diff --git a/tests/graphics/graphbitmap.cpp b/tests/graphics/graphbitmap.cpp index 12c817308b..05149891f4 100644 --- a/tests/graphics/graphbitmap.cpp +++ b/tests/graphics/graphbitmap.cpp @@ -101,12 +101,12 @@ wxBitmap CreateBitmapRGBA(int w, int h, bool withMask) const wxColour clrBg(*wxGREEN); const unsigned char alpha = 51; -#if defined(__WXMSW__) || defined(__WXOSX__) || defined(__WXQT__) +#ifdef wxHAS_PREMULTIPLIED_ALPHA // premultiplied values const wxColour clrFgAlpha(((clrFg.Red() * alpha) + 127) / 255, ((clrFg.Green() * alpha) + 127) / 255, ((clrFg.Blue() * alpha) + 127) / 255); #else const wxColour clrFgAlpha(clrFg); -#endif // __WXMSW__ || __WXOSX__ || __WXQT__ +#endif // wxHAS_PREMULTIPLIED_ALPHA wxAlphaPixelData data(bmp); REQUIRE(data);