]> git.saurik.com Git - wxWidgets.git/commitdiff
Allow wxTextMeasure to work with non-native wxDC objects too.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 27 Oct 2012 12:27:56 +0000 (12:27 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 27 Oct 2012 12:27:56 +0000 (12:27 +0000)
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

include/wx/private/textmeasure.h
src/common/textmeasurecmn.cpp
src/gtk/textmeasure.cpp
src/msw/textmeasure.cpp
tests/graphics/measuring.cpp

index dbd89136b35dd408ab56d138af4060a7d3628e49..1270e8ecdc88b21e81f0d03968131af0b8a7629d 100644 (file)
@@ -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;
 
index 90894bf0c603bcc205f64b5c735c5b7686239b2c..df91ca38bdceb7fd383bd9bfbc4714ef85cc662c 100644 (file)
@@ -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<wxString>& strings
           i != strings.end();
           ++i )
     {
-        DoGetTextExtent(*i, &w, &h);
+        CallGetTextExtent(*i, &w, &h);
 
         if ( w > widthMax )
             widthMax = w;
index 8aa2ae2c590fd12a3a703ad16cd64d92d1a92673..2032a45df0d771696f3db6aae72d5a1f9f1df652 100644 (file)
@@ -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.
index 189fc7737f29f70010b146c6418f6b158d3b89d3..e25eeac859327511d04d49aae9f021367b4149bf 100644 (file)
@@ -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()
index a45d45032d200669e9b33f59a30d9c29355aa414..ce59b7743439b64cbef69786d6a90cad3b89fcdb 100644 (file)
@@ -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()