📄 agg_color_rgba.h
字号:
//----------------------------------------------------------------------------// Anti-Grain Geometry - Version 2.3// 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.////----------------------------------------------------------------------------//// 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.// //----------------------------------------------------------------------------// Contact: mcseem@antigrain.com// mcseemagg@yahoo.com// http://www.antigrain.com//----------------------------------------------------------------------------#ifndef AGG_COLOR_RGBA_INCLUDED#define AGG_COLOR_RGBA_INCLUDED#include <math.h>#include "agg_basics.h"namespace agg{ // Supported byte orders for RGB and RGBA pixel formats //======================================================================= struct order_rgb { enum { R=0, G=1, B=2, rgb_tag }; }; //----order_rgb struct order_bgr { enum { B=0, G=1, R=2, rgb_tag }; }; //----order_bgr struct order_rgba { enum { R=0, G=1, B=2, A=3, rgba_tag }; }; //----order_rgba struct order_argb { enum { A=0, R=1, G=2, B=3, rgba_tag }; }; //----order_argb struct order_abgr { enum { A=0, B=1, G=2, R=3, rgba_tag }; }; //----order_abgr struct order_bgra { enum { B=0, G=1, R=2, A=3, rgba_tag }; }; //----order_bgra //====================================================================rgba struct rgba { typedef double value_type; double r; double g; double b; double a; //-------------------------------------------------------------------- rgba() {} //-------------------------------------------------------------------- rgba(double r_, double g_, double b_, double a_=1.0) : r(r_), g(g_), b(b_), a(a_) {} //-------------------------------------------------------------------- rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {} //-------------------------------------------------------------------- void clear() { r = g = b = a = 0; } //-------------------------------------------------------------------- const rgba& transparent() { a = 0.0; return *this; } //-------------------------------------------------------------------- const rgba& opacity(double a_) { if(a_ < 0.0) a_ = 0.0; if(a_ > 1.0) a_ = 1.0; a = a_; return *this; } //-------------------------------------------------------------------- double opacity() const { return a; } //-------------------------------------------------------------------- const rgba& premultiply() { r *= a; g *= a; b *= a; return *this; } //-------------------------------------------------------------------- const rgba& premultiply(double a_) { if(a == 0.0 || a_ == 0.0) { r = g = b = a = 0.0; return *this; } a_ /= a; r *= a_; g *= a_; b *= a_; a = a_; return *this; } //-------------------------------------------------------------------- const rgba& demultiply() { if(a == 0) { r = g = b = 0; return *this; } double a_ = 1.0 / a; r *= a_; g *= a_; b *= a_; return *this; } //-------------------------------------------------------------------- rgba gradient(rgba c, double k) const { rgba ret; ret.r = r + (c.r - r) * k; ret.g = g + (c.g - g) * k; ret.b = b + (c.b - b) * k; ret.a = a + (c.a - a) * k; return ret; } //-------------------------------------------------------------------- static rgba no_color() { return rgba(0,0,0,0); } //-------------------------------------------------------------------- static rgba from_wavelength(double wl, double gamma = 1.0); //-------------------------------------------------------------------- rgba(double wavelen, double gamma=1.0) { *this = from_wavelength(wavelen, gamma); } }; //----------------------------------------------------------------rgba_pre inline rgba rgba_pre(double r, double g, double b, double a=1.0) { return rgba(r, g, b, a).premultiply(); } inline rgba rgba_pre(const rgba& c) { return rgba(c).premultiply(); } inline rgba rgba_pre(const rgba& c, double a) { return rgba(c, a).premultiply(); } //------------------------------------------------------------------------ inline rgba rgba::from_wavelength(double wl, double gamma) { rgba t(0.0, 0.0, 0.0); if(wl >= 380.0 && wl <= 440.0) { t.r = -1.0 * (wl - 440.0) / (440.0 - 380.0); t.b = 1.0; } else if(wl >= 440.0 && wl <= 490.0) { t.g = (wl - 440.0) / (490.0 - 440.0); t.b = 1.0; } else if(wl >= 490.0 && wl <= 510.0) { t.g = 1.0; t.b = -1.0 * (wl - 510.0) / (510.0 - 490.0); } else if(wl >= 510.0 && wl <= 580.0) { t.r = (wl - 510.0) / (580.0 - 510.0); t.g = 1.0; } else if(wl >= 580.0 && wl <= 645.0) { t.r = 1.0; t.g = -1.0 * (wl - 645.0) / (645.0 - 580.0); } else if(wl >= 645.0 && wl <= 780.0) { t.r = 1.0; } double s = 1.0; if(wl > 700.0) s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0); else if(wl < 420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0); t.r = pow(t.r * s, gamma); t.g = pow(t.g * s, gamma); t.b = pow(t.b * s, gamma); return t; } //===================================================================rgba8 struct rgba8 { typedef int8u value_type; typedef int32u calc_type; typedef int32 long_type; enum { base_shift = 8, base_size = 1 << base_shift, base_mask = base_size - 1 }; typedef rgba8 self_type; value_type r; value_type g; value_type b; value_type a; //-------------------------------------------------------------------- rgba8() {} //-------------------------------------------------------------------- rgba8(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) : r(value_type(r_)), g(value_type(g_)), b(value_type(b_)), a(value_type(a_)) {} //-------------------------------------------------------------------- rgba8(const rgba& c, double a_) : r(value_type(c.r * double(base_mask) + 0.5)), g(value_type(c.g * double(base_mask) + 0.5)), b(value_type(c.b * double(base_mask) + 0.5)), a(value_type(a_ * double(base_mask) + 0.5)) {} //-------------------------------------------------------------------- rgba8(const self_type& c, unsigned a_) : r(c.r), g(c.g), b(c.b), a(value_type(a_)) {} //-------------------------------------------------------------------- rgba8(const rgba& c) : r(value_type(c.r * double(base_mask) + 0.5)), g(value_type(c.g * double(base_mask) + 0.5)), b(value_type(c.b * double(base_mask) + 0.5)), a(value_type(c.a * double(base_mask) + 0.5)) {} //-------------------------------------------------------------------- void clear() { r = g = b = a = 0; } //-------------------------------------------------------------------- const self_type& transparent() { a = 0; return *this; } //-------------------------------------------------------------------- const self_type& opacity(double a_) { if(a_ < 0.0) a_ = 0.0; if(a_ > 1.0) a_ = 1.0; a = value_type(a_ * double(base_mask) + 0.5); return *this; } //-------------------------------------------------------------------- double opacity() const { return double(a) / double(base_mask); } //-------------------------------------------------------------------- const self_type& premultiply() { if(a == base_mask) return *this; if(a == 0) { r = g = b = 0; return *this; } r = value_type((calc_type(r) * a) >> base_shift); g = value_type((calc_type(g) * a) >> base_shift); b = value_type((calc_type(b) * a) >> base_shift); return *this;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -