minetest-mapper-cpp/Minetestmapper/PixelAttributes.h

162 lines
4.4 KiB
C
Raw Normal View History

2012-08-25 04:19:58 -07:00
/*
* =====================================================================
* Version: 1.0
* Created: 25.08.2012 10:55:29
* Author: Miroslav Bendík
* Company: LinuxOS.sk
* =====================================================================
*/
#ifndef PIXELATTRIBUTES_H_ADZ35GYF
#define PIXELATTRIBUTES_H_ADZ35GYF
2012-08-25 04:27:40 -07:00
#include <limits>
#include <cmath>
#include <cstdint>
#include <stdexcept>
Make the geometry pixel-accurate instead of map-block accurate When requesting, for instance, a 75x85 map, the mapper will now create a 75x85 map, instead of an 80x96 (or even 96x108) map as it did before. This new behavior is the default when using one of the options --centergeometry or --cornergeometry. In addition, both of these options will no longer shrink the map, to remove rows or columns of empty blocks at the edges. Previously, this behavior was enabled with --forcegeometry. An option --geometrymode has been added as well, to tune the interpretation of the geometry. It supports 4 flags: - pixel: the requested geometry is interpreted with pixel granularity. The map is not enlarged to include entire map blocks. - block: the requested geometry is interpreted with block granularity. The map is enlarged with at most 15 nodes at each of the four edges, so that it includes entire map blocks only. - fixed: a map of the requested geometry is created (after adjustmens for 'block' mode). Empty rows or columns at the edges are not removed. - shrink: Empty rows and columns at the map edges are removed to generate the smallest picture possible. Lastly, a new geometry syntax has been added, which is more compatible with known syntax (i.e. X-Windows), and which allows the offset to be optional. If the offset is omitted, the picture defaults to be centered around 0,0. `<width>x<height>[+|-<xoffset>+|-<yoffset>]` For compatibility, the behavior of the option --geometry was not changed. If (and only if) used before --geometrymode, it enables block granularity and shrink. The old option --forcegeometry is no longer documented, but still recognised for compatibility.
2014-04-15 01:46:21 -07:00
#include <cassert>
2012-09-01 05:36:14 -07:00
#include "config.h"
#include "Color.h"
2012-08-25 04:19:58 -07:00
class PixelAttribute {
public:
enum AlphaMixingMode {
AlphaMixDarkenBit = 0x01,
AlphaMixCumulative = 0x02,
AlphaMixCumulativeDarken = 0x03,
AlphaMixAverage = 0x04,
};
static void setMixMode(AlphaMixingMode mode);
PixelAttribute(): nextEmpty(true), m_n(0), m_h(NAN), m_t(0), m_a(0), m_r(0), m_g(0), m_b(0) {};
// PixelAttribute(const PixelAttribute &p);
PixelAttribute(const Color &color, double height);
PixelAttribute(const ColorEntry &entry, double height);
bool nextEmpty;
double h(void) const { return m_h / (m_n ? m_n : 1); }
double t(void) const { return m_t / (m_n ? m_n : 1); }
double a(void) const { return m_a / (m_n ? m_n : 1); }
double r(void) const { return m_r / (m_n ? m_a : 1); }
double g(void) const { return m_g / (m_n ? m_a : 1); }
double b(void) const { return m_b / (m_n ? m_a : 1); }
uint8_t red(void) const { return int(r() * 255 + 0.5); }
uint8_t green(void) const { return int(g() * 255 + 0.5); }
uint8_t blue(void) const { return int(b() * 255 + 0.5); }
uint8_t alpha(void) const { return int(a() * 255 + 0.5); }
uint8_t thicken(void) const { return int(t() * 255 + 0.5); }
unsigned height(void) const { return unsigned(h() + 0.5); }
bool isNormalized(void) const { return !m_n; }
Color color(void) const { return Color(red(), green(), blue(), alpha()); }
inline bool is_valid() const { return !std::isnan(m_h); }
PixelAttribute &operator=(const PixelAttribute &p);
void normalize(double count = 0, Color defaultColor = Color(127, 127, 127));
void add(const PixelAttribute &p);
void mixUnder(const PixelAttribute &p);
private:
static AlphaMixingMode m_mixMode;
double m_n;
double m_h;
double m_t;
double m_a;
double m_r;
double m_g;
double m_b;
friend class PixelAttributes;
2012-08-25 04:19:58 -07:00
};
class PixelAttributes
{
public:
PixelAttributes();
2012-09-01 05:36:14 -07:00
virtual ~PixelAttributes();
void setParameters(int width, int lines, int nextY, int scale, bool defaultEmpty);
void scroll(int keepY);
Make the geometry pixel-accurate instead of map-block accurate When requesting, for instance, a 75x85 map, the mapper will now create a 75x85 map, instead of an 80x96 (or even 96x108) map as it did before. This new behavior is the default when using one of the options --centergeometry or --cornergeometry. In addition, both of these options will no longer shrink the map, to remove rows or columns of empty blocks at the edges. Previously, this behavior was enabled with --forcegeometry. An option --geometrymode has been added as well, to tune the interpretation of the geometry. It supports 4 flags: - pixel: the requested geometry is interpreted with pixel granularity. The map is not enlarged to include entire map blocks. - block: the requested geometry is interpreted with block granularity. The map is enlarged with at most 15 nodes at each of the four edges, so that it includes entire map blocks only. - fixed: a map of the requested geometry is created (after adjustmens for 'block' mode). Empty rows or columns at the edges are not removed. - shrink: Empty rows and columns at the map edges are removed to generate the smallest picture possible. Lastly, a new geometry syntax has been added, which is more compatible with known syntax (i.e. X-Windows), and which allows the offset to be optional. If the offset is omitted, the picture defaults to be centered around 0,0. `<width>x<height>[+|-<xoffset>+|-<yoffset>]` For compatibility, the behavior of the option --geometry was not changed. If (and only if) used before --geometrymode, it enables block granularity and shrink. The old option --forcegeometry is no longer documented, but still recognised for compatibility.
2014-04-15 01:46:21 -07:00
PixelAttribute &attribute(int y, int x);
void renderShading(double emphasis, bool drawAlpha);
int getNextY(void) { return m_nextY; }
void setLastY(int y);
Make the geometry pixel-accurate instead of map-block accurate When requesting, for instance, a 75x85 map, the mapper will now create a 75x85 map, instead of an 80x96 (or even 96x108) map as it did before. This new behavior is the default when using one of the options --centergeometry or --cornergeometry. In addition, both of these options will no longer shrink the map, to remove rows or columns of empty blocks at the edges. Previously, this behavior was enabled with --forcegeometry. An option --geometrymode has been added as well, to tune the interpretation of the geometry. It supports 4 flags: - pixel: the requested geometry is interpreted with pixel granularity. The map is not enlarged to include entire map blocks. - block: the requested geometry is interpreted with block granularity. The map is enlarged with at most 15 nodes at each of the four edges, so that it includes entire map blocks only. - fixed: a map of the requested geometry is created (after adjustmens for 'block' mode). Empty rows or columns at the edges are not removed. - shrink: Empty rows and columns at the map edges are removed to generate the smallest picture possible. Lastly, a new geometry syntax has been added, which is more compatible with known syntax (i.e. X-Windows), and which allows the offset to be optional. If the offset is omitted, the picture defaults to be centered around 0,0. `<width>x<height>[+|-<xoffset>+|-<yoffset>]` For compatibility, the behavior of the option --geometry was not changed. If (and only if) used before --geometrymode, it enables block granularity and shrink. The old option --forcegeometry is no longer documented, but still recognised for compatibility.
2014-04-15 01:46:21 -07:00
int getLastY(void) { return m_lastY; }
2012-08-25 04:19:58 -07:00
private:
int yCoord2Line(int y) { return y - m_firstY + m_firstLine; }
2012-09-01 05:36:14 -07:00
void freeAttributes();
private:
int m_previousLine;
int m_firstLine;
int m_lastLine;
int m_emptyLine;
int m_lineCount;
PixelAttribute **m_pixelAttributes;
2012-09-01 05:36:14 -07:00
int m_width;
int m_firstY;
int m_nextY;
int m_lastY;
int m_firstUnshadedY;
int m_scale;
2012-08-25 04:19:58 -07:00
};
inline void PixelAttributes::setLastY(int y)
{
#ifdef DEBUG
assert(y - m_firstY <= m_lastLine - m_firstLine);
#else
if (y - m_firstY > m_lastLine - m_firstLine)
// Not sure whether this will actually avoid a crash...
y = m_firstY + (m_lastLine - m_firstLine);
#endif
m_lastY = y;
}
inline void PixelAttribute::setMixMode(AlphaMixingMode mode)
{
if (mode == AlphaMixDarkenBit)
mode = AlphaMixCumulativeDarken;
m_mixMode = mode;
}
Make the geometry pixel-accurate instead of map-block accurate When requesting, for instance, a 75x85 map, the mapper will now create a 75x85 map, instead of an 80x96 (or even 96x108) map as it did before. This new behavior is the default when using one of the options --centergeometry or --cornergeometry. In addition, both of these options will no longer shrink the map, to remove rows or columns of empty blocks at the edges. Previously, this behavior was enabled with --forcegeometry. An option --geometrymode has been added as well, to tune the interpretation of the geometry. It supports 4 flags: - pixel: the requested geometry is interpreted with pixel granularity. The map is not enlarged to include entire map blocks. - block: the requested geometry is interpreted with block granularity. The map is enlarged with at most 15 nodes at each of the four edges, so that it includes entire map blocks only. - fixed: a map of the requested geometry is created (after adjustmens for 'block' mode). Empty rows or columns at the edges are not removed. - shrink: Empty rows and columns at the map edges are removed to generate the smallest picture possible. Lastly, a new geometry syntax has been added, which is more compatible with known syntax (i.e. X-Windows), and which allows the offset to be optional. If the offset is omitted, the picture defaults to be centered around 0,0. `<width>x<height>[+|-<xoffset>+|-<yoffset>]` For compatibility, the behavior of the option --geometry was not changed. If (and only if) used before --geometrymode, it enables block granularity and shrink. The old option --forcegeometry is no longer documented, but still recognised for compatibility.
2014-04-15 01:46:21 -07:00
inline PixelAttribute &PixelAttributes::attribute(int y, int x)
{
#ifdef DEBUG
assert(yCoord2Line(y) >= m_firstLine && yCoord2Line(y) <= m_lastLine);
#else
static PixelAttribute p;
if (!(yCoord2Line(y) >= m_firstLine && yCoord2Line(y) <= m_lastLine))
return p;
#endif
return m_pixelAttributes[yCoord2Line(y)][x + 1];
}
//inline PixelAttribute::PixelAttribute(const PixelAttribute &p) :
//{
// operator=(p);
//}
inline PixelAttribute::PixelAttribute(const Color &color, double height) :
nextEmpty(false), m_n(0), m_h(height), m_t(0), m_a(color.a/255.0),
m_r(color.r/255.0), m_g(color.g/255.0), m_b(color.b/255.0)
{
}
inline PixelAttribute::PixelAttribute(const ColorEntry &entry, double height) :
nextEmpty(false), m_n(0), m_h(height), m_t(entry.t/255.0), m_a(entry.a/255.0),
m_r(entry.r/255.0), m_g(entry.g/255.0), m_b(entry.b/255.0)
{
}
inline PixelAttribute &PixelAttribute::operator=(const PixelAttribute &p)
{
m_n = p.m_n;
m_h = p.m_h;
m_t = p.m_t;
m_a = p.m_a;
m_r = p.m_r;
m_g = p.m_g;
m_b = p.m_b;
return *this;
}
2012-08-25 04:19:58 -07:00
#endif /* end of include guard: PIXELATTRIBUTES_H_ADZ35GYF */