Move color string parsing to constructor of class Color & add a constructor using an integer

Added formats for Color constructor:
- plain interger (2^24 * alpha + 2^16 * red + 2^8 * green + blue)
- Color string consisting of:
  - '#'
  - 3, 4, 6 or 8 hex digits
master
Rogier 2014-04-24 15:59:41 +02:00
parent 6ccb2285a1
commit 5e4ee45575
6 changed files with 83 additions and 43 deletions

View File

@ -80,6 +80,7 @@ set(mapper_SRCS
PlayerAttributes.cpp
TileGenerator.cpp
ZlibDecompressor.cpp
Color.cpp
mapper.cpp
db-sqlite3.cpp
)

54
Color.cpp Normal file
View File

@ -0,0 +1,54 @@
#include <cctype>
#include <stdexcept>
#include "Color.h"
// alpha:
// 0: don't expect/allow alpha
// 1: allow alpha; defaults to 255 (0xff)
// -1: allow alpha but ignore - set to to 255 (0xff)
Color::Color(const std::string &color, int alpha)
{
if (color[0] != '#') {
throw std::runtime_error("Color does not begin with #");
}
if (std::string::npos != color.find_first_not_of("0123456789abcdefABCDEF",1)) {
throw std::runtime_error("Color value has invalid digits (expected: [0-9a-zA-Z])");
}
if (alpha) {
if (color.length() != 4 && color.length() != 5 && color.length() != 7 && color.length() != 9)
throw std::runtime_error("Color not in the expected format (#xxx, #xxxx, #xxxxxx or #xxxxxxxx)");
}
else {
if (color.length() == 5 || color.length() == 9)
throw std::runtime_error("Color not in the expected format (#xxx or #xxxxxx) - alpha not allowed");
if (color.length() != 4 && color.length() != 7)
throw std::runtime_error("Color not in the expected format (#xxx or #xxxxxx)");
}
unsigned col = strtoul(color.c_str() + 1, NULL, 16);
if (color.length() < 6) {
if (color.length() == 5)
a = (col >> 12) & 0x0f;
else
a = 0x0f;
a |= a << 4;
r = (col >> 8) & 0x0f;
r |= r << 4;
g = (col >> 4) & 0x0f;
g |= g << 4;
b = (col >> 0) & 0x0f;
b |= b << 4;
}
else {
if (color.length() == 9)
a = (col >> 24) & 0xff;
else
a = 0xff;
r = (col >> 16) & 0xff;
g = (col >> 8) & 0xff;
b = (col >> 0) & 0xff;
}
if (alpha <= 0)
a = 0xff;
}

View File

@ -2,10 +2,14 @@
#ifndef COLOR_H
#define COLOR_H
#include <string>
struct Color {
Color(): r(0xFF), g(0xFF), b(0xFF), a(0) {};
Color(uint8_t r, uint8_t g, uint8_t b): r(r), g(g), b(b), a(0xFF) {};
Color(): r(0xff), g(0xff), b(0xff), a(0) {};
Color(uint32_t c): r((c >> 16) & 0xff), g((c >> 8) & 0xff), b((c >> 0) & 0xff ), a((c >> 24) & 0xff) {};
Color(uint8_t r, uint8_t g, uint8_t b): r(r), g(g), b(b), a(0xff) {};
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a): r(r), g(g), b(b), a(a) {};
Color(const std::string &s, int alpha = 1);
Color &operator=(const Color &c);
unsigned to_uint() const { return (unsigned(a) << 24) + (unsigned(r) << 16) + (unsigned(g) << 8) + unsigned(b); }
//libgd treats 255 as transparent, and 0 as opaque ...

View File

