Add an include directive for colors files
A colors file can now specify other colors files, from which additional node color specifications will be read. This allows, for instance, using system-installed colors file for most colors, and only overriding some of its colors in a custom colors file. As a purpose of using a custom colors file may be to leave the colors for some nodes undefined, it is now also possible to undefine a previously defined node color (i.e. after reading another colors file which defines a color for the node).
This commit is contained in:
parent
224c6b1df7
commit
e6322f2911
17
README.rst
17
README.rst
@ -89,6 +89,23 @@ colors <file>:
|
|||||||
# Entry that is used with 'drawalpha':
|
# Entry that is used with 'drawalpha':
|
||||||
default:water-source 78 132 212 64 224
|
default:water-source 78 132 212 64 224
|
||||||
|
|
||||||
|
The colors file can include other colors files using:
|
||||||
|
`@include filename`
|
||||||
|
Any entries after the inclusion point override entries from the
|
||||||
|
included file. Already defined colors can be 'undefined' by specifying
|
||||||
|
'-' as color:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
default:stone 71 68 67
|
||||||
|
# default-colors.txt might override the color of default:stone
|
||||||
|
@include default-colors.txt
|
||||||
|
# color of default:dirt_with_grass from default-colors.txt is overridden:
|
||||||
|
default:dirt_with_grass 82 117 54
|
||||||
|
# Color of water is undefined here:
|
||||||
|
default:water_source -
|
||||||
|
default:water_flowing -
|
||||||
|
|
||||||
bgcolor:
|
bgcolor:
|
||||||
Background color of image, `--bgcolor #ffffff`
|
Background color of image, `--bgcolor #ffffff`
|
||||||
|
|
||||||
|
@ -325,9 +325,11 @@ void TileGenerator::setMaxY(int y)
|
|||||||
m_reqYMaxNode = y - 16 * m_reqYMax;
|
m_reqYMaxNode = y - 16 * m_reqYMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileGenerator::parseColorsFile(const std::string &fileName)
|
void TileGenerator::parseColorsFile(const std::string &fileName, int depth)
|
||||||
{
|
{
|
||||||
if (verboseReadColors >= 2)
|
if (depth > 100)
|
||||||
|
throw std::runtime_error(std::string("Excessive inclusion depth of colors files - suspected recursion (i.e. cycle); current file: '") + fileName + "'");
|
||||||
|
if (depth == 0 && verboseReadColors >= 2)
|
||||||
cout << "Checking for colors file: " << fileName << std::endl;
|
cout << "Checking for colors file: " << fileName << std::endl;
|
||||||
ifstream in;
|
ifstream in;
|
||||||
in.open(fileName.c_str(), ifstream::in);
|
in.open(fileName.c_str(), ifstream::in);
|
||||||
@ -337,7 +339,7 @@ void TileGenerator::parseColorsFile(const std::string &fileName)
|
|||||||
}
|
}
|
||||||
if (verboseReadColors >= 1)
|
if (verboseReadColors >= 1)
|
||||||
cout << "Reading colors file: " << fileName << std::endl;
|
cout << "Reading colors file: " << fileName << std::endl;
|
||||||
parseColorsStream(in, fileName.c_str());
|
parseColorsStream(in, fileName.c_str(), depth);
|
||||||
in.close();
|
in.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,7 +376,7 @@ void TileGenerator::generate(const std::string &input, const std::string &output
|
|||||||
printUnknown();
|
printUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileGenerator::parseColorsStream(std::istream &in, const std::string &filename)
|
void TileGenerator::parseColorsStream(std::istream &in, const std::string &filename, int depth)
|
||||||
{
|
{
|
||||||
string line;
|
string line;
|
||||||
int linenr = 0;
|
int linenr = 0;
|
||||||
@ -388,45 +390,79 @@ void TileGenerator::parseColorsStream(std::istream &in, const std::string &filen
|
|||||||
iline >> std::skipws;
|
iline >> std::skipws;
|
||||||
string name;
|
string name;
|
||||||
ColorEntry color;
|
ColorEntry color;
|
||||||
iline >> name;
|
iline >> name >> std::ws;
|
||||||
if (name.length() == 0)
|
if (name.length() == 0)
|
||||||
continue;
|
continue;
|
||||||
int r, g, b, a, t;
|
if (name == "@include") {
|
||||||
iline >> r;
|
string includeFile;
|
||||||
iline >> g;
|
getline(iline,includeFile);
|
||||||
iline >> b;
|
size_t lastChar = includeFile.find_last_not_of(" \t\r\n");
|
||||||
if (iline.fail()) {
|
if (lastChar != string::npos)
|
||||||
std::cerr << filename << ":" << linenr << ": bad line in colors file (" << line << ")" << std::endl;
|
includeFile.erase(lastChar + 1);
|
||||||
continue;
|
if (includeFile == "") {
|
||||||
}
|
std::cerr << filename << ":" << linenr << ": include filename missing in colors file (" << line << ")" << std::endl;
|
||||||
a = 0xff;
|
continue;
|
||||||
iline >> a;
|
}
|
||||||
t = 0;
|
#if ! (MSDOS || __OS2__ || __NT__ || _WIN32)
|
||||||
iline >> t;
|
// This same feature seems needlessly complicated on windows - so it is not supported
|
||||||
color = ColorEntry(r,g,b,a,t);
|
if (includeFile[0] != '/') {
|
||||||
if ((m_drawAlpha && a == 0xff) || (!m_drawAlpha && a != 0xff)) {
|
string includePath = filename;
|
||||||
// If drawing alpha, and the colors file contains both
|
size_t offset = includePath.find_last_of('/');
|
||||||
// an opaque entry and a non-opaque entry for a name, prefer
|
if (offset != string::npos) {
|
||||||
// the non-opaque entry
|
includePath.erase(offset);
|
||||||
// If not drawing alpha, and the colors file contains both
|
includeFile = includePath + '/' + includeFile;
|
||||||
// an opaque entry and a non-opaque entry for a name, prefer
|
|
||||||
// the opaque entry
|
|
||||||
// Otherwise, any later entry overrides any previous entry
|
|
||||||
ColorMap::iterator it = m_colors.find(name);
|
|
||||||
if (it != m_colors.end()) {
|
|
||||||
if (m_drawAlpha && (a == 0xff && it->second.a != 0xff)) {
|
|
||||||
// drawing alpha: don't use opaque color to override
|
|
||||||
// non-opaque color
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!m_drawAlpha && (a != 0xff && it->second.a == 0xff)) {
|
|
||||||
// not drawing alpha: don't use non-opaque color to
|
|
||||||
// override opaque color
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
parseColorsFile(includeFile, depth + 1);
|
||||||
|
}
|
||||||
|
else if (iline.good() && iline.peek() == '-') {
|
||||||
|
char c;
|
||||||
|
iline >> c >> std::ws;
|
||||||
|
if (iline.bad() || !iline.eof()) {
|
||||||
|
std::cerr << filename << ":" << linenr << ": bad line in colors file (" << line << ")" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m_colors.erase(name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int r, g, b, a, t;
|
||||||
|
iline >> r;
|
||||||
|
iline >> g;
|
||||||
|
iline >> b;
|
||||||
|
if (iline.fail()) {
|
||||||
|
std::cerr << filename << ":" << linenr << ": bad line in colors file (" << line << ")" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
a = 0xff;
|
||||||
|
iline >> a;
|
||||||
|
t = 0;
|
||||||
|
iline >> t;
|
||||||
|
color = ColorEntry(r,g,b,a,t);
|
||||||
|
if ((m_drawAlpha && a == 0xff) || (!m_drawAlpha && a != 0xff)) {
|
||||||
|
// If drawing alpha, and the colors file contains both
|
||||||
|
// an opaque entry and a non-opaque entry for a name, prefer
|
||||||
|
// the non-opaque entry
|
||||||
|
// If not drawing alpha, and the colors file contains both
|
||||||
|
// an opaque entry and a non-opaque entry for a name, prefer
|
||||||
|
// the opaque entry
|
||||||
|
// Otherwise, any later entry overrides any previous entry
|
||||||
|
ColorMap::iterator it = m_colors.find(name);
|
||||||
|
if (it != m_colors.end()) {
|
||||||
|
if (m_drawAlpha && (a == 0xff && it->second.a != 0xff)) {
|
||||||
|
// drawing alpha: don't use opaque color to override
|
||||||
|
// non-opaque color
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!m_drawAlpha && (a != 0xff && it->second.a == 0xff)) {
|
||||||
|
// not drawing alpha: don't use non-opaque color to
|
||||||
|
// override opaque color
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_colors[name] = color;
|
||||||
}
|
}
|
||||||
m_colors[name] = color;
|
|
||||||
}
|
}
|
||||||
if (!in.eof()) {
|
if (!in.eof()) {
|
||||||
std::cerr << filename << ": error reading colors file after line " << linenr << std::endl;
|
std::cerr << filename << ": error reading colors file after line " << linenr << std::endl;
|
||||||
|
@ -105,12 +105,12 @@ public:
|
|||||||
void setTileOrigin(int x, int y);
|
void setTileOrigin(int x, int y);
|
||||||
void setTileCenter(int x, int y);
|
void setTileCenter(int x, int y);
|
||||||
void enableProgressIndicator(void);
|
void enableProgressIndicator(void);
|
||||||
void parseColorsFile(const std::string &fileName);
|
void parseColorsFile(const std::string &fileName, int depth = 0);
|
||||||
void setBackend(std::string backend);
|
void setBackend(std::string backend);
|
||||||
void generate(const std::string &input, const std::string &output);
|
void generate(const std::string &input, const std::string &output);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parseColorsStream(std::istream &in, const std::string &filename);
|
void parseColorsStream(std::istream &in, const std::string &filename, int depth);
|
||||||
std::string getWorldDatabaseBackend(const std::string &input);
|
std::string getWorldDatabaseBackend(const std::string &input);
|
||||||
void openDb(const std::string &input);
|
void openDb(const std::string &input);
|
||||||
void loadBlocks();
|
void loadBlocks();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user