#include "wx/dcscreen.h"
#include "wx/dcprint.h"
#include "wx/prntbase.h"
+#include "wx/scopeguard.h"
#ifndef WX_PRECOMP
#include "wx/math.h"
#endif
#ifdef __WXMAC__
- #include "wx/mac/dcclient.h"
- #include "wx/mac/dcmemory.h"
- #include "wx/mac/dcscreen.h"
+ #include "wx/osx/dcclient.h"
+ #include "wx/osx/dcmemory.h"
+ #include "wx/osx/dcscreen.h"
#endif
#ifdef __WXPM__
// wxNativeDCFactory
//-----------------------------------------------------------------------------
-wxDCImpl* wxNativeDCFactory::CreateWindowDC( wxWindowDC *owner )
-{
- return new wxWindowDCImpl( owner );
-}
-
wxDCImpl* wxNativeDCFactory::CreateWindowDC( wxWindowDC *owner, wxWindow *window )
{
- return new wxWindowDCImpl( owner, window );
-}
-
-wxDCImpl* wxNativeDCFactory::CreateClientDC( wxClientDC *owner )
-{
- return new wxClientDCImpl( owner );
+ wxDCImpl * const impl = new wxWindowDCImpl( owner, window );
+ impl->InheritAttributes(window);
+ return impl;
}
wxDCImpl* wxNativeDCFactory::CreateClientDC( wxClientDC *owner, wxWindow *window )
{
- return new wxClientDCImpl( owner, window );
-}
-
-wxDCImpl* wxNativeDCFactory::CreatePaintDC( wxPaintDC *owner )
-{
- return new wxPaintDCImpl( owner );
+ wxDCImpl * const impl = new wxClientDCImpl( owner, window );
+ impl->InheritAttributes(window);
+ return impl;
}
wxDCImpl* wxNativeDCFactory::CreatePaintDC( wxPaintDC *owner, wxWindow *window )
{
- return new wxPaintDCImpl( owner, window );
+ wxDCImpl * const impl = new wxPaintDCImpl( owner, window );
+ impl->InheritAttributes(window);
+ return impl;
}
wxDCImpl* wxNativeDCFactory::CreateMemoryDC( wxMemoryDC *owner )
return new wxMemoryDCImpl( owner );
}
-wxDCImpl* wxNativeDCFactory::CreateMemoryDC( wxMemoryDC *owner, wxBitmap &bitmap )
+wxDCImpl* wxNativeDCFactory::CreateMemoryDC(wxMemoryDC *owner, wxBitmap& bitmap)
{
- return new wxMemoryDCImpl( owner, bitmap );
+ // the bitmap may be modified when it's selected into a memory DC so make
+ // sure changing this bitmap doesn't affect any other shallow copies of it
+ // (see wxMemoryDC::SelectObject())
+ //
+ // notice that we don't provide any ctor equivalent to SelectObjectAsSource
+ // method because this should be rarely needed and easy to work around by
+ // using the default ctor and calling SelectObjectAsSource itself
+ if ( bitmap.IsOk() )
+ bitmap.UnShare();
+
+ return new wxMemoryDCImpl(owner, bitmap);
}
wxDCImpl* wxNativeDCFactory::CreateMemoryDC( wxMemoryDC *owner, wxDC *dc )
{
}
-wxRect wxPrinterDC::GetPaperRect()
+wxRect wxPrinterDC::GetPaperRect() const
{
return GetImpl()->GetPaperRect();
}
-int wxPrinterDC::GetResolution()
+int wxPrinterDC::GetResolution() const
{
return GetImpl()->GetResolution();
}
, m_minX(0), m_minY(0), m_maxX(0), m_maxY(0)
, m_clipX1(0), m_clipY1(0), m_clipX2(0), m_clipY2(0)
, m_logicalFunction(wxCOPY)
- , m_backgroundMode(wxTRANSPARENT)
+ , m_backgroundMode(wxBRUSHSTYLE_TRANSPARENT)
, m_mappingMode(wxMM_TEXT)
, m_pen()
, m_brush()
wxCoord wxDCImpl::DeviceToLogicalX(wxCoord x) const
{
- return wxRound((double)(x - m_deviceOriginX - m_deviceLocalOriginX) / m_scaleX) * m_signX + m_logicalOriginX;
+ return wxRound( (double)((x - m_deviceOriginX - m_deviceLocalOriginX) * m_signX) / m_scaleX ) + m_logicalOriginX ;
}
wxCoord wxDCImpl::DeviceToLogicalY(wxCoord y) const
{
- return wxRound((double)(y - m_deviceOriginY - m_deviceLocalOriginY) / m_scaleY) * m_signY + m_logicalOriginY;
+ return wxRound( (double)((y - m_deviceOriginY - m_deviceLocalOriginY) * m_signY) / m_scaleY ) + m_logicalOriginY ;
}
wxCoord wxDCImpl::DeviceToLogicalXRel(wxCoord x) const
wxCoord wxDCImpl::LogicalToDeviceX(wxCoord x) const
{
- return wxRound((double)(x - m_logicalOriginX) * m_scaleX) * m_signX + m_deviceOriginX * m_signY + m_deviceLocalOriginX;
+ return wxRound( (double)((x - m_logicalOriginX) * m_signX) * m_scaleX) + m_deviceOriginX + m_deviceLocalOriginX;
}
wxCoord wxDCImpl::LogicalToDeviceY(wxCoord y) const
{
- return wxRound((double)(y - m_logicalOriginY) * m_scaleY) * m_signY + m_deviceOriginY * m_signY + m_deviceLocalOriginY;
+ return wxRound( (double)((y - m_logicalOriginY) * m_signY) * m_scaleY) + m_deviceOriginY + m_deviceLocalOriginY;
}
wxCoord wxDCImpl::LogicalToDeviceXRel(wxCoord x) const
m_scaleY = m_logicalScaleY * m_userScaleY;
}
-void wxDCImpl::SetMapMode( int mode )
+void wxDCImpl::SetMapMode( wxMappingMode mode )
{
switch (mode)
{
wxString curLine;
for ( wxString::const_iterator pc = text.begin(); ; ++pc )
{
- if ( pc == text.end() || *pc == _T('\n') )
+ if ( pc == text.end() || *pc == wxT('\n') )
{
if ( curLine.empty() )
{
if ( !heightLineDefault )
{
// but we don't know it yet - choose something reasonable
- DoGetTextExtent(_T("W"), NULL, &heightLineDefault,
+ DoGetTextExtent(wxT("W"), NULL, &heightLineDefault,
NULL, NULL, font);
}
wxDC *source,
wxCoord xsrc, wxCoord ysrc,
wxCoord srcWidth, wxCoord srcHeight,
- int rop,
+ wxRasterOperationMode rop,
bool useMask,
wxCoord xsrcMask,
wxCoord ysrcMask)
{
wxCHECK_MSG( srcWidth && srcHeight && dstWidth && dstHeight, false,
- _T("invalid blit size") );
+ wxT("invalid blit size") );
// emulate the stretching by modifying the DC scale
double xscale = (double)srcWidth/dstWidth,
void wxDCImpl::DrawPolygon(const wxPointList *list,
wxCoord xoffset, wxCoord yoffset,
- int fillStyle)
+ wxPolygonFillMode fillStyle)
{
int n = list->GetCount();
wxPoint *points = new wxPoint[n];
int count[],
wxPoint points[],
wxCoord xoffset, wxCoord yoffset,
- int fillStyle)
+ wxPolygonFillMode fillStyle)
{
if ( n == 1 )
{
}
pen = GetPen();
- SetPen(wxPen(*wxBLACK, 0, wxTRANSPARENT));
+ SetPen(wxPen(*wxBLACK, 0, wxPENSTYLE_TRANSPARENT));
DoDrawPolygon(j, pts, xoffset, yoffset, fillStyle);
SetPen(pen);
for (i = j = 0; i < n; i++)
#if wxUSE_SPLINES
-void wxDCImpl::DoDrawSpline(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord x3, wxCoord y3)
+void wxDCImpl::DrawSpline(wxCoord x1, wxCoord y1,
+ wxCoord x2, wxCoord y2,
+ wxCoord x3, wxCoord y3)
{
- wxPointList point_list;
-
- wxPoint *point1 = new wxPoint;
- point1->x = x1; point1->y = y1;
- point_list.Append( point1 );
-
- wxPoint *point2 = new wxPoint;
- point2->x = x2; point2->y = y2;
- point_list.Append( point2 );
-
- wxPoint *point3 = new wxPoint;
- point3->x = x3; point3->y = y3;
- point_list.Append( point3 );
-
- DoDrawSpline(&point_list);
-
- for( wxPointList::compatibility_iterator node = point_list.GetFirst(); node; node = node->GetNext() )
- {
- wxPoint *p = node->GetData();
- delete p;
- }
+ wxPoint points[] = { wxPoint(x1, y1), wxPoint(x2, y2), wxPoint(x3, y3) };
+ DrawSpline(WXSIZEOF(points), points);
}
-void wxDCImpl::DoDrawSpline(int n, wxPoint points[])
+void wxDCImpl::DrawSpline(int n, wxPoint points[])
{
wxPointList list;
- for (int i =0; i < n; i++)
- list.Append( &points[i] );
+ for ( int i = 0; i < n; i++ )
+ list.Append(&points[i]);
- DoDrawSpline(&list);
+ DrawSpline(&list);
}
// ----------------------------------- spline code ----------------------------------------
static bool wx_spline_add_point(double x, double y);
static void wx_spline_draw_point_array(wxDC *dc);
-wxPointList wx_spline_point_list;
+static wxPointList wx_spline_point_list;
#define half(z1, z2) ((z1+z2)/2.0)
#define THRESHOLD 5
nB = nB1 + (nB2-nB1)*(w-x)/w;
wxColour colour(nR,nG,nB);
- SetPen(wxPen(colour, 1, wxSOLID));
+ SetPen(wxPen(colour, 1, wxPENSTYLE_SOLID));
SetBrush(wxBrush(colour));
if(nDirection == wxEAST)
DoDrawRectangle(rect.GetRight()-x-xDelta+1, rect.GetTop(),
nB = nB1 + (nB2-nB1)*(w-y)/w;
wxColour colour(nR,nG,nB);
- SetPen(wxPen(colour, 1, wxSOLID));
+ SetPen(wxPen(colour, 1, wxPENSTYLE_SOLID));
SetBrush(wxBrush(colour));
if(nDirection == wxNORTH)
DoDrawRectangle(rect.GetLeft(), rect.GetTop()+y,
const wxColour& destColour,
const wxPoint& circleCenter)
{
- //save the old pen color
- wxColour oldPenColour = m_pen.GetColour();
+ // save the old pen and ensure it is restored on exit
+ const wxPen penOrig = m_pen;
+ wxON_BLOCK_EXIT_SET(m_pen, penOrig);
wxUint8 nR1 = destColour.Red();
wxUint8 nG1 = destColour.Green();
nB = (wxUint8)(nB1 + ((nB2 - nB1) * nGradient / 100));
//set the pixel
- m_pen.SetColour(wxColour(nR,nG,nB));
+ m_pen = wxColour(nR,nG,nB);
DoDrawPoint(x + rect.GetLeft(), y + rect.GetTop());
}
}
- //return old pen color
- m_pen.SetColour(oldPenColour);
+}
+
+void wxDCImpl::InheritAttributes(wxWindow *win)
+{
+ wxCHECK_RET( win, "window can't be NULL" );
+
+ SetFont(win->GetFont());
+ SetTextForeground(win->GetForegroundColour());
+ SetTextBackground(win->GetBackgroundColour());
+ SetBackground(win->GetBackgroundColour());
+ SetLayoutDirection(win->GetLayoutDirection());
}
//-----------------------------------------------------------------------------
IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
+void wxDC::CopyAttributes(const wxDC& dc)
+{
+ SetFont(dc.GetFont());
+ SetTextForeground(dc.GetTextForeground());
+ SetTextBackground(dc.GetTextBackground());
+ SetBackground(dc.GetBackground());
+ SetLayoutDirection(dc.GetLayoutDirection());
+}
+
void wxDC::DrawLabel(const wxString& text,
const wxBitmap& bitmap,
const wxRect& rect,
yUnderscore = 0;
// split the string into lines and draw each of them separately
+ //
+ // NB: while wxDC::DrawText() on some platforms supports drawing multi-line
+ // strings natively, this is not the case for all of them, notably not
+ // wxMSW which uses this function for multi-line texts, so we may only
+ // call DrawText() for single-line strings from here to avoid infinite
+ // recursion.
wxString curLine;
for ( wxString::const_iterator pc = text.begin(); ; ++pc )
{
- if ( *pc == _T('\n') || pc == text.end() )
+ if ( pc == text.end() || *pc == '\n' )
{
int xRealStart = x; // init it here to avoid compielr warnings
if ( startUnderscore != endUnderscore )
{
// it should be of the same colour as text
- SetPen(wxPen(GetTextForeground(), 0, wxSOLID));
+ SetPen(wxPen(GetTextForeground(), 0, wxPENSTYLE_SOLID));
yUnderscore--;
if (h) *h = hh;
}
+void wxDC::DrawObject(wxDrawObject* drawobject)
+{
+ drawobject->Draw(*this);
+ CalcBoundingBox(drawobject->MinX(),drawobject->MinY());
+ CalcBoundingBox(drawobject->MaxX(),drawobject->MaxY());
+}
+
#endif // WXWIN_COMPATIBILITY_2_8
/*
} // CalculateEllipticPoints
#endif // __WXWINCE__
+
+float wxDCImpl::GetFontPointSizeAdjustment(float dpi)
+{
+ // wxMSW has long-standing bug where wxFont point size is interpreted as
+ // "pixel size corresponding to given point size *on screen*". In other
+ // words, on a typical 600dpi printer and a typical 96dpi screen, fonts
+ // are ~6 times smaller when printing. Unfortunately, this bug is so severe
+ // that *all* printing code has to account for it and consequently, other
+ // ports need to emulate this bug too:
+ const wxSize screenPPI = wxGetDisplayPPI();
+ return float(screenPPI.y) / dpi;
+}