]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/graphics.cpp
preserve type when loaded image is rescaled, #11543
[wxWidgets.git] / src / msw / graphics.cpp
index 3b5317b7c0ab769ac17a46ab60efbcb5f36439f2..62d56a1023fa78f40ea0d7ad46f7387e08f7fdf2 100644 (file)
@@ -40,6 +40,7 @@
 #include "wx/private/graphics.h"
 #include "wx/msw/wrapgdip.h"
 #include "wx/msw/dc.h"
+#include "wx/dcgraph.h"
 
 #include "wx/stack.h"
 
@@ -1453,23 +1454,37 @@ void wxGDIPlusContext::GetPartialTextExtents(const wxString& text, wxArrayDouble
     RectF layoutRect(0,0, 100000.0f, 100000.0f);
     StringFormat strFormat( StringFormat::GenericTypographic() );
 
-    CharacterRange* ranges = new CharacterRange[len] ;
-    Region* regions = new Region[len];
-    for( size_t i = 0 ; i < len ; ++i)
-    {
-        ranges[i].First = i ;
-        ranges[i].Length = 1 ;
-    }
-    strFormat.SetMeasurableCharacterRanges(len,ranges);
-    strFormat.SetFormatFlags( StringFormatFlagsMeasureTrailingSpaces | strFormat.GetFormatFlags() );
-    m_context->MeasureCharacterRanges(ws, -1 , f,layoutRect, &strFormat,1,regions) ;
+    size_t startPosition = 0;
+    size_t remainder = len;
+    const size_t maxSpan = 32;
+    CharacterRange* ranges = new CharacterRange[maxSpan] ;
+    Region* regions = new Region[maxSpan];
 
-    RectF bbox ;
-    for ( size_t i = 0 ; i < len ; ++i)
+    while( remainder > 0 )
     {
-        regions[i].GetBounds(&bbox,m_context);
-        widths[i] = bbox.GetRight()-bbox.GetLeft();
+        size_t span = wxMin( maxSpan, remainder );
+
+        for( size_t i = 0 ; i < span ; ++i)
+        {
+            ranges[i].First = 0 ;
+            ranges[i].Length = startPosition+i+1 ;
+        }
+        strFormat.SetMeasurableCharacterRanges(span,ranges);
+        strFormat.SetFormatFlags( StringFormatFlagsMeasureTrailingSpaces | strFormat.GetFormatFlags() );
+        m_context->MeasureCharacterRanges(ws, -1 , f,layoutRect, &strFormat,span,regions) ;
+
+        RectF bbox ;
+        for ( size_t i = 0 ; i < span ; ++i)
+        {
+            regions[i].GetBounds(&bbox,m_context);
+            widths[startPosition+i] = bbox.Width;
+        }
+        remainder -= span;
+        startPosition += span;
     }
+
+    delete[] ranges;
+    delete[] regions;
 }
 
 bool wxGDIPlusContext::ShouldOffset() const
@@ -1580,6 +1595,9 @@ public :
     // create a native bitmap representation
     virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap );
 
+    // create a graphics bitmap from a native bitmap
+    virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap );
+    
     // create a subimage from a native image representation
     virtual wxGraphicsBitmap CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h  );
 
@@ -1807,6 +1825,19 @@ wxGraphicsBitmap wxGDIPlusRenderer::CreateBitmap( const wxBitmap &bitmap )
         return wxNullGraphicsBitmap;
 }
 
+wxGraphicsBitmap wxGDIPlusRenderer::CreateBitmapFromNativeBitmap( void *bitmap )
+{
+    ENSURE_LOADED_OR_RETURN(wxNullGraphicsBitmap);
+    if ( bitmap != NULL )
+    {
+        wxGraphicsBitmap p;
+        p.SetRefData(new wxGDIPlusBitmapData( this , (Bitmap*) bitmap ));
+        return p;
+    }
+    else
+        return wxNullGraphicsBitmap;
+}
+
 wxGraphicsBitmap wxGDIPlusRenderer::CreateSubBitmap( const wxGraphicsBitmap &bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h  )
 {
     ENSURE_LOADED_OR_RETURN(wxNullGraphicsBitmap);
@@ -1834,4 +1865,32 @@ private:
 
 IMPLEMENT_DYNAMIC_CLASS(wxGDIPlusRendererModule, wxModule)
 
+// ----------------------------------------------------------------------------
+// wxMSW-specific parts of wxGCDC
+// ----------------------------------------------------------------------------
+
+WXHDC wxGCDC::AcquireHDC()
+{
+    wxGraphicsContext * const gc = GetGraphicsContext();
+    if ( !gc )
+        return NULL;
+
+    Graphics * const g = static_cast<Graphics *>(gc->GetNativeContext());
+    return g ? g->GetHDC() : NULL;
+}
+
+void wxGCDC::ReleaseHDC(WXHDC hdc)
+{
+    if ( !hdc )
+        return;
+
+    wxGraphicsContext * const gc = GetGraphicsContext();
+    wxCHECK_RET( gc, "can't release HDC because there is no wxGraphicsContext" );
+
+    Graphics * const g = static_cast<Graphics *>(gc->GetNativeContext());
+    wxCHECK_RET( g, "can't release HDC because there is no Graphics" );
+
+    g->ReleaseHDC((HDC)hdc);
+}
+
 #endif  // wxUSE_GRAPHICS_CONTEXT