#pragma once #include #include "./Geometry.h" #include class Display; /** * A high performance and hardware-independent rendering surface which * represents a full 2d display ranging from (0,0) to (255, 255), that may be * rotated. * * Simple brushes and complex shaders may be applied to a Surface using * @paintWith and @paintShader. The Surface will only execute each shader or * brush once for each physical pixel in the display, allowing you to design * display-independent graphics. */ class Surface { public: Surface(Display* dpy, const VirtualCoordinates& start, const VirtualCoordinates& end); Surface(Display* dpy, const VirtualCoordinates& start, const VirtualCoordinates& end, uint8_t rotation); /** * Sets the entire surface to one solid color */ Surface& operator=(const CRGB& color); /** * Adds the given color to every pixel on the surface */ Surface& operator+=(const CRGB& color); /** * OR operation that applies the given color to every pixel on the surface */ template Surface& operator|=(const T& val) { paintWith([&](CRGB& pixel) { pixel |= val; }); return *this; } /** * A lambda function that maps coordinates to colors. */ using Shader = std::function; /** * A simple lambda that is called for every pixel in a surface. Commonly * used for solid fills; if you want to map pixel coordinates to colors or * textures, you probably want to use a Shader instead. */ using BrushFunc = std::function; /** * Applies the given BrushFunc to every physical pixel in the surface */ void paintWith(BrushFunc func); /** * Applies the given Shader to every physical pixel in the surface */ void paintShader(Shader shader); const PhysicalCoordinates start; const PhysicalCoordinates end; const VirtualCoordinates virtStart; const VirtualCoordinates virtEnd; private: Display* m_display; uint8_t m_rotation = 0; };