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_IMAGE_ACCESSORS_INCLUDED
17 #define AGG_IMAGE_ACCESSORS_INCLUDED
19 #include "agg_basics.h"
24 //-----------------------------------------------------image_accessor_clip
25 template<class PixFmt
> class image_accessor_clip
28 typedef PixFmt pixfmt_type
;
29 typedef typename
pixfmt_type::color_type color_type
;
30 typedef typename
pixfmt_type::order_type order_type
;
31 typedef typename
pixfmt_type::value_type value_type
;
32 enum pix_width_e
{ pix_width
= pixfmt_type::pix_width
};
34 image_accessor_clip() {}
35 image_accessor_clip(const pixfmt_type
& pixf
, const color_type
& bk
) :
38 pixfmt_type::make_pix(m_bk_buf
, bk
);
41 void attach(const pixfmt_type
& pixf
)
46 void background_color(const color_type
& bk
)
48 pixfmt_type::make_pix(m_bk_buf
, bk
);
52 AGG_INLINE
const int8u
* pixel() const
54 if(m_y
>= 0 && m_y
< (int)m_pixf
->height() &&
55 m_x
>= 0 && m_x
< (int)m_pixf
->width())
57 return m_pixf
->pix_ptr(m_x
, m_y
);
63 AGG_INLINE
const int8u
* span(int x
, int y
, unsigned len
)
67 if(y
>= 0 && y
< (int)m_pixf
->height() &&
68 x
>= 0 && x
+(int)len
<= (int)m_pixf
->width())
70 return m_pix_ptr
= m_pixf
->pix_ptr(x
, y
);
76 AGG_INLINE
const int8u
* next_x()
78 if(m_pix_ptr
) return m_pix_ptr
+= pix_width
;
83 AGG_INLINE
const int8u
* next_y()
88 m_y
>= 0 && m_y
< (int)m_pixf
->height())
90 return m_pix_ptr
= m_pixf
->pix_ptr(m_x
, m_y
);
97 const pixfmt_type
* m_pixf
;
100 const int8u
* m_pix_ptr
;
106 //--------------------------------------------------image_accessor_no_clip
107 template<class PixFmt
> class image_accessor_no_clip
110 typedef PixFmt pixfmt_type
;
111 typedef typename
pixfmt_type::color_type color_type
;
112 typedef typename
pixfmt_type::order_type order_type
;
113 typedef typename
pixfmt_type::value_type value_type
;
114 enum pix_width_e
{ pix_width
= pixfmt_type::pix_width
};
116 image_accessor_no_clip() {}
117 image_accessor_no_clip(const pixfmt_type
& pixf
) : m_pixf(&pixf
) {}
119 void attach(const pixfmt_type
& pixf
)
124 AGG_INLINE
const int8u
* span(int x
, int y
, unsigned)
128 return m_pix_ptr
= m_pixf
->pix_ptr(x
, y
);
131 AGG_INLINE
const int8u
* next_x()
133 return m_pix_ptr
+= pix_width
;
136 AGG_INLINE
const int8u
* next_y()
139 return m_pix_ptr
= m_pixf
->pix_ptr(m_x
, m_y
);
143 const pixfmt_type
* m_pixf
;
145 const int8u
* m_pix_ptr
;
151 //----------------------------------------------------image_accessor_clone
152 template<class PixFmt
> class image_accessor_clone
155 typedef PixFmt pixfmt_type
;
156 typedef typename
pixfmt_type::color_type color_type
;
157 typedef typename
pixfmt_type::order_type order_type
;
158 typedef typename
pixfmt_type::value_type value_type
;
159 enum pix_width_e
{ pix_width
= pixfmt_type::pix_width
};
161 image_accessor_clone() {}
162 image_accessor_clone(const pixfmt_type
& pixf
) : m_pixf(&pixf
) {}
164 void attach(const pixfmt_type
& pixf
)
170 AGG_INLINE
const int8u
* pixel() const
172 register int x
= m_x
;
173 register int y
= m_y
;
176 if(x
>= (int)m_pixf
->width()) x
= m_pixf
->width() - 1;
177 if(y
>= (int)m_pixf
->height()) y
= m_pixf
->height() - 1;
178 return m_pixf
->pix_ptr(x
, y
);
182 AGG_INLINE
const int8u
* span(int x
, int y
, unsigned len
)
186 if(y
>= 0 && y
< (int)m_pixf
->height() &&
187 x
>= 0 && (int)(x
+len
) <= (int)m_pixf
->width())
189 return m_pix_ptr
= m_pixf
->pix_ptr(x
, y
);
195 AGG_INLINE
const int8u
* next_x()
197 if(m_pix_ptr
) return m_pix_ptr
+= pix_width
;
202 AGG_INLINE
const int8u
* next_y()
207 m_y
>= 0 && m_y
< (int)m_pixf
->height())
209 return m_pix_ptr
= m_pixf
->pix_ptr(m_x
, m_y
);
216 const pixfmt_type
* m_pixf
;
218 const int8u
* m_pix_ptr
;
225 //-----------------------------------------------------image_accessor_wrap
226 template<class PixFmt
, class WrapX
, class WrapY
> class image_accessor_wrap
229 typedef PixFmt pixfmt_type
;
230 typedef typename
pixfmt_type::color_type color_type
;
231 typedef typename
pixfmt_type::order_type order_type
;
232 typedef typename
pixfmt_type::value_type value_type
;
233 enum pix_width_e
{ pix_width
= pixfmt_type::pix_width
};
235 image_accessor_wrap() {}
236 image_accessor_wrap(const pixfmt_type
& pixf
) :
238 m_wrap_x(pixf
.width()),
239 m_wrap_y(pixf
.height())
242 void attach(const pixfmt_type
& pixf
)
247 AGG_INLINE
const int8u
* span(int x
, int y
, unsigned)
250 m_row_ptr
= m_pixf
->row_ptr(m_wrap_y(y
));
251 return m_row_ptr
+ m_wrap_x(x
) * pix_width
;
254 AGG_INLINE
const int8u
* next_x()
257 return m_row_ptr
+ x
* pix_width
;
260 AGG_INLINE
const int8u
* next_y()
262 m_row_ptr
= m_pixf
->row_ptr(++m_wrap_y
);
263 return m_row_ptr
+ m_wrap_x(m_x
) * pix_width
;
267 const pixfmt_type
* m_pixf
;
268 const int8u
* m_row_ptr
;
277 //--------------------------------------------------------wrap_mode_repeat
278 class wrap_mode_repeat
281 wrap_mode_repeat() {}
282 wrap_mode_repeat(unsigned size
) :
284 m_add(size
* (0x3FFFFFFF / size
)),
288 AGG_INLINE
unsigned operator() (int v
)
290 return m_value
= (unsigned(v
) + m_add
) % m_size
;
293 AGG_INLINE
unsigned operator++ ()
296 if(m_value
>= m_size
) m_value
= 0;
306 //---------------------------------------------------wrap_mode_repeat_pow2
307 class wrap_mode_repeat_pow2
310 wrap_mode_repeat_pow2() {}
311 wrap_mode_repeat_pow2(unsigned size
) : m_value(0)
314 while(m_mask
< size
) m_mask
= (m_mask
<< 1) | 1;
317 AGG_INLINE
unsigned operator() (int v
)
319 return m_value
= unsigned(v
) & m_mask
;
321 AGG_INLINE
unsigned operator++ ()
324 if(m_value
> m_mask
) m_value
= 0;
333 //----------------------------------------------wrap_mode_repeat_auto_pow2
334 class wrap_mode_repeat_auto_pow2
337 wrap_mode_repeat_auto_pow2() {}
338 wrap_mode_repeat_auto_pow2(unsigned size
) :
340 m_add(size
* (0x3FFFFFFF / size
)),
341 m_mask((m_size
& (m_size
-1)) ? 0 : m_size
-1),
345 AGG_INLINE
unsigned operator() (int v
)
347 if(m_mask
) return m_value
= unsigned(v
) & m_mask
;
348 return m_value
= (unsigned(v
) + m_add
) % m_size
;
350 AGG_INLINE
unsigned operator++ ()
353 if(m_value
>= m_size
) m_value
= 0;
365 //-------------------------------------------------------wrap_mode_reflect
366 class wrap_mode_reflect
369 wrap_mode_reflect() {}
370 wrap_mode_reflect(unsigned size
) :
373 m_add(m_size2
* (0x3FFFFFFF / m_size2
)),
377 AGG_INLINE
unsigned operator() (int v
)
379 m_value
= (unsigned(v
) + m_add
) % m_size2
;
380 if(m_value
>= m_size
) return m_size2
- m_value
- 1;
384 AGG_INLINE
unsigned operator++ ()
387 if(m_value
>= m_size2
) m_value
= 0;
388 if(m_value
>= m_size
) return m_size2
- m_value
- 1;
400 //--------------------------------------------------wrap_mode_reflect_pow2
401 class wrap_mode_reflect_pow2
404 wrap_mode_reflect_pow2() {}
405 wrap_mode_reflect_pow2(unsigned size
) : m_value(0)
411 m_mask
= (m_mask
<< 1) | 1;
415 AGG_INLINE
unsigned operator() (int v
)
417 m_value
= unsigned(v
) & m_mask
;
418 if(m_value
>= m_size
) return m_mask
- m_value
;
421 AGG_INLINE
unsigned operator++ ()
425 if(m_value
>= m_size
) return m_mask
- m_value
;
436 //---------------------------------------------wrap_mode_reflect_auto_pow2
437 class wrap_mode_reflect_auto_pow2
440 wrap_mode_reflect_auto_pow2() {}
441 wrap_mode_reflect_auto_pow2(unsigned size
) :
444 m_add(m_size2
* (0x3FFFFFFF / m_size2
)),
445 m_mask((m_size2
& (m_size2
-1)) ? 0 : m_size2
-1),
449 AGG_INLINE
unsigned operator() (int v
)
451 m_value
= m_mask
? unsigned(v
) & m_mask
:
452 (unsigned(v
) + m_add
) % m_size2
;
453 if(m_value
>= m_size
) return m_size2
- m_value
- 1;
456 AGG_INLINE
unsigned operator++ ()
459 if(m_value
>= m_size2
) m_value
= 0;
460 if(m_value
>= m_size
) return m_size2
- m_value
- 1;