]> git.saurik.com Git - wxWidgets.git/commitdiff
Add wxDC::SetTransformMatrix() and related methods and implement them in wxMSW.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 23 Apr 2011 16:03:10 +0000 (16:03 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 23 Apr 2011 16:03:10 +0000 (16:03 +0000)
Add support for world transformations to wxDC too. Currently this is
implemented in wxMSW only but could be easily provided in the ports that use
wxGraphicsContext for wxDC implementation later.

Closes #13092.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67588 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

19 files changed:
configure
configure.in
docs/changes.txt
docs/doxygen/mainpages/const_wxusedef.h
include/wx/chkconf.h
include/wx/dc.h
include/wx/motif/setup0.h
include/wx/msw/chkconf.h
include/wx/msw/dc.h
include/wx/msw/setup0.h
include/wx/msw/wince/setup.h
include/wx/os2/setup0.h
include/wx/osx/setup0.h
include/wx/palmos/setup0.h
include/wx/setup_inc.h
include/wx/univ/setup0.h
interface/wx/dc.h
setup.h.in
src/msw/dc.cpp

index a48880cce76eef008a324b8de6e3c11a3413862d..a97ed92aff409a0fd4940872dd8ad2a8c99a8a2f 100755 (executable)
--- a/configure
+++ b/configure
@@ -1899,6 +1899,7 @@ Optional Features:
   --enable-dragimage      use wxDragImage
   --enable-accessibility  enable accessibility support
   --enable-uiactionsim    use wxUIActionSimulator (experimental)
+  --enable-dctransform    use wxDC::SetTransformMatrix and related
   --enable-palette        use wxPalette class
   --enable-image          use wxImage class
   --enable-gif            use gif images (GIF file format)
 echo "${ECHO_T}$result" >&6; }
 
 
+          enablestring=
+          defaultval=$wxUSE_ALL_FEATURES
+          if test -z "$defaultval"; then
+              if test x"$enablestring" = xdisable; then
+                  defaultval=yes
+              else
+                  defaultval=no
+              fi
+          fi
+
+          { echo "$as_me:$LINENO: checking for --${enablestring:-enable}-dctransform" >&5
+echo $ECHO_N "checking for --${enablestring:-enable}-dctransform... $ECHO_C" >&6; }
+          # Check whether --enable-dctransform was given.
+if test "${enable_dctransform+set}" = set; then
+  enableval=$enable_dctransform;
+                          if test "$enableval" = yes; then
+                            wx_cv_use_dctransform='wxUSE_DC_TRANSFORM_MATRIX=yes'
+                          else
+                            wx_cv_use_dctransform='wxUSE_DC_TRANSFORM_MATRIX=no'
+                          fi
+
+else
+
+                          wx_cv_use_dctransform='wxUSE_DC_TRANSFORM_MATRIX=${'DEFAULT_wxUSE_DC_TRANSFORM_MATRIX":-$defaultval}"
+
+fi
+
+
+          eval "$wx_cv_use_dctransform"
+
+          if test x"$enablestring" = xdisable; then
+            if test $wxUSE_DC_TRANSFORM_MATRIX = no; then
+              result=yes
+            else
+              result=no
+            fi
+          else
+            result=$wxUSE_DC_TRANSFORM_MATRIX
+          fi
+
+          { echo "$as_me:$LINENO: result: $result" >&5
+echo "${ECHO_T}$result" >&6; }
+
+
 
 
           enablestring=
@@ -47154,6 +47199,13 @@ _ACEOF
     SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS uiaction"
 fi
 
+if test "$wxUSE_DC_TRANSFORM_MATRIX" = "yes" ; then
+    cat >>confdefs.h <<\_ACEOF
+#define wxUSE_DC_TRANSFORM_MATRIX 1
+_ACEOF
+
+fi
+
 
 USES_CONTROLS=0
 if test "$wxUSE_CONTROLS" = "yes"; then
