#include "wx/dcprint.h"
#endif
+#include "wx/stack.h"
+
#include "wx/private/graphics.h"
#include "wx/msw/wrapgdip.h"
#include "wx/msw/dc.h"
-#include "wx/dcgraph.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 <commdlg.h>
#include <commdlg.h>
#endif
-#include "wx/stack.h"
-
-WX_DECLARE_STACK(GraphicsState, GraphicsStates);
-
namespace
{
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);
virtual bool SetAntialiasMode(wxAntialiasMode antialias);
+ virtual bool SetInterpolationQuality(wxInterpolationQuality interpolation);
+
virtual bool SetCompositionMode(wxCompositionMode op);
virtual void BeginLayer(wxDouble opacity);
virtual void GetSize( wxDouble* width, wxDouble *height );
Graphics* GetGraphics() const { return m_context; }
- bool IsPrinting() const { return m_isPrinting; }
- // utility to setup page scale etc for printing
- void SetupForPrinting();
+protected:
+
+ wxDouble m_fontScaleRatio;
private:
void Init();
const wxGraphicsBrush& backgroundBrush);
Graphics* m_context;
-
- GraphicsStates m_stateStack;
+ wxStack<GraphicsState> m_stateStack;
GraphicsState m_state1;
GraphicsState m_state2;
- wxDouble m_width;
- wxDouble m_height;
-
- bool m_isPrinting;
-
DECLARE_DYNAMIC_CLASS_NO_COPY(wxGDIPlusContext)
};
}
private:
- HDC m_hdc;
+ HDC m_hdc ;
DECLARE_DYNAMIC_CLASS_NO_COPY(wxGDIPlusMeasuringContext)
} ;
+class wxGDIPlusPrintingContext : public wxGDIPlusContext
+{
+public:
+ wxGDIPlusPrintingContext( wxGraphicsRenderer* renderer, const wxDC& dc );
+ virtual ~wxGDIPlusPrintingContext() { }
+protected:
+};
+
//-----------------------------------------------------------------------------
// wxGDIPlusRenderer declaration
//-----------------------------------------------------------------------------
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;
}
}
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 );
}
}
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
(
}
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
(
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);
}
}
if ( font.GetWeight() == wxFONTWEIGHT_BOLD )
style |= FontStyleBold;
- if ( gc->IsPrinting() )
- {
- Graphics* context = gc->GetGraphics();
+ 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;
+ 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();
- REAL size = points * (100.0 / 72.0);
+ REAL points = font.GetPointSize();
- // 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 );
- }
- else
- {
- m_font = new Font( s, font.GetPointSize(), style );
- }
+ // 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));
}
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();
}
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();
bool m_offset;
} ;
-wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, HDC hdc, wxDouble width, wxDouble height )
+wxGDIPlusContext::wxGDIPlusContext( wxGraphicsRenderer* renderer, HDC hdc, wxDouble width, wxDouble height )
: wxGraphicsContext(renderer)
{
Init();
-
- m_context = new Graphics(hdc);
+ m_context = new Graphics( hdc);
m_width = width;
m_height = height;
-
SetDefaults();
}
: wxGraphicsContext(renderer)
{
Init();
+ m_enableOffset = true;
m_context = new Graphics( hwnd);
RECT rect = wxGetWindowRect(hwnd);
m_width = rect.right - rect.left;
m_state2= 0;
m_height = 0;
m_width = 0;
- m_isPrinting = false;
+ m_fontScaleRatio = 1.0;
}
void wxGDIPlusContext::SetDefaults()
m_state2 = m_context->Save();
}
-void wxGDIPlusContext::SetupForPrinting()
-{
- //m_context->SetPageUnit(UnitDocument);
-
- // 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);
-
- m_isPrinting = true;
-}
-
wxGDIPlusContext::~wxGDIPlusContext()
{
if ( m_context )
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)
return true;
}
+bool wxGDIPlusContext::SetInterpolationQuality(wxInterpolationQuality WXUNUSED(interpolation))
+{
+ // placeholder
+ return false;
+}
+
bool wxGDIPlusContext::SetCompositionMode(wxCompositionMode op)
{
if ( m_composition == op )
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);
{
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
return renderer->CreateGDIPlusFont(this, font, col);
}
-
void wxGDIPlusContext::DoDrawFilledText(const wxString& str,
wxDouble x, wxDouble y,
const wxGraphicsBrush& brush)
f->GetFamily(&ffamily) ;
- REAL factorY;
- if ( !IsPrinting() )
- factorY = m_context->GetDpiY() / 72.0;
- else
- // when printing the page scaling already does the trick
- factorY = 1.0;
+ REAL factorY = m_fontScaleRatio;
REAL rDescent = ffamily.GetCellDescent(FontStyleRegular) *
f->GetSize() / ffamily.GetEmHeight(FontStyleRegular);
bool wxGDIPlusContext::ShouldOffset() const
{
+ if ( !m_enableOffset )
+ return false;
+
int penwidth = 0 ;
if ( !m_pen.IsNull() )
{
*height = m_height;
}
+//-----------------------------------------------------------------------------
+// wxGDIPlusPrintingContext implementation
+//-----------------------------------------------------------------------------
+
+wxGDIPlusPrintingContext::wxGDIPlusPrintingContext( wxGraphicsRenderer* renderer,
+ const wxDC& dc )
+ : wxGDIPlusContext(renderer, dc)
+{
+ Graphics* context = GetGraphics();
+
+ //m_context->SetPageUnit(UnitDocument);
+
+ // 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);
+
+ // 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
//-----------------------------------------------------------------------------
if ( m_gditoken )
{
GdiplusShutdown(m_gditoken);
- m_gditoken = NULL;
+ m_gditoken = 0;
}
m_loaded = -1; // next Load() will try again
}
wxGraphicsContext * wxGDIPlusRenderer::CreateContext( const wxWindowDC& dc)
{
ENSURE_LOADED_OR_RETURN(NULL);
- return new wxGDIPlusContext(this, dc);
+ 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);
- wxGDIPlusContext* context = new wxGDIPlusContext(this, dc);
- context->SetupForPrinting();
+ wxGDIPlusContext* context = new wxGDIPlusPrintingContext(this, dc);
return context;
}
#endif
wxGraphicsContext * wxGDIPlusRenderer::CreateContext( const wxEnhMetaFileDC& dc)
{
ENSURE_LOADED_OR_RETURN(NULL);
- wxGDIPlusContext* context = new wxGDIPlusContext(this, dc);
- context->SetupForPrinting();
+ wxGDIPlusContext* context = new wxGDIPlusPrintingContext(this, dc);
return context;
}
#endif
wxGraphicsContext * wxGDIPlusRenderer::CreateContext( const wxMemoryDC& dc)
{
ENSURE_LOADED_OR_RETURN(NULL);
- return new wxGDIPlusContext(this, dc);
+ wxGDIPlusContext* context = new wxGDIPlusContext(this, dc);
+ context->EnableOffset(true);
+ return context;
}
wxGraphicsContext * wxGDIPlusRenderer::CreateMeasuringContext()
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
{
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
{
const wxColour &col )
{
ENSURE_LOADED_OR_RETURN(wxNullGraphicsFont);
- if ( font.Ok() )
+ if ( font.IsOk() )
{
wxGraphicsFont p;
p.SetRefData(new wxGDIPlusFontData( this, gc, font, col ));
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 ));