From: Vadim Zeitlin Date: Sat, 27 Oct 2012 12:27:56 +0000 (+0000) Subject: Allow wxTextMeasure to work with non-native wxDC objects too. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/1bce253a23047c6153e130d02e776d3d34b05793 Allow wxTextMeasure to work with non-native wxDC objects too. Just forward back to wxDC itself in this case instead of using the platform-specific code in wxTextMeasure that only works with native DCs. See #14781. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72801 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/private/textmeasure.h b/include/wx/private/textmeasure.h index dbd89136b3..1270e8ecdc 100644 --- a/include/wx/private/textmeasure.h +++ b/include/wx/private/textmeasure.h @@ -111,12 +111,32 @@ protected: wxArrayInt& widths, double scaleX) = 0; + // Call either DoGetTextExtent() or wxDC::GetTextExtent() depending on the + // value of m_useDCImpl. + // + // This must be always used instead of calling DoGetTextExtent() directly! + void CallGetTextExtent(const wxString& string, + wxCoord *width, + wxCoord *height, + wxCoord *descent = NULL, + wxCoord *externalLeading = NULL); + // Exactly one of m_dc and m_win is non-NULL for any given object of this // class. const wxDC* const m_dc; const wxWindow* const m_win; + // If this is true, simply forward to wxDC::GetTextExtent() from our + // CallGetTextExtent() instead of calling our own DoGetTextExtent(). + // + // We need this because our DoGetTextExtent() typically only works with + // native DCs, i.e. those having an HDC under Windows or using Pango under + // GTK+. However wxTextMeasure object can be constructed for any wxDC, not + // necessarily a native one and in this case we must call back into the DC + // implementation of text measuring itself. + bool m_useDCImpl; + // This one can be NULL or not. const wxFont* const m_font; diff --git a/src/common/textmeasurecmn.cpp b/src/common/textmeasurecmn.cpp index 90894bf0c6..df91ca38bd 100644 --- a/src/common/textmeasurecmn.cpp +++ b/src/common/textmeasurecmn.cpp @@ -36,6 +36,10 @@ wxTextMeasureBase::wxTextMeasureBase(const wxDC *dc, const wxFont *theFont) m_font(theFont) { wxASSERT_MSG( dc, wxS("wxTextMeasure needs a valid wxDC") ); + + // By default, use wxDC version, we'll explicitly reset this to false in + // the derived classes if the DC is of native variety. + m_useDCImpl = true; } wxTextMeasureBase::wxTextMeasureBase(const wxWindow *win, const wxFont *theFont) @@ -44,6 +48,21 @@ wxTextMeasureBase::wxTextMeasureBase(const wxWindow *win, const wxFont *theFont) m_font(theFont) { wxASSERT_MSG( win, wxS("wxTextMeasure needs a valid wxWindow") ); + + // We don't have any wxDC so we can't forward to it. + m_useDCImpl = false; +} + +void wxTextMeasureBase::CallGetTextExtent(const wxString& string, + wxCoord *width, + wxCoord *height, + wxCoord *descent, + wxCoord *externalLeading) +{ + if ( m_useDCImpl ) + m_dc->GetTextExtent(string, width, height, descent, externalLeading); + else + DoGetTextExtent(string, width, height, descent, externalLeading); } void wxTextMeasureBase::GetTextExtent(const wxString& string, @@ -70,7 +89,7 @@ void wxTextMeasureBase::GetTextExtent(const wxString& string, MeasuringGuard guard(*this); - DoGetTextExtent(string, width, height, descent, externalLeading); + CallGetTextExtent(string, width, height, descent, externalLeading); } void wxTextMeasureBase::GetMultiLineTextExtent(const wxString& text, @@ -103,14 +122,14 @@ void wxTextMeasureBase::GetMultiLineTextExtent(const wxString& text, { // but we don't know it yet - choose something reasonable int dummy; - DoGetTextExtent(wxS("W"), &dummy, &heightLineDefault); + CallGetTextExtent(wxS("W"), &dummy, &heightLineDefault); } heightTextTotal += heightLineDefault; } else { - DoGetTextExtent(curLine, &widthLine, &heightLine); + CallGetTextExtent(curLine, &widthLine, &heightLine); if ( widthLine > widthTextMax ) widthTextMax = widthLine; heightTextTotal += heightLine; @@ -150,7 +169,7 @@ void wxTextMeasureBase::GetLargestStringExtent(const wxVector& strings i != strings.end(); ++i ) { - DoGetTextExtent(*i, &w, &h); + CallGetTextExtent(*i, &w, &h); if ( w > widthMax ) widthMax = w; diff --git a/src/gtk/textmeasure.cpp b/src/gtk/textmeasure.cpp index 8aa2ae2c59..2032a45df0 100644 --- a/src/gtk/textmeasure.cpp +++ b/src/gtk/textmeasure.cpp @@ -28,6 +28,7 @@ #include "wx/fontutil.h" #include "wx/gtk/private.h" +#include "wx/gtk/dc.h" #ifndef __WXGTK3__ #include "wx/gtk/dcclient.h" @@ -41,11 +42,24 @@ void wxTextMeasure::Init() { wxASSERT_MSG( m_font, wxT("wxTextMeasure needs a valid wxFont") ); + m_context = NULL; + m_layout = NULL; + #ifndef __WXGTK3__ m_wdc = NULL; + + if ( m_dc ) + { + wxClassInfo* const ci = m_dc->GetImpl()->GetClassInfo(); + + // Currently the code here only works with wxWindowDCImpl and only in + // wxGTK2 as wxGTK3 uses Cairo and not Pango for all its DCs. + if ( ci->IsKindOf(wxCLASSINFO(wxWindowDCImpl))) + { + m_useDCImpl = false; + } + } #endif // GTK+ < 3 - m_context = NULL; - m_layout = NULL; } // Get Gtk needed elements, if we have not them yet. diff --git a/src/msw/textmeasure.cpp b/src/msw/textmeasure.cpp index 189fc7737f..e25eeac859 100644 --- a/src/msw/textmeasure.cpp +++ b/src/msw/textmeasure.cpp @@ -24,7 +24,6 @@ #endif #include "wx/msw/private.h" -#include "wx/msw/dc.h" #ifndef WX_PRECOMP #include "wx/window.h" @@ -33,6 +32,8 @@ #include "wx/private/textmeasure.h" +#include "wx/msw/dc.h" + // ============================================================================ // wxTextMeasure implementation // ============================================================================ @@ -41,6 +42,16 @@ void wxTextMeasure::Init() { m_hdc = NULL; m_hfontOld = NULL; + + if ( m_dc ) + { + wxClassInfo* const ci = m_dc->GetImpl()->GetClassInfo(); + + if ( ci->IsKindOf(wxCLASSINFO(wxMSWDCImpl))) + { + m_useDCImpl = false; + } + } } void wxTextMeasure::BeginMeasuring() diff --git a/tests/graphics/measuring.cpp b/tests/graphics/measuring.cpp index a45d45032d..ce59b77434 100644 --- a/tests/graphics/measuring.cpp +++ b/tests/graphics/measuring.cpp @@ -31,6 +31,8 @@ #endif #include "wx/dcclient.h" +#include "wx/dcps.h" +#include "wx/metafile.h" // ---------------------------------------------------------------------------- // test class @@ -102,6 +104,22 @@ void MeasuringTextTestCase::DCGetTextExtent() CPPUNIT_ASSERT_EQUAL( sz.x, w ); CPPUNIT_ASSERT( dc.GetMultiLineTextExtent("Good\nbye").y >= 2*sz.y ); + + // Test the functions with some other DC kinds also. +#if wxUSE_PRINTING_ARCHITECTURE && wxUSE_POSTSCRIPT + wxPostScriptDC psdc; + // wxPostScriptDC doesn't have any font set by default but its + // GetTextExtent() requires one to be set. This is probably a bug and we + // should set the default font in it implicitly but for now just work + // around it. + psdc.SetFont(*wxNORMAL_FONT); + DoTestGetTextExtent(psdc); +#endif + +#if wxUSE_ENH_METAFILE + wxEnhMetaFileDC metadc; + DoTestGetTextExtent(metadc); +#endif } void MeasuringTextTestCase::WindowGetTextExtent()