1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
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.
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
25 #include "agg_trans_affine.h"
39 //----------------------------------------------------------trans_viewport
43 //-------------------------------------------------------------------
53 m_aspect(aspect_ratio_stretch
),
67 //-------------------------------------------------------------------
68 void preserve_aspect_ratio(double alignx
,
70 aspect_ratio_e aspect
)
78 //-------------------------------------------------------------------
79 void device_viewport(double x1
, double y1
, double x2
, double y2
)
88 //-------------------------------------------------------------------
89 void world_viewport(double x1
, double y1
, double x2
, double y2
)
98 //-------------------------------------------------------------------
99 void device_viewport(double* x1
, double* y1
, double* x2
, double* y2
) const
107 //-------------------------------------------------------------------
108 void world_viewport(double* x1
, double* y1
, double* x2
, double* y2
) const
116 //-------------------------------------------------------------------
117 void world_viewport_actual(double* x1
, double* y1
,
118 double* x2
, double* y2
) const
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
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
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
170 //-------------------------------------------------------------------
171 double scale_y() const
176 //-------------------------------------------------------------------
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
);
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));
224 aspect_ratio_e m_aspect
;
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
)
251 m_wx2
= m_world_x1
+ 1.0;
252 m_wy2
= m_world_y2
+ 1.0;
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
)
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
;
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
;
294 m_kx
= (device_x2
- device_x1
) / (world_x2
- world_x1
);
295 m_ky
= (device_y2
- device_y1
) / (world_y2
- world_y1
);