]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/graphics.cpp
Back to previous call with -1 replacement.
[wxWidgets.git] / src / msw / graphics.cpp
index 7e9d5da60ef0ff53171a541a724e85f60cf8bc0f..69f3a08e672fb95bf5d74dd41854beb538b13a76 100644 (file)
@@ -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 <vector>
 
 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