rpi-fb-matrix/GridTransformer.cpp
2015-12-15 12:03:46 +00:00

87 lines
2.8 KiB
C++

// LED matrix library transformer to map a rectangular canvas onto a complex
// chain of matrices.
// Author: Tony DiCola
#include "GridTransformer.h"
using namespace rgb_matrix;
using namespace std;
GridTransformer::GridTransformer(int width, int height, int panel_width, int panel_height,
int chain_length, const std::vector<Panel>& panels):
_width(width),
_height(height),
_panel_width(panel_width),
_panel_height(panel_height),
_chain_length(chain_length),
_source(NULL),
_panels(panels)
{
// Display width must be a multiple of the panel pixel column count.
assert(_width % _panel_width == 0);
// Display height must be a multiple of the panel pixel row count.
assert(_height % _panel_height == 0);
// Compute number of rows and columns of panels.
_rows = _height / _panel_height;
_cols = _width / _panel_width;
// Check panel definition list has exactly the expected number of panels.
assert((_rows * _cols) == (int)_panels.size());
}
void GridTransformer::SetPixel(int x, int y, uint8_t red, uint8_t green, uint8_t blue) {
assert(_source != NULL);
if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) {
return;
}
// Figure out what row and column panel this pixel is within.
int row = y / _panel_height;
int col = x / _panel_width;
// Get the panel information for this pixel.
Panel panel = _panels[_cols*row + col];
// Compute location of the pixel within the panel.
x = x % _panel_width;
y = y % _panel_height;
// Perform any panel rotation to the pixel.
// NOTE: 90 and 270 degree rotation only possible on 32 row (square) panels.
if (panel.rotate == 90) {
assert(_panel_height == _panel_width);
int old_x = x;
x = (_panel_height-1)-y;
y = old_x;
}
else if (panel.rotate == 180) {
x = (_panel_width-1)-x;
y = (_panel_height-1)-y;
}
else if (panel.rotate == 270) {
assert(_panel_height == _panel_width);
int old_y = y;
y = (_panel_width-1)-x;
x = old_y;
}
// Determine x offset into the source panel based on its order along the chain.
// The order needs to be inverted because the matrix library starts with the
// origin of an image at the end of the chain and not at the start (where
// ordering begins for this transformer).
int x_offset = ((_chain_length-1)-panel.order)*_panel_width;
// Determine y offset into the source panel based on its parrallel chain value.
int y_offset = panel.parallel*_panel_height;
_source->SetPixel(x_offset + x,
y_offset + y,
red, green, blue);
}
Canvas* GridTransformer::Transform(Canvas* source) {
assert(source != NULL);
int swidth = source->width();
int sheight = source->height();
assert((_width * _height) == (swidth * sheight));
_source = source;
return this;
}