xref: /haiku/headers/libs/agg/agg_span_interpolator_linear.h (revision c90684742e7361651849be4116d0e5de3a817194)
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 //----------------------------------------------------------------------------
15 
16 #ifndef AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED
17 #define AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED
18 
19 #include "agg_basics.h"
20 #include "agg_dda_line.h"
21 #include "agg_trans_affine.h"
22 
23 namespace agg
24 {
25 
26     //================================================span_interpolator_linear
27     template<class Transformer = trans_affine, unsigned SubpixelShift = 8>
28     class span_interpolator_linear
29     {
30     public:
31         typedef Transformer trans_type;
32 
33         enum subpixel_scale_e
34         {
35             subpixel_shift = SubpixelShift,
36             subpixel_scale  = 1 << subpixel_shift
37         };
38 
39         //--------------------------------------------------------------------
40         span_interpolator_linear() {}
41         span_interpolator_linear(const trans_type& trans) : m_trans(&trans) {}
42         span_interpolator_linear(const trans_type& trans,
43                                  double x, double y, unsigned len) :
44             m_trans(&trans)
45         {
46             begin(x, y, len);
47         }
48 
49         //----------------------------------------------------------------
50         const trans_type& transformer() const { return *m_trans; }
51         void transformer(const trans_type& trans) { m_trans = &trans; }
52 
53         //----------------------------------------------------------------
54         void begin(double x, double y, unsigned len)
55         {
56             double tx;
57             double ty;
58 
59             tx = x;
60             ty = y;
61             m_trans->transform(&tx, &ty);
62             int x1 = iround(tx * subpixel_scale);
63             int y1 = iround(ty * subpixel_scale);
64 
65             tx = x + len;
66             ty = y;
67             m_trans->transform(&tx, &ty);
68             int x2 = iround(tx * subpixel_scale);
69             int y2 = iround(ty * subpixel_scale);
70 
71             m_li_x = dda2_line_interpolator(x1, x2, len);
72             m_li_y = dda2_line_interpolator(y1, y2, len);
73         }
74 
75         //----------------------------------------------------------------
76         void resynchronize(double xe, double ye, unsigned len)
77         {
78             m_trans->transform(&xe, &ye);
79             m_li_x = dda2_line_interpolator(m_li_x.y(), iround(xe * subpixel_scale), len);
80             m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ye * subpixel_scale), len);
81         }
82 
83         //----------------------------------------------------------------
84         void operator++()
85         {
86             ++m_li_x;
87             ++m_li_y;
88         }
89 
90         //----------------------------------------------------------------
91         void coordinates(int* x, int* y) const
92         {
93             *x = m_li_x.y();
94             *y = m_li_y.y();
95         }
96 
97     private:
98         const trans_type* m_trans;
99         dda2_line_interpolator m_li_x;
100         dda2_line_interpolator m_li_y;
101     };
102 
103 
104 
105 
106 
107 
108     //=====================================span_interpolator_linear_subdiv
109     template<class Transformer = trans_affine, unsigned SubpixelShift = 8>
110     class span_interpolator_linear_subdiv
111     {
112     public:
113         typedef Transformer trans_type;
114 
115         enum subpixel_scale_e
116         {
117             subpixel_shift = SubpixelShift,
118             subpixel_scale = 1 << subpixel_shift
119         };
120 
121 
122         //----------------------------------------------------------------
123         span_interpolator_linear_subdiv() :
124             m_subdiv_shift(4),
125             m_subdiv_size(1 << m_subdiv_shift),
126             m_subdiv_mask(m_subdiv_size - 1) {}
127 
128         span_interpolator_linear_subdiv(const trans_type& trans,
129                                         unsigned subdiv_shift = 4) :
130             m_subdiv_shift(subdiv_shift),
131             m_subdiv_size(1 << m_subdiv_shift),
132             m_subdiv_mask(m_subdiv_size - 1),
133             m_trans(&trans) {}
134 
135         span_interpolator_linear_subdiv(const trans_type& trans,
136                                         double x, double y, unsigned len,
137                                         unsigned subdiv_shift = 4) :
138             m_subdiv_shift(subdiv_shift),
139             m_subdiv_size(1 << m_subdiv_shift),
140             m_subdiv_mask(m_subdiv_size - 1),
141             m_trans(&trans)
142         {
143             begin(x, y, len);
144         }
145 
146         //----------------------------------------------------------------
147         const trans_type& transformer() const { return *m_trans; }
148         void transformer(const trans_type& trans) { m_trans = &trans; }
149 
150         //----------------------------------------------------------------
151         unsigned subdiv_shift() const { return m_subdiv_shift; }
152         void subdiv_shift(unsigned shift)
153         {
154             m_subdiv_shift = shift;
155             m_subdiv_size = 1 << m_subdiv_shift;
156             m_subdiv_mask = m_subdiv_size - 1;
157         }
158 
159         //----------------------------------------------------------------
160         void begin(double x, double y, unsigned len)
161         {
162             double tx;
163             double ty;
164             m_pos   = 1;
165             m_src_x = iround(x * subpixel_scale) + subpixel_scale;
166             m_src_y = y;
167             m_len   = len;
168 
169             if(len > m_subdiv_size) len = m_subdiv_size;
170             tx = x;
171             ty = y;
172             m_trans->transform(&tx, &ty);
173             int x1 = iround(tx * subpixel_scale);
174             int y1 = iround(ty * subpixel_scale);
175 
176             tx = x + len;
177             ty = y;
178             m_trans->transform(&tx, &ty);
179 
180             m_li_x = dda2_line_interpolator(x1, iround(tx * subpixel_scale), len);
181             m_li_y = dda2_line_interpolator(y1, iround(ty * subpixel_scale), len);
182         }
183 
184         //----------------------------------------------------------------
185         void operator++()
186         {
187             ++m_li_x;
188             ++m_li_y;
189             if(m_pos >= m_subdiv_size)
190             {
191                 unsigned len = m_len;
192                 if(len > m_subdiv_size) len = m_subdiv_size;
193                 double tx = double(m_src_x) / double(subpixel_scale) + len;
194                 double ty = m_src_y;
195                 m_trans->transform(&tx, &ty);
196                 m_li_x = dda2_line_interpolator(m_li_x.y(), iround(tx * subpixel_scale), len);
197                 m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ty * subpixel_scale), len);
198                 m_pos = 0;
199             }
200             m_src_x += subpixel_scale;
201             ++m_pos;
202             --m_len;
203         }
204 
205         //----------------------------------------------------------------
206         void coordinates(int* x, int* y) const
207         {
208             *x = m_li_x.y();
209             *y = m_li_y.y();
210         }
211 
212     private:
213         unsigned m_subdiv_shift;
214         unsigned m_subdiv_size;
215         unsigned m_subdiv_mask;
216         const trans_type* m_trans;
217         dda2_line_interpolator m_li_x;
218         dda2_line_interpolator m_li_y;
219         int      m_src_x;
220         double   m_src_y;
221         unsigned m_pos;
222         unsigned m_len;
223     };
224 
225 
226 }
227 
228 
229 
230 #endif
231 
232 
233