83 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			83 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "./Surface.h"
 | 
						|
#include "./Display.h"
 | 
						|
#include <ArduinoLog.h>
 | 
						|
 | 
						|
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::blend(const CRGB& color, uint8_t pct)
 | 
						|
{
 | 
						|
    paintWith([&](CRGB& pixel) {
 | 
						|
        nblend(pixel, color, pct);
 | 
						|
    });
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
Surface::paintWith(std::function<void(CRGB&)> 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);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |