24 #ifndef AGG_PIXFMT_RGB_INCLUDED 25 #define AGG_PIXFMT_RGB_INCLUDED 28 #include "agg_pixfmt_base.h" 29 #include "agg_rendering_buffer.h" 38 typedef typename ColorT::value_type value_type;
42 AGG_INLINE
void operator () (value_type* p)
44 p[Order::R] = m_gamma.dir(p[Order::R]);
45 p[Order::G] = m_gamma.dir(p[Order::G]);
46 p[Order::B] = m_gamma.dir(p[Order::B]);
50 const GammaLut& m_gamma;
59 typedef typename ColorT::value_type value_type;
63 AGG_INLINE
void operator () (value_type* p)
65 p[Order::R] = m_gamma.inv(p[Order::R]);
66 p[Order::G] = m_gamma.inv(p[Order::G]);
67 p[Order::B] = m_gamma.inv(p[Order::B]);
71 const GammaLut& m_gamma;
76 template<
class ColorT,
class Order>
79 typedef ColorT color_type;
80 typedef Order order_type;
81 typedef typename color_type::value_type value_type;
82 typedef typename color_type::calc_type calc_type;
83 typedef typename color_type::long_type long_type;
90 static AGG_INLINE
void blend_pix(value_type* p,
91 value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
93 blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
97 static AGG_INLINE
void blend_pix(value_type* p,
98 value_type cr, value_type cg, value_type cb, value_type alpha)
100 p[Order::R] = color_type::lerp(p[Order::R], cr, alpha);
101 p[Order::G] = color_type::lerp(p[Order::G], cg, alpha);
102 p[Order::B] = color_type::lerp(p[Order::B], cb, alpha);
107 template<
class ColorT,
class Order>
110 typedef ColorT color_type;
111 typedef Order order_type;
112 typedef typename color_type::value_type value_type;
113 typedef typename color_type::calc_type calc_type;
114 typedef typename color_type::long_type long_type;
120 static AGG_INLINE
void blend_pix(value_type* p,
121 value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
124 color_type::mult_cover(cr, cover),
125 color_type::mult_cover(cg, cover),
126 color_type::mult_cover(cb, cover),
127 color_type::mult_cover(alpha, cover));
131 static AGG_INLINE
void blend_pix(value_type* p,
132 value_type cr, value_type cg, value_type cb, value_type alpha)
134 p[Order::R] = color_type::prelerp(p[Order::R], cr, alpha);
135 p[Order::G] = color_type::prelerp(p[Order::G], cg, alpha);
136 p[Order::B] = color_type::prelerp(p[Order::B], cb, alpha);
141 template<
class ColorT,
class Order,
class Gamma>
145 typedef ColorT color_type;
146 typedef Order order_type;
147 typedef Gamma gamma_type;
148 typedef typename color_type::value_type value_type;
149 typedef typename color_type::calc_type calc_type;
150 typedef typename color_type::long_type long_type;
154 void gamma(
const gamma_type& g) { m_gamma = &g; }
157 AGG_INLINE
void blend_pix(value_type* p,
158 value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover)
160 blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
164 AGG_INLINE
void blend_pix(value_type* p,
165 value_type cr, value_type cg, value_type cb, value_type alpha)
167 calc_type r = m_gamma->dir(p[Order::R]);
168 calc_type g = m_gamma->dir(p[Order::G]);
169 calc_type b = m_gamma->dir(p[Order::B]);
170 p[Order::R] = m_gamma->inv(color_type::downscale((m_gamma->dir(cr) - r) * alpha) + r);
171 p[Order::G] = m_gamma->inv(color_type::downscale((m_gamma->dir(cg) - g) * alpha) + g);
172 p[Order::B] = m_gamma->inv(color_type::downscale((m_gamma->dir(cb) - b) * alpha) + b);
176 const gamma_type* m_gamma;
181 template<
class Blender,
class RenBuf,
unsigned Step,
unsigned Offset = 0>
186 typedef RenBuf rbuf_type;
187 typedef Blender blender_type;
188 typedef typename rbuf_type::row_data row_data;
189 typedef typename blender_type::color_type color_type;
190 typedef typename blender_type::order_type order_type;
191 typedef typename color_type::value_type value_type;
192 typedef typename color_type::calc_type calc_type;
198 pix_width =
sizeof(value_type) * pix_step
202 value_type c[num_components];
204 void set(value_type r, value_type g, value_type b)
206 c[order_type::R] = r;
207 c[order_type::G] = g;
208 c[order_type::B] = b;
211 void set(
const color_type& color)
213 set(color.r, color.g, color.b);
216 void get(value_type& r, value_type& g, value_type& b)
const 218 r = c[order_type::R];
219 g = c[order_type::G];
220 b = c[order_type::B];
223 color_type
get()
const 255 value_type r, value_type g, value_type b, value_type a,
258 m_blender.blend_pix(p->c, r, g, b, a, cover);
263 value_type r, value_type g, value_type b, value_type a)
265 m_blender.blend_pix(p->c, r, g, b, a);
269 AGG_INLINE
void blend_pix(
pixel_type* p,
const color_type& c,
unsigned cover)
271 m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover);
275 AGG_INLINE
void blend_pix(
pixel_type* p,
const color_type& c)
277 m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a);
281 AGG_INLINE
void copy_or_blend_pix(
pixel_type* p,
const color_type& c,
unsigned cover)
283 if (!c.is_transparent())
285 if (c.is_opaque() && cover == cover_mask)
291 blend_pix(p, c, cover);
297 AGG_INLINE
void copy_or_blend_pix(
pixel_type* p,
const color_type& c)
299 if (!c.is_transparent())
317 void attach(rbuf_type& rb) { m_rbuf = &rb; }
320 template<
class PixFmt>
321 bool attach(PixFmt& pixf,
int x1,
int y1,
int x2,
int y2)
324 if (r.clip(
rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
326 int stride = pixf.stride();
327 m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
337 Blender& blender() {
return m_blender; }
340 AGG_INLINE
unsigned width()
const {
return m_rbuf->width(); }
341 AGG_INLINE
unsigned height()
const {
return m_rbuf->height(); }
342 AGG_INLINE
int stride()
const {
return m_rbuf->stride(); }
345 AGG_INLINE int8u* row_ptr(
int y) {
return m_rbuf->row_ptr(y); }
346 AGG_INLINE
const int8u* row_ptr(
int y)
const {
return m_rbuf->row_ptr(y); }
347 AGG_INLINE row_data row(
int y)
const {
return m_rbuf->row(y); }
350 AGG_INLINE int8u* pix_ptr(
int x,
int y)
352 return m_rbuf->row_ptr(y) +
sizeof(value_type) * (x * pix_step + pix_offset);
355 AGG_INLINE
const int8u* pix_ptr(
int x,
int y)
const 357 return m_rbuf->row_ptr(y) +
sizeof(value_type) * (x * pix_step + pix_offset);
361 AGG_INLINE
pixel_type* pix_value_ptr(
int x,
int y,
unsigned len)
363 return (
pixel_type*)(m_rbuf->row_ptr(x, y, len) +
sizeof(value_type) * (x * pix_step + pix_offset));
367 AGG_INLINE
const pixel_type* pix_value_ptr(
int x,
int y)
const 369 int8u* p = m_rbuf->row_ptr(y);
370 return p ? (
pixel_type*)(p +
sizeof(value_type) * (x * pix_step + pix_offset)) : 0;
374 AGG_INLINE
static pixel_type* pix_value_ptr(
void* p)
376 return (
pixel_type*)((value_type*)p + pix_offset);
380 AGG_INLINE
static const pixel_type* pix_value_ptr(
const void* p)
382 return (
const pixel_type*)((
const value_type*)p + pix_offset);
386 AGG_INLINE
static void write_plain_color(
void* p, color_type c)
390 pix_value_ptr(p)->set(c);
394 AGG_INLINE
static color_type read_plain_color(
const void* p)
396 return pix_value_ptr(p)->get();
400 AGG_INLINE
static void make_pix(int8u* p,
const color_type& c)
406 AGG_INLINE color_type pixel(
int x,
int y)
const 408 if (
const pixel_type* p = pix_value_ptr(x, y))
412 return color_type::no_color();
416 AGG_INLINE
void copy_pixel(
int x,
int y,
const color_type& c)
418 pix_value_ptr(x, y, 1)->set(c);
422 AGG_INLINE
void blend_pixel(
int x,
int y,
const color_type& c, int8u cover)
424 copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover);
428 AGG_INLINE
void copy_hline(
int x,
int y,
443 AGG_INLINE
void copy_vline(
int x,
int y,
449 pix_value_ptr(x, y++, 1)->set(c);
455 void blend_hline(
int x,
int y,
460 if (!c.is_transparent())
464 if (c.is_opaque() && cover == cover_mask)
477 blend_pix(p, c, cover);
487 void blend_vline(
int x,
int y,
492 if (!c.is_transparent())
494 if (c.is_opaque() && cover == cover_mask)
498 pix_value_ptr(x, y++, 1)->set(c);
506 blend_pix(pix_value_ptr(x, y++, 1), c, cover);
514 void blend_solid_hspan(
int x,
int y,
519 if (!c.is_transparent())
525 if (c.is_opaque() && *covers == cover_mask)
531 blend_pix(p, c, *covers);
542 void blend_solid_vspan(
int x,
int y,
547 if (!c.is_transparent())
553 if (c.is_opaque() && *covers == cover_mask)
559 blend_pix(p, c, *covers);
568 void copy_color_hspan(
int x,
int y,
570 const color_type* colors)
584 void copy_color_vspan(
int x,
int y,
586 const color_type* colors)
590 pix_value_ptr(x, y++, 1)->set(*colors++);
596 void blend_color_hspan(
int x,
int y,
598 const color_type* colors,
608 copy_or_blend_pix(p, *colors++, *covers++);
615 if (cover == cover_mask)
619 copy_or_blend_pix(p, *colors++);
628 copy_or_blend_pix(p, *colors++, cover);
637 void blend_color_vspan(
int x,
int y,
639 const color_type* colors,
647 copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++);
653 if (cover == cover_mask)
657 copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++);
665 copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover);
673 template<
class Function>
void for_each_pixel(Function f)
675 for (
unsigned y = 0; y < height(); ++y)
677 row_data r = m_rbuf->row(y);
680 unsigned len = r.x2 - r.x1 + 1;
693 template<
class GammaLut>
void apply_gamma_dir(
const GammaLut& g)
699 template<
class GammaLut>
void apply_gamma_inv(
const GammaLut& g)
705 template<
class RenBuf2>
706 void copy_from(
const RenBuf2& from,
711 if (
const int8u* p = from.row_ptr(ysrc))
713 std::memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
714 p + xsrc * pix_width,
721 template<
class SrcPixelFormatRenderer>
722 void blend_from(
const SrcPixelFormatRenderer& from,
728 typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
729 typedef typename SrcPixelFormatRenderer::order_type src_order;
731 if (
const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
733 pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
735 if (cover == cover_mask)
739 value_type alpha = psrc->c[src_order::A];
740 if (alpha <= color_type::empty_value())
742 if (alpha >= color_type::full_value())
744 pdst->c[order_type::R] = psrc->c[src_order::R];
745 pdst->c[order_type::G] = psrc->c[src_order::G];
746 pdst->c[order_type::B] = psrc->c[src_order::B];
751 psrc->c[src_order::R],
752 psrc->c[src_order::G],
753 psrc->c[src_order::B],
766 copy_or_blend_pix(pdst, psrc->get(), cover);
777 template<
class SrcPixelFormatRenderer>
778 void blend_from_color(
const SrcPixelFormatRenderer& from,
779 const color_type& color,
785 typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
786 typedef typename SrcPixelFormatRenderer::color_type src_color_type;
788 if (
const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
790 pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
794 copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0]));
805 template<
class SrcPixelFormatRenderer>
806 void blend_from_lut(
const SrcPixelFormatRenderer& from,
807 const color_type* color_lut,
813 typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type;
815 if (
const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc))
817 pixel_type* pdst = pix_value_ptr(xdst, ydst, len);
819 if (cover == cover_mask)
823 const color_type& color = color_lut[psrc->c[0]];
824 blend_pix(pdst, color);
834 copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover);
928 this->blender().gamma(g);
940 this->blender().gamma(g);
952 this->blender().gamma(g);
964 this->blender().gamma(g);
976 this->blender().gamma(g);
988 this->blender().gamma(g);