Add wxDC::SetTransformMatrix() and related methods and implement them in wxMSW.

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
This commit is contained in:
Vadim Zeitlin
2011-04-23 16:03:10 +00:00
parent 54580df4e2
commit e71508e160
19 changed files with 429 additions and 0 deletions

52
configure vendored
View File

@@ -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)
@@ -14002,6 +14003,50 @@ fi
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

View 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 ---------------------------------------------------------------------------

View 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:

View 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.}

View File

@@ -615,6 +615,14 @@
# 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."

View 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 ); }

View File

@@ -1363,6 +1363,16 @@
// 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
// ----------------------------------------------------------------------------

View File

@@ -336,6 +336,14 @@
#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"

View 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

View File

@@ -1363,6 +1363,16 @@
// 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
// ----------------------------------------------------------------------------

View File

@@ -1363,6 +1363,16 @@
// 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
// ----------------------------------------------------------------------------

View File

@@ -1363,6 +1363,16 @@
// 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
// ----------------------------------------------------------------------------

View File

@@ -1364,6 +1364,16 @@
// 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
// ----------------------------------------------------------------------------

View File

@@ -1363,6 +1363,16 @@
// 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
// ----------------------------------------------------------------------------

View File

@@ -1359,6 +1359,16 @@
// 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
// ----------------------------------------------------------------------------

View File

@@ -1362,6 +1362,16 @@
// 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
// ----------------------------------------------------------------------------

View 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();
//@}
};

View File

@@ -573,6 +573,8 @@
#define wxUSE_SVG 0
#define wxUSE_DC_TRANSFORM_MATRIX 0
#define wxUSE_IMAGE 0

View 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
// ---------------------------------------------------------------------------