1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
///////////////////////////////////////////////////////////////////////////////
// Name: wx/private/rescale.h
// Purpose: Helpers for rescaling coordinates
// Author: Vadim Zeitlin
// Created: 2021-07-13
// Copyright: (c) 2021 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_PRIVATE_RESCALE_H_
#define _WX_PRIVATE_RESCALE_H_
#include "wx/gdicmn.h"
#include "wx/math.h"
#ifdef __WINDOWS__
// Required in order to use wxMulDivInt32().
#include "wx/msw/wrapwin.h"
#endif
// wxRescaleCoord is used to scale the components of the given wxSize by the
// ratio between 2 scales, with rounding. It doesn't scale the components
// if they're set to -1 (wxDefaultCoord), as this value is special in wxSize.
//
// The way it's used is special because we want to ensure there is no confusion
// between the scale being converted from and the scale being converted to, so
// instead of just using a single function, we use an intermediate object,
// which is not supposed to be used directly, but is only returned by From() in
// order to allow calling To() on it.
//
// Another complication is that we want this to work for both wxSize and
// wxPoint, as well as for just plain coordinate values, so wxRescaleCoord() is
// an overloaded function and the helper classes are templates, with their
// template parameter being either wxSize, wxPoint or int.
namespace wxPrivate
{
template <typename T> class wxRescaleCoordWithValue;
template <typename T>
class wxRescaleCoordWithFrom
{
public:
T To(wxSize newScale) const
{
T value(m_value);
if ( value.x != wxDefaultCoord )
value.x = wxMulDivInt32(value.x, newScale.x, m_oldScale.x);
if ( value.y != wxDefaultCoord )
value.y = wxMulDivInt32(value.y, newScale.y, m_oldScale.y);
return value;
}
T To(int newScaleX, int newScaleY) const
{
return To(wxSize(newScaleX, newScaleY));
}
private:
wxRescaleCoordWithFrom(T value, wxSize oldScale)
: m_value(value), m_oldScale(oldScale)
{
}
const T m_value;
const wxSize m_oldScale;
// Only it can create objects of this class.
friend class wxRescaleCoordWithValue<T>;
};
// Specialization for just a single value.
template <>
class wxRescaleCoordWithFrom<int>
{
public:
int To(wxSize newScale) const
{
return m_value == wxDefaultCoord
? wxDefaultCoord
: wxMulDivInt32(m_value, newScale.x, m_oldScale.x);
}
private:
wxRescaleCoordWithFrom(int value, wxSize oldScale)
: m_value(value), m_oldScale(oldScale)
{
}
const int m_value;
const wxSize m_oldScale;
// Only it can create objects of this class.
friend class wxRescaleCoordWithValue<int>;
};
template <typename T>
class wxRescaleCoordWithValue
{
public:
explicit wxRescaleCoordWithValue(T value)
: m_value(value)
{
}
wxRescaleCoordWithFrom<T> From(wxSize oldScale)
{
return wxRescaleCoordWithFrom<T>(m_value, oldScale);
}
wxRescaleCoordWithFrom<T> From(int oldScaleX, int oldScaleY)
{
return From(wxSize(oldScaleX, oldScaleY));
}
private:
const T m_value;
};
} // namespace wxPrivate
inline wxPrivate::wxRescaleCoordWithValue<int> wxRescaleCoord(int coord)
{
return wxPrivate::wxRescaleCoordWithValue<int>(coord);
}
inline wxPrivate::wxRescaleCoordWithValue<wxSize> wxRescaleCoord(wxSize sz)
{
return wxPrivate::wxRescaleCoordWithValue<wxSize>(sz);
}
inline wxPrivate::wxRescaleCoordWithValue<wxSize> wxRescaleCoord(int x, int y)
{
return wxPrivate::wxRescaleCoordWithValue<wxSize>(wxSize(x, y));
}
inline wxPrivate::wxRescaleCoordWithValue<wxPoint> wxRescaleCoord(wxPoint pt)
{
return wxPrivate::wxRescaleCoordWithValue<wxPoint>(pt);
}
#endif // _WX_PRIVATE_RESCALE_H_
|