@ -128,9 +128,9 @@ TileGenerator::~TileGenerator()
{
}
void TileGenerator::setBgColor(const std::string &bgColor)
void TileGenerator::setBgColor(const Color &bgColor)
{
m_bgColor = parseColor(bgColor);
m_bgColor = bgColor;
}
void TileGenerator::setShrinkGeometry(bool shrink)
@ -148,24 +148,24 @@ void TileGenerator::setSqliteCacheWorldRow(bool cacheWorldRow)
m_sqliteCacheWorldRow = cacheWorldRow;
}
void TileGenerator::setScaleColor(const std::string &scaleColor)
void TileGenerator::setScaleColor(const Color &scaleColor)
{
m_scaleColor = parseColor(scaleColor);
m_scaleColor = scaleColor;
}
void TileGenerator::setOriginColor(const std::string &originColor)
void TileGenerator::setOriginColor(const Color &originColor)
{
m_originColor = parseColor(originColor);
m_originColor = originColor;
}
void TileGenerator::setPlayerColor(const std::string &playerColor)
void TileGenerator::setPlayerColor(const Color &playerColor)
{
m_playerColor = parseColor(playerColor);
m_playerColor = playerColor;
}
void TileGenerator::setTileBorderColor(const std::string &tileBorderColor)
void TileGenerator::setTileBorderColor(const Color &tileBorderColor)
{
m_tileBorderColor = parseColor(tileBorderColor);
m_tileBorderColor = tileBorderColor;
}
void TileGenerator::setTileBorderSize(int size)
@ -185,25 +185,6 @@ void TileGenerator::setTileOrigin(int x, int y)
m_tileZOrigin = y;
}
Color TileGenerator::parseColor(const std::string &color)
{
Color parsed;
if (color.length() != 7) {
throw std::runtime_error("Color not 7 characters long");
}
if (color[0] != '#') {
throw std::runtime_error("Color does not begin with #");
}
long col = strtol(color.c_str() + 1, NULL, 16);
parsed.a = 255;
parsed.b = col % 256;
col = col / 256;
parsed.g = col % 256;
col = col / 256;
parsed.r = col % 256;
return parsed;
}
void TileGenerator::setDrawOrigin(bool drawOrigin)
{
m_drawOrigin = drawOrigin;

View File

@ -86,11 +86,11 @@ private:
public:
TileGenerator();
~TileGenerator();
void setBgColor(const std::string &bgColor);
void setScaleColor(const std::string &scaleColor);
void setOriginColor(const std::string &originColor);
void setPlayerColor(const std::string &playerColor);
Color parseColor(const std::string &color);
void setBgColor(const Color &bgColor);
void setScaleColor(const Color &scaleColor);
void setOriginColor(const Color &originColor);
void setPlayerColor(const Color &playerColor);
Color parseColor(const Color &color);
void setDrawOrigin(bool drawOrigin);
void setDrawPlayers(bool drawPlayers);
void setDrawScale(bool drawScale);
@ -102,7 +102,7 @@ public:
void setShrinkGeometry(bool shrink);
void setBlockGeometry(bool block);
void setSqliteCacheWorldRow(bool cacheWorldRow);
void setTileBorderColor(const std::string &tileBorderColor);
void setTileBorderColor(const Color &tileBorderColor);
void setTileBorderSize(int size);
void setTileSize(int width, int heigth);
void setTileOrigin(int x, int y);

View File

@ -49,7 +49,7 @@ void usage()
" --tileorigin <x>,<y>|center-world|center-map\n"
" --verbose[=n]\n"
" --progress\n"
"Color format: '#000000'\n"
"Color format: '#000' or '#000000'\n"
"Geometry formats:\n"
"\t<width>x<heigth>[+|-<xoffset>+|-<yoffset>]\n"
"\t<xoffset>:<yoffset>+<width>+<height>\n";
@ -122,19 +122,19 @@ int main(int argc, char *argv[])
colorsFile = optarg;
break;
case 'b':
generator.setBgColor(optarg);
generator.setBgColor(Color(optarg, 0));
break;
case 's':
generator.setScaleColor(optarg);
generator.setScaleColor(Color(optarg,0));
break;
case 'r':
generator.setOriginColor(optarg);
generator.setOriginColor(Color(optarg,0));
break;
case 'p':
generator.setPlayerColor(optarg);
generator.setPlayerColor(Color(optarg,0));
break;
case 'B':
generator.setTileBorderColor(optarg);
generator.setTileBorderColor(Color(optarg,0));
break;
case 'R':
generator.setDrawOrigin(true);