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 #ifndef AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED
17 #define AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED
19 #include "agg_basics.h"
20 #include "agg_dda_line.h"
21 #include "agg_trans_affine.h"
26 //================================================span_interpolator_linear
27 template<class Transformer
= trans_affine
, unsigned SubpixelShift
= 8>
28 class span_interpolator_linear
31 typedef Transformer trans_type
;
35 subpixel_shift
= SubpixelShift
,
36 subpixel_scale
= 1 << subpixel_shift
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
) :
49 //----------------------------------------------------------------
50 const trans_type
& transformer() const { return *m_trans
; }
51 void transformer(const trans_type
& trans
) { m_trans
= &trans
; }
53 //----------------------------------------------------------------
54 void begin(double x
, double y
, unsigned len
)
61 m_trans
->transform(&tx
, &ty
);
62 int x1
= iround(tx
* subpixel_scale
);
63 int y1
= iround(ty
* subpixel_scale
);
67 m_trans
->transform(&tx
, &ty
);
68 int x2
= iround(tx
* subpixel_scale
);
69 int y2
= iround(ty
* subpixel_scale
);
71 m_li_x
= dda2_line_interpolator(x1
, x2
, len
);
72 m_li_y
= dda2_line_interpolator(y1
, y2
, len
);
75 //----------------------------------------------------------------
76 void resynchronize(double xe
, double ye
, unsigned len
)
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
);
83 //----------------------------------------------------------------
90 //----------------------------------------------------------------
91 void coordinates(int* x
, int* y
) const
98 const trans_type
* m_trans
;
99 dda2_line_interpolator m_li_x
;
100 dda2_line_interpolator m_li_y
;
108 //=====================================span_interpolator_linear_subdiv
109 template<class Transformer
= trans_affine
, unsigned SubpixelShift
= 8>
110 class span_interpolator_linear_subdiv
113 typedef Transformer trans_type
;
115 enum subpixel_scale_e
117 subpixel_shift
= SubpixelShift
,
118 subpixel_scale
= 1 << subpixel_shift
122 //----------------------------------------------------------------
123 span_interpolator_linear_subdiv() :
125 m_subdiv_size(1 << m_subdiv_shift
),
126 m_subdiv_mask(m_subdiv_size
- 1) {}
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),
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),
146 //----------------------------------------------------------------
147 const trans_type
& transformer() const { return *m_trans
; }
148 void transformer(const trans_type
& trans
) { m_trans
= &trans
; }
150 //----------------------------------------------------------------
151 unsigned subdiv_shift() const { return m_subdiv_shift
; }
152 void subdiv_shift(unsigned shift
)
154 m_subdiv_shift
= shift
;
155 m_subdiv_size
= 1 << m_subdiv_shift
;
156 m_subdiv_mask
= m_subdiv_size
- 1;
159 //----------------------------------------------------------------
160 void begin(double x
, double y
, unsigned len
)
165 m_src_x
= iround(x
* subpixel_scale
) + subpixel_scale
;
169 if(len
> m_subdiv_size
) len
= m_subdiv_size
;
172 m_trans
->transform(&tx
, &ty
);
173 int x1
= iround(tx
* subpixel_scale
);
174 int y1
= iround(ty
* subpixel_scale
);
178 m_trans
->transform(&tx
, &ty
);
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
);
184 //----------------------------------------------------------------
189 if(m_pos
>= m_subdiv_size
)
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
;
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
);
200 m_src_x
+= subpixel_scale
;
205 //----------------------------------------------------------------
206 void coordinates(int* x
, int* y
) const
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
;