Anti-Grain Geometry Tutorial
agg_alpha_mask_u8.h
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 // scanline_u8 class
17 //
18 //----------------------------------------------------------------------------
19 #ifndef AGG_ALPHA_MASK_U8_INCLUDED
20 #define AGG_ALPHA_MASK_U8_INCLUDED
21 
22 #include <cstring>
23 #include "agg_basics.h"
24 #include "agg_rendering_buffer.h"
25 
26 namespace agg
27 {
28  //===================================================one_component_mask_u8
30  {
31  static unsigned calculate(const int8u* p) { return *p; }
32  };
33 
34 
35  //=====================================================rgb_to_gray_mask_u8
36  template<unsigned R, unsigned G, unsigned B>
38  {
39  static unsigned calculate(const int8u* p)
40  {
41  return (p[R]*77 + p[G]*150 + p[B]*29) >> 8;
42  }
43  };
44 
45  //==========================================================alpha_mask_u8
46  template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8>
48  {
49  public:
50  typedef int8u cover_type;
52  enum cover_scale_e
53  {
54  cover_shift = 8,
55  cover_none = 0,
56  cover_full = 255
57  };
58 
59  alpha_mask_u8() : m_rbuf(0) {}
60  explicit alpha_mask_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {}
61 
62  void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; }
63 
64  MaskF& mask_function() { return m_mask_function; }
65  const MaskF& mask_function() const { return m_mask_function; }
66 
67 
68  //--------------------------------------------------------------------
69  cover_type pixel(int x, int y) const
70  {
71  if(x >= 0 && y >= 0 &&
72  x < (int)m_rbuf->width() &&
73  y < (int)m_rbuf->height())
74  {
75  return (cover_type)m_mask_function.calculate(
76  m_rbuf->row_ptr(y) + x * Step + Offset);
77  }
78  return 0;
79  }
80 
81  //--------------------------------------------------------------------
82  cover_type combine_pixel(int x, int y, cover_type val) const
83  {
84  if(x >= 0 && y >= 0 &&
85  x < (int)m_rbuf->width() &&
86  y < (int)m_rbuf->height())
87  {
88  return (cover_type)((cover_full + val *
89  m_mask_function.calculate(
90  m_rbuf->row_ptr(y) + x * Step + Offset)) >>
91  cover_shift);
92  }
93  return 0;
94  }
95 
96 
97  //--------------------------------------------------------------------
98  void fill_hspan(int x, int y, cover_type* dst, int num_pix) const
99  {
100  int xmax = m_rbuf->width() - 1;
101  int ymax = m_rbuf->height() - 1;
102 
103  int count = num_pix;
104  cover_type* covers = dst;
105 
106  if(y < 0 || y > ymax)
107  {
108  std::memset(dst, 0, num_pix * sizeof(cover_type));
109  return;
110  }
111 
112  if(x < 0)
113  {
114  count += x;
115  if(count <= 0)
116  {
117  std::memset(dst, 0, num_pix * sizeof(cover_type));
118  return;
119  }
120  std::memset(covers, 0, -x * sizeof(cover_type));
121  covers -= x;
122  x = 0;
123  }
124 
125  if(x + count > xmax)
126  {
127  int rest = x + count - xmax - 1;
128  count -= rest;
129  if(count <= 0)
130  {
131  std::memset(dst, 0, num_pix * sizeof(cover_type));
132  return;
133  }
134  std::memset(covers + count, 0, rest * sizeof(cover_type));
135  }
136 
137  const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
138  do
139  {
140  *covers++ = (cover_type)m_mask_function.calculate(mask);
141  mask += Step;
142  }
143  while(--count);
144  }
145 
146 
147  //--------------------------------------------------------------------
148  void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
149  {
150  int xmax = m_rbuf->width() - 1;
151  int ymax = m_rbuf->height() - 1;
152 
153  int count = num_pix;
154  cover_type* covers = dst;
155 
156  if(y < 0 || y > ymax)
157  {
158  std::memset(dst, 0, num_pix * sizeof(cover_type));
159  return;
160  }
161 
162  if(x < 0)
163  {
164  count += x;
165  if(count <= 0)
166  {
167  std::memset(dst, 0, num_pix * sizeof(cover_type));
168  return;
169  }
170  std::memset(covers, 0, -x * sizeof(cover_type));
171  covers -= x;
172  x = 0;
173  }
174 
175  if(x + count > xmax)
176  {
177  int rest = x + count - xmax - 1;
178  count -= rest;
179  if(count <= 0)
180  {
181  std::memset(dst, 0, num_pix * sizeof(cover_type));
182  return;
183  }
184  std::memset(covers + count, 0, rest * sizeof(cover_type));
185  }
186 
187  const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
188  do
189  {
190  *covers = (cover_type)((cover_full + (*covers) *
191  m_mask_function.calculate(mask)) >>
192  cover_shift);
193  ++covers;
194  mask += Step;
195  }
196  while(--count);
197  }
198 
199  //--------------------------------------------------------------------
200  void fill_vspan(int x, int y, cover_type* dst, int num_pix) const
201  {
202  int xmax = m_rbuf->width() - 1;
203  int ymax = m_rbuf->height() - 1;
204 
205  int count = num_pix;
206  cover_type* covers = dst;
207 
208  if(x < 0 || x > xmax)
209  {
210  std::memset(dst, 0, num_pix * sizeof(cover_type));
211  return;
212  }
213 
214  if(y < 0)
215  {
216  count += y;
217  if(count <= 0)
218  {
219  std::memset(dst, 0, num_pix * sizeof(cover_type));
220  return;
221  }
222  std::memset(covers, 0, -y * sizeof(cover_type));
223  covers -= y;
224  y = 0;
225  }
226 
227  if(y + count > ymax)
228  {
229  int rest = y + count - ymax - 1;
230  count -= rest;
231  if(count <= 0)
232  {
233  std::memset(dst, 0, num_pix * sizeof(cover_type));
234  return;
235  }
236  std::memset(covers + count, 0, rest * sizeof(cover_type));
237  }
238 
239  const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
240  do
241  {
242  *covers++ = (cover_type)m_mask_function.calculate(mask);
243  mask += m_rbuf->stride();
244  }
245  while(--count);
246  }
247 
248  //--------------------------------------------------------------------
249  void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
250  {
251  int xmax = m_rbuf->width() - 1;
252  int ymax = m_rbuf->height() - 1;
253 
254  int count = num_pix;
255  cover_type* covers = dst;
256 
257  if(x < 0 || x > xmax)
258  {
259  std::memset(dst, 0, num_pix * sizeof(cover_type));
260  return;
261  }
262 
263  if(y < 0)
264  {
265  count += y;
266  if(count <= 0)
267  {
268  std::memset(dst, 0, num_pix * sizeof(cover_type));
269  return;
270  }
271  std::memset(covers, 0, -y * sizeof(cover_type));
272  covers -= y;
273  y = 0;
274  }
275 
276  if(y + count > ymax)
277  {
278  int rest = y + count - ymax - 1;
279  count -= rest;
280  if(count <= 0)
281  {
282  std::memset(dst, 0, num_pix * sizeof(cover_type));
283  return;
284  }
285  std::memset(covers + count, 0, rest * sizeof(cover_type));
286  }
287 
288  const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
289  do
290  {
291  *covers = (cover_type)((cover_full + (*covers) *
292  m_mask_function.calculate(mask)) >>
293  cover_shift);
294  ++covers;
295  mask += m_rbuf->stride();
296  }
297  while(--count);
298  }
299 
300 
301  private:
302  alpha_mask_u8(const self_type&);
303  const self_type& operator = (const self_type&);
304 
305  rendering_buffer* m_rbuf;
306  MaskF m_mask_function;
307  };
308 
309 
310  typedef alpha_mask_u8<1, 0> alpha_mask_gray8; //----alpha_mask_gray8
311 
312  typedef alpha_mask_u8<3, 0> alpha_mask_rgb24r; //----alpha_mask_rgb24r
313  typedef alpha_mask_u8<3, 1> alpha_mask_rgb24g; //----alpha_mask_rgb24g
314  typedef alpha_mask_u8<3, 2> alpha_mask_rgb24b; //----alpha_mask_rgb24b
315 
316  typedef alpha_mask_u8<3, 2> alpha_mask_bgr24r; //----alpha_mask_bgr24r
317  typedef alpha_mask_u8<3, 1> alpha_mask_bgr24g; //----alpha_mask_bgr24g
318  typedef alpha_mask_u8<3, 0> alpha_mask_bgr24b; //----alpha_mask_bgr24b
319 
320  typedef alpha_mask_u8<4, 0> alpha_mask_rgba32r; //----alpha_mask_rgba32r
321  typedef alpha_mask_u8<4, 1> alpha_mask_rgba32g; //----alpha_mask_rgba32g
322  typedef alpha_mask_u8<4, 2> alpha_mask_rgba32b; //----alpha_mask_rgba32b
323  typedef alpha_mask_u8<4, 3> alpha_mask_rgba32a; //----alpha_mask_rgba32a
324 
325  typedef alpha_mask_u8<4, 1> alpha_mask_argb32r; //----alpha_mask_argb32r
326  typedef alpha_mask_u8<4, 2> alpha_mask_argb32g; //----alpha_mask_argb32g
327  typedef alpha_mask_u8<4, 3> alpha_mask_argb32b; //----alpha_mask_argb32b
328  typedef alpha_mask_u8<4, 0> alpha_mask_argb32a; //----alpha_mask_argb32a
329 
330  typedef alpha_mask_u8<4, 2> alpha_mask_bgra32r; //----alpha_mask_bgra32r
331  typedef alpha_mask_u8<4, 1> alpha_mask_bgra32g; //----alpha_mask_bgra32g
332  typedef alpha_mask_u8<4, 0> alpha_mask_bgra32b; //----alpha_mask_bgra32b
333  typedef alpha_mask_u8<4, 3> alpha_mask_bgra32a; //----alpha_mask_bgra32a
334 
335  typedef alpha_mask_u8<4, 3> alpha_mask_abgr32r; //----alpha_mask_abgr32r
336  typedef alpha_mask_u8<4, 2> alpha_mask_abgr32g; //----alpha_mask_abgr32g
337  typedef alpha_mask_u8<4, 1> alpha_mask_abgr32b; //----alpha_mask_abgr32b
338  typedef alpha_mask_u8<4, 0> alpha_mask_abgr32a; //----alpha_mask_abgr32a
339 
340  typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgb24gray; //----alpha_mask_rgb24gray
341  typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgr24gray; //----alpha_mask_bgr24gray
342  typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgba32gray; //----alpha_mask_rgba32gray
343  typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_argb32gray; //----alpha_mask_argb32gray
344  typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgra32gray; //----alpha_mask_bgra32gray
345  typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_abgr32gray; //----alpha_mask_abgr32gray
346 
347 
348 
349  //==========================================================amask_no_clip_u8
350  template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8>
352  {
353  public:
354  typedef int8u cover_type;
356  enum cover_scale_e
357  {
358  cover_shift = 8,
359  cover_none = 0,
360  cover_full = 255
361  };
362 
363  amask_no_clip_u8() : m_rbuf(0) {}
364  explicit amask_no_clip_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {}
365 
366  void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; }
367 
368  MaskF& mask_function() { return m_mask_function; }
369  const MaskF& mask_function() const { return m_mask_function; }
370 
371 
372  //--------------------------------------------------------------------
373  cover_type pixel(int x, int y) const
374  {
375  return (cover_type)m_mask_function.calculate(
376  m_rbuf->row_ptr(y) + x * Step + Offset);
377  }
378 
379 
380  //--------------------------------------------------------------------
381  cover_type combine_pixel(int x, int y, cover_type val) const
382  {
383  return (cover_type)((cover_full + val *
384  m_mask_function.calculate(
385  m_rbuf->row_ptr(y) + x * Step + Offset)) >>
386  cover_shift);
387  }
388 
389 
390  //--------------------------------------------------------------------
391  void fill_hspan(int x, int y, cover_type* dst, int num_pix) const
392  {
393  const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
394  do
395  {
396  *dst++ = (cover_type)m_mask_function.calculate(mask);
397  mask += Step;
398  }
399  while(--num_pix);
400  }
401 
402 
403 
404  //--------------------------------------------------------------------
405  void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
406  {
407  const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
408  do
409  {
410  *dst = (cover_type)((cover_full + (*dst) *
411  m_mask_function.calculate(mask)) >>
412  cover_shift);
413  ++dst;
414  mask += Step;
415  }
416  while(--num_pix);
417  }
418 
419 
420  //--------------------------------------------------------------------
421  void fill_vspan(int x, int y, cover_type* dst, int num_pix) const
422  {
423  const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
424  do
425  {
426  *dst++ = (cover_type)m_mask_function.calculate(mask);
427  mask += m_rbuf->stride();
428  }
429  while(--num_pix);
430  }
431 
432 
433  //--------------------------------------------------------------------
434  void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
435  {
436  const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
437  do
438  {
439  *dst = (cover_type)((cover_full + (*dst) *
440  m_mask_function.calculate(mask)) >>
441  cover_shift);
442  ++dst;
443  mask += m_rbuf->stride();
444  }
445  while(--num_pix);
446  }
447 
448  private:
449  amask_no_clip_u8(const self_type&);
450  const self_type& operator = (const self_type&);
451 
452  rendering_buffer* m_rbuf;
453  MaskF m_mask_function;
454  };
455 
456 
457  typedef amask_no_clip_u8<1, 0> amask_no_clip_gray8; //----amask_no_clip_gray8
458 
459  typedef amask_no_clip_u8<3, 0> amask_no_clip_rgb24r; //----amask_no_clip_rgb24r
460  typedef amask_no_clip_u8<3, 1> amask_no_clip_rgb24g; //----amask_no_clip_rgb24g
461  typedef amask_no_clip_u8<3, 2> amask_no_clip_rgb24b; //----amask_no_clip_rgb24b
462 
463  typedef amask_no_clip_u8<3, 2> amask_no_clip_bgr24r; //----amask_no_clip_bgr24r
464  typedef amask_no_clip_u8<3, 1> amask_no_clip_bgr24g; //----amask_no_clip_bgr24g
465  typedef amask_no_clip_u8<3, 0> amask_no_clip_bgr24b; //----amask_no_clip_bgr24b
466 
467  typedef amask_no_clip_u8<4, 0> amask_no_clip_rgba32r; //----amask_no_clip_rgba32r
468  typedef amask_no_clip_u8<4, 1> amask_no_clip_rgba32g; //----amask_no_clip_rgba32g
469  typedef amask_no_clip_u8<4, 2> amask_no_clip_rgba32b; //----amask_no_clip_rgba32b
470  typedef amask_no_clip_u8<4, 3> amask_no_clip_rgba32a; //----amask_no_clip_rgba32a
471 
472  typedef amask_no_clip_u8<4, 1> amask_no_clip_argb32r; //----amask_no_clip_argb32r
473  typedef amask_no_clip_u8<4, 2> amask_no_clip_argb32g; //----amask_no_clip_argb32g
474  typedef amask_no_clip_u8<4, 3> amask_no_clip_argb32b; //----amask_no_clip_argb32b
475  typedef amask_no_clip_u8<4, 0> amask_no_clip_argb32a; //----amask_no_clip_argb32a
476 
477  typedef amask_no_clip_u8<4, 2> amask_no_clip_bgra32r; //----amask_no_clip_bgra32r
478  typedef amask_no_clip_u8<4, 1> amask_no_clip_bgra32g; //----amask_no_clip_bgra32g
479  typedef amask_no_clip_u8<4, 0> amask_no_clip_bgra32b; //----amask_no_clip_bgra32b
480  typedef amask_no_clip_u8<4, 3> amask_no_clip_bgra32a; //----amask_no_clip_bgra32a
481 
482  typedef amask_no_clip_u8<4, 3> amask_no_clip_abgr32r; //----amask_no_clip_abgr32r
483  typedef amask_no_clip_u8<4, 2> amask_no_clip_abgr32g; //----amask_no_clip_abgr32g
484  typedef amask_no_clip_u8<4, 1> amask_no_clip_abgr32b; //----amask_no_clip_abgr32b
485  typedef amask_no_clip_u8<4, 0> amask_no_clip_abgr32a; //----amask_no_clip_abgr32a
486 
489  typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgba32gray; //----amask_no_clip_rgba32gray
490  typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_argb32gray; //----amask_no_clip_argb32gray
491  typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgra32gray; //----amask_no_clip_bgra32gray
492  typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_abgr32gray; //----amask_no_clip_abgr32gray
493 
494 
495 }
496 
497 
498 
499 #endif
Definition: agg_arc.cpp:24