X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6fea499ca8a3e99bfb7c16ce167146f1fa754367..3f4a2351e4c677c88c18ea812b609477adee7380:/src/msw/graphics.cpp?ds=sidebyside diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index 7e9d5da60e..69f3a08e67 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -1,11 +1,11 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: src/mac/carbon/dccg.cpp +// Name: src/msw/graphics.cpp // Purpose: wxGCDC class // Author: Stefan Csomor // Modified by: -// Created: 01/02/97 +// Created: 2006-09-30 // RCS-ID: $Id$ -// Copyright: (c) Stefan Csomor +// Copyright: (c) 2006 Stefan Csomor // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -13,9 +13,6 @@ #include "wx/dc.h" -// For compilers that support precompilation, includes "wx.h". -#include "wx/wxprec.h" - #ifdef __BORLANDC__ #pragma hdrstop #endif @@ -38,6 +35,8 @@ #include "wx/graphics.h" +#if wxUSE_GRAPHICS_CONTEXT + #include using namespace std; @@ -349,6 +348,7 @@ wxGDIPlusContext::wxGDIPlusContext( WXHDC hdc ) { gGDILoader.EnsureIsLoaded(); m_context = new Graphics( (HDC) hdc); + m_context->SetSmoothingMode(SmoothingModeHighQuality); m_state1 = m_context->Save(); m_state2 = m_context->Save(); @@ -417,7 +417,7 @@ wxGraphicsPath* wxGDIPlusContext::CreatePath() void wxGDIPlusContext::Rotate( wxDouble angle ) { - m_context->RotateTransform( angle ); + m_context->RotateTransform( RadToDeg(angle) ); } void wxGDIPlusContext::Translate( wxDouble dx , wxDouble dy ) @@ -427,21 +427,7 @@ void wxGDIPlusContext::Translate( wxDouble dx , wxDouble dy ) void wxGDIPlusContext::Scale( wxDouble xScale , wxDouble yScale ) { - PointF penWidth( m_pen->GetWidth(), 0); - Matrix matrix ; - if ( !m_penTransparent ) - { - m_context->GetTransform(&matrix); - matrix.TransformVectors(&penWidth); - } m_context->ScaleTransform(xScale,yScale); - if ( !m_penTransparent ) - { - m_context->GetTransform(&matrix); - matrix.Invert(); - matrix.TransformVectors(&penWidth) ; - m_pen->SetWidth( sqrt( penWidth.X*penWidth.X + penWidth.Y*penWidth.Y)); - } } void wxGDIPlusContext::PushState() @@ -705,18 +691,134 @@ void wxGDIPlusContext::SetRadialGradientBrush( wxDouble xo, wxDouble yo, wxDoubl b->SetSurroundColors(colors, &count); } +// the built-in conversions functions create non-premultiplied bitmaps, while GDIPlus needs them in the +// premultiplied format, therefore in the failing cases we create a new bitmap using the non-premultiplied +// bytes as parameter + void wxGDIPlusContext::DrawBitmap( const wxBitmap &bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) { - Bitmap* image = Bitmap::FromHBITMAP((HBITMAP)bmp.GetHBITMAP(),(HPALETTE)bmp.GetPalette()->GetHPALETTE()); - m_context->DrawImage(image,(REAL) x,(REAL) y,(REAL) w,(REAL) h) ; + Bitmap* image = NULL; + Bitmap* helper = NULL; + if ( bmp.GetMask() ) + { + Bitmap interim((HBITMAP)bmp.GetHBITMAP(),(HPALETTE)bmp.GetPalette()->GetHPALETTE()) ; + + size_t width = interim.GetWidth(); + size_t height = interim.GetHeight(); + Rect bounds(0,0,width,height); + + image = new Bitmap(width,height,PixelFormat32bppPARGB) ; + + Bitmap interimMask((HBITMAP)bmp.GetMask()->GetMaskBitmap(),NULL); + wxASSERT(interimMask.GetPixelFormat() == PixelFormat1bppIndexed); + + BitmapData dataMask ; + interimMask.LockBits(&bounds,ImageLockModeRead, + interimMask.GetPixelFormat(),&dataMask); + + + BitmapData imageData ; + image->LockBits(&bounds,ImageLockModeWrite, PixelFormat32bppPARGB, &imageData); + + BYTE maskPattern = 0 ; + BYTE maskByte = 0; + size_t maskIndex ; + + for ( size_t y = 0 ; y < height ; ++y) + { + maskIndex = 0 ; + for( size_t x = 0 ; x < width; ++x) + { + if ( x % 8 == 0) + { + maskPattern = 0x80; + maskByte = *((BYTE*)dataMask.Scan0 + dataMask.Stride*y + maskIndex); + maskIndex++; + } + else + maskPattern = maskPattern >> 1; + + ARGB *dest = (ARGB*)((BYTE*)imageData.Scan0 + imageData.Stride*y + x*4); + if ( (maskByte & maskPattern) == 0 ) + *dest = 0x00000000; + else + { + Color c ; + interim.GetPixel(x,y,&c) ; + *dest = (c.GetValue() | Color::AlphaMask); + } + } + } + + image->UnlockBits(&imageData); + + interimMask.UnlockBits(&dataMask); + interim.UnlockBits(&dataMask); + } + else + { + image = Bitmap::FromHBITMAP((HBITMAP)bmp.GetHBITMAP(),(HPALETTE)bmp.GetPalette()->GetHPALETTE()); + if ( GetPixelFormatSize(image->GetPixelFormat()) == 32 ) + { + size_t width = image->GetWidth(); + size_t height = image->GetHeight(); + Rect bounds(0,0,width,height); + BitmapData data ; + + helper = image ; + image = NULL ; + helper->LockBits(&bounds, ImageLockModeRead, + helper->GetPixelFormat(),&data); + + image = new Bitmap(data.Width, data.Height, data.Stride, + PixelFormat32bppARGB , (BYTE*) data.Scan0); + + helper->UnlockBits(&data); + } + } + if ( image ) + m_context->DrawImage(image,(REAL) x,(REAL) y,(REAL) w,(REAL) h) ; delete image ; + delete helper ; } void wxGDIPlusContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxDouble w, wxDouble h ) { - Bitmap* image = Bitmap::FromHICON((HICON)icon.GetHICON()); + HICON hIcon = (HICON)icon.GetHICON(); + ICONINFO iconInfo ; + // IconInfo creates the bitmaps for color and mask, we must dispose of them after use + if (!GetIconInfo(hIcon,&iconInfo)) + return; + + BITMAP iconBmpData ; + GetObject(iconInfo.hbmColor,sizeof(BITMAP),&iconBmpData); + Bitmap interim(iconInfo.hbmColor,NULL); + + Bitmap* image = NULL ; + + if( GetPixelFormatSize(interim.GetPixelFormat())!= 32 ) + { + image = Bitmap::FromHICON(hIcon); + } + else + { + size_t width = interim.GetWidth(); + size_t height = interim.GetHeight(); + Rect bounds(0,0,width,height); + BitmapData data ; + + interim.LockBits(&bounds, ImageLockModeRead, + interim.GetPixelFormat(),&data); + image = new Bitmap(data.Width, data.Height, data.Stride, + PixelFormat32bppARGB , (BYTE*) data.Scan0); + interim.UnlockBits(&data); + } + m_context->DrawImage(image,(REAL) x,(REAL) y,(REAL) w,(REAL) h) ; + delete image ; + DeleteObject(iconInfo.hbmColor); + DeleteObject(iconInfo.hbmMask); } @@ -829,3 +931,6 @@ wxGraphicsContext* wxGraphicsContext::Create( const wxWindowDC& dc) { return new wxGDIPlusContext( (HDC) dc.GetHDC() ); } + + +#endif // wxUSE_GRAPHICS_CONTEXT