xref: /haiku/headers/libs/agg/agg_trans_viewport.h (revision 2e7da8455a92f61db667fdaf602308344c4426d6)
139241fe2SDarkWyrm //----------------------------------------------------------------------------
2*e39da397SStephan Aßmus // Anti-Grain Geometry - Version 2.4
3*e39da397SStephan Aßmus // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
439241fe2SDarkWyrm //
539241fe2SDarkWyrm // Permission to copy, use, modify, sell and distribute this software
639241fe2SDarkWyrm // is granted provided this copyright notice appears in all copies.
739241fe2SDarkWyrm // This software is provided "as is" without express or implied
839241fe2SDarkWyrm // warranty, and with no claim as to its suitability for any purpose.
939241fe2SDarkWyrm //
1039241fe2SDarkWyrm //----------------------------------------------------------------------------
1139241fe2SDarkWyrm // Contact: mcseem@antigrain.com
1239241fe2SDarkWyrm //          mcseemagg@yahoo.com
1339241fe2SDarkWyrm //          http://www.antigrain.com
1439241fe2SDarkWyrm //----------------------------------------------------------------------------
1539241fe2SDarkWyrm //
1639241fe2SDarkWyrm // Viewport transformer - simple orthogonal conversions from world coordinates
1739241fe2SDarkWyrm //                        to screen (device) ones.
1839241fe2SDarkWyrm //
1939241fe2SDarkWyrm //----------------------------------------------------------------------------
2039241fe2SDarkWyrm 
2139241fe2SDarkWyrm #ifndef AGG_TRANS_VIEWPORT_INCLUDED
2239241fe2SDarkWyrm #define AGG_TRANS_VIEWPORT_INCLUDED
2339241fe2SDarkWyrm 
2439241fe2SDarkWyrm #include <string.h>
25*e39da397SStephan Aßmus #include "agg_trans_affine.h"
2639241fe2SDarkWyrm 
2739241fe2SDarkWyrm 
2839241fe2SDarkWyrm namespace agg
2939241fe2SDarkWyrm {
3039241fe2SDarkWyrm 
3139241fe2SDarkWyrm     enum aspect_ratio_e
3239241fe2SDarkWyrm     {
3339241fe2SDarkWyrm         aspect_ratio_stretch,
3439241fe2SDarkWyrm         aspect_ratio_meet,
3539241fe2SDarkWyrm         aspect_ratio_slice
3639241fe2SDarkWyrm     };
3739241fe2SDarkWyrm 
3839241fe2SDarkWyrm 
3939241fe2SDarkWyrm     //----------------------------------------------------------trans_viewport
4039241fe2SDarkWyrm     class trans_viewport
4139241fe2SDarkWyrm     {
4239241fe2SDarkWyrm     public:
4339241fe2SDarkWyrm         //-------------------------------------------------------------------
trans_viewport()4439241fe2SDarkWyrm         trans_viewport() :
4539241fe2SDarkWyrm             m_world_x1(0.0),
4639241fe2SDarkWyrm             m_world_y1(0.0),
4739241fe2SDarkWyrm             m_world_x2(1.0),
4839241fe2SDarkWyrm             m_world_y2(1.0),
4939241fe2SDarkWyrm             m_device_x1(0.0),
5039241fe2SDarkWyrm             m_device_y1(0.0),
5139241fe2SDarkWyrm             m_device_x2(1.0),
5239241fe2SDarkWyrm             m_device_y2(1.0),
5339241fe2SDarkWyrm             m_aspect(aspect_ratio_stretch),
54*e39da397SStephan Aßmus             m_is_valid(true),
5539241fe2SDarkWyrm             m_align_x(0.5),
5639241fe2SDarkWyrm             m_align_y(0.5),
5739241fe2SDarkWyrm             m_wx1(0.0),
5839241fe2SDarkWyrm             m_wy1(0.0),
5939241fe2SDarkWyrm             m_wx2(1.0),
6039241fe2SDarkWyrm             m_wy2(1.0),
6139241fe2SDarkWyrm             m_dx1(0.0),
6239241fe2SDarkWyrm             m_dy1(0.0),
6339241fe2SDarkWyrm             m_kx(1.0),
6439241fe2SDarkWyrm             m_ky(1.0)
6539241fe2SDarkWyrm         {}
6639241fe2SDarkWyrm 
6739241fe2SDarkWyrm         //-------------------------------------------------------------------
preserve_aspect_ratio(double alignx,double aligny,aspect_ratio_e aspect)6839241fe2SDarkWyrm         void preserve_aspect_ratio(double alignx,
6939241fe2SDarkWyrm                                    double aligny,
7039241fe2SDarkWyrm                                    aspect_ratio_e aspect)
7139241fe2SDarkWyrm         {
7239241fe2SDarkWyrm             m_align_x = alignx;
7339241fe2SDarkWyrm             m_align_y = aligny;
7439241fe2SDarkWyrm             m_aspect  = aspect;
7539241fe2SDarkWyrm             update();
7639241fe2SDarkWyrm         }
7739241fe2SDarkWyrm 
7839241fe2SDarkWyrm         //-------------------------------------------------------------------
device_viewport(double x1,double y1,double x2,double y2)7939241fe2SDarkWyrm         void device_viewport(double x1, double y1, double x2, double y2)
8039241fe2SDarkWyrm         {
8139241fe2SDarkWyrm             m_device_x1 = x1;
8239241fe2SDarkWyrm             m_device_y1 = y1;
8339241fe2SDarkWyrm             m_device_x2 = x2;
8439241fe2SDarkWyrm             m_device_y2 = y2;
8539241fe2SDarkWyrm             update();
8639241fe2SDarkWyrm         }
8739241fe2SDarkWyrm 
8839241fe2SDarkWyrm         //-------------------------------------------------------------------
world_viewport(double x1,double y1,double x2,double y2)8939241fe2SDarkWyrm         void world_viewport(double x1, double y1, double x2, double y2)
9039241fe2SDarkWyrm         {
9139241fe2SDarkWyrm             m_world_x1 = x1;
9239241fe2SDarkWyrm             m_world_y1 = y1;
9339241fe2SDarkWyrm             m_world_x2 = x2;
9439241fe2SDarkWyrm             m_world_y2 = y2;
9539241fe2SDarkWyrm             update();
9639241fe2SDarkWyrm         }
9739241fe2SDarkWyrm 
9839241fe2SDarkWyrm         //-------------------------------------------------------------------
device_viewport(double * x1,double * y1,double * x2,double * y2)9939241fe2SDarkWyrm         void device_viewport(double* x1, double* y1, double* x2, double* y2) const
10039241fe2SDarkWyrm         {
10139241fe2SDarkWyrm             *x1 = m_device_x1;
10239241fe2SDarkWyrm             *y1 = m_device_y1;
10339241fe2SDarkWyrm             *x2 = m_device_x2;
10439241fe2SDarkWyrm             *y2 = m_device_y2;
10539241fe2SDarkWyrm         }
10639241fe2SDarkWyrm 
10739241fe2SDarkWyrm         //-------------------------------------------------------------------
world_viewport(double * x1,double * y1,double * x2,double * y2)10839241fe2SDarkWyrm         void world_viewport(double* x1, double* y1, double* x2, double* y2) const
10939241fe2SDarkWyrm         {
11039241fe2SDarkWyrm             *x1 = m_world_x1;
11139241fe2SDarkWyrm             *y1 = m_world_y1;
11239241fe2SDarkWyrm             *x2 = m_world_x2;
11339241fe2SDarkWyrm             *y2 = m_world_y2;
11439241fe2SDarkWyrm         }
11539241fe2SDarkWyrm 
11639241fe2SDarkWyrm         //-------------------------------------------------------------------
world_viewport_actual(double * x1,double * y1,double * x2,double * y2)11739241fe2SDarkWyrm         void world_viewport_actual(double* x1, double* y1,
11839241fe2SDarkWyrm                                    double* x2, double* y2) const
11939241fe2SDarkWyrm         {
12039241fe2SDarkWyrm             *x1 = m_wx1;
12139241fe2SDarkWyrm             *y1 = m_wy1;
12239241fe2SDarkWyrm             *x2 = m_wx2;
12339241fe2SDarkWyrm             *y2 = m_wy2;
12439241fe2SDarkWyrm         }
12539241fe2SDarkWyrm 
12639241fe2SDarkWyrm         //-------------------------------------------------------------------
is_valid()127*e39da397SStephan Aßmus         bool   is_valid()             const { return m_is_valid; }
align_x()12839241fe2SDarkWyrm         double align_x()              const { return m_align_x; }
align_y()12939241fe2SDarkWyrm         double align_y()              const { return m_align_y; }
aspect_ratio()13039241fe2SDarkWyrm         aspect_ratio_e aspect_ratio() const { return m_aspect; }
13139241fe2SDarkWyrm 
13239241fe2SDarkWyrm         //-------------------------------------------------------------------
transform(double * x,double * y)13339241fe2SDarkWyrm         void transform(double* x, double* y) const
13439241fe2SDarkWyrm         {
13539241fe2SDarkWyrm             *x = (*x - m_wx1) * m_kx + m_dx1;
13639241fe2SDarkWyrm             *y = (*y - m_wy1) * m_ky + m_dy1;
13739241fe2SDarkWyrm         }
13839241fe2SDarkWyrm 
13939241fe2SDarkWyrm         //-------------------------------------------------------------------
transform_scale_only(double * x,double * y)140*e39da397SStephan Aßmus         void transform_scale_only(double* x, double* y) const
141*e39da397SStephan Aßmus         {
142*e39da397SStephan Aßmus             *x *= m_kx;
143*e39da397SStephan Aßmus             *y *= m_ky;
144*e39da397SStephan Aßmus         }
145*e39da397SStephan Aßmus 
146*e39da397SStephan Aßmus         //-------------------------------------------------------------------
inverse_transform(double * x,double * y)14739241fe2SDarkWyrm         void inverse_transform(double* x, double* y) const
14839241fe2SDarkWyrm         {
14939241fe2SDarkWyrm             *x = (*x - m_dx1) / m_kx + m_wx1;
15039241fe2SDarkWyrm             *y = (*y - m_dy1) / m_ky + m_wy1;
15139241fe2SDarkWyrm         }
15239241fe2SDarkWyrm 
15339241fe2SDarkWyrm         //-------------------------------------------------------------------
inverse_transform_scale_only(double * x,double * y)154*e39da397SStephan Aßmus         void inverse_transform_scale_only(double* x, double* y) const
155*e39da397SStephan Aßmus         {
156*e39da397SStephan Aßmus             *x /= m_kx;
157*e39da397SStephan Aßmus             *y /= m_ky;
158*e39da397SStephan Aßmus         }
159*e39da397SStephan Aßmus 
160*e39da397SStephan Aßmus         //-------------------------------------------------------------------
device_dx()161*e39da397SStephan Aßmus         double device_dx() const { return m_dx1 - m_wx1 * m_kx; }
device_dy()162*e39da397SStephan Aßmus         double device_dy() const { return m_dy1 - m_wy1 * m_ky; }
163*e39da397SStephan Aßmus 
164*e39da397SStephan Aßmus         //-------------------------------------------------------------------
scale_x()165abd00302SDarkWyrm         double scale_x() const
166abd00302SDarkWyrm         {
167abd00302SDarkWyrm             return m_kx;
168abd00302SDarkWyrm         }
169abd00302SDarkWyrm 
170abd00302SDarkWyrm         //-------------------------------------------------------------------
scale_y()171abd00302SDarkWyrm         double scale_y() const
172abd00302SDarkWyrm         {
173abd00302SDarkWyrm             return m_ky;
174abd00302SDarkWyrm         }
175abd00302SDarkWyrm 
176abd00302SDarkWyrm         //-------------------------------------------------------------------
scale()17739241fe2SDarkWyrm         double scale() const
17839241fe2SDarkWyrm         {
17939241fe2SDarkWyrm             return (m_kx + m_ky) * 0.5;
18039241fe2SDarkWyrm         }
18139241fe2SDarkWyrm 
182*e39da397SStephan Aßmus         //-------------------------------------------------------------------
to_affine()183*e39da397SStephan Aßmus         trans_affine to_affine() const
184*e39da397SStephan Aßmus         {
185*e39da397SStephan Aßmus             trans_affine mtx = trans_affine_translation(-m_wx1, -m_wy1);
186*e39da397SStephan Aßmus             mtx *= trans_affine_scaling(m_kx, m_ky);
187*e39da397SStephan Aßmus             mtx *= trans_affine_translation(m_dx1, m_dy1);
188*e39da397SStephan Aßmus             return mtx;
189*e39da397SStephan Aßmus         }
190*e39da397SStephan Aßmus 
191*e39da397SStephan Aßmus         //-------------------------------------------------------------------
to_affine_scale_only()192*e39da397SStephan Aßmus         trans_affine to_affine_scale_only() const
193*e39da397SStephan Aßmus         {
194*e39da397SStephan Aßmus             return trans_affine_scaling(m_kx, m_ky);
195*e39da397SStephan Aßmus         }
196abd00302SDarkWyrm 
19739241fe2SDarkWyrm         //-------------------------------------------------------------------
byte_size()19839241fe2SDarkWyrm         unsigned byte_size() const
19939241fe2SDarkWyrm         {
200*e39da397SStephan Aßmus             return sizeof(*this);
20139241fe2SDarkWyrm         }
20239241fe2SDarkWyrm 
serialize(int8u * ptr)20339241fe2SDarkWyrm         void serialize(int8u* ptr) const
20439241fe2SDarkWyrm         {
205*e39da397SStephan Aßmus             memcpy(ptr, this, sizeof(*this));
20639241fe2SDarkWyrm         }
20739241fe2SDarkWyrm 
deserialize(const int8u * ptr)20839241fe2SDarkWyrm         void deserialize(const int8u* ptr)
20939241fe2SDarkWyrm         {
210*e39da397SStephan Aßmus             memcpy(this,  ptr, sizeof(*this));
21139241fe2SDarkWyrm         }
21239241fe2SDarkWyrm 
21339241fe2SDarkWyrm     private:
21439241fe2SDarkWyrm         void update();
21539241fe2SDarkWyrm 
21639241fe2SDarkWyrm         double         m_world_x1;
21739241fe2SDarkWyrm         double         m_world_y1;
21839241fe2SDarkWyrm         double         m_world_x2;
21939241fe2SDarkWyrm         double         m_world_y2;
22039241fe2SDarkWyrm         double         m_device_x1;
22139241fe2SDarkWyrm         double         m_device_y1;
22239241fe2SDarkWyrm         double         m_device_x2;
22339241fe2SDarkWyrm         double         m_device_y2;
22439241fe2SDarkWyrm         aspect_ratio_e m_aspect;
225*e39da397SStephan Aßmus         bool           m_is_valid;
22639241fe2SDarkWyrm         double         m_align_x;
22739241fe2SDarkWyrm         double         m_align_y;
22839241fe2SDarkWyrm         double         m_wx1;
22939241fe2SDarkWyrm         double         m_wy1;
23039241fe2SDarkWyrm         double         m_wx2;
23139241fe2SDarkWyrm         double         m_wy2;
23239241fe2SDarkWyrm         double         m_dx1;
23339241fe2SDarkWyrm         double         m_dy1;
23439241fe2SDarkWyrm         double         m_kx;
23539241fe2SDarkWyrm         double         m_ky;
23639241fe2SDarkWyrm     };
23739241fe2SDarkWyrm 
23839241fe2SDarkWyrm 
23939241fe2SDarkWyrm 
24039241fe2SDarkWyrm     //-----------------------------------------------------------------------
update()24139241fe2SDarkWyrm     inline void trans_viewport::update()
24239241fe2SDarkWyrm     {
243*e39da397SStephan Aßmus         const double epsilon = 1e-30;
244*e39da397SStephan Aßmus         if(fabs(m_world_x1  - m_world_x2)  < epsilon ||
245*e39da397SStephan Aßmus            fabs(m_world_y1  - m_world_y2)  < epsilon ||
246*e39da397SStephan Aßmus            fabs(m_device_x1 - m_device_x2) < epsilon ||
247*e39da397SStephan Aßmus            fabs(m_device_y1 - m_device_y2) < epsilon)
248*e39da397SStephan Aßmus         {
249*e39da397SStephan Aßmus             m_wx1 = m_world_x1;
250*e39da397SStephan Aßmus             m_wy1 = m_world_y1;
251*e39da397SStephan Aßmus             m_wx2 = m_world_x1 + 1.0;
252*e39da397SStephan Aßmus             m_wy2 = m_world_y2 + 1.0;
253*e39da397SStephan Aßmus             m_dx1 = m_device_x1;
254*e39da397SStephan Aßmus             m_dy1 = m_device_y1;
255*e39da397SStephan Aßmus             m_kx  = 1.0;
256*e39da397SStephan Aßmus             m_ky  = 1.0;
257*e39da397SStephan Aßmus             m_is_valid = false;
258*e39da397SStephan Aßmus             return;
259*e39da397SStephan Aßmus         }
260*e39da397SStephan Aßmus 
26139241fe2SDarkWyrm         double world_x1  = m_world_x1;
26239241fe2SDarkWyrm         double world_y1  = m_world_y1;
26339241fe2SDarkWyrm         double world_x2  = m_world_x2;
26439241fe2SDarkWyrm         double world_y2  = m_world_y2;
26539241fe2SDarkWyrm         double device_x1 = m_device_x1;
26639241fe2SDarkWyrm         double device_y1 = m_device_y1;
26739241fe2SDarkWyrm         double device_x2 = m_device_x2;
26839241fe2SDarkWyrm         double device_y2 = m_device_y2;
26939241fe2SDarkWyrm         if(m_aspect != aspect_ratio_stretch)
27039241fe2SDarkWyrm         {
27139241fe2SDarkWyrm             double d;
27239241fe2SDarkWyrm             m_kx = (device_x2 - device_x1) / (world_x2 - world_x1);
27339241fe2SDarkWyrm             m_ky = (device_y2 - device_y1) / (world_y2 - world_y1);
27439241fe2SDarkWyrm 
27539241fe2SDarkWyrm             if((m_aspect == aspect_ratio_meet) == (m_kx < m_ky))
27639241fe2SDarkWyrm             {
27739241fe2SDarkWyrm                 d         = (world_y2 - world_y1) * m_ky / m_kx;
27839241fe2SDarkWyrm                 world_y1 += (world_y2 - world_y1 - d) * m_align_y;
27939241fe2SDarkWyrm                 world_y2  =  world_y1 + d;
28039241fe2SDarkWyrm             }
28139241fe2SDarkWyrm             else
28239241fe2SDarkWyrm             {
28339241fe2SDarkWyrm                 d         = (world_x2 - world_x1) * m_kx / m_ky;
28439241fe2SDarkWyrm                 world_x1 += (world_x2 - world_x1 - d) * m_align_x;
28539241fe2SDarkWyrm                 world_x2  =  world_x1 + d;
28639241fe2SDarkWyrm             }
28739241fe2SDarkWyrm         }
28839241fe2SDarkWyrm         m_wx1 = world_x1;
28939241fe2SDarkWyrm         m_wy1 = world_y1;
29039241fe2SDarkWyrm         m_wx2 = world_x2;
29139241fe2SDarkWyrm         m_wy2 = world_y2;
29239241fe2SDarkWyrm         m_dx1 = device_x1;
29339241fe2SDarkWyrm         m_dy1 = device_y1;
29439241fe2SDarkWyrm         m_kx  = (device_x2 - device_x1) / (world_x2 - world_x1);
29539241fe2SDarkWyrm         m_ky  = (device_y2 - device_y1) / (world_y2 - world_y1);
296*e39da397SStephan Aßmus         m_is_valid = true;
29739241fe2SDarkWyrm     }
29839241fe2SDarkWyrm 
29939241fe2SDarkWyrm 
30039241fe2SDarkWyrm }
30139241fe2SDarkWyrm 
30239241fe2SDarkWyrm 
30339241fe2SDarkWyrm #endif
304