162 lines
4.4 KiB
C++
162 lines
4.4 KiB
C++
/*
|
|
* =====================================================================
|
|
* 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
|
|
|
|
#include <limits>
|
|
#include <cmath>
|
|
#include <stdint.h>
|
|
#include <stdexcept>
|
|
#include <cassert>
|
|
#include "config.h"
|
|
#include "Color.h"
|
|
|
|
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;
|
|
};
|
|
|
|
class PixelAttributes
|
|
{
|
|
public:
|
|
PixelAttributes();
|
|
virtual ~PixelAttributes();
|
|
void setParameters(int width, int lines, int nextY, int scale, bool defaultEmpty);
|
|
void scroll(int keepY);
|
|
PixelAttribute &attribute(int y, int x);
|
|
void renderShading(double emphasis, bool drawAlpha);
|
|
int getNextY(void) { return m_nextY; }
|
|
void setLastY(int y);
|
|
int getLastY(void) { return m_lastY; }
|
|
|
|
private:
|
|
int yCoord2Line(int y) { return y - m_firstY + m_firstLine; }
|
|
void freeAttributes();
|
|
|
|
private:
|
|
int m_previousLine;
|
|
int m_firstLine;
|
|
int m_lastLine;
|
|
int m_emptyLine;
|
|
int m_lineCount;
|
|
PixelAttribute **m_pixelAttributes;
|
|
int m_width;
|
|
int m_firstY;
|
|
int m_nextY;
|
|
int m_lastY;
|
|
int m_firstUnshadedY;
|
|
int m_scale;
|
|
};
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
#endif /* end of include guard: PIXELATTRIBUTES_H_ADZ35GYF */
|
|
|