From 3dc16a7419a69dfda8b23510531dceac15dc8854 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 6 Dec 2018 03:19:42 +0100 Subject: [PATCH] Compute wxDCImpl::m_mm_to_pix_[xy] on demand If nothing else, this avoids 2 calls to each of wxGetDisplaySize() and wxGetDisplaySizeMM() on each and every wxGCDC construction which are completely unnecessary as wxGCDCImpl uses its own hardcoded resolution of 72 DPI, as do some other classes deriving from wxDCImpl. And even for the classes which do compute these fields using the display resolution, it may still be unnecessary to do it as they can be never used if neither GetSizeMM() nor SetLogicalScale() are called on the corresponding wxDC object. Finally, this is more than an optimization as when using Cairo-based wxGCDC without display (which is explicitly supported), calling wxGetDisplaySize() simply doesn't work at all. --- include/wx/dc.h | 19 ++++++++++++++++--- src/common/dcbase.cpp | 36 +++++++++++++++++++++++++++--------- src/common/dcgraph.cpp | 4 ++-- src/common/dcsvg.cpp | 4 ++-- src/dfb/dc.cpp | 8 ++++---- src/gtk/dc.cpp | 4 ++-- src/gtk/dcclient.cpp | 2 +- src/gtk1/dc.cpp | 4 ++-- src/gtk1/dcclient.cpp | 2 +- src/motif/dc.cpp | 4 ++-- src/x11/dc.cpp | 4 ++-- 11 files changed, 61 insertions(+), 30 deletions(-) diff --git a/include/wx/dc.h b/include/wx/dc.h index a34a73b698..8d445e9f6b 100644 --- a/include/wx/dc.h +++ b/include/wx/dc.h @@ -686,6 +686,16 @@ protected: // for rendering on higher-resolution DCs such as printer ones static float GetFontPointSizeAdjustment(float dpi); + // Return the number of pixels per mm in the horizontal and vertical + // directions, respectively. + // + // If the physical size of the DC is not known, or doesn't make sense, as + // for a SVG DC, for example, a fixed value corresponding to the standard + // DPI is used. + double GetMMToPXx() const; + double GetMMToPXy() const; + + // window on which the DC draws or NULL wxWindow *m_window; @@ -715,9 +725,12 @@ protected: double m_contentScaleFactor; // used by high resolution displays (retina) - // what is a mm on a screen you don't know the size of? - double m_mm_to_pix_x, - m_mm_to_pix_y; + // Pixel per mm in horizontal and vertical directions. + // + // These variables are computed on demand by GetMMToPX[xy]() functions, + // don't access them directly other than for assigning to them. + mutable double m_mm_to_pix_x, + m_mm_to_pix_y; // bounding and clipping boxes wxCoord m_minX, m_minY, m_maxX, m_maxY; // Bounding box is stored in device units. diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index 8b070995d8..47000e5f1f 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -331,6 +331,7 @@ wxDCImpl::wxDCImpl( wxDC *owner ) , m_scaleX(1.0), m_scaleY(1.0) , m_signX(1), m_signY(1) , m_contentScaleFactor(1) + , m_mm_to_pix_x(0.0), m_mm_to_pix_y(0.0) , 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) @@ -348,11 +349,6 @@ wxDCImpl::wxDCImpl( wxDC *owner ) #endif // wxUSE_PALETTE { m_owner = owner; - - m_mm_to_pix_x = (double)wxGetDisplaySize().GetWidth() / - (double)wxGetDisplaySizeMM().GetWidth(); - m_mm_to_pix_y = (double)wxGetDisplaySize().GetHeight() / - (double)wxGetDisplaySizeMM().GetHeight(); } wxDCImpl::~wxDCImpl() @@ -517,16 +513,16 @@ void wxDCImpl::SetMapMode( wxMappingMode mode ) switch (mode) { case wxMM_TWIPS: - SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y ); + SetLogicalScale( twips2mm*GetMMToPXx(), twips2mm*GetMMToPXy() ); break; case wxMM_POINTS: - SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y ); + SetLogicalScale( pt2mm*GetMMToPXx(), pt2mm*GetMMToPXy() ); break; case wxMM_METRIC: - SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y ); + SetLogicalScale( GetMMToPXx(), GetMMToPXy() ); break; case wxMM_LOMETRIC: - SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 ); + SetLogicalScale( GetMMToPXx()/10.0, GetMMToPXy()/10.0 ); break; default: case wxMM_TEXT: @@ -1441,3 +1437,25 @@ float wxDCImpl::GetFontPointSizeAdjustment(float dpi) const wxSize screenPPI = wxGetDisplayPPI(); return float(screenPPI.y) / dpi; } + +double wxDCImpl::GetMMToPXx() const +{ + if ( wxIsNullDouble(m_mm_to_pix_x) ) + { + m_mm_to_pix_x = (double)wxGetDisplaySize().GetWidth() / + (double)wxGetDisplaySizeMM().GetWidth(); + } + + return m_mm_to_pix_x; +} + +double wxDCImpl::GetMMToPXy() const +{ + if ( wxIsNullDouble(m_mm_to_pix_x) ) + { + m_mm_to_pix_y = (double)wxGetDisplaySize().GetHeight() / + (double)wxGetDisplaySizeMM().GetHeight(); + } + + return m_mm_to_pix_y; +} diff --git a/src/common/dcgraph.cpp b/src/common/dcgraph.cpp index 5812e393f3..832eb2bdc6 100644 --- a/src/common/dcgraph.cpp +++ b/src/common/dcgraph.cpp @@ -390,9 +390,9 @@ void wxGCDCImpl::DoGetSizeMM( int* width, int* height ) const GetOwner()->GetSize( &w, &h ); if (width) - *width = long( double(w) / (m_scaleX * m_mm_to_pix_x) ); + *width = long( double(w) / (m_scaleX * GetMMToPXx()) ); if (height) - *height = long( double(h) / (m_scaleY * m_mm_to_pix_y) ); + *height = long( double(h) / (m_scaleY * GetMMToPXy()) ); } void wxGCDCImpl::SetTextForeground( const wxColour &col ) diff --git a/src/common/dcsvg.cpp b/src/common/dcsvg.cpp index 2913548a12..ff212b8829 100644 --- a/src/common/dcsvg.cpp +++ b/src/common/dcsvg.cpp @@ -442,10 +442,10 @@ wxSVGFileDCImpl::~wxSVGFileDCImpl() void wxSVGFileDCImpl::DoGetSizeMM(int *width, int *height) const { if (width) - *width = wxRound( (double)m_width / m_mm_to_pix_x ); + *width = wxRound( (double)m_width / GetMMToPXx() ); if (height) - *height = wxRound( (double)m_height / m_mm_to_pix_y ); + *height = wxRound( (double)m_height / GetMMToPXy() ); } wxSize wxSVGFileDCImpl::GetPPI() const diff --git a/src/dfb/dc.cpp b/src/dfb/dc.cpp index a65f9bca0b..241bcd0562 100644 --- a/src/dfb/dc.cpp +++ b/src/dfb/dc.cpp @@ -563,15 +563,15 @@ void wxDFBDCImpl::DoGetSizeMM(int *width, int *height) const int w = 0; int h = 0; GetSize(&w, &h); - if ( width ) *width = int(double(w) / (m_userScaleX*m_mm_to_pix_x)); - if ( height ) *height = int(double(h) / (m_userScaleY*m_mm_to_pix_y)); + if ( width ) *width = int(double(w) / (m_userScaleX*GetMMToPXx())); + if ( height ) *height = int(double(h) / (m_userScaleY*GetMMToPXy())); } wxSize wxDFBDCImpl::GetPPI() const { #warning "move this to common code?" - return wxSize(int(double(m_mm_to_pix_x) * inches2mm), - int(double(m_mm_to_pix_y) * inches2mm)); + return wxSize(int(double(GetMMToPXx()) * inches2mm), + int(double(GetMMToPXy()) * inches2mm)); } diff --git a/src/gtk/dc.cpp b/src/gtk/dc.cpp index a41910ac32..016c7cd4de 100644 --- a/src/gtk/dc.cpp +++ b/src/gtk/dc.cpp @@ -506,8 +506,8 @@ void wxGTKDCImpl::DoGetSizeMM( int* width, int* height ) const int w = 0; int h = 0; GetOwner()->GetSize( &w, &h ); - if (width) *width = int( double(w) / (m_userScaleX*m_mm_to_pix_x) ); - if (height) *height = int( double(h) / (m_userScaleY*m_mm_to_pix_y) ); + if (width) *width = int( double(w) / (m_userScaleX*GetMMToPXx()) ); + if (height) *height = int( double(h) / (m_userScaleY*GetMMToPXy()) ); } // Resolution in pixels per logical inch diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 52349d0e0a..feea364099 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -2072,7 +2072,7 @@ void wxWindowDCImpl::ComputeScaleAndOrigin() // Resolution in pixels per logical inch wxSize wxWindowDCImpl::GetPPI() const { - return wxSize( (int) (m_mm_to_pix_x * 25.4 + 0.5), (int) (m_mm_to_pix_y * 25.4 + 0.5)); + return wxSize( (int) (GetMMToPXx() * 25.4 + 0.5), (int) (GetMMToPXy() * 25.4 + 0.5)); } int wxWindowDCImpl::GetDepth() const diff --git a/src/gtk1/dc.cpp b/src/gtk1/dc.cpp index 7c75e571f2..77f130450c 100644 --- a/src/gtk1/dc.cpp +++ b/src/gtk1/dc.cpp @@ -50,8 +50,8 @@ void wxGTKDCImpl::DoGetSizeMM( int* width, int* height ) const int w = 0; int h = 0; GetSize( &w, &h ); - if (width) *width = int( double(w) / (m_userScaleX*m_mm_to_pix_x) ); - if (height) *height = int( double(h) / (m_userScaleY*m_mm_to_pix_y) ); + if (width) *width = int( double(w) / (m_userScaleX*GetMMToPXx()) ); + if (height) *height = int( double(h) / (m_userScaleY*GetMMToPXy()) ); } // Resolution in pixels per logical inch diff --git a/src/gtk1/dcclient.cpp b/src/gtk1/dcclient.cpp index 623f049e72..4d3e9d120a 100644 --- a/src/gtk1/dcclient.cpp +++ b/src/gtk1/dcclient.cpp @@ -2113,7 +2113,7 @@ void wxWindowDCImpl::ComputeScaleAndOrigin() // Resolution in pixels per logical inch wxSize wxWindowDCImpl::GetPPI() const { - return wxSize( (int) (m_mm_to_pix_x * 25.4 + 0.5), (int) (m_mm_to_pix_y * 25.4 + 0.5)); + return wxSize( (int) (GetMMToPXx() * 25.4 + 0.5), (int) (GetMMToPXy() * 25.4 + 0.5)); } int wxWindowDCImpl::GetDepth() const diff --git a/src/motif/dc.cpp b/src/motif/dc.cpp index 908c8f76d1..c79c4eb07d 100644 --- a/src/motif/dc.cpp +++ b/src/motif/dc.cpp @@ -87,9 +87,9 @@ void wxMotifDCImpl::DoGetSizeMM( int* width, int* height ) const GetSize( &w, &h ); if ( width ) - *width = int( double(w) / (m_scaleX*m_mm_to_pix_x) ); + *width = int( double(w) / (m_scaleX*GetMMToPXx()) ); if ( height ) - *height = int( double(h) / (m_scaleY*m_mm_to_pix_y) ); + *height = int( double(h) / (m_scaleY*GetMMToPXy()) ); } // Resolution in pixels per logical inch diff --git a/src/x11/dc.cpp b/src/x11/dc.cpp index 888f15eb58..41e39ef80e 100644 --- a/src/x11/dc.cpp +++ b/src/x11/dc.cpp @@ -51,9 +51,9 @@ void wxX11DCImpl::DoGetSizeMM( int* width, int* height ) const DoGetSize( &w, &h ); if ( width ) - *width = int( double(w) / (m_scaleX*m_mm_to_pix_x) ); + *width = int( double(w) / (m_scaleX*GetMMToPXx()) ); if ( height ) - *height = int( double(h) / (m_scaleY*m_mm_to_pix_y) ); + *height = int( double(h) / (m_scaleY*GetMMToPXy()) ); } // Resolution in pixels per logical inch