#pragma once #include #include #include class Color { public: Color() : l{0} {} Color(uint8_t l) : l{l} {} uint8_t l{}; // luminence void Blend(const Color& src, uint8_t alpha) { l = BlendChannel(l, src.l, alpha); // l = alpha; } private: static uint8_t BlendChannel(uint8_t a, uint8_t b, uint8_t alpha) { return static_cast( (static_cast(a) * (255 - static_cast(alpha)) + static_cast(b) * static_cast(alpha)) / 255); } }; class Bitmap { public: Bitmap(size_t width, size_t height, const Color& clearColor) : m_width(width), m_height(height), m_data(width * height, clearColor) { } // std::span operator[](size_t row) // { // return {&m_data[row * m_width], m_width}; // }; // std::span operator[](size_t row) const // { // return {&m_data[row * m_width], m_width}; // }; Color* operator[](size_t row) { return &m_data[row * m_width]; }; const Color* operator[](size_t row) const { return &m_data[row * m_width]; }; size_t GetWidth() const { return m_width; } size_t GetHeight() const { return m_height; } void Put(int x, int y, const Color& color, uint8_t alpha) { if (x < 0 || y < 0 || x >= m_width || y >= m_height) return; // out of bounds (*this)[y][x].Blend(color, alpha); } private: size_t m_width, m_height; std::vector m_data; };