X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/465642da29f90bee7865319214a276c64620e077..74a8f67d96591cec101def2a7d47c64072aff7fd:/src/msw/graphics.cpp diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index 65377a464e..0bc8226142 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -37,9 +37,14 @@ #include "wx/dcprint.h" #endif +#include "wx/stack.h" + #include "wx/private/graphics.h" #include "wx/msw/wrapgdip.h" #include "wx/msw/dc.h" +#if wxUSE_ENH_METAFILE + #include "wx/msw/enhmeta.h" +#endif #include "wx/dcgraph.h" #include "wx/msw/private.h" // needs to be before #include @@ -48,10 +53,6 @@ #include #endif -#include "wx/stack.h" - -WX_DECLARE_STACK(GraphicsState, GraphicsStates); - namespace { @@ -95,6 +96,8 @@ inline Color wxColourToColor(const wxColour& col) // wxGraphicsPath implementation //----------------------------------------------------------------------------- +class wxGDIPlusContext; + class wxGDIPlusPathData : public wxGraphicsPathData { public : @@ -286,7 +289,10 @@ private : class wxGDIPlusFontData : public wxGraphicsObjectRefData { public: - wxGDIPlusFontData( wxGraphicsRenderer* renderer, const wxFont &font, const wxColour& col ); + wxGDIPlusFontData( wxGraphicsRenderer* renderer, + const wxGDIPlusContext* gc, + const wxFont &font, + const wxColour& col ); ~wxGDIPlusFontData(); virtual Brush* GetGDIPlusBrush() { return m_textBrush; } @@ -299,7 +305,8 @@ private : class wxGDIPlusContext : public wxGraphicsContext { public: - wxGDIPlusContext( wxGraphicsRenderer* renderer, HDC hdc , wxDouble width, wxDouble height ); + wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc ); + wxGDIPlusContext( wxGraphicsRenderer* renderer, HDC hdc, wxDouble width, wxDouble height ); wxGDIPlusContext( wxGraphicsRenderer* renderer, HWND hwnd ); wxGDIPlusContext( wxGraphicsRenderer* renderer, Graphics* gr); wxGDIPlusContext(); @@ -318,6 +325,8 @@ public: virtual void StrokePath( const wxGraphicsPath& p ); virtual void FillPath( const wxGraphicsPath& p , wxPolygonFillMode fillStyle = wxODDEVEN_RULE ); + virtual void DrawRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h ); + // stroke lines connecting each of the points virtual void StrokeLines( size_t n, const wxPoint2DDouble *points); @@ -326,6 +335,8 @@ public: virtual bool SetAntialiasMode(wxAntialiasMode antialias); + virtual bool SetInterpolationQuality(wxInterpolationQuality interpolation); + virtual bool SetCompositionMode(wxCompositionMode op); virtual void BeginLayer(wxDouble opacity); @@ -351,12 +362,21 @@ public: virtual void PushState(); virtual void PopState(); + // sets the font of this context + virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) const; + virtual void GetTextExtent( const wxString &str, wxDouble *width, wxDouble *height, wxDouble *descent, wxDouble *externalLeading ) const; virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const; virtual bool ShouldOffset() const; virtual void GetSize( wxDouble* width, wxDouble *height ); + Graphics* GetGraphics() const { return m_context; } + +protected: + + wxDouble m_fontScaleRatio; + private: void Init(); void SetDefaults(); @@ -367,13 +387,10 @@ private: const wxGraphicsBrush& backgroundBrush); Graphics* m_context; - GraphicsStates m_stateStack; + wxStack m_stateStack; GraphicsState m_state1; GraphicsState m_state2; - wxDouble m_width; - wxDouble m_height; - DECLARE_DYNAMIC_CLASS_NO_COPY(wxGDIPlusContext) }; @@ -397,6 +414,114 @@ private: DECLARE_DYNAMIC_CLASS_NO_COPY(wxGDIPlusMeasuringContext) } ; +class wxGDIPlusPrintingContext : public wxGDIPlusContext +{ +public: + wxGDIPlusPrintingContext( wxGraphicsRenderer* renderer, const wxDC& dc ); + virtual ~wxGDIPlusPrintingContext() { } +protected: +}; + +//----------------------------------------------------------------------------- +// wxGDIPlusRenderer declaration +//----------------------------------------------------------------------------- + +class wxGDIPlusRenderer : public wxGraphicsRenderer +{ +public : + wxGDIPlusRenderer() + { + m_loaded = -1; + m_gditoken = 0; + } + + virtual ~wxGDIPlusRenderer() + { + if ( m_loaded == 1 ) + { + Unload(); + } + } + + // Context + + virtual wxGraphicsContext * CreateContext( const wxWindowDC& dc); + + virtual wxGraphicsContext * CreateContext( const wxMemoryDC& dc); + +#if wxUSE_PRINTING_ARCHITECTURE + virtual wxGraphicsContext * CreateContext( const wxPrinterDC& dc); +#endif + +#if wxUSE_ENH_METAFILE + virtual wxGraphicsContext * CreateContext( const wxEnhMetaFileDC& dc); +#endif + + virtual wxGraphicsContext * CreateContextFromNativeContext( void * context ); + + virtual wxGraphicsContext * CreateContextFromNativeWindow( void * window ); + + virtual wxGraphicsContext * CreateContext( wxWindow* window ); + + virtual wxGraphicsContext * CreateMeasuringContext(); + + // Path + + virtual wxGraphicsPath CreatePath(); + + // Matrix + + virtual wxGraphicsMatrix CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, + wxDouble tx=0.0, wxDouble ty=0.0); + + + virtual wxGraphicsPen CreatePen(const wxPen& pen) ; + + virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) ; + + virtual wxGraphicsBrush + CreateLinearGradientBrush(wxDouble x1, wxDouble y1, + wxDouble x2, wxDouble y2, + const wxGraphicsGradientStops& stops); + + virtual wxGraphicsBrush + CreateRadialGradientBrush(wxDouble xo, wxDouble yo, + wxDouble xc, wxDouble yc, + wxDouble radius, + const wxGraphicsGradientStops& stops); + + // create a native bitmap representation + virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ); + + // stub: should not be called directly + virtual wxGraphicsFont CreateFont( const wxFont& WXUNUSED(font), + const wxColour& WXUNUSED(col) ) + { wxFAIL; return wxNullGraphicsFont; } + + // this is used to really create the font + wxGraphicsFont CreateGDIPlusFont( const wxGDIPlusContext* gc, + const wxFont &font, + const wxColour &col ); + + // 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 ); + +protected : + bool EnsureIsLoaded(); + void Load(); + void Unload(); + friend class wxGDIPlusRendererModule; + +private : + int m_loaded; + ULONG_PTR m_gditoken; + + DECLARE_DYNAMIC_CLASS_NO_COPY(wxGDIPlusRenderer) +} ; + //----------------------------------------------------------------------------- // wxGDIPlusPen implementation //----------------------------------------------------------------------------- @@ -473,25 +598,25 @@ wxGDIPlusPenData::wxGDIPlusPenData( wxGraphicsRenderer* renderer, const wxPen &p DashStyle dashStyle = DashStyleSolid; switch ( pen.GetStyle() ) { - case wxSOLID : + case wxPENSTYLE_SOLID : break; - case wxDOT : + case wxPENSTYLE_DOT : dashStyle = DashStyleDot; break; - case wxLONG_DASH : + case wxPENSTYLE_LONG_DASH : dashStyle = DashStyleDash; // TODO verify break; - case wxSHORT_DASH : + case wxPENSTYLE_SHORT_DASH : dashStyle = DashStyleDash; break; - case wxDOT_DASH : + case wxPENSTYLE_DOT_DASH : dashStyle = DashStyleDashDot; break; - case wxUSER_DASH : + case wxPENSTYLE_USER_DASH : { dashStyle = DashStyleCustom; wxDash *dashes; @@ -508,12 +633,18 @@ wxGDIPlusPenData::wxGDIPlusPenData( wxGraphicsRenderer* renderer, const wxPen &p } } break; - case wxSTIPPLE : + case wxPENSTYLE_STIPPLE : { wxBitmap* bmp = pen.GetStipple(); - if ( bmp && bmp->Ok() ) + if ( bmp && bmp->IsOk() ) { - m_penImage = Bitmap::FromHBITMAP((HBITMAP)bmp->GetHBITMAP(),(HPALETTE)bmp->GetPalette()->GetHPALETTE()); + m_penImage = Bitmap::FromHBITMAP((HBITMAP)bmp->GetHBITMAP(), +#if wxUSE_PALETTE + (HPALETTE)bmp->GetPalette()->GetHPALETTE() +#else + NULL +#endif + ); m_penBrush = new TextureBrush(m_penImage); m_pen->SetBrush( m_penBrush ); } @@ -521,30 +652,32 @@ wxGDIPlusPenData::wxGDIPlusPenData( wxGraphicsRenderer* renderer, const wxPen &p } break; default : - if ( pen.GetStyle() >= wxFIRST_HATCH && pen.GetStyle() <= wxLAST_HATCH ) + if ( pen.GetStyle() >= wxPENSTYLE_FIRST_HATCH && + pen.GetStyle() <= wxPENSTYLE_LAST_HATCH ) { - HatchStyle style = HatchStyleHorizontal; + HatchStyle style; switch( pen.GetStyle() ) { - case wxBDIAGONAL_HATCH : + case wxPENSTYLE_BDIAGONAL_HATCH : style = HatchStyleBackwardDiagonal; break ; - case wxCROSSDIAG_HATCH : + case wxPENSTYLE_CROSSDIAG_HATCH : style = HatchStyleDiagonalCross; break ; - case wxFDIAGONAL_HATCH : + case wxPENSTYLE_FDIAGONAL_HATCH : style = HatchStyleForwardDiagonal; break ; - case wxCROSS_HATCH : + case wxPENSTYLE_CROSS_HATCH : style = HatchStyleCross; break ; - case wxHORIZONTAL_HATCH : + case wxPENSTYLE_HORIZONTAL_HATCH : style = HatchStyleHorizontal; break ; - case wxVERTICAL_HATCH : + case wxPENSTYLE_VERTICAL_HATCH : style = HatchStyleVertical; break ; - + default: + style = HatchStyleHorizontal; } m_penBrush = new HatchBrush ( @@ -580,28 +713,29 @@ wxGDIPlusBrushData::wxGDIPlusBrushData( wxGraphicsRenderer* renderer , const wxB } else if ( brush.IsHatch() ) { - HatchStyle style = HatchStyleHorizontal; + HatchStyle style; switch( brush.GetStyle() ) { - case wxBDIAGONAL_HATCH : + case wxBRUSHSTYLE_BDIAGONAL_HATCH : style = HatchStyleBackwardDiagonal; break ; - case wxCROSSDIAG_HATCH : + case wxBRUSHSTYLE_CROSSDIAG_HATCH : style = HatchStyleDiagonalCross; break ; - case wxFDIAGONAL_HATCH : + case wxBRUSHSTYLE_FDIAGONAL_HATCH : style = HatchStyleForwardDiagonal; break ; - case wxCROSS_HATCH : + case wxBRUSHSTYLE_CROSS_HATCH : style = HatchStyleCross; break ; - case wxHORIZONTAL_HATCH : + case wxBRUSHSTYLE_HORIZONTAL_HATCH : style = HatchStyleHorizontal; break ; - case wxVERTICAL_HATCH : + case wxBRUSHSTYLE_VERTICAL_HATCH : style = HatchStyleVertical; break ; - + default: + style = HatchStyleHorizontal; } m_brush = new HatchBrush ( @@ -613,10 +747,16 @@ wxGDIPlusBrushData::wxGDIPlusBrushData( wxGraphicsRenderer* renderer , const wxB else { wxBitmap* bmp = brush.GetStipple(); - if ( bmp && bmp->Ok() ) + if ( bmp && bmp->IsOk() ) { wxDELETE( m_brushImage ); - m_brushImage = Bitmap::FromHBITMAP((HBITMAP)bmp->GetHBITMAP(),(HPALETTE)bmp->GetPalette()->GetHPALETTE()); + m_brushImage = Bitmap::FromHBITMAP((HBITMAP)bmp->GetHBITMAP(), +#if wxUSE_PALETTE + (HPALETTE)bmp->GetPalette()->GetHPALETTE() +#else + NULL +#endif + ); m_brush = new TextureBrush(m_brushImage); } } @@ -703,14 +843,13 @@ wxGDIPlusBrushData::CreateRadialGradientBrush(wxDouble xo, wxDouble yo, // wxGDIPlusFont implementation //----------------------------------------------------------------------------- -wxGDIPlusFontData::wxGDIPlusFontData( wxGraphicsRenderer* renderer, const wxFont &font, - const wxColour& col ) : wxGraphicsObjectRefData( renderer ) +wxGDIPlusFontData::wxGDIPlusFontData( wxGraphicsRenderer* renderer, + const wxGDIPlusContext* gc, + const wxFont &font, + const wxColour& col ) + : wxGraphicsObjectRefData( renderer ) { - m_textBrush = NULL; - m_font = NULL; - wxWCharBuffer s = font.GetFaceName().wc_str( *wxConvUI ); - int size = font.GetPointSize(); int style = FontStyleRegular; if ( font.GetStyle() == wxFONTSTYLE_ITALIC ) style |= FontStyleItalic; @@ -718,7 +857,25 @@ wxGDIPlusFontData::wxGDIPlusFontData( wxGraphicsRenderer* renderer, const wxFont style |= FontStyleUnderline; if ( font.GetWeight() == wxFONTWEIGHT_BOLD ) style |= FontStyleBold; - m_font = new Font( s , size , style ); + + Graphics* context = gc->GetGraphics(); + + Unit fontUnit = context->GetPageUnit(); + // if fontUnit is UnitDisplay, then specify UnitPixel, otherwise + // you'll get a "InvalidParameter" from GDI+ + if ( fontUnit == UnitDisplay ) + fontUnit = UnitPixel; + + REAL points = font.GetPointSize(); + + // This scaling is needed when we use unit other than the + // default UnitPoint. It works for both display and printing. + REAL size = points * (100.0 / 72.0); + + // NB: font unit should match context's unit. We can use UnitPixel, + // as that is what the print context should use. + m_font = new Font( s, size, style, fontUnit ); + m_textBrush = new SolidBrush(wxColourToColor(col)); } @@ -752,7 +909,13 @@ wxGDIPlusBitmapData::wxGDIPlusBitmapData( wxGraphicsRenderer* renderer, Bitmap* image = NULL; if ( bmp.GetMask() ) { - Bitmap interim((HBITMAP)bmp.GetHBITMAP(),(HPALETTE)bmp.GetPalette()->GetHPALETTE()) ; + Bitmap interim((HBITMAP)bmp.GetHBITMAP(), +#if wxUSE_PALETTE + (HPALETTE)bmp.GetPalette()->GetHPALETTE() +#else + NULL +#endif + ); size_t width = interim.GetWidth(); size_t height = interim.GetHeight(); @@ -808,7 +971,13 @@ wxGDIPlusBitmapData::wxGDIPlusBitmapData( wxGraphicsRenderer* renderer, } else { - image = Bitmap::FromHBITMAP((HBITMAP)bmp.GetHBITMAP(),(HPALETTE)bmp.GetPalette()->GetHPALETTE()); + image = Bitmap::FromHBITMAP((HBITMAP)bmp.GetHBITMAP(), +#if wxUSE_PALETTE + (HPALETTE)bmp.GetPalette()->GetHPALETTE() +#else + NULL +#endif + ); if ( bmp.HasAlpha() && GetPixelFormatSize(image->GetPixelFormat()) == 32 ) { size_t width = image->GetWidth(); @@ -1043,7 +1212,7 @@ void wxGDIPlusMatrixData::Scale( wxDouble xScale , wxDouble yScale ) // add the rotation to this matrix (radians) void wxGDIPlusMatrixData::Rotate( wxDouble angle ) { - m_matrix->Rotate( angle ); + m_matrix->Rotate( RadToDeg(angle) ); } // @@ -1111,10 +1280,27 @@ wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, HDC hdc, wxDou SetDefaults(); } +wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, const wxDC& dc ) + : wxGraphicsContext(renderer) +{ + Init(); + + wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl ); + HDC hdc = (HDC) msw->GetHDC(); + + m_context = new Graphics(hdc); + wxSize sz = dc.GetSize(); + m_width = sz.x; + m_height = sz.y; + + SetDefaults(); +} + wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, HWND hwnd ) : wxGraphicsContext(renderer) { Init(); + m_enableOffset = true; m_context = new Graphics( hwnd); RECT rect = wxGetWindowRect(hwnd); m_width = rect.right - rect.left; @@ -1142,6 +1328,7 @@ void wxGDIPlusContext::Init() m_state2= 0; m_height = 0; m_width = 0; + m_fontScaleRatio = 1.0; } void wxGDIPlusContext::SetDefaults() @@ -1151,14 +1338,6 @@ void wxGDIPlusContext::SetDefaults() m_context->SetSmoothingMode(SmoothingModeHighQuality); m_state1 = m_context->Save(); m_state2 = m_context->Save(); - - // Setup page scale, based on DPI ratio. - // Antecedent should be 100dpi when the default page unit (UnitDisplay) - // is used. Page unit UnitDocument would require 300dpi instead. - // Note that calling SetPageScale() does not have effect on non-printing - // DCs (that is, any other than wxPrinterDC or wxEnhMetaFileDC). - REAL dpiRatio = 100.0 / m_context->GetDpiY(); - m_context->SetPageScale(dpiRatio); } wxGDIPlusContext::~wxGDIPlusContext() @@ -1188,6 +1367,31 @@ void wxGDIPlusContext::ResetClip() m_context->ResetClip(); } +void wxGDIPlusContext::DrawRectangle( wxDouble x, wxDouble y, wxDouble w, wxDouble h ) +{ + if (m_composition == wxCOMPOSITION_DEST) + return; + + wxGDIPlusOffsetHelper helper( m_context , ShouldOffset() ); + Brush *brush = m_brush.IsNull() ? NULL : ((wxGDIPlusBrushData*)m_brush.GetRefData())->GetGDIPlusBrush(); + Pen *pen = m_pen.IsNull() ? NULL : ((wxGDIPlusPenData*)m_pen.GetGraphicsData())->GetGDIPlusPen(); + + if ( brush ) + { + // the offset is used to fill only the inside of the rectangle and not paint underneath + // its border which may influence a transparent Pen + REAL offset = 0; + if ( pen ) + offset = pen->GetWidth(); + m_context->FillRectangle( brush, (REAL)x + offset/2, (REAL)y + offset/2, (REAL)w - offset, (REAL)h - offset); + } + + if ( pen ) + { + m_context->DrawRectangle( pen, (REAL)x, (REAL)y, (REAL)w, (REAL)h ); + } +} + void wxGDIPlusContext::StrokeLines( size_t n, const wxPoint2DDouble *points) { if (m_composition == wxCOMPOSITION_DEST) @@ -1277,6 +1481,12 @@ bool wxGDIPlusContext::SetAntialiasMode(wxAntialiasMode antialias) return true; } +bool wxGDIPlusContext::SetInterpolationQuality(wxInterpolationQuality WXUNUSED(interpolation)) +{ + // placeholder + return false; +} + bool wxGDIPlusContext::SetCompositionMode(wxCompositionMode op) { if ( m_composition == op ) @@ -1337,6 +1547,8 @@ void wxGDIPlusContext::PushState() void wxGDIPlusContext::PopState() { + wxCHECK_RET( !m_stateStack.empty(), wxT("No state to pop") ); + GraphicsState state = m_stateStack.top(); m_stateStack.pop(); m_context->Restore(state); @@ -1354,7 +1566,7 @@ void wxGDIPlusContext::DrawBitmap( const wxGraphicsBitmap &bmp, wxDouble x, wxDo { Rect drawRect((REAL) x, (REAL)y, (REAL)w, (REAL)h); m_context->SetPixelOffsetMode( PixelOffsetModeNone ); - m_context->DrawImage(image, drawRect, 0 , 0 , image->GetWidth()-1, image->GetHeight()-1, UnitPixel ) ; + m_context->DrawImage(image, drawRect, 0 , 0 , image->GetWidth(), image->GetHeight(), UnitPixel ) ; m_context->SetPixelOffsetMode( PixelOffsetModeHalf ); } else @@ -1432,6 +1644,14 @@ void wxGDIPlusContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxD DeleteObject(iconInfo.hbmMask); } +wxGraphicsFont wxGDIPlusContext::CreateFont( const wxFont &font, + const wxColour &col ) const +{ + wxGDIPlusRenderer* renderer = + static_cast(GetRenderer()); + return renderer->CreateGDIPlusFont(this, font, col); +} + void wxGDIPlusContext::DoDrawFilledText(const wxString& str, wxDouble x, wxDouble y, const wxGraphicsBrush& brush) @@ -1473,7 +1693,7 @@ void wxGDIPlusContext::GetTextExtent( const wxString &str, wxDouble *width, wxDo f->GetFamily(&ffamily) ; - REAL factorY = m_context->GetDpiY() / 72.0 ; + REAL factorY = m_fontScaleRatio; REAL rDescent = ffamily.GetCellDescent(FontStyleRegular) * f->GetSize() / ffamily.GetEmHeight(FontStyleRegular); @@ -1562,6 +1782,9 @@ void wxGDIPlusContext::GetPartialTextExtents(const wxString& text, wxArrayDouble bool wxGDIPlusContext::ShouldOffset() const { + if ( !m_enableOffset ) + return false; + int penwidth = 0 ; if ( !m_pen.IsNull() ) { @@ -1602,91 +1825,32 @@ void wxGDIPlusContext::GetSize( wxDouble* width, wxDouble *height ) *width = m_width; *height = m_height; } + //----------------------------------------------------------------------------- -// wxGDIPlusRenderer declaration +// wxGDIPlusPrintingContext implementation //----------------------------------------------------------------------------- -class wxGDIPlusRenderer : public wxGraphicsRenderer +wxGDIPlusPrintingContext::wxGDIPlusPrintingContext( wxGraphicsRenderer* renderer, + const wxDC& dc ) + : wxGDIPlusContext(renderer, dc) { -public : - wxGDIPlusRenderer() - { - m_loaded = -1; - m_gditoken = 0; - } + Graphics* context = GetGraphics(); - virtual ~wxGDIPlusRenderer() - { - if ( m_loaded == 1 ) - { - Unload(); - } - } - - // Context - - virtual wxGraphicsContext * CreateContext( const wxWindowDC& dc); - - virtual wxGraphicsContext * CreateContext( const wxMemoryDC& dc); - - virtual wxGraphicsContext * CreateContext( const wxPrinterDC& dc); - - virtual wxGraphicsContext * CreateContextFromNativeContext( void * context ); - - virtual wxGraphicsContext * CreateContextFromNativeWindow( void * window ); - - virtual wxGraphicsContext * CreateContext( wxWindow* window ); + //m_context->SetPageUnit(UnitDocument); - virtual wxGraphicsContext * CreateMeasuringContext(); - - // Path - - virtual wxGraphicsPath CreatePath(); - - // Matrix - - virtual wxGraphicsMatrix CreateMatrix( wxDouble a=1.0, wxDouble b=0.0, wxDouble c=0.0, wxDouble d=1.0, - wxDouble tx=0.0, wxDouble ty=0.0); - - - virtual wxGraphicsPen CreatePen(const wxPen& pen) ; - - virtual wxGraphicsBrush CreateBrush(const wxBrush& brush ) ; - - virtual wxGraphicsBrush - CreateLinearGradientBrush(wxDouble x1, wxDouble y1, - wxDouble x2, wxDouble y2, - const wxGraphicsGradientStops& stops); - - virtual wxGraphicsBrush - CreateRadialGradientBrush(wxDouble xo, wxDouble yo, - wxDouble xc, wxDouble yc, - wxDouble radius, - const wxGraphicsGradientStops& stops); - // sets the font - virtual wxGraphicsFont CreateFont( const wxFont &font , const wxColour &col = *wxBLACK ) ; - - // 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 ); - -protected : - bool EnsureIsLoaded(); - void Load(); - void Unload(); - friend class wxGDIPlusRendererModule; - -private : - int m_loaded; - ULONG_PTR m_gditoken; + // Setup page scale, based on DPI ratio. + // Antecedent should be 100dpi when the default page unit + // (UnitDisplay) is used. Page unit UnitDocument would require 300dpi + // instead. Note that calling SetPageScale() does not have effect on + // non-printing DCs (that is, any other than wxPrinterDC or + // wxEnhMetaFileDC). + REAL dpiRatio = 100.0 / context->GetDpiY(); + context->SetPageScale(dpiRatio); - DECLARE_DYNAMIC_CLASS_NO_COPY(wxGDIPlusRenderer) -} ; + // We use this modifier when measuring fonts. It is needed because the + // page scale is modified above. + m_fontScaleRatio = context->GetDpiY() / 72.0; +} //----------------------------------------------------------------------------- // wxGDIPlusRenderer implementation @@ -1742,7 +1906,7 @@ void wxGDIPlusRenderer::Unload() if ( m_gditoken ) { GdiplusShutdown(m_gditoken); - m_gditoken = NULL; + m_gditoken = 0; } m_loaded = -1; // next Load() will try again } @@ -1750,25 +1914,35 @@ void wxGDIPlusRenderer::Unload() wxGraphicsContext * wxGDIPlusRenderer::CreateContext( const wxWindowDC& dc) { ENSURE_LOADED_OR_RETURN(NULL); - wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl ); - wxSize sz = dc.GetSize(); - return new wxGDIPlusContext(this,(HDC) msw->GetHDC(), sz.x, sz.y); + wxGDIPlusContext* context = new wxGDIPlusContext(this, dc); + context->EnableOffset(true); + return context; } +#if wxUSE_PRINTING_ARCHITECTURE wxGraphicsContext * wxGDIPlusRenderer::CreateContext( const wxPrinterDC& dc) { ENSURE_LOADED_OR_RETURN(NULL); - wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl ); - wxSize sz = dc.GetSize(); - return new wxGDIPlusContext(this,(HDC) msw->GetHDC(), sz.x, sz.y); + wxGDIPlusContext* context = new wxGDIPlusPrintingContext(this, dc); + return context; } +#endif + +#if wxUSE_ENH_METAFILE +wxGraphicsContext * wxGDIPlusRenderer::CreateContext( const wxEnhMetaFileDC& dc) +{ + ENSURE_LOADED_OR_RETURN(NULL); + wxGDIPlusContext* context = new wxGDIPlusPrintingContext(this, dc); + return context; +} +#endif wxGraphicsContext * wxGDIPlusRenderer::CreateContext( const wxMemoryDC& dc) { ENSURE_LOADED_OR_RETURN(NULL); - wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl ); - wxSize sz = dc.GetSize(); - return new wxGDIPlusContext(this,(HDC) msw->GetHDC(), sz.x, sz.y); + wxGDIPlusContext* context = new wxGDIPlusContext(this, dc); + context->EnableOffset(true); + return context; } wxGraphicsContext * wxGDIPlusRenderer::CreateMeasuringContext() @@ -1824,7 +1998,7 @@ wxGraphicsMatrix wxGDIPlusRenderer::CreateMatrix( wxDouble a, wxDouble b, wxDoub wxGraphicsPen wxGDIPlusRenderer::CreatePen(const wxPen& pen) { ENSURE_LOADED_OR_RETURN(wxNullGraphicsPen); - if ( !pen.Ok() || pen.GetStyle() == wxTRANSPARENT ) + if ( !pen.IsOk() || pen.GetStyle() == wxTRANSPARENT ) return wxNullGraphicsPen; else { @@ -1837,7 +2011,7 @@ wxGraphicsPen wxGDIPlusRenderer::CreatePen(const wxPen& pen) wxGraphicsBrush wxGDIPlusRenderer::CreateBrush(const wxBrush& brush ) { ENSURE_LOADED_OR_RETURN(wxNullGraphicsBrush); - if ( !brush.Ok() || brush.GetStyle() == wxTRANSPARENT ) + if ( !brush.IsOk() || brush.GetStyle() == wxTRANSPARENT ) return wxNullGraphicsBrush; else { @@ -1874,14 +2048,16 @@ wxGDIPlusRenderer::CreateRadialGradientBrush(wxDouble xo, wxDouble yo, return p; } -// sets the font -wxGraphicsFont wxGDIPlusRenderer::CreateFont( const wxFont &font , const wxColour &col ) +wxGraphicsFont +wxGDIPlusRenderer::CreateGDIPlusFont( const wxGDIPlusContext* gc, + const wxFont &font, + const wxColour &col ) { ENSURE_LOADED_OR_RETURN(wxNullGraphicsFont); - if ( font.Ok() ) + if ( font.IsOk() ) { wxGraphicsFont p; - p.SetRefData(new wxGDIPlusFontData( this , font, col )); + p.SetRefData(new wxGDIPlusFontData( this, gc, font, col )); return p; } else @@ -1891,7 +2067,7 @@ wxGraphicsFont wxGDIPlusRenderer::CreateFont( const wxFont &font , const wxColou wxGraphicsBitmap wxGDIPlusRenderer::CreateBitmap( const wxBitmap &bitmap ) { ENSURE_LOADED_OR_RETURN(wxNullGraphicsBitmap); - if ( bitmap.Ok() ) + if ( bitmap.IsOk() ) { wxGraphicsBitmap p; p.SetRefData(new wxGDIPlusBitmapData( this , bitmap ));