index 606bae14567e6cf39d0050b4ae3be1c31248662f..04a3e14e7be7e289702c019b6e6ec1f3a95bf569 100644 (file)
@@ -1035,6 +1035,7 @@ WX_ARG_FEATURE(metafile,    [  --enable-metafiles      use wxMetaFile (Win32 onl
 WX_ARG_FEATURE(dragimage,   [  --enable-dragimage      use wxDragImage], wxUSE_DRAGIMAGE)
 WX_ARG_FEATURE(accessibility,[  --enable-accessibility  enable accessibility support], wxUSE_ACCESSIBILITY)
 WX_ARG_FEATURE(uiactionsim,  [  --enable-uiactionsim    use wxUIActionSimulator (experimental)], wxUSE_UIACTIONSIMULATOR)
+WX_ARG_FEATURE(dctransform,  [  --enable-dctransform    use wxDC::SetTransformMatrix and related], wxUSE_DC_TRANSFORM_MATRIX)
 
 dnl ---------------------------------------------------------------------------
 dnl support for image formats that do not rely on external library
@@ -6752,6 +6753,10 @@ if test "$wxUSE_UIACTIONSIMULATOR" = "yes" ; then
     SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS uiaction"
 fi
 
+if test "$wxUSE_DC_TRANSFORM_MATRIX" = "yes" ; then
+    AC_DEFINE(wxUSE_DC_TRANSFORM_MATRIX)
+fi
+
 dnl ---------------------------------------------------------------------------
 dnl GUI controls
 dnl ---------------------------------------------------------------------------
index e742a7880741a8bcbdb3133bd334413afb9d1108..3e0b49cde79839fdff49cadd0693ec2dc942a8db 100644 (file)
@@ -522,6 +522,7 @@ MSW:
 - Center task dialog-based wxProgressDialog on the parent (John Roberts).
 - wxAutomationObject::GetInstance() creates objects on demand (Kolya Kosenko).
 - Fix EVT_UPDATE_UI generation for items in submenus (wsu).
+- Added support for world transformation matrix to wxDC (Catalin Raceanu).
 
 OSX:
 
index 2367dfcde987819df316302b06b891d7e77b4b38..bb4dc79ce1c513fe67dd6fce1ad966bcb5108879 100644 (file)
@@ -102,6 +102,7 @@ library:
 @itemdef{wxUSE_DATEPICKCTRL, Use wxDatePickerCtrl class.}
 @itemdef{wxUSE_DATETIME, Use wxDateTime and related classes.}
 @itemdef{wxUSE_DBGHELP, Use wxDbgHelpDLL class.}
+@itemdef{wxUSE_DC_TRANSFORM_MATRIX, Use wxDC::SetTransformMatrix() and related methods.}
 @itemdef{wxUSE_DEBUG_CONTEXT, Use wxDebugContext class.}
 @itemdef{wxUSE_DEBUG_NEW_ALWAYS, See @ref overview_debugging}
 @itemdef{wxUSE_DEBUGREPORT, Use wxDebugReport class.}
index fa88745fc57d396c82ff235c086df84a2750d932..4b355fc53707cd5f463cef9ae35d9253970c3fe8 100644 (file)
 #   endif
 #endif /* !defined(wxUSE_DATEPICKCTRL) */
 
+#ifndef wxUSE_DC_TRANSFORM_MATRIX
+#   ifdef wxABORT_ON_CONFIG_ERROR
+#       error "wxUSE_DC_TRANSFORM_MATRIX must be defined, please read comment near the top of this file."
+#   else
+#       define wxUSE_DC_TRANSFORM_MATRIX 1
+#   endif
+#endif /* wxUSE_DC_TRANSFORM_MATRIX */
+
 #ifndef wxUSE_DIRPICKERCTRL
 #   ifdef wxABORT_ON_CONFIG_ERROR
 #       error "wxUSE_DIRPICKERCTRL must be defined, please read comment near the top of this file."
index a06217ab45365a51eb772427f9c0bcc31d72a893..5734cde4380d22e550315db576d405e06dce957f 100644 (file)
@@ -30,6 +30,7 @@
 #include "wx/math.h"
 #include "wx/image.h"
 #include "wx/region.h"
+#include "wx/affinematrix2d.h"
 
 #define wxUSE_NEW_DC 1
 
@@ -490,6 +491,20 @@ public:
         if ( y ) *y = m_deviceOriginY;
     }
 
+#if wxUSE_DC_TRANSFORM_MATRIX
+    // Transform matrix support is not available in most ports right now
+    // (currently only wxMSW provides it) so do nothing in these methods by
+    // default.
+    virtual bool CanUseTransformMatrix() const
+        { return false; }
+    virtual bool SetTransformMatrix(const wxAffineMatrix2D& WXUNUSED(matrix))
+        { return false; }
+    virtual wxAffineMatrix2D GetTransformMatrix() const
+        { return wxAffineMatrix2D(); }
+    virtual void ResetTransformMatrix()
+        { }
+#endif // wxUSE_DC_TRANSFORM_MATRIX
+
     virtual void SetDeviceLocalOrigin( wxCoord x, wxCoord y );
 
     virtual void ComputeScaleAndOrigin();
@@ -1001,6 +1016,20 @@ public:
     void SetAxisOrientation(bool xLeftRight, bool yBottomUp)
         { m_pimpl->SetAxisOrientation(xLeftRight, yBottomUp); }
 
+#if wxUSE_DC_TRANSFORM_MATRIX
+    bool CanUseTransformMatrix() const
+        { return m_pimpl->CanUseTransformMatrix(); }
+
+    bool SetTransformMatrix(const wxAffineMatrix2D &matrix)
+        { return m_pimpl->SetTransformMatrix(matrix); }
+
+    wxAffineMatrix2D GetTransformMatrix() const
+        { return m_pimpl->GetTransformMatrix(); }
+
+    void ResetTransformMatrix()
+        { m_pimpl->ResetTransformMatrix(); }
+#endif // wxUSE_DC_TRANSFORM_MATRIX
+
     // mostly internal
     void SetDeviceLocalOrigin( wxCoord x, wxCoord y )
         { m_pimpl->SetDeviceLocalOrigin( x, y ); }
index 4f0758aa59b72a15538fbc8afa9e139f16280f25..c5e3883fc7b4b294e7caba39990c60d0afb5e699 100644 (file)
 // to create files in SVG (Scalable Vector Graphics) format.
 #define wxUSE_SVG 1
 
+// Should wxDC provide SetTransformMatrix() and related methods?
+//
+// Default is 1 but can be set to 0 if this functionality is not used. Notice
+// that currently only wxMSW supports this so setting this to 0 doesn't change
+// much for non-MSW platforms (although it will still save a few bytes
+// probably).
+//
+// Recommended setting: 1.
+#define wxUSE_DC_TRANSFORM_MATRIX 1
+
 // ----------------------------------------------------------------------------
 // image format support
 // ----------------------------------------------------------------------------
index cff866e18a9886936bc756ead3c2762d40cd5367..5643870029123b1a65f06f9c275e3a98641388fd 100644 (file)
 #endif  /* !wxUSE_DYNAMIC_LOADER */
 
 #if !wxUSE_DYNLIB_CLASS
+#   if wxUSE_DC_TRANSFORM_MATRIX
+#       ifdef wxABORT_ON_CONFIG_ERROR
+#           error "wxUSE_DC_TRANSFORM_MATRIX requires wxUSE_DYNLIB_CLASS"
+#       else
+#           undef wxUSE_DC_TRANSFORM_MATRIX
+#           define wxUSE_DC_TRANSFORM_MATRIX 0
+#       endif
+#   endif
 #   if wxUSE_UXTHEME
 #       ifdef wxABORT_ON_CONFIG_ERROR
 #           error "wxUSE_UXTHEME requires wxUSE_DYNLIB_CLASS"
index b99da69a1dc1835b6d7207f5d815ed1b387cc274..f874111c8d539b419ff0323b58f6cb47604a5a7a 100644 (file)
@@ -87,6 +87,13 @@ public:
     virtual void SetDeviceOrigin(wxCoord x, wxCoord y);
     virtual void SetAxisOrientation(bool xLeftRight, bool yBottomUp);
 
+#if wxUSE_DC_TRANSFORM_MATRIX
+    virtual bool CanUseTransformMatrix() const;
+    virtual bool SetTransformMatrix(const wxAffineMatrix2D& matrix);
+    virtual wxAffineMatrix2D GetTransformMatrix() const;
+    virtual void ResetTransformMatrix();
+#endif // wxUSE_DC_TRANSFORM_MATRIX
+
     virtual void SetLogicalFunction(wxRasterOperationMode function);
 
     // implementation from now on
index 6f370d3044a405b45e78fdbf09a1babcca3ae998..896e56b3ef28934077bbffbc63802d226206910a 100644 (file)
 // to create files in SVG (Scalable Vector Graphics) format.
 #define wxUSE_SVG 1
 
+// Should wxDC provide SetTransformMatrix() and related methods?
+//
+// Default is 1 but can be set to 0 if this functionality is not used. Notice
+// that currently only wxMSW supports this so setting this to 0 doesn't change
+// much for non-MSW platforms (although it will still save a few bytes
+// probably).
+//
+// Recommended setting: 1.
+#define wxUSE_DC_TRANSFORM_MATRIX 1
+
 // ----------------------------------------------------------------------------
 // image format support
 // ----------------------------------------------------------------------------
index 372b9727c531e1cd9d78bbb0ec14fc423f77f12a..1bc89e2d7a269f18a57e49e145e2ad8583568e3e 100644 (file)
 // to create files in SVG (Scalable Vector Graphics) format.
 #define wxUSE_SVG 1
 
+// Should wxDC provide SetTransformMatrix() and related methods?
+//
+// Default is 1 but can be set to 0 if this functionality is not used. Notice
+// that currently only wxMSW supports this so setting this to 0 doesn't change
+// much for non-MSW platforms (although it will still save a few bytes
+// probably).
+//
+// Recommended setting: 1.
+#define wxUSE_DC_TRANSFORM_MATRIX 1
+
 // ----------------------------------------------------------------------------
 // image format support
 // ----------------------------------------------------------------------------
index 9312b3ecd574df3fa874d72c731a6d546ebf5922..711a8ba78a8bf97f2acbf23386f3963b382633e5 100644 (file)
 // to create files in SVG (Scalable Vector Graphics) format.
 #define wxUSE_SVG 1
 
+// Should wxDC provide SetTransformMatrix() and related methods?
+//
+// Default is 1 but can be set to 0 if this functionality is not used. Notice
+// that currently only wxMSW supports this so setting this to 0 doesn't change
+// much for non-MSW platforms (although it will still save a few bytes
+// probably).
+//
+// Recommended setting: 1.
+#define wxUSE_DC_TRANSFORM_MATRIX 1
+
 // ----------------------------------------------------------------------------
 // image format support
 // ----------------------------------------------------------------------------
index 28d9a18a1dade698060c425b4e432b680782f3da..4967f7bf5b1fe9b510144701431f46c6567cb814 100644 (file)
 // to create files in SVG (Scalable Vector Graphics) format.
 #define wxUSE_SVG 1
 
+// Should wxDC provide SetTransformMatrix() and related methods?
+//
+// Default is 1 but can be set to 0 if this functionality is not used. Notice
+// that currently only wxMSW supports this so setting this to 0 doesn't change
+// much for non-MSW platforms (although it will still save a few bytes
+// probably).
+//
+// Recommended setting: 1.
+#define wxUSE_DC_TRANSFORM_MATRIX 1
+
 // ----------------------------------------------------------------------------
 // image format support
 // ----------------------------------------------------------------------------
index de8d5c7998a883d44f7dca88c81151d216568a61..53b87abe956e8971de3c866d5177efad101616a9 100644 (file)
 // to create files in SVG (Scalable Vector Graphics) format.
 #define wxUSE_SVG 1
 
+// Should wxDC provide SetTransformMatrix() and related methods?
+//
+// Default is 1 but can be set to 0 if this functionality is not used. Notice
+// that currently only wxMSW supports this so setting this to 0 doesn't change
+// much for non-MSW platforms (although it will still save a few bytes
+// probably).
+//
+// Recommended setting: 1.
+#define wxUSE_DC_TRANSFORM_MATRIX 1
+
 // ----------------------------------------------------------------------------
 // image format support
 // ----------------------------------------------------------------------------
index bcf7254b4f748278f58add1aa68bef095254023d..66cb3e25d89d3f8fc0a94c409cab20c1615b3990 100644 (file)
 // to create files in SVG (Scalable Vector Graphics) format.
 #define wxUSE_SVG 1
 
+// Should wxDC provide SetTransformMatrix() and related methods?
+//
+// Default is 1 but can be set to 0 if this functionality is not used. Notice
+// that currently only wxMSW supports this so setting this to 0 doesn't change
+// much for non-MSW platforms (although it will still save a few bytes
+// probably).
+//
+// Recommended setting: 1.
+#define wxUSE_DC_TRANSFORM_MATRIX 1
+
 // ----------------------------------------------------------------------------
 // image format support
 // ----------------------------------------------------------------------------
index c98489ab7d04d09f877ffacd0ca0160f347603a8..fd37d88b06046834115e993ee6d3c116b13c018a 100644 (file)
 // to create files in SVG (Scalable Vector Graphics) format.
 #define wxUSE_SVG 1
 
+// Should wxDC provide SetTransformMatrix() and related methods?
+//
+// Default is 1 but can be set to 0 if this functionality is not used. Notice
+// that currently only wxMSW supports this so setting this to 0 doesn't change
+// much for non-MSW platforms (although it will still save a few bytes
+// probably).
+//
+// Recommended setting: 1.
+#define wxUSE_DC_TRANSFORM_MATRIX 1
+
 // ----------------------------------------------------------------------------
 // image format support
 // ----------------------------------------------------------------------------
index 32b986bd1e97bc77b092c79a7196af42a92e9674..607830fa3a14a5a43c4e34f1e7c248a579c4df9f 100644 (file)
@@ -163,6 +163,17 @@ struct wxFontMetrics
     wxColour use the colour's alpha values when stroking or filling.
 
 
+    @section Support for Transformation Matrix
+
+    On some platforms (currently only under MSW and only on Windows NT, i.e.
+    not Windows 9x/ME, systems) wxDC has support for applying an arbitrary
+    affine transformation matrix to its coordinate system. Call
+    CanUseTransformMatrix() to check if this support is available and then call
+    SetTransformMatrix() if it is. If the transformation matrix is not
+    supported, SetTransformMatrix() always simply returns false and doesn't do
+    anything.
+
+
     @library{wxcore}
     @category{dc,gdi}
 
@@ -1499,6 +1510,58 @@ public:
         'zooming'.
     */
     void SetUserScale(double xScale, double yScale);
+
+
+    /**
+        @name Transformation matrix
+
+        See the notes about the availability of these functions in the class
+        documentation.
+    */
+    //@{
+
+    /**
+        Check if the use of transformation matrix is supported by the current
+        system.
+
+        Currently this function always returns @false for non-MSW platforms and
+        may return @false for old (Windows 9x/ME) Windows systems. Normally
+        support for the transformation matrix is always available in any
+        relatively recent Windows versions.
+
+        @since 2.9.2
+    */
+    bool CanUseTransformMatrix() const;
+
+    /**
+        Set the transformation matrix.
+
+        If transformation matrix is supported on the current system, the
+        specified @a matrix will be used to transform between wxDC and physical
+        coordinates. Otherwise the function returns @false and doesn't change
+        the coordinate mapping.
+
+        @since 2.9.2
+    */
+    bool SetTransformMatrix(const wxAffineMatrix2D& matrix);
+
+    /**
+        Return the transformation matrix used by this device context.
+
+        By default the transformation matrix is the identity matrix.
+
+        @since 2.9.2
+    */
+    wxAffineMatrix2D GetTransformMatrix() const;
+
+    /**
+        Revert the transformation matrix to identity matrix.
+
+        @since 2.9.2
+    */
+    void ResetTransformMatrix();
+
+    //@}
 };
 
 
index fe2e031afbfe266ee60de2f9e08aa50a93d1585e..456f24fa1201214bc7fd1d2fb884e6027e2c6d0e 100644 (file)
 
 #define wxUSE_SVG 0
 
+#define wxUSE_DC_TRANSFORM_MATRIX 0
+
 
 
 #define wxUSE_IMAGE         0
index c630843c6751945836b61785fd7f00cca06b5ee6..5079795653467c33fff3bb3246dde2d7e290cf1d 100644 (file)
@@ -273,6 +273,98 @@ private:
 
 IMPLEMENT_DYNAMIC_CLASS(wxGDIDLLsCleanupModule, wxModule)
 
+namespace
+{
+
+#if wxUSE_DC_TRANSFORM_MATRIX
+
+// Class used to dynamically load world transform related API functions.
+class GdiWorldTransformFuncs
+{
+public:
+    static bool IsOk()
+    {
+        if ( !ms_worldTransformSymbolsLoaded )
+            LoadWorldTransformSymbols();
+
+        return ms_pfnSetGraphicsMode &&
+                ms_pfnSetWorldTransform &&
+                 ms_pfnGetWorldTransform &&
+                  ms_pfnModifyWorldTransform;
+    }
+
+    typedef int (WINAPI *SetGraphicsMode_t)(HDC, int);
+    static SetGraphicsMode_t SetGraphicsMode()
+    {
+        if ( !ms_worldTransformSymbolsLoaded )
+            LoadWorldTransformSymbols();
+
+        return ms_pfnSetGraphicsMode;
+    }
+
+    typedef BOOL (WINAPI *SetWorldTransform_t)(HDC, const XFORM *);
+    static SetWorldTransform_t SetWorldTransform()
+    {
+        if ( !ms_worldTransformSymbolsLoaded )
+            LoadWorldTransformSymbols();
+
+        return ms_pfnSetWorldTransform;
+    }
+
+    typedef BOOL (WINAPI *GetWorldTransform_t)(HDC, LPXFORM);
+    static GetWorldTransform_t GetWorldTransform()
+    {
+        if ( !ms_worldTransformSymbolsLoaded )
+            LoadWorldTransformSymbols();
+
+        return ms_pfnGetWorldTransform;
+    }
+
+    typedef BOOL (WINAPI *ModifyWorldTransform_t)(HDC, const XFORM *, DWORD);
+    static ModifyWorldTransform_t ModifyWorldTransform()
+    {
+        if ( !ms_worldTransformSymbolsLoaded )
+            LoadWorldTransformSymbols();
+
+        return ms_pfnModifyWorldTransform;
+    }
+
+private:
+    static void LoadWorldTransformSymbols()
+    {
+        wxDynamicLibrary dll(wxT("gdi32.dll"));
+
+        wxDL_INIT_FUNC(ms_pfn, SetGraphicsMode, dll);
+        wxDL_INIT_FUNC(ms_pfn, SetWorldTransform, dll);
+        wxDL_INIT_FUNC(ms_pfn, GetWorldTransform, dll);
+        wxDL_INIT_FUNC(ms_pfn, ModifyWorldTransform, dll);
+
+        ms_worldTransformSymbolsLoaded = true;
+    }
+
+    static SetGraphicsMode_t ms_pfnSetGraphicsMode;
+    static SetWorldTransform_t ms_pfnSetWorldTransform;
+    static GetWorldTransform_t ms_pfnGetWorldTransform;
+    static ModifyWorldTransform_t ms_pfnModifyWorldTransform;
+
+    static bool ms_worldTransformSymbolsLoaded;
+};
+
+GdiWorldTransformFuncs::SetGraphicsMode_t
+    GdiWorldTransformFuncs::ms_pfnSetGraphicsMode = NULL;
+GdiWorldTransformFuncs::SetWorldTransform_t
+    GdiWorldTransformFuncs::ms_pfnSetWorldTransform = NULL;
+GdiWorldTransformFuncs::GetWorldTransform_t
+    GdiWorldTransformFuncs::ms_pfnGetWorldTransform = NULL;
+GdiWorldTransformFuncs::ModifyWorldTransform_t
+    GdiWorldTransformFuncs::ms_pfnModifyWorldTransform = NULL;
+
+bool GdiWorldTransformFuncs::ms_worldTransformSymbolsLoaded = false;
+
+#endif // wxUSE_DC_TRANSFORM_MATRIX
+
+} // anonymous namespace
+
 #endif // wxUSE_DYNLIB_CLASS
 
 // ===========================================================================
@@ -2005,6 +2097,87 @@ void wxMSWDCImpl::SetDeviceOrigin(wxCoord x, wxCoord y)
     ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX, (int)m_deviceOriginY, NULL);
 }
 
