/* ************************************************************************** */ /* */ /* / ) */ /* pix.hpp (\__/) ( ( */ /* ) ( ) ) */ /* By: lejulien ={ }= / / */ /* ) `-------/ / */ /* Created: 2023/01/24 01:30:02 by lejulien ( / */ /* Updated: 2023/01/28 09:49:29 by lejulien \ | */ /* */ /* ************************************************************************** */ #include "pix_font.hpp" #include #include #include #include #include #include #include /* * All code will be in header file for access simplification */ #pragma once namespace pix { typedef struct pixel { int red; int green; int blue; } pixel; typedef struct pos { int x; int y; } pos; class Image { private: int _width; int _height; std::vector _data; public: // create image from size Image(int width, int height) : _width(width), _height(height), _data(std::vector(width * height, {50, 50, 50})) { } // create image from file Image(std::string path) { if (path.length() < 4 || strcmp(&(path.c_str())[path.length() - 4], ".ppm") != 0) { std::cerr << "image is not a ppm file" << std::endl; return ; } try { std::ifstream file(path, std::ifstream::in); int value_range = 0; std::string type; file >> type >> _width >> _height >> value_range; _data = std::vector(_width * _height, {0, 0, 0}); for (int j = 0; j < _height; j++) { for (int i = 0; i < _width; i++) { int r, g, b = 0; file >> r >> g >> b; _data[i + j * _width] = {r, g, b}; } } file.close(); } catch (std::exception e) { std::cerr << "Cannot open : " << path << std::endl; } } void fillImg(pixel color) { for (int y = 0; y < _height; y++) { for (int x = 0; x < _width; x++) { _data[x + y * _width] = color; } } } void saveAs(const char *filename) { // open file std::fstream output; output.open(filename, std::fstream::in | std::fstream::out | std::fstream::app); // set header output << "P3\n"; output << _width << " " << _height << " 255\n"; // write data for (int y = 0; y < _height; y++) { for (int x = 0; x < _width; x++) { pixel pix = _data[x + y * _width]; output << pix.red << " " << pix.green << " " << pix.blue; if (x != _width - 1) output << " "; } output << "\n"; } output.close(); } void drawRect(pos p, pos size, pixel color) { for (int y = p.y; y < p.y + size.y; y++) { for (int x = p.x; x < p.x + size.x; x++) { if (x >= 0 && y >= 0 && x < _width && y < _height) _data[x + y * _width] = color; } } } void drawCircle(pos p, int radius, pixel color) { for (int y = p.y - radius; y < p.y + radius; y++) { for (int x = p.x - radius; x < p.x + radius; x++) { if (x >= 0 && y >= 0 && x <_width && y < _height) { if ((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y) < radius * radius) _data[x + y * _width] = color; } } } } void displayChar(std::vector *src, pos p, pixel color) { for (int y = 0; y < 7; y++) { for (int x = 0; x < 6; x++) if (x + p.x >= 0 && x + p.x < _width && y + p.y >= 0 && y + p.y < _height) { if ((*src)[x + y * 6]) _data[x + p.x + (y + p.y) * _width] = color; } } } void charSelector(char c, pos p, pixel color) { try { displayChar(&charset.at(tolower(c)), p, color); } catch (std::exception e) { displayChar(&inter, p, color); } } void print(std::string s, pos p, pixel color) { for (int i = 0; i < s.length(); i++) { charSelector(s[i], {p.x + i * 8, p.y}, color); } } void line(pos src, pos dst, pixel color) { pos d = {dst.x - src.x, dst.y - src.y}; pos tmp = src; int p = 2 * d.x - d.y; while (tmp.x < dst.x) { if (p >= 0) { if (tmp.x >= 0 && tmp.y >= 0 && tmp.x < _width && tmp.y < _height) _data[tmp.x + tmp.y * _width] = color; tmp.y++; p = p + 2 * d.y - 2 * d.x; } else { if (tmp.x >= 0 && tmp.y >= 0 && tmp.x < _width && tmp.y < _height) _data[tmp.x + tmp.y * _width] = color; p = p + 2 * d.y; } tmp.x++; } } }; };