Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

282 lines (243 sloc) 5.922 kb
#include <sstream>
#include <string>
#include <vector>
#include "color_chart.hpp"
#include "graphics.hpp"
#include "color_utils.hpp"
#include "string_utils.hpp"
#include "unit_test.hpp"
#include "utils.hpp"
SDL_Color string_to_color(const std::string& str)
{
SDL_Color res = {0,0,0,0};
if(str.size() == 6) {
unsigned int num = strtol(str.c_str(), NULL, 16);
res.r = (num >> 16)&0xFF;
res.g = (num >> 8)&0xFF;
res.b = num&0xFF;
}
return res;
}
namespace graphics {
color::color( int r, int g, int b, int a)
{
c_.rgba[0] = truncate_to_char(r);
c_.rgba[1] = truncate_to_char(g);
c_.rgba[2] = truncate_to_char(b);
c_.rgba[3] = truncate_to_char(a);
}
color::color( uint32_t rgba)
{
c_.value = rgba;
c_ = convert_pixel_byte_order(c_);
}
color::color( const std::string& str)
{
std::vector<std::string> components;
components = util::split(str);
if( components.size() == 4){
int i=0;
for( std::vector<std::string>::iterator itor = components.begin();
itor != components.end(); ++itor)
{
c_.rgba[i] = atoi(itor->c_str());
++i;
}
} else if ( components.size() == 3){ //assume that the fourth value, alpha, is 255
int i=0;
for( std::vector<std::string>::iterator itor = components.begin();
itor != components.end(); ++itor)
{
c_.rgba[i] = atoi(itor->c_str());
++i;
}
c_.rgba[3] = 255; //no need to read the string element, b/c there isn't one
} else {
//c_.value = 0;
SDL_Color c = graphics::get_color_from_name(str);
c_.rgba[0] = c.r;
c_.rgba[1] = c.g;
c_.rgba[2] = c.b;
c_.rgba[3] = c.unused;
}
}
color::color(const SDL_Color& col)
{
c_.rgba[0] = col.r;
c_.rgba[1] = col.g;
c_.rgba[2] = col.b;
c_.rgba[3] = 255;
}
color::color(const variant& v)
{
if(v.is_string()) {
*this = color(graphics::get_color_from_name(v.as_string()));
} else {
std::vector<int> vec = v.as_list_int();
const int r = vec.size() > 0 ? vec[0] : 0;
const int g = vec.size() > 1 ? vec[1] : 0;
const int b = vec.size() > 2 ? vec[2] : 0;
const int a = vec.size() > 3 ? vec[3] : 255;
*this = color(r,g,b,a);
}
}
variant color::write() const
{
std::vector<variant> v;
v.reserve(4);
v.push_back(variant(static_cast<int>(r())));
v.push_back(variant(static_cast<int>(g())));
v.push_back(variant(static_cast<int>(b())));
v.push_back(variant(static_cast<int>(a())));
return variant(&v);
}
variant color::get_value(const std::string& key) const
{
if(key == "r"){
return variant(r());
} else if(key == "g"){
return variant(g());
} else if(key == "b"){
return variant(b());
} else if(key == "a"){
return variant(a());
} else {
return variant();
}
}
void color::set_as_current_color() const
{
glColor4ub(c_.rgba[0], c_.rgba[1], c_.rgba[2], c_.rgba[3]);
}
void color::add_to_vector(std::vector<GLfloat>* v) const
{
v->push_back(r()/255.0);
v->push_back(g()/255.0);
v->push_back(b()/255.0);
v->push_back(a()/255.0);
}
SDL_Color color::as_sdl_color() const
{
SDL_Color result = {r(), g(), b(), a()};
return result;
}
color_transform::color_transform(const color& c)
{
rgba_[0] = c.r();
rgba_[1] = c.g();
rgba_[2] = c.b();
rgba_[3] = c.a();
}
color_transform::color_transform(int16_t r, int16_t g, int16_t b, int16_t a)
{
rgba_[0] = r;
rgba_[1] = g;
rgba_[2] = b;
rgba_[3] = a;
}
color_transform::color_transform(const std::string& str)
{
std::fill(rgba_, rgba_ + 4, 255);
std::vector<std::string> components = util::split(str);
for(int n = 0; n != components.size(); ++n) {
if(n < 4) {
rgba_[n] = atoi(components[n].c_str());
}
}
}
color_transform::color_transform(const variant& v)
{
for(int n = 0; n != 4; ++n) {
if(n < v.num_elements()) {
rgba_[n] = v[n].as_int();
} else {
rgba_[n] = 255;
}
}
}
variant color_transform::write() const
{
std::vector<variant> res;
for(int n = 0; n != 4; ++n) {
res.push_back(variant(static_cast<int>(rgba_[n])));
}
return variant(&res);
}
std::string color_transform::to_string() const
{
std::ostringstream s;
for(int n = 0; n != 4; ++n) {
if(n) {
s << ",";
}
s << rgba_[n];
}
return s.str();
}
variant color_transform::get_value(const std::string& key) const
{
if(key == "r"){
return variant(r());
} else if(key == "g"){
return variant(g());
} else if(key == "b"){
return variant(b());
} else if(key == "a"){
return variant(a());
} else {
return variant();
}
}
namespace {
int16_t clip(int16_t val) {
return val < 0 ? 0 : (val > 255 ? 255 : val);
}
}
color color_transform::to_color() const
{
return color(clip(r()),clip(g()),clip(b()),clip(a()));
}
bool color_transform::fits_in_color() const
{
for(int n = 0; n != 4; ++n) {
if(rgba_[n] > 255) {
return false;
}
}
return true;
}
color_transform operator+(const color_transform& a, const color_transform& b)
{
return color_transform(a.r() + b.r(), a.g() + b.g(), a.b() + b.b(), std::max(a.a(), b.a()));
}
color_transform operator-(const color_transform& a, const color_transform& b)
{
color_transform result = a;
for(int n = 0; n != 3; ++n) {
if(result.buf()[n] > b.buf()[n]) {
result.buf()[n] -= b.buf()[n];
} else {
result.buf()[n] = 0;
}
}
if(result.buf()[3] > 255) {
result.buf()[3] = 255;
}
return result;
}
UNIT_TEST(color)
{
//check that a value plugged into the color is returned when we
//ask for it.
CHECK_EQ(color(758492).rgba(), 758492);
//check that an rgba value is equal to an expected int value.
CHECK_EQ(color(255,255,0,255).rgba(), color(0xFFFF00FF).rgba());
//check that parsing from a string works properly
CHECK_EQ(color("255,128,255,128").rgba(), color(255,128,255,128).rgba());
//it would be nice to be able to specify a string with three instead of
//four values, and have it just assume 255 for the alpha.
CHECK_EQ(color("255,128,255").rgba(), color(255,128,255,255).rgba());
//check that we can get a value out of a color
CHECK_EQ(color(255,128,64,0).get_value("g").as_int(), 128);
}
}
Jump to Line
Something went wrong with that request. Please try again.