File: rescale.h

package info (click to toggle)
wxpython4.0 4.2.3%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 221,752 kB
  • sloc: cpp: 962,555; python: 230,573; ansic: 170,731; makefile: 51,756; sh: 9,342; perl: 1,564; javascript: 584; php: 326; xml: 200
file content (146 lines) | stat: -rw-r--r-- 3,961 bytes parent folder | download | duplicates (4)
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_