Make UEFI boot-platform build again
[haiku.git] / headers / libs / agg / agg_trans_viewport.h
blob7088f990780e7f91c386f6758b41d48935863969
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
16 // Viewport transformer - simple orthogonal conversions from world coordinates
17 // to screen (device) ones.
19 //----------------------------------------------------------------------------
21 #ifndef AGG_TRANS_VIEWPORT_INCLUDED
22 #define AGG_TRANS_VIEWPORT_INCLUDED
24 #include <string.h>
25 #include "agg_trans_affine.h"
28 namespace agg
31 enum aspect_ratio_e
33 aspect_ratio_stretch,
34 aspect_ratio_meet,
35 aspect_ratio_slice
39 //----------------------------------------------------------trans_viewport
40 class trans_viewport
42 public:
43 //-------------------------------------------------------------------
44 trans_viewport() :
45 m_world_x1(0.0),
46 m_world_y1(0.0),
47 m_world_x2(1.0),
48 m_world_y2(1.0),
49 m_device_x1(0.0),
50 m_device_y1(0.0),
51 m_device_x2(1.0),
52 m_device_y2(1.0),
53 m_aspect(aspect_ratio_stretch),
54 m_is_valid(true),
55 m_align_x(0.5),
56 m_align_y(0.5),
57 m_wx1(0.0),
58 m_wy1(0.0),
59 m_wx2(1.0),
60 m_wy2(1.0),
61 m_dx1(0.0),
62 m_dy1(0.0),
63 m_kx(1.0),
64 m_ky(1.0)
67 //-------------------------------------------------------------------
68 void preserve_aspect_ratio(double alignx,
69 double aligny,
70 aspect_ratio_e aspect)
72 m_align_x = alignx;
73 m_align_y = aligny;
74 m_aspect = aspect;
75 update();
78 //-------------------------------------------------------------------
79 void device_viewport(double x1, double y1, double x2, double y2)
81 m_device_x1 = x1;
82 m_device_y1 = y1;
83 m_device_x2 = x2;
84 m_device_y2 = y2;
85 update();
88 //-------------------------------------------------------------------
89 void world_viewport(double x1, double y1, double x2, double y2)
91 m_world_x1 = x1;
92 m_world_y1 = y1;
93 m_world_x2 = x2;
94 m_world_y2 = y2;
95 update();
98 //-------------------------------------------------------------------
99 void device_viewport(double* x1, double* y1, double* x2, double* y2) const
101 *x1 = m_device_x1;
102 *y1 = m_device_y1;
103 *x2 = m_device_x2;
104 *y2 = m_device_y2;
107 //-------------------------------------------------------------------
108 void world_viewport(double* x1, double* y1, double* x2, double* y2) const
110 *x1 = m_world_x1;
111 *y1 = m_world_y1;
112 *x2 = m_world_x2;
113 *y2 = m_world_y2;
116 //-------------------------------------------------------------------
117 void world_viewport_actual(double* x1, double* y1,
118 double* x2, double* y2) const
120 *x1 = m_wx1;
121 *y1 = m_wy1;
122 *x2 = m_wx2;
123 *y2 = m_wy2;
126 //-------------------------------------------------------------------
127 bool is_valid() const { return m_is_valid; }
128 double align_x() const { return m_align_x; }
129 double align_y() const { return m_align_y; }
130 aspect_ratio_e aspect_ratio() const { return m_aspect; }
132 //-------------------------------------------------------------------
133 void transform(double* x, double* y) const
135 *x = (*x - m_wx1) * m_kx + m_dx1;
136 *y = (*y - m_wy1) * m_ky + m_dy1;
139 //-------------------------------------------------------------------
140 void transform_scale_only(double* x, double* y) const
142 *x *= m_kx;
143 *y *= m_ky;
146 //-------------------------------------------------------------------
147 void inverse_transform(double* x, double* y) const
149 *x = (*x - m_dx1) / m_kx + m_wx1;
150 *y = (*y - m_dy1) / m_ky + m_wy1;
153 //-------------------------------------------------------------------
154 void inverse_transform_scale_only(double* x, double* y) const
156 *x /= m_kx;
157 *y /= m_ky;
160 //-------------------------------------------------------------------
161 double device_dx() const { return m_dx1 - m_wx1 * m_kx; }
162 double device_dy() const { return m_dy1 - m_wy1 * m_ky; }
164 //-------------------------------------------------------------------
165 double scale_x() const
167 return m_kx;
170 //-------------------------------------------------------------------
171 double scale_y() const
173 return m_ky;
176 //-------------------------------------------------------------------
177 double scale() const
179 return (m_kx + m_ky) * 0.5;
182 //-------------------------------------------------------------------
183 trans_affine to_affine() const
185 trans_affine mtx = trans_affine_translation(-m_wx1, -m_wy1);
186 mtx *= trans_affine_scaling(m_kx, m_ky);
187 mtx *= trans_affine_translation(m_dx1, m_dy1);
188 return mtx;
191 //-------------------------------------------------------------------
192 trans_affine to_affine_scale_only() const
194 return trans_affine_scaling(m_kx, m_ky);
197 //-------------------------------------------------------------------
198 unsigned byte_size() const
200 return sizeof(*this);
203 void serialize(int8u* ptr) const
205 memcpy(ptr, this, sizeof(*this));
208 void deserialize(const int8u* ptr)
210 memcpy(this, ptr, sizeof(*this));
213 private:
214 void update();
216 double m_world_x1;
217 double m_world_y1;
218 double m_world_x2;
219 double m_world_y2;
220 double m_device_x1;
221 double m_device_y1;
222 double m_device_x2;
223 double m_device_y2;
224 aspect_ratio_e m_aspect;
225 bool m_is_valid;
226 double m_align_x;
227 double m_align_y;
228 double m_wx1;
229 double m_wy1;
230 double m_wx2;
231 double m_wy2;
232 double m_dx1;
233 double m_dy1;
234 double m_kx;
235 double m_ky;
240 //-----------------------------------------------------------------------
241 inline void trans_viewport::update()
243 const double epsilon = 1e-30;
244 if(fabs(m_world_x1 - m_world_x2) < epsilon ||
245 fabs(m_world_y1 - m_world_y2) < epsilon ||
246 fabs(m_device_x1 - m_device_x2) < epsilon ||
247 fabs(m_device_y1 - m_device_y2) < epsilon)
249 m_wx1 = m_world_x1;
250 m_wy1 = m_world_y1;
251 m_wx2 = m_world_x1 + 1.0;
252 m_wy2 = m_world_y2 + 1.0;
253 m_dx1 = m_device_x1;
254 m_dy1 = m_device_y1;
255 m_kx = 1.0;
256 m_ky = 1.0;
257 m_is_valid = false;
258 return;
261 double world_x1 = m_world_x1;
262 double world_y1 = m_world_y1;
263 double world_x2 = m_world_x2;
264 double world_y2 = m_world_y2;
265 double device_x1 = m_device_x1;
266 double device_y1 = m_device_y1;
267 double device_x2 = m_device_x2;
268 double device_y2 = m_device_y2;
269 if(m_aspect != aspect_ratio_stretch)
271 double d;
272 m_kx = (device_x2 - device_x1) / (world_x2 - world_x1);
273 m_ky = (device_y2 - device_y1) / (world_y2 - world_y1);
275 if((m_aspect == aspect_ratio_meet) == (m_kx < m_ky))
277 d = (world_y2 - world_y1) * m_ky / m_kx;
278 world_y1 += (world_y2 - world_y1 - d) * m_align_y;
279 world_y2 = world_y1 + d;
281 else
283 d = (world_x2 - world_x1) * m_kx / m_ky;
284 world_x1 += (world_x2 - world_x1 - d) * m_align_x;
285 world_x2 = world_x1 + d;
288 m_wx1 = world_x1;
289 m_wy1 = world_y1;
290 m_wx2 = world_x2;
291 m_wy2 = world_y2;
292 m_dx1 = device_x1;
293 m_dy1 = device_y1;
294 m_kx = (device_x2 - device_x1) / (world_x2 - world_x1);
295 m_ky = (device_y2 - device_y1) / (world_y2 - world_y1);
296 m_is_valid = true;
303 #endif