// Specific implementations for high-color mode // This gets included from inside the template definition in ssd1351.h, which is crazy, but it's the only way I know to make this compile. MEMBER_REQUIRES(std::is_same::value) void drawPixel(int16_t x, int16_t y, const C &color) { // Single-buffered pixel drawing is trivial: just put the color in the buffer. if((x < 0) || (x >= W) || (y < 0) || (y >= H)) { return; } frontBuffer()[x + (W * y)] = color; } MEMBER_REQUIRES(std::is_same::value) void updateScreen() { // Updating the screen in single buffer mode means first setting the video ram // to the entire display, and then pushing out every pixel of the buffer. // The display automatically increments its internal pointer to point to the next pixel. beginSPITransaction(); setVideoRamPosition(0, 0, W - 1, H - 1); sendCommandAndContinue(CMD_WRITE_TO_RAM); ArrayType &buffer = frontBuffer(); for (int16_t i = 0; i < W * H; i++) { if (i % W) { pushColor(buffer[i]); } else { // Once every row, start a new SPI transaction to give other devices a chance to communicate. pushColor(buffer[i], true); endSPITransaction(); beginSPITransaction(); } } endSPITransaction(); } MEMBER_REQUIRES(std::is_same::value) void fillScreen(const C &color) { // just writing to every pixel in the buffer is fast, but std::fill is faster. std::fill(frontBuffer().begin(), frontBuffer().end(), color); } MEMBER_REQUIRES(std::is_same::value) void drawFastVLine(int16_t x, int16_t y, int16_t h, const C &color) { // Trying to optimize line drawing in buffered mode is pretty pointless, it's stupid fast anyway. drawLine(x, y, x, y + h - 1, color); } MEMBER_REQUIRES(std::is_same::value) void drawFastHLine(int16_t x, int16_t y, int16_t w, const C &color) { // Trying to optimize line drawing in buffered mode is pretty pointless, it's stupid fast anyway. drawLine(x, y, x + w - 1, y, color); } MEMBER_REQUIRES(std::is_same::value) void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, const C &color) { if((x >= W) || (y >= H)) { return; } if (x < 0) { w -= abs(x); x = 0; } if (y < 0) { y -= abs(y); y = 0; } if((x + w - 1) >= W) { w = W - x; } if((y + h - 1) >= H) { h = H - y; } ArrayType &buffer = frontBuffer(); for(int _y = y; _y < (y + h); _y++) { for(int _x = x; _x < (x + w); _x++) { buffer[_x + (W * _y)] = color; } } } MEMBER_REQUIRES(std::is_same::value) void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, const C &color) { int16_t steep = abs(y1 - y0) > abs(x1 - x0); if (steep) { swap(x0, y0); swap(x1, y1); } if (x0 > x1) { swap(x0, x1); swap(y0, y1); } int16_t dx, dy; dx = x1 - x0; dy = abs(y1 - y0); int16_t err = dx / 2; int16_t ystep; if (y0 < y1) { ystep = 1; } else { ystep = -1; } for (; x0<=x1; x0++) { if (steep) { drawPixel(y0, x0, color); } else { drawPixel(x0, y0, color); } err -= dy; if (err < 0) { y0 += ystep; err += dx; } } }