#include "./Surface.h" #include "./Display.h" #include Surface::Surface(Display* dpy, const VirtualCoordinates& start, const VirtualCoordinates& end) : start(dpy->coordinateMapping()->virtualToPhysicalCoords(start)), end(dpy->coordinateMapping()->virtualToPhysicalCoords(end)), virtStart(start), virtEnd(end), m_display(dpy) { //assert(start.x <= end.x); //assert(start.y <= end.y); } Surface::Surface(Display* dpy, const VirtualCoordinates& start, const VirtualCoordinates& end, uint8_t rotation) : start(dpy->coordinateMapping()->virtualToPhysicalCoords(start)), end(dpy->coordinateMapping()->virtualToPhysicalCoords(end)), virtStart(start), virtEnd(end), m_display(dpy), m_rotation(rotation) { //assert(start.x <= end.x); //assert(start.y <= end.y); } Surface& Surface::operator=(const CRGB& color) { paintWith([&](CRGB& pixel) { pixel = color; }); return *this; } Surface& Surface::operator+=(const CRGB& color) { paintWith([&](CRGB& pixel) { pixel += color; }); return *this; } void Surface::paintWith(std::function func) { paintShader([=](CRGB& pixel, const VirtualCoordinates&, const PhysicalCoordinates&, const VirtualCoordinates&){ func(pixel); }); } void Surface::paintShader(Surface::Shader shader) { uint8_t startX = min(start.x, end.x); uint8_t startY = min(start.y, end.y); uint8_t endX = max(start.x, end.x); uint8_t endY = max(start.y, end.y); const uint16_t width = endX - startX + 1; const uint16_t height = endY - startY + 1; const uint8_t xMod = 255 / width; const uint8_t yMod = 255 / height; for(auto x = 0; x < width; x++) { for(auto y = 0; y < height; y++) { PhysicalCoordinates coords{x + startX, y + startY}; VirtualCoordinates virtCoords{m_display->coordinateMapping()->physicalToVirtualCoords(coords)}; VirtualCoordinates surfaceCoords{xMod * x, yMod * y}; //Log.notice("width=%d height=%d vx=%d vy=%d sx=%d sy=%d x=%d y=%d px=%d py=%d", width, height, startX, startY, x, y, coords.x, coords.y); // 256 = 1.0 // 128 = 0.0 // 0 = 1.0 shader(m_display->pixelAt(coords), virtCoords, coords, surfaceCoords); } } }