+// ----------------------------------------------------------------------------
+// Transform matrix
+// ----------------------------------------------------------------------------
+
+#if wxUSE_DC_TRANSFORM_MATRIX
+
+bool wxMSWDCImpl::CanUseTransformMatrix() const
+{
+    return GdiWorldTransformFuncs::IsOk();
+}
+
+bool wxMSWDCImpl::SetTransformMatrix(const wxAffineMatrix2D &matrix)
+{
+    if ( !GdiWorldTransformFuncs::IsOk() )
+        return false;
+
+    if ( matrix.IsIdentity() )
+    {
+        ResetTransformMatrix();
+        return true;
+    }
+
+    if ( !GdiWorldTransformFuncs::SetGraphicsMode()(GetHdc(), GM_ADVANCED) )
+    {
+        wxLogLastError(wxT("SetGraphicsMode"));
+        return false;
+    }
+
+    wxMatrix2D mat;
+    wxPoint2DDouble tr;
+    matrix.Get(&mat, &tr);
+
+    XFORM xform;
+    xform.eM11 = mat.m_11;
+    xform.eM12 = mat.m_12;
+    xform.eM21 = mat.m_21;
+    xform.eM22 = mat.m_22;
+    xform.eDx = tr.m_x;
+    xform.eDy = tr.m_y;
+
+    if ( !GdiWorldTransformFuncs::SetWorldTransform()(GetHdc(), &xform) )
+    {
+        wxLogLastError(wxT("SetWorldTransform"));
+        return false;
+    }
+
+    return true;
+}
+
+wxAffineMatrix2D wxMSWDCImpl::GetTransformMatrix() const
+{
+    wxAffineMatrix2D transform;
+
+    if ( !GdiWorldTransformFuncs::IsOk() )
+        return transform;
+
+    XFORM xform;
+    if ( !GdiWorldTransformFuncs::GetWorldTransform()(GetHdc(), &xform) )
+    {
+        wxLogLastError(wxT("GetWorldTransform"));
+        return transform;
+    }
+
+    wxMatrix2D m(xform.eM11, xform.eM12, xform.eM21, xform.eM22);
+    wxPoint2DDouble p(xform.eDx, xform.eDy);
+    transform.Set(m, p);
+
+    return transform;
+}
+
+void wxMSWDCImpl::ResetTransformMatrix()
+{
+    if ( GdiWorldTransformFuncs::IsOk() )
+    {
+        GdiWorldTransformFuncs::ModifyWorldTransform()(GetHdc(), NULL, MWT_IDENTITY);
+        GdiWorldTransformFuncs::SetGraphicsMode()(GetHdc(), GM_COMPATIBLE);
+    }
+}
+
+#endif // wxUSE_DC_TRANSFORM_MATRIX
+
 // ---------------------------------------------------------------------------
 // bit blit
 // ---------------------------------------------------------------------------