From 2f040fc77fb679eafd151a157054ca106061b6c9 Mon Sep 17 00:00:00 2001 From: Pablo2048 Date: Sat, 14 Aug 2021 12:18:15 +0200 Subject: [PATCH] Aktualizace o kresleni trojuhelniku --- src/OLEDDisplay.cpp | 141 ++++++++++++++++++++++++++++++++++++++------ src/OLEDDisplay.h | 25 +++++--- 2 files changed, 141 insertions(+), 25 deletions(-) diff --git a/src/OLEDDisplay.cpp b/src/OLEDDisplay.cpp index 5dd0398..168742c 100644 --- a/src/OLEDDisplay.cpp +++ b/src/OLEDDisplay.cpp @@ -65,7 +65,7 @@ bool OLEDDisplay::allocateBuffer() { logBufferMaxLines = 0; logBuffer = NULL; - if (!this->connect()) { + if (!connect()) { DEBUG_OLEDDISPLAY("[OLEDDISPLAY][init] Can't establish connection to display\n"); return false; } @@ -302,6 +302,90 @@ void OLEDDisplay::fillCircle(int16_t x0, int16_t y0, int16_t radius) { } +void OLEDDisplay::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, + int16_t x2, int16_t y2) { + drawLine(x0, y0, x1, y1); + drawLine(x1, y1, x2, y2); + drawLine(x2, y2, x0, y0); +} + +void OLEDDisplay::fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, + int16_t x2, int16_t y2) { + int16_t a, b, y, last; + + if (y0 > y1) { + _swap_int16_t(y0, y1); + _swap_int16_t(x0, x1); + } + if (y1 > y2) { + _swap_int16_t(y2, y1); + _swap_int16_t(x2, x1); + } + if (y0 > y1) { + _swap_int16_t(y0, y1); + _swap_int16_t(x0, x1); + } + + if (y0 == y2) { + a = b = x0; + if (x1 < a) { + a = x1; + } else if (x1 > b) { + b = x1; + } + if (x2 < a) { + a = x2; + } else if (x2 > b) { + b = x2; + } + drawHorizontalLine(a, y0, b - a + 1); + return; + } + + int16_t + dx01 = x1 - x0, + dy01 = y1 - y0, + dx02 = x2 - x0, + dy02 = y2 - y0, + dx12 = x2 - x1, + dy12 = y2 - y1; + int32_t + sa = 0, + sb = 0; + + if (y1 == y2) { + last = y1; // Include y1 scanline + } else { + last = y1 - 1; // Skip it + } + + for (y = y0; y <= last; y++) { + a = x0 + sa / dy01; + b = x0 + sb / dy02; + sa += dx01; + sb += dx02; + + if (a > b) { + _swap_int16_t(a, b); + } + drawHorizontalLine(a, y, b - a + 1); + } + + sa = dx12 * (y - y1); + sb = dx02 * (y - y0); + for (; y <= y2; y++) { + a = x1 + sa / dy12; + b = x0 + sb / dy02; + sa += dx12; + sb += dx02; + + if (a > b) { + _swap_int16_t(a, b); + } + drawHorizontalLine(a, y, b - a + 1); + } +} + void OLEDDisplay::drawHorizontalLine(int16_t x, int16_t y, int16_t length) { if (y < 0 || y >= this->height()) { return; } @@ -451,7 +535,7 @@ void OLEDDisplay::drawXbm(int16_t xMove, int16_t yMove, int16_t width, int16_t h } } -void OLEDDisplay::drawIco16x16(int16_t xMove, int16_t yMove, const char *ico, bool inverse) { +void OLEDDisplay::drawIco16x16(int16_t xMove, int16_t yMove, const uint8_t *ico, bool inverse) { uint16_t data; for(int16_t y = 0; y < 16; y++) { @@ -549,6 +633,15 @@ void OLEDDisplay::drawString(int16_t xMove, int16_t yMove, const String &strUser free(text); } +void OLEDDisplay::drawStringf( int16_t x, int16_t y, char* buffer, String format, ... ) +{ + va_list myargs; + va_start(myargs, format); + vsprintf(buffer, format.c_str(), myargs); + va_end(myargs); + drawString( x, y, buffer ); +} + void OLEDDisplay::drawStringMaxWidth(int16_t xMove, int16_t yMove, uint16_t maxLineWidth, const String &strUser) { uint16_t firstChar = pgm_read_byte(fontData + FIRST_CHAR_POS); uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS); @@ -836,21 +929,30 @@ int OLEDDisplay::_putc(int c) { // Private functions void OLEDDisplay::setGeometry(OLEDDISPLAY_GEOMETRY g, uint16_t width, uint16_t height) { this->geometry = g; + switch (g) { - case GEOMETRY_128_64: - this->displayWidth = 128; - this->displayHeight = 64; - break; - case GEOMETRY_128_32: - this->displayWidth = 128; - this->displayHeight = 32; - break; - case GEOMETRY_RAWMODE: - this->displayWidth = width > 0 ? width : 128; - this->displayHeight = height > 0 ? height : 64; - break; + case GEOMETRY_128_64: + this->displayWidth = 128; + this->displayHeight = 64; + break; + case GEOMETRY_128_32: + this->displayWidth = 128; + this->displayHeight = 32; + break; + case GEOMETRY_64_48: + this->displayWidth = 64; + this->displayHeight = 48; + break; + case GEOMETRY_64_32: + this->displayWidth = 64; + this->displayHeight = 32; + break; + case GEOMETRY_RAWMODE: + this->displayWidth = width > 0 ? width : 128; + this->displayHeight = height > 0 ? height : 64; + break; } - this->displayBufferSize = displayWidth * displayHeight /8; + this->displayBufferSize = displayWidth * displayHeight / 8; } void OLEDDisplay::sendInitCommands(void) { @@ -863,7 +965,10 @@ void OLEDDisplay::sendInitCommands(void) { sendCommand(this->height() - 1); sendCommand(SETDISPLAYOFFSET); sendCommand(0x00); - sendCommand(SETSTARTLINE); + if(geometry == GEOMETRY_64_32) + sendCommand(0x00); + else + sendCommand(SETSTARTLINE); sendCommand(CHARGEPUMP); sendCommand(0x14); sendCommand(MEMORYMODE); @@ -872,7 +977,7 @@ void OLEDDisplay::sendInitCommands(void) { sendCommand(COMSCANINC); sendCommand(SETCOMPINS); - if (geometry == GEOMETRY_128_64) { + if (geometry == GEOMETRY_128_64 || geometry == GEOMETRY_64_48 || geometry == GEOMETRY_64_32) { sendCommand(0x12); } else if (geometry == GEOMETRY_128_32) { sendCommand(0x02); @@ -880,7 +985,7 @@ void OLEDDisplay::sendInitCommands(void) { sendCommand(SETCONTRAST); - if (geometry == GEOMETRY_128_64) { + if (geometry == GEOMETRY_128_64 || geometry == GEOMETRY_64_48 || geometry == GEOMETRY_64_32) { sendCommand(0xCF); } else if (geometry == GEOMETRY_128_32) { sendCommand(0x8F); diff --git a/src/OLEDDisplay.h b/src/OLEDDisplay.h index c2555d2..955463f 100644 --- a/src/OLEDDisplay.h +++ b/src/OLEDDisplay.h @@ -137,8 +137,10 @@ enum OLEDDISPLAY_TEXT_ALIGNMENT { enum OLEDDISPLAY_GEOMETRY { GEOMETRY_128_64 = 0, - GEOMETRY_128_32, - GEOMETRY_RAWMODE, + GEOMETRY_128_32 = 1, + GEOMETRY_64_48 = 2, + GEOMETRY_64_32 = 3, + GEOMETRY_RAWMODE = 4 }; enum HW_I2C { @@ -220,6 +222,12 @@ class OLEDDisplay : public Stream { // Fill circle void fillCircle(int16_t x, int16_t y, int16_t radius); + // Draw an empty triangle i.e. only the outline + void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2); + + // Draw a solid triangle i.e. filled + void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2); + // Draw a line horizontally void drawHorizontalLine(int16_t x, int16_t y, int16_t length); @@ -237,24 +245,27 @@ class OLEDDisplay : public Stream { void drawXbm(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *xbm); // Draw icon 16x16 xbm format - void drawIco16x16(int16_t x, int16_t y, const char *ico, bool inverse = false); + void drawIco16x16(int16_t x, int16_t y, const uint8_t *ico, bool inverse = false); /* Text functions */ // Draws a string at the given location - void drawString(int16_t x, int16_t y, const String& text); + void drawString(int16_t x, int16_t y, const String &text); + + // Draws a formatted string (like printf) at the given location + void drawStringf(int16_t x, int16_t y, char* buffer, String format, ... ); // Draws a String with a maximum width at the given location. // If the given String is wider than the specified width // The text will be wrapped to the next line at a space or dash - void drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, const String& text); + void drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, const String &text); // Returns the width of the const char* with the current // font settings uint16_t getStringWidth(const char* text, uint16_t length); // Convencience method for the const char version - uint16_t getStringWidth(const String& text); + uint16_t getStringWidth(const String &text); uint16_t getTextHeight(void); @@ -378,7 +389,7 @@ class OLEDDisplay : public Stream { void sendInitCommands(); // converts utf8 characters to extended ascii - char* utf8ascii(const String& s); + char* utf8ascii(const String &s); void inline drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *data, uint16_t offset, uint16_t bytesInData) __attribute__((always_inline));