Scaling.h
1 /* Copyright (C) 2015 Marc Boris Duerner
2 
3  This library is free software; you can redistribute it and/or
4  modify it under the terms of the GNU Lesser General Public
5  License as published by the Free Software Foundation; either
6  version 2.1 of the License, or (at your option) any later version.
7 
8  As a special exception, you may use this file as part of a free
9  software library without restriction. Specifically, if other files
10  instantiate templates or use macros or inline functions from this
11  file, or you compile this file and link it with other files to
12  produce an executable, this file does not by itself cause the
13  resulting executable to be covered by the GNU General Public
14  License. This exception does not however invalidate any other
15  reasons why the executable file might be covered by the GNU Library
16  General Public License.
17 
18  This library is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  Lesser General Public License for more details.
22 
23  You should have received a copy of the GNU Lesser General Public
24  License along with this library; if not, write to the Free Software
25  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26  MA 02110-1301 USA
27 */
28 
29 #ifndef Pt_Gfx_Scaling_h
30 #define Pt_Gfx_Scaling_h
31 
32 #include <Pt/Gfx/Api.h>
33 #include <Pt/Gfx/Point.h>
34 #include <Pt/Gfx/Size.h>
35 #include <Pt/Gfx/Rect.h>
36 
37 namespace Pt {
38 
39 namespace Gfx {
40 
48 class Scaling
49 {
50  friend bool operator ==(const Scaling&, const Scaling&);
51  friend bool operator <(const Scaling&, const Scaling&);
52 
53  public:
56  Scaling(double scaleFactor = 1.0)
57  : _scaleFactor(scaleFactor)
58  { }
59 
62  double scaleFactor() const
63  {
64  return _scaleFactor;
65  }
66 
70  {
71  _scaleFactor = scaleFactor;
72  }
73 
74  public:
77  double toPhysical(double n) const
78  {
79  return n * scaleFactor();
80  }
81 
85  {
86  return p * scaleFactor();
87  }
88 
92  {
93  return s * scaleFactor();
94  }
95 
99  {
100  Gfx::PointF p = toPhysical( r.topLeft() );
101  Gfx::SizeF s = toPhysical( r.size() );
102  return Gfx::RectF(p, s);
103  }
104 
107  double toLogical(double n) const
108  {
109  return n / scaleFactor();
110  }
111 
115  {
116  return p / scaleFactor();
117  }
118 
122  {
123  return s / scaleFactor();
124  }
125 
129  {
130  Gfx::PointF p = toLogical( r.topLeft() );
131  Gfx::SizeF s = toLogical( r.size() );
132  return Gfx::RectF(p, s);
133  }
134 
135  public:
138  double align(double n) const
139  {
140  // better name: alignGrid()
141 
142  double p = toPhysical(n);
143  p = lround(p);
144  return toLogical(p);
145  }
146 
149  double alignPixel(double n) const
150  {
151  double p = toPhysical(n);
152  p = lround(p + 0.5) - 0.5;
153  return toLogical(p);
154  }
155 
158  double alignContour(size_t n) const
159  {
160  // keep contour size when downscaling
161  if (_scaleFactor < 1.0)
162  return toLogical( static_cast<double>(n) );
163 
164  double p = toPhysical( static_cast<double>(n) );
165  size_t s = static_cast<size_t>(p);
166  return toLogical( static_cast<double>(s) );
167  }
168 
171  Gfx::PointF align(const Gfx::PointF& p) const
172  {
173  Gfx::PointF pos = toPhysical(p);
174  pos.setX(lround(pos.x()));
175  pos.setY(lround(pos.y()));
176  return toLogical(pos);
177  }
178 
181  Gfx::SizeF align(const Gfx::SizeF& s) const
182  {
183  Gfx::SizeF size = toPhysical(s);
184  size.setWidth(lround(size.width()));
185  size.setHeight(lround(size.height()));
186  return toLogical(size);
187  }
188 
191  Gfx::RectF align(const Gfx::RectF& rect) const
192  {
193  Gfx::PointF pos = toPhysical(rect.topLeft());
194  pos.setX(lround(pos.x()));
195  pos.setY(lround(pos.y()));
196 
197  Gfx::SizeF size = toPhysical(rect.size());
198  size.setWidth(lround(size.width()));
199  size.setHeight(lround(size.height()));
200 
201  return toLogical(Gfx::RectF(pos, size));
202  }
203 
204  private:
205  double _scaleFactor;
206 };
207 
208 
212 inline bool operator == (const Scaling& a, const Scaling& b)
213 {
214  return a._scaleFactor == b._scaleFactor;
215 }
216 
217 
221 inline bool operator != (const Scaling& a, const Scaling& b)
222 {
223  return ! (a == b);
224 }
225 
226 
230 inline bool operator < (const Scaling& a, const Scaling& b)
231 {
232  return a._scaleFactor < b._scaleFactor;
233 }
234 
235 } // namespace
236 
237 } // namespace
238 
239 #endif
Gfx::SizeF align(const Gfx::SizeF &s) const
Aligns a size to physical pixels.
Definition: Scaling.h:181
Core module.
Definition: Allocator.h:33
double alignContour(size_t n) const
Aligns a contour width while preserving visible thickness.
Definition: Scaling.h:158
Gfx::RectF toPhysical(const Gfx::RectF &r) const
Converts a rectangle to physical units.
Definition: Scaling.h:98
double scaleFactor() const
Returns the scale factor.
Definition: Scaling.h:62
Logical-to-physical unit conversion.
Definition: Scaling.h:49
Size with floating-point width and height.
Definition: Size.h:45
Point with floating-point X and Y coordinates.
Definition: Point.h:45
Pt::int32_t lround(float x)
Rounds to nearest integer value.
Definition: Math.h:289
Gfx::PointF align(const Gfx::PointF &p) const
Aligns a point to physical pixels.
Definition: Scaling.h:171
double align(double n) const
Aligns a scalar value to the nearest physical pixel.
Definition: Scaling.h:138
void setScaleFactor(double scaleFactor)
Sets the scale factor.
Definition: Scaling.h:69
double toPhysical(double n) const
Converts a scalar value to physical units.
Definition: Scaling.h:77
Gfx::PointF toLogical(const Gfx::PointF &p) const
Converts a point to logical units.
Definition: Scaling.h:114
Scaling(double scaleFactor=1.0)
Constructs a scaling with the given factor.
Definition: Scaling.h:56
Gfx::SizeF toLogical(const Gfx::SizeF &s) const
Converts a size to logical units.
Definition: Scaling.h:121
double toLogical(double n) const
Converts a scalar value to logical units.
Definition: Scaling.h:107
Gfx::RectF toLogical(const Gfx::RectF &r) const
Converts a rectangle to logical units.
Definition: Scaling.h:128
Gfx::PointF toPhysical(const Gfx::PointF &p) const
Converts a point to physical units.
Definition: Scaling.h:84
Rect with floating-point coordinates.
Definition: Rect.h:45
Gfx::RectF align(const Gfx::RectF &rect) const
Aligns a rectangle to physical pixels.
Definition: Scaling.h:191
double alignPixel(double n) const
Aligns a scalar value to a pixel center.
Definition: Scaling.h:149
Gfx::SizeF toPhysical(const Gfx::SizeF &s) const
Converts a size to physical units.
Definition: Scaling.h:91