diff --git a/src/input_file.cpp b/src/input_file.cpp index fd65db1..717d441 100644 --- a/src/input_file.cpp +++ b/src/input_file.cpp @@ -14,16 +14,8 @@ InputFile::InputFile(const std::filesystem::path& path) : m_file(path), m_cmdsProcessed(0) { - if (m_file.bad()) - { - throw std::runtime_error("Cannot open " + path.string() + " for reading"); - } -} - -// istream >> operator for math::Vector -static std::istream& operator>>(std::istream& is, math::Vector& vec) -{ - return is >> vec.x >> vec.y; + if (!m_file) + throw std::runtime_error(std::format("Cannot open {} for reading", path.string())); } // command name -> command handler map @@ -53,12 +45,6 @@ const char* GetTypeName() return "float"; } -template <> -const char* GetTypeName() -{ - return "vector"; -} - template <> const char* GetTypeName() { @@ -78,7 +64,7 @@ static T ReadVal(std::istream& is) T v; is >> v; - if (is.bad()) + if (!is) throw std::runtime_error(std::format("Could not parse {} from stream", GetTypeName())); return v; @@ -166,7 +152,7 @@ shapes::Group InputFile::Parse() auto cmd = cmds.find(cmdName); if (cmd == cmds.end()) - throw std::runtime_error("Unknown command: " + cmdName); + throw std::runtime_error(std::format("Unknown command: {}", cmdName)); cmd->second(iss); ++m_cmdsProcessed; diff --git a/src/renderers/bitmap.hpp b/src/renderers/bitmap.hpp index ccd2ff7..174562a 100644 --- a/src/renderers/bitmap.hpp +++ b/src/renderers/bitmap.hpp @@ -2,64 +2,37 @@ #include #include +#include #include -class Color +using Color = uint8_t; + +namespace colors { -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); - } -}; +constexpr Color BLACK{0}; +constexpr Color WHITE{1}; +} // namespace colors class Bitmap { public: - Bitmap(size_t width, size_t height, const Color& clearColor) + Bitmap(size_t width, size_t height, 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]; }; + 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}; }; 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) + void SetPixel(int x, int y, Color color) { if (x < 0 || y < 0 || x >= m_width || y >= m_height) - return; // out of bounds + return; // out of bounds, ignore - (*this)[y][x].Blend(color, alpha); + (*this)[y][x] = color; } private: diff --git a/src/renderers/pgm_renderer.cpp b/src/renderers/pgm_renderer.cpp index 85a1be7..4d6ca2d 100644 --- a/src/renderers/pgm_renderer.cpp +++ b/src/renderers/pgm_renderer.cpp @@ -3,7 +3,7 @@ #include #include -PgmRenderer::PgmRenderer(size_t width, size_t height) : m_bitmap(width, height, Color{0xFF}) {} +PgmRenderer::PgmRenderer(size_t width, size_t height) : m_bitmap(width, height, colors::WHITE) {} void PgmRenderer::DrawLine(const math::Vector& p0, const math::Vector& p1) { @@ -47,13 +47,13 @@ void PgmRenderer::Save(const std::filesystem::path& path) file << "P2" << std::endl; file << "# KIV/CPP" << std::endl; file << m_bitmap.GetWidth() << ' ' << m_bitmap.GetHeight() << std::endl; - file << 255 << std::endl; + file << 1 << std::endl; for (size_t y = 0; y < m_bitmap.GetHeight(); ++y) { for (size_t x = 0; x < m_bitmap.GetWidth(); ++x) { - file << static_cast(m_bitmap[y][x].l) << ' '; + file << static_cast(m_bitmap[y][x]) << ' '; } file << std::endl; @@ -62,9 +62,7 @@ void PgmRenderer::Save(const std::filesystem::path& path) void PgmRenderer::RasterizeLine(int x0, int y0, int x1, int y1) { - // TODO: fix - const Color lineColor{0x00}; - float w = 2.0f; + int w = 2; // thickness int dx = abs(x1 - x0); int dy = abs(y1 - y0); @@ -90,7 +88,7 @@ void PgmRenderer::RasterizeLine(int x0, int y0, int x1, int y1) { for (int j = -w / 2; j <= w / 2; j++) { - m_bitmap.Put(x0 + i * ox, y0 + j * oy, lineColor, 0xFF); + m_bitmap.SetPixel(x0 + i * ox, y0 + j * oy, colors::BLACK); } } @@ -112,10 +110,7 @@ void PgmRenderer::RasterizeLine(int x0, int y0, int x1, int y1) void PgmRenderer::RasterizeCircle(int cx, int cy, int r) { - // TODO: fix - - const Color circleColor{0x00}; - float w = 2.0f; + int w = 2; // thickness int r_outer = r + w / 2; int r_inner = r - w / 2; @@ -129,7 +124,7 @@ void PgmRenderer::RasterizeCircle(int cx, int cy, int r) int dist2 = x * x + y * y; if (dist2 <= r_outer * r_outer && dist2 >= r_inner * r_inner) { - m_bitmap.Put(cx + x, cy + y, circleColor, 0xFF); + m_bitmap.SetPixel(cx + x, cy + y, colors::BLACK); } } } diff --git a/src/renderers/svg_renderer.cpp b/src/renderers/svg_renderer.cpp index 138a3fb..195447a 100644 --- a/src/renderers/svg_renderer.cpp +++ b/src/renderers/svg_renderer.cpp @@ -1,33 +1,40 @@ #include "svg_renderer.hpp" #include "math/constants.hpp" +#include #include SvgRenderer::SvgRenderer(size_t width, size_t height) : m_width{width}, m_height{height} { // white bg - m_out << " " << std::endl; + m_out << R"SVG( )SVG" << std::endl; } void SvgRenderer::DrawLine(const math::Vector& p0, const math::Vector& p1) { - m_out << " " << std::endl; + m_out + << std::format( + R"SVG( )SVG", + p0.x, p0.y, p1.x, p1.y) + << std::endl; } void SvgRenderer::DrawRectangle(const math::Vector& pos, const math::Vector& size, float angle) { float angleDeg = angle * math::RAD_TO_DEG; - m_out << " " << std::endl; + m_out + << std::format( + R"SVG( )SVG", + pos.x, pos.y, size.x, size.y, angleDeg) + << std::endl; } void SvgRenderer::DrawCircle(const math::Vector& center, float radius) { - m_out << " " << std::endl; + m_out << std::format(R"SVG( )SVG", + center.x, center.y, radius) + << std::endl; } void SvgRenderer::Save(const std::filesystem::path& path) @@ -38,9 +45,12 @@ void SvgRenderer::Save(const std::filesystem::path& path) { throw std::runtime_error{"Cannot open file for writing: " + path.string()}; } - - file << "" << std::endl; + + file + << std::format( + R"SVG()SVG", + m_width, m_height) + << std::endl; file << m_out.str();