📄 agg_pixfmt_rgb.h
字号:
//----------------------------------------------------------------------------// Anti-Grain Geometry - Version 2.4// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)//// Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied// warranty, and with no claim as to its suitability for any purpose.////----------------------------------------------------------------------------// Contact: mcseem@antigrain.com// mcseemagg@yahoo.com// http://www.antigrain.com//----------------------------------------------------------------------------//// Adaptation for high precision colors has been sponsored by // Liberty Technology Systems, Inc., visit http://lib-sys.com//// Liberty Technology Systems, Inc. is the provider of// PostScript and PDF technology for software developers.// //----------------------------------------------------------------------------#ifndef AGG_PIXFMT_RGB_INCLUDED#define AGG_PIXFMT_RGB_INCLUDED#include <string.h>#include "agg_basics.h"#include "agg_color_rgba.h"#include "agg_rendering_buffer.h"namespace agg{ //=====================================================apply_gamma_dir_rgb template<class ColorT, class Order, class GammaLut> class apply_gamma_dir_rgb { public: typedef typename ColorT::value_type value_type; apply_gamma_dir_rgb(const GammaLut& gamma) : m_gamma(gamma) {} AGG_INLINE void operator () (value_type* p) { p[Order::R] = m_gamma.dir(p[Order::R]); p[Order::G] = m_gamma.dir(p[Order::G]); p[Order::B] = m_gamma.dir(p[Order::B]); } private: const GammaLut& m_gamma; }; //=====================================================apply_gamma_inv_rgb template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgb { public: typedef typename ColorT::value_type value_type; apply_gamma_inv_rgb(const GammaLut& gamma) : m_gamma(gamma) {} AGG_INLINE void operator () (value_type* p) { p[Order::R] = m_gamma.inv(p[Order::R]); p[Order::G] = m_gamma.inv(p[Order::G]); p[Order::B] = m_gamma.inv(p[Order::B]); } private: const GammaLut& m_gamma; }; //=========================================================blender_rgb template<class ColorT, class Order> struct blender_rgb { typedef ColorT color_type; typedef Order order_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; enum base_scale_e { base_shift = color_type::base_shift }; //-------------------------------------------------------------------- static AGG_INLINE void blend_pix(value_type* p, unsigned cr, unsigned cg, unsigned cb, unsigned alpha, unsigned cover=0) { p[Order::R] += (value_type)(((cr - p[Order::R]) * alpha) >> base_shift); p[Order::G] += (value_type)(((cg - p[Order::G]) * alpha) >> base_shift); p[Order::B] += (value_type)(((cb - p[Order::B]) * alpha) >> base_shift); } }; //======================================================blender_rgb_pre template<class ColorT, class Order> struct blender_rgb_pre { typedef ColorT color_type; typedef Order order_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; enum base_scale_e { base_shift = color_type::base_shift }; //-------------------------------------------------------------------- static AGG_INLINE void blend_pix(value_type* p, unsigned cr, unsigned cg, unsigned cb, unsigned alpha, unsigned cover) { alpha = color_type::base_mask - alpha; cover = (cover + 1) << (base_shift - 8); p[Order::R] = (value_type)((p[Order::R] * alpha + cr * cover) >> base_shift); p[Order::G] = (value_type)((p[Order::G] * alpha + cg * cover) >> base_shift); p[Order::B] = (value_type)((p[Order::B] * alpha + cb * cover) >> base_shift); } //-------------------------------------------------------------------- static AGG_INLINE void blend_pix(value_type* p, unsigned cr, unsigned cg, unsigned cb, unsigned alpha) { alpha = color_type::base_mask - alpha; p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr); p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg); p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb); } }; //===================================================blender_rgb_gamma template<class ColorT, class Order, class Gamma> class blender_rgb_gamma { public: typedef ColorT color_type; typedef Order order_type; typedef Gamma gamma_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; enum base_scale_e { base_shift = color_type::base_shift }; //-------------------------------------------------------------------- blender_rgb_gamma() : m_gamma(0) {} void gamma(const gamma_type& g) { m_gamma = &g; } //-------------------------------------------------------------------- AGG_INLINE void blend_pix(value_type* p, unsigned cr, unsigned cg, unsigned cb, unsigned alpha, unsigned cover=0) { calc_type r = m_gamma->dir(p[Order::R]); calc_type g = m_gamma->dir(p[Order::G]); calc_type b = m_gamma->dir(p[Order::B]); p[Order::R] = m_gamma->inv((((m_gamma->dir(cr) - r) * alpha) >> base_shift) + r); p[Order::G] = m_gamma->inv((((m_gamma->dir(cg) - g) * alpha) >> base_shift) + g); p[Order::B] = m_gamma->inv((((m_gamma->dir(cb) - b) * alpha) >> base_shift) + b); } private: const gamma_type* m_gamma; }; //==================================================pixfmt_alpha_blend_rgb template<class Blender, class RenBuf> class pixfmt_alpha_blend_rgb { public: typedef RenBuf rbuf_type; typedef typename rbuf_type::row_data row_data; typedef Blender blender_type; typedef typename blender_type::color_type color_type; typedef typename blender_type::order_type order_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; enum base_scale_e { base_shift = color_type::base_shift, base_scale = color_type::base_scale, base_mask = color_type::base_mask, pix_width = sizeof(value_type) * 3 }; private: //-------------------------------------------------------------------- AGG_INLINE void copy_or_blend_pix(value_type* p, const color_type& c, unsigned cover) { if (c.a) { calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; if(alpha == base_mask) { p[order_type::R] = c.r; p[order_type::G] = c.g; p[order_type::B] = c.b; } else { m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); } } } //-------------------------------------------------------------------- AGG_INLINE void copy_or_blend_pix(value_type* p, const color_type& c) { if (c.a) { if(c.a == base_mask) { p[order_type::R] = c.r; p[order_type::G] = c.g; p[order_type::B] = c.b; } else { m_blender.blend_pix(p, c.r, c.g, c.b, c.a); } } } public: //-------------------------------------------------------------------- pixfmt_alpha_blend_rgb(rbuf_type& rb) : m_rbuf(&rb) {} void attach(rbuf_type& rb) { m_rbuf = &rb; } //-------------------------------------------------------------------- Blender& blender() { return m_blender; } //-------------------------------------------------------------------- AGG_INLINE unsigned width() const { return m_rbuf->width(); } AGG_INLINE unsigned height() const { return m_rbuf->height(); } //-------------------------------------------------------------------- const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } //-------------------------------------------------------------------- const int8u* pix_ptr(int x, int y) const { return m_rbuf->row_ptr(y) + x * pix_width; } //-------------------------------------------------------------------- row_data row(int x, int y) const { return m_rbuf->row(y); } //-------------------------------------------------------------------- AGG_INLINE static void make_pix(int8u* p, const color_type& c) { ((value_type*)p)[order_type::R] = c.r; ((value_type*)p)[order_type::G] = c.g; ((value_type*)p)[order_type::B] = c.b; } //-------------------------------------------------------------------- AGG_INLINE color_type pixel(int x, int y) const { value_type* p = (value_type*)m_rbuf->row_ptr(y) + x + x + x; return color_type(p[order_type::R], p[order_type::G], p[order_type::B]); } //-------------------------------------------------------------------- AGG_INLINE void copy_pixel(int x, int y, const color_type& c) { value_type* p = (value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x; p[order_type::R] = c.r; p[order_type::G] = c.g; p[order_type::B] = c.b; } //-------------------------------------------------------------------- AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) { copy_or_blend_pix((value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x, c, cover); } //-------------------------------------------------------------------- AGG_INLINE void copy_hline(int x, int y, unsigned len, const color_type& c) { value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + x + x + x; do { p[order_type::R] = c.r; p[order_type::G] = c.g; p[order_type::B] = c.b; p += 3; } while(--len); } //-------------------------------------------------------------------- AGG_INLINE void copy_vline(int x, int y, unsigned len, const color_type& c) { do { value_type* p = (value_type*) m_rbuf->row_ptr(x, y++, 1) + x + x + x; p[order_type::R] = c.r; p[order_type::G] = c.g; p[order_type::B] = c.b; } while(--len); } //-------------------------------------------------------------------- void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { if (c.a) { value_type* p = (value_type*) m_rbuf->row_ptr(x, y, len) + x + x + x; calc_type alpha = (calc_type(c.a) * (calc_type(cover) + 1)) >> 8; if(alpha == base_mask) { do { p[order_type::R] = c.r; p[order_type::G] = c.g; p[order_type::B] = c.b; p += 3; } while(--len); } else { do { m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); p += 3; } while(--len); } } } //-------------------------------------------------------------------- void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { if (c.a) { value_type* p; calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; if(alpha == base_mask) { do {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -