Reintegrated Adafruit-GFX-Library.
This commit is contained in:
parent
4df80297ea
commit
4687d67162
|
@ -8,8 +8,9 @@
|
||||||
This example will show you how you can draw some simple graphics using
|
This example will show you how you can draw some simple graphics using
|
||||||
Adafruit GFX functions. Yes, Inkplate library is 100% compatible with GFX lib!
|
Adafruit GFX functions. Yes, Inkplate library is 100% compatible with GFX lib!
|
||||||
Learn more about Adafruit GFX: https://learn.adafruit.com/adafruit-gfx-graphics-library
|
Learn more about Adafruit GFX: https://learn.adafruit.com/adafruit-gfx-graphics-library
|
||||||
Inkplate will be used in grayscale mode which is 3 bit, so you can have up to 8 different colors (black, 6 gray colors and white)
|
Inkplate will be used in grayscale mode which is 3 bit, so you can have up to 8 different colors (black, 6 gray
|
||||||
Color is represented by number, where number 0 means black and number 7 means white, while everything in between are shades of gray.
|
colors and white) Color is represented by number, where number 0 means black and number 7 means white, while
|
||||||
|
everything in between are shades of gray.
|
||||||
|
|
||||||
Want to learn more about Inkplate? Visit www.inkplate.io
|
Want to learn more about Inkplate? Visit www.inkplate.io
|
||||||
Looking to get support? Write on our forums: http://forum.e-radionica.com/en/
|
Looking to get support? Write on our forums: http://forum.e-radionica.com/en/
|
||||||
|
@ -19,16 +20,20 @@
|
||||||
#include "Inkplate.h" //Include Inkplate library to the sketch
|
#include "Inkplate.h" //Include Inkplate library to the sketch
|
||||||
#include "image.h" //Include image file that holds grayscale image data. You can see it in next tab inside Arduino IDE.
|
#include "image.h" //Include image file that holds grayscale image data. You can see it in next tab inside Arduino IDE.
|
||||||
Inkplate display(INKPLATE_3BIT); // Create object on Inkplate library and set library to work in grayscale mode (3-bit)
|
Inkplate display(INKPLATE_3BIT); // Create object on Inkplate library and set library to work in grayscale mode (3-bit)
|
||||||
//Other option is monochrome mode, which is demonstrated in next example "2-Inkplate_basic_monochrome"
|
// Other option is monochrome mode, which is demonstrated in next example
|
||||||
|
// "2-Inkplate_basic_monochrome"
|
||||||
|
|
||||||
#define DELAY_MS 5000 //Delay in milliseconds between screen refresh. Refreshing e-paper screens more often than 5s is not recommended \
|
|
||||||
|
#define DELAY_MS \
|
||||||
|
5000 //Delay in milliseconds between screen refresh. Refreshing e-paper screens more often than 5s is not recommended \
|
||||||
//Want to refresh faster? Use partial update! Find example in "3-Inkplate-basic_partial_update"
|
//Want to refresh faster? Use partial update! Find example in "3-Inkplate-basic_partial_update"
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
display.begin(); // Init library (you should call this function ONLY ONCE)
|
display.begin(); // Init library (you should call this function ONLY ONCE)
|
||||||
display.clearDisplay(); // Clear any data that may have been in (software) frame buffer.
|
display.clearDisplay(); // Clear any data that may have been in (software) frame buffer.
|
||||||
//(NOTE! This does not clean image on screen, it only clears it in the frame buffer inside ESP32).
|
//(NOTE! This does not clean image on screen, it only clears it in the frame buffer inside
|
||||||
|
// ESP32).
|
||||||
display.clean(); // Clear everything that has previously been on a screen
|
display.clean(); // Clear everything that has previously been on a screen
|
||||||
display.setTextColor(0, 7);
|
display.setTextColor(0, 7);
|
||||||
display.setCursor(150, 320);
|
display.setCursor(150, 320);
|
||||||
|
@ -40,22 +45,25 @@ void setup()
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
//Example will demostrate funcionality one by one. You always first set everything in the frame buffer and afterwards you show
|
// Example will demostrate funcionality one by one. You always first set everything in the frame buffer and
|
||||||
//it on the screen using display.display().
|
// afterwards you show it on the screen using display.display().
|
||||||
|
|
||||||
// Let'sstart by drawing pixel at x = 100 and y = 50 location
|
// Let'sstart by drawing pixel at x = 100 and y = 50 location
|
||||||
display.clearDisplay(); // Clear everytning that is inside frame buffer in ESP32
|
display.clearDisplay(); // Clear everytning that is inside frame buffer in ESP32
|
||||||
display.drawPixel(100, 50, 0); // Draw one black pixel at X = 100, Y = 50 position in 0 (BLACK) color
|
display.drawPixel(100, 50, 0); // Draw one black pixel at X = 100, Y = 50 position in 0 (BLACK) color
|
||||||
displayCurrentAction("Drawing a pixel"); //Function which writes small text at bottom left indicating what's currently done
|
displayCurrentAction(
|
||||||
|
"Drawing a pixel"); // Function which writes small text at bottom left indicating what's currently done
|
||||||
// NOTE: you do not need displayCurrentAction function to use Inkplate!
|
// NOTE: you do not need displayCurrentAction function to use Inkplate!
|
||||||
display.display(); //Send image to display. You need to call this one each time you want to transfer frame buffer to the screen.
|
display.display(); // Send image to display. You need to call this one each time you want to transfer frame buffer
|
||||||
|
// to the screen.
|
||||||
delay(DELAY_MS); // Wait a little bit
|
delay(DELAY_MS); // Wait a little bit
|
||||||
|
|
||||||
// Now, let's draw some random pixels!
|
// Now, let's draw some random pixels!
|
||||||
display.clearDisplay(); // Clear everything that is inside frame buffer in ESP32
|
display.clearDisplay(); // Clear everything that is inside frame buffer in ESP32
|
||||||
for (int i = 0; i < 1000; i++)
|
for (int i = 0; i < 1000; i++)
|
||||||
{ // Write 1000 random colored pixels at random locations
|
{ // Write 1000 random colored pixels at random locations
|
||||||
display.drawPixel(random(0, 799), random(0, 599), random(0, 7)); //We are setting color of the pixels using numbers from 0 to 7,
|
display.drawPixel(random(0, 799), random(0, 599),
|
||||||
|
random(0, 7)); // We are setting color of the pixels using numbers from 0 to 7,
|
||||||
} // where 0 mens black, 7 white and gray is in between
|
} // where 0 mens black, 7 white and gray is in between
|
||||||
displayCurrentAction("Drawing 600 random pixels in random colors");
|
displayCurrentAction("Drawing 600 random pixels in random colors");
|
||||||
display.display(); // Write everything from frame buffer to screen
|
display.display(); // Write everything from frame buffer to screen
|
||||||
|
@ -63,7 +71,9 @@ void loop()
|
||||||
|
|
||||||
// Draw two diagonal lines accros screen
|
// Draw two diagonal lines accros screen
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
display.drawLine(0, 0, 799, 599, 0); //All of those drawing fuctions originate from Adafruit GFX library, so maybe you are already familiar
|
display.drawLine(
|
||||||
|
0, 0, 799, 599,
|
||||||
|
0); // All of those drawing fuctions originate from Adafruit GFX library, so maybe you are already familiar
|
||||||
display.drawLine(799, 0, 0, 599, 0); // with those. Arguments are: start X, start Y, ending X, ending Y, color.
|
display.drawLine(799, 0, 0, 599, 0); // with those. Arguments are: start X, start Y, ending X, ending Y, color.
|
||||||
displayCurrentAction("Drawing two diagonal lines");
|
displayCurrentAction("Drawing two diagonal lines");
|
||||||
display.display();
|
display.display();
|
||||||
|
@ -83,7 +93,8 @@ void loop()
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
for (int i = 0; i < 100; i++)
|
for (int i = 0; i < 100; i++)
|
||||||
{
|
{
|
||||||
display.drawThickLine(random(0, 799), random(0, 599), random(0, 799), random(0, 599), random(0, 7), (float)random(1, 20));
|
display.drawThickLine(random(0, 799), random(0, 599), random(0, 799), random(0, 599), random(0, 7),
|
||||||
|
(float)random(1, 20));
|
||||||
}
|
}
|
||||||
displayCurrentAction("Drawing 50 random lines in random colors and thickness");
|
displayCurrentAction("Drawing 50 random lines in random colors and thickness");
|
||||||
display.display();
|
display.display();
|
||||||
|
@ -95,7 +106,8 @@ void loop()
|
||||||
{
|
{
|
||||||
int startColor = random(0, 7);
|
int startColor = random(0, 7);
|
||||||
int endColor = random(startColor, 7);
|
int endColor = random(startColor, 7);
|
||||||
display.drawGradientLine(random(0, 799), random(0, 599), random(0, 799), random(0, 599), startColor, endColor, (float)random(1, 20));
|
display.drawGradientLine(random(0, 799), random(0, 599), random(0, 799), random(0, 599), startColor, endColor,
|
||||||
|
(float)random(1, 20));
|
||||||
}
|
}
|
||||||
displayCurrentAction("Drawing 50 random gradient lines in random colors and thickness");
|
displayCurrentAction("Drawing 50 random gradient lines in random colors and thickness");
|
||||||
display.display();
|
display.display();
|
||||||
|
@ -243,10 +255,11 @@ void loop()
|
||||||
display.display();
|
display.display();
|
||||||
delay(DELAY_MS);
|
delay(DELAY_MS);
|
||||||
|
|
||||||
//Display some grayscale image on screen. We are going to display e-radionica logo on display at location X = 100, Y = 100
|
// Display some grayscale image on screen. We are going to display e-radionica logo on display at location X = 100,
|
||||||
//Image size is 500x332 pixels.
|
// Y = 100 Image size is 500x332 pixels.
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
display.drawBitmap3Bit(100, 100, picture1, 500, 332); //Arguments are: start X, start Y, array variable name, size X, size Y
|
display.drawBitmap3Bit(100, 100, picture1, 500,
|
||||||
|
332); // Arguments are: start X, start Y, array variable name, size X, size Y
|
||||||
displayCurrentAction("Drawing a bitmap image");
|
displayCurrentAction("Drawing a bitmap image");
|
||||||
display.display();
|
display.display();
|
||||||
delay(DELAY_MS);
|
delay(DELAY_MS);
|
||||||
|
@ -256,8 +269,10 @@ void loop()
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
display.setTextColor(i);
|
display.setTextColor(i);
|
||||||
display.setTextSize(i + 1); //textSize parameter starts at 0 and goes up to 10 (larger won't fit Inkplate 6 screen)
|
display.setTextSize(i +
|
||||||
display.setCursor(200, (i * i * 8)); //setCursor works as same as on LCD displays - sets "the cursor" at the place you want to write someting next
|
1); // textSize parameter starts at 0 and goes up to 10 (larger won't fit Inkplate 6 screen)
|
||||||
|
display.setCursor(200, (i * i * 8)); // setCursor works as same as on LCD displays - sets "the cursor" at the
|
||||||
|
// place you want to write someting next
|
||||||
display.print("INKPLATE6!"); // The actual text you want to show on e-paper as String
|
display.print("INKPLATE6!"); // The actual text you want to show on e-paper as String
|
||||||
}
|
}
|
||||||
displayCurrentAction("Text in different sizes and shadings");
|
displayCurrentAction("Text in different sizes and shadings");
|
||||||
|
@ -265,7 +280,8 @@ void loop()
|
||||||
delay(DELAY_MS);
|
delay(DELAY_MS);
|
||||||
|
|
||||||
// Write same text on different location, but now invert colors (text is white, text background is black)
|
// Write same text on different location, but now invert colors (text is white, text background is black)
|
||||||
display.setTextColor(7, 0); //First argument is text color, while second argument is background color. In greyscale,
|
display.setTextColor(7, 0); // First argument is text color, while second argument is background color. In
|
||||||
|
// greyscale,
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{ // you are able to choose from 8 different colors (0-7)
|
{ // you are able to choose from 8 different colors (0-7)
|
||||||
display.setTextSize(i + 1);
|
display.setTextSize(i + 1);
|
||||||
|
@ -336,7 +352,8 @@ void loop()
|
||||||
{
|
{
|
||||||
display.setCursor(100, 100);
|
display.setCursor(100, 100);
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
display.setRotation(r); //Set rotation will sent rotation for the entire display, so you can use it sideways or upside-down
|
display.setRotation(
|
||||||
|
r); // Set rotation will sent rotation for the entire display, so you can use it sideways or upside-down
|
||||||
display.print("INKPLATE6");
|
display.print("INKPLATE6");
|
||||||
display.display();
|
display.display();
|
||||||
r++;
|
r++;
|
||||||
|
|
|
@ -95,7 +95,7 @@
|
||||||
|
|
||||||
#define DATA 0x0E8C0030
|
#define DATA 0x0E8C0030
|
||||||
|
|
||||||
Inkplate::Inkplate(uint8_t _mode) : Graphics(E_INK_WIDTH, E_INK_HEIGHT)
|
Inkplate::Inkplate(uint8_t _mode) : Adafruit_GFX(E_INK_WIDTH, E_INK_HEIGHT), Graphics(E_INK_WIDTH, E_INK_HEIGHT)
|
||||||
{
|
{
|
||||||
setDisplayMode(_mode);
|
setDisplayMode(_mode);
|
||||||
for (uint32_t i = 0; i < 256; ++i)
|
for (uint32_t i = 0; i < 256; ++i)
|
||||||
|
@ -194,7 +194,7 @@ void Inkplate::display1b()
|
||||||
{
|
{
|
||||||
memcpy(DMemoryNew, _partial, 60000);
|
memcpy(DMemoryNew, _partial, 60000);
|
||||||
|
|
||||||
uint16_t _pos;
|
|
||||||
uint32_t _send;
|
uint32_t _send;
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
uint8_t dram;
|
uint8_t dram;
|
||||||
|
@ -209,23 +209,23 @@ void Inkplate::display1b()
|
||||||
cleanFast(0, 11);
|
cleanFast(0, 11);
|
||||||
for (int k = 0; k < 3; ++k)
|
for (int k = 0; k < 3; ++k)
|
||||||
{
|
{
|
||||||
_pos = 59999;
|
uint8_t *DMemoryNewPtr = DMemoryNew + 59999;
|
||||||
vscan_start();
|
vscan_start();
|
||||||
for (int i = 0; i < 600; ++i)
|
for (int i = 0; i < 600; ++i)
|
||||||
{
|
{
|
||||||
dram = *(DMemoryNew + _pos);
|
dram = *(DMemoryNewPtr--);
|
||||||
data = LUTB[(dram >> 4) & 0x0F];
|
data = LUTB[dram >> 4];
|
||||||
_send = pinLUT[data];
|
_send = pinLUT[data];
|
||||||
hscan_start(_send);
|
hscan_start(_send);
|
||||||
data = LUTB[dram & 0x0F];
|
data = LUTB[dram & 0x0F];
|
||||||
_send = pinLUT[data];
|
_send = pinLUT[data];
|
||||||
GPIO.out_w1ts = (_send) | CL;
|
GPIO.out_w1ts = (_send) | CL;
|
||||||
GPIO.out_w1tc = DATA | CL;
|
GPIO.out_w1tc = DATA | CL;
|
||||||
_pos--;
|
|
||||||
for (int j = 0; j < 99; ++j)
|
for (int j = 0; j < 99; ++j)
|
||||||
{
|
{
|
||||||
dram = *(DMemoryNew + _pos);
|
dram = *(DMemoryNewPtr--);
|
||||||
data = LUTB[(dram >> 4) & 0x0F];
|
data = LUTB[dram >> 4];
|
||||||
_send = pinLUT[data];
|
_send = pinLUT[data];
|
||||||
GPIO.out_w1ts = (_send) | CL;
|
GPIO.out_w1ts = (_send) | CL;
|
||||||
GPIO.out_w1tc = DATA | CL;
|
GPIO.out_w1tc = DATA | CL;
|
||||||
|
@ -233,7 +233,6 @@ void Inkplate::display1b()
|
||||||
_send = pinLUT[data];
|
_send = pinLUT[data];
|
||||||
GPIO.out_w1ts = (_send) | CL;
|
GPIO.out_w1ts = (_send) | CL;
|
||||||
GPIO.out_w1tc = DATA | CL;
|
GPIO.out_w1tc = DATA | CL;
|
||||||
_pos--;
|
|
||||||
}
|
}
|
||||||
GPIO.out_w1ts = (_send) | CL;
|
GPIO.out_w1ts = (_send) | CL;
|
||||||
GPIO.out_w1tc = DATA | CL;
|
GPIO.out_w1tc = DATA | CL;
|
||||||
|
@ -242,12 +241,12 @@ void Inkplate::display1b()
|
||||||
delayMicroseconds(230);
|
delayMicroseconds(230);
|
||||||
}
|
}
|
||||||
|
|
||||||
_pos = 59999;
|
uint16_t _pos = 59999;
|
||||||
vscan_start();
|
vscan_start();
|
||||||
for (int i = 0; i < 600; ++i)
|
for (int i = 0; i < 600; ++i)
|
||||||
{
|
{
|
||||||
dram = *(DMemoryNew + _pos);
|
dram = *(DMemoryNew + _pos);
|
||||||
data = LUT2[(dram >> 4) & 0x0F];
|
data = LUT2[dram >> 4];
|
||||||
_send = pinLUT[data];
|
_send = pinLUT[data];
|
||||||
hscan_start(_send);
|
hscan_start(_send);
|
||||||
data = LUT2[dram & 0x0F];
|
data = LUT2[dram & 0x0F];
|
||||||
|
@ -258,7 +257,7 @@ void Inkplate::display1b()
|
||||||
for (int j = 0; j < 99; ++j)
|
for (int j = 0; j < 99; ++j)
|
||||||
{
|
{
|
||||||
dram = *(DMemoryNew + _pos);
|
dram = *(DMemoryNew + _pos);
|
||||||
data = LUT2[(dram >> 4) & 0x0F];
|
data = LUT2[dram >> 4];
|
||||||
_send = pinLUT[data];
|
_send = pinLUT[data];
|
||||||
GPIO.out_w1ts = (_send) | CL;
|
GPIO.out_w1ts = (_send) | CL;
|
||||||
GPIO.out_w1tc = DATA | CL;
|
GPIO.out_w1tc = DATA | CL;
|
||||||
|
@ -278,10 +277,10 @@ void Inkplate::display1b()
|
||||||
for (int i = 0; i < 600; ++i)
|
for (int i = 0; i < 600; ++i)
|
||||||
{
|
{
|
||||||
dram = *(DMemoryNew + _pos);
|
dram = *(DMemoryNew + _pos);
|
||||||
data = 0b00000000;
|
data = 0;
|
||||||
_send = pinLUT[data];
|
_send = pinLUT[data];
|
||||||
hscan_start(_send);
|
hscan_start(_send);
|
||||||
data = 0b00000000;
|
data = 0;
|
||||||
GPIO.out_w1ts = (_send) | CL;
|
GPIO.out_w1ts = (_send) | CL;
|
||||||
GPIO.out_w1tc = DATA | CL;
|
GPIO.out_w1tc = DATA | CL;
|
||||||
for (int j = 0; j < 99; ++j)
|
for (int j = 0; j < 99; ++j)
|
||||||
|
@ -387,10 +386,9 @@ void Inkplate::partialUpdate()
|
||||||
|
|
||||||
uint16_t _pos = 59999;
|
uint16_t _pos = 59999;
|
||||||
uint32_t _send;
|
uint32_t _send;
|
||||||
uint8_t data;
|
uint8_t data = 0;
|
||||||
uint8_t diffw, diffb;
|
uint8_t diffw, diffb;
|
||||||
uint32_t n = 119999;
|
uint32_t n = 119999;
|
||||||
uint8_t dram;
|
|
||||||
|
|
||||||
for (int i = 0; i < 600; ++i)
|
for (int i = 0; i < 600; ++i)
|
||||||
{
|
{
|
||||||
|
@ -459,7 +457,7 @@ void Inkplate::clean()
|
||||||
void Inkplate::cleanFast(uint8_t c, uint8_t rep)
|
void Inkplate::cleanFast(uint8_t c, uint8_t rep)
|
||||||
{
|
{
|
||||||
einkOn();
|
einkOn();
|
||||||
uint8_t data;
|
uint8_t data = 0;
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
data = B10101010;
|
data = B10101010;
|
||||||
else if (c == 1)
|
else if (c == 1)
|
||||||
|
|
|
@ -1,346 +0,0 @@
|
||||||
#include "Font.h"
|
|
||||||
|
|
||||||
inline GFXglyph *pgm_read_glyph_ptr(const GFXfont *gfxFont, uint8_t c)
|
|
||||||
{
|
|
||||||
return gfxFont->glyph + c;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t *pgm_read_bitmap_ptr(const GFXfont *gfxFont)
|
|
||||||
{
|
|
||||||
return gfxFont->bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::setCursor(int16_t x, int16_t y)
|
|
||||||
{
|
|
||||||
cursor_x = x;
|
|
||||||
cursor_y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::setTextColor(uint16_t c)
|
|
||||||
{
|
|
||||||
textcolor = textbgcolor = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::setTextColor(uint16_t c, uint16_t bg)
|
|
||||||
{
|
|
||||||
textcolor = c;
|
|
||||||
textbgcolor = bg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::setTextWrap(bool w)
|
|
||||||
{
|
|
||||||
wrap = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::cp437(bool x = true)
|
|
||||||
{
|
|
||||||
_cp437 = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t Font::getCursorX()
|
|
||||||
{
|
|
||||||
return cursor_x;
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t Font::getCursorY()
|
|
||||||
{
|
|
||||||
return cursor_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::setTextSize(uint8_t s)
|
|
||||||
{
|
|
||||||
setTextSize(s, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::setTextSize(uint8_t s_x, uint8_t s_y)
|
|
||||||
{
|
|
||||||
textsize_x = (s_x > 0) ? s_x : 1;
|
|
||||||
textsize_y = (s_y > 0) ? s_y : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size)
|
|
||||||
{
|
|
||||||
drawChar(x, y, c, color, bg, size, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size_x, uint8_t size_y)
|
|
||||||
{
|
|
||||||
if (!gfxFont)
|
|
||||||
{
|
|
||||||
if ((x >= width()) || // Clip right
|
|
||||||
(y >= height()) || // Clip bottom
|
|
||||||
((x + 6 * size_x - 1) < 0) || // Clip left
|
|
||||||
((y + 8 * size_y - 1) < 0)) // Clip top
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!_cp437 && (c >= 176))
|
|
||||||
c++;
|
|
||||||
|
|
||||||
startWrite();
|
|
||||||
for (int8_t i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
uint8_t line = pgm_read_byte(&font[c * 5 + i]);
|
|
||||||
for (int8_t j = 0; j < 8; j++, line >>= 1)
|
|
||||||
{
|
|
||||||
if (line & 1)
|
|
||||||
{
|
|
||||||
if (size_x == 1 && size_y == 1)
|
|
||||||
writePixel(x + i, y + j, color);
|
|
||||||
else
|
|
||||||
writeFillRect(x + i * size_x, y + j * size_y, size_x, size_y, color);
|
|
||||||
}
|
|
||||||
else if (bg != color)
|
|
||||||
{
|
|
||||||
if (size_x == 1 && size_y == 1)
|
|
||||||
writePixel(x + i, y + j, bg);
|
|
||||||
else
|
|
||||||
writeFillRect(x + i * size_x, y + j * size_y, size_x, size_y, bg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bg != color)
|
|
||||||
{
|
|
||||||
if (size_x == 1 && size_y == 1)
|
|
||||||
writeFastVLine(x + 5, y, 8, bg);
|
|
||||||
else
|
|
||||||
writeFillRect(x + 5 * size_x, y, size_x, 8 * size_y, bg);
|
|
||||||
}
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c -= (uint8_t)pgm_read_byte(&gfxFont->first);
|
|
||||||
GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c);
|
|
||||||
uint8_t *bitmap = pgm_read_bitmap_ptr(gfxFont);
|
|
||||||
|
|
||||||
uint16_t bo = pgm_read_word(&glyph->bitmapOffset);
|
|
||||||
uint8_t w = pgm_read_byte(&glyph->width), h = pgm_read_byte(&glyph->height);
|
|
||||||
int8_t xo = pgm_read_byte(&glyph->xOffset), yo = pgm_read_byte(&glyph->yOffset);
|
|
||||||
uint8_t xx, yy, bits = 0, bit = 0;
|
|
||||||
int16_t xo16 = 0, yo16 = 0;
|
|
||||||
|
|
||||||
if (size_x > 1 || size_y > 1)
|
|
||||||
{
|
|
||||||
xo16 = xo;
|
|
||||||
yo16 = yo;
|
|
||||||
}
|
|
||||||
|
|
||||||
startWrite();
|
|
||||||
for (yy = 0; yy < h; yy++)
|
|
||||||
{
|
|
||||||
for (xx = 0; xx < w; xx++)
|
|
||||||
{
|
|
||||||
if (!(bit++ & 7))
|
|
||||||
{
|
|
||||||
bits = pgm_read_byte(&bitmap[bo++]);
|
|
||||||
}
|
|
||||||
if (bits & 0x80)
|
|
||||||
{
|
|
||||||
if (size_x == 1 && size_y == 1)
|
|
||||||
{
|
|
||||||
writePixel(x + xo + xx, y + yo + yy, color);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
writeFillRect(x + (xo16 + xx) * size_x, y + (yo16 + yy) * size_y, size_x, size_y, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bits <<= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Font::write(uint8_t c)
|
|
||||||
{
|
|
||||||
if (!gfxFont)
|
|
||||||
{ // 'Classic' built-in font
|
|
||||||
|
|
||||||
if (c == '\n')
|
|
||||||
{ // Newline?
|
|
||||||
cursor_x = 0; // Reset x to zero,
|
|
||||||
cursor_y += textsize_y * 8; // advance y one line
|
|
||||||
}
|
|
||||||
else if (c != '\r')
|
|
||||||
{ // Ignore carriage returns
|
|
||||||
if (wrap && ((cursor_x + textsize_x * 6) > width()))
|
|
||||||
{ // Off right?
|
|
||||||
cursor_x = 0; // Reset x to zero,
|
|
||||||
cursor_y += textsize_y * 8; // advance y one line
|
|
||||||
}
|
|
||||||
drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize_x, textsize_y);
|
|
||||||
cursor_x += textsize_x * 6; // Advance x one char
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // Custom font
|
|
||||||
|
|
||||||
if (c == '\n')
|
|
||||||
{
|
|
||||||
cursor_x = 0;
|
|
||||||
cursor_y += (int16_t)textsize_y * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
|
||||||
}
|
|
||||||
else if (c != '\r')
|
|
||||||
{
|
|
||||||
uint8_t first = pgm_read_byte(&gfxFont->first);
|
|
||||||
if ((c >= first) && (c <= (uint8_t)pgm_read_byte(&gfxFont->last)))
|
|
||||||
{
|
|
||||||
GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c - first);
|
|
||||||
uint8_t w = pgm_read_byte(&glyph->width), h = pgm_read_byte(&glyph->height);
|
|
||||||
if ((w > 0) && (h > 0))
|
|
||||||
{ // Is there an associated bitmap?
|
|
||||||
int16_t xo = (int8_t)pgm_read_byte(&glyph->xOffset); // sic
|
|
||||||
if (wrap && ((cursor_x + textsize_x * (xo + w)) > width()))
|
|
||||||
{
|
|
||||||
cursor_x = 0;
|
|
||||||
cursor_y += (int16_t)textsize_y * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
|
||||||
}
|
|
||||||
drawChar(cursor_x, cursor_y, c, textcolor, textbgcolor, textsize_x, textsize_y);
|
|
||||||
}
|
|
||||||
cursor_x += (uint8_t)pgm_read_byte(&glyph->xAdvance) * (int16_t)textsize_x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::setFont(const GFXfont *f)
|
|
||||||
{
|
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
if (!gfxFont)
|
|
||||||
{
|
|
||||||
cursor_y += 6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (gfxFont)
|
|
||||||
{
|
|
||||||
cursor_y -= 6;
|
|
||||||
}
|
|
||||||
gfxFont = (GFXfont *)f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::charBounds(char c, int16_t *x, int16_t *y, int16_t *minx, int16_t *miny, int16_t *maxx, int16_t *maxy)
|
|
||||||
{
|
|
||||||
if (gfxFont)
|
|
||||||
{
|
|
||||||
if (c == '\n')
|
|
||||||
{
|
|
||||||
*x = 0;
|
|
||||||
*y += textsize_y * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
|
||||||
}
|
|
||||||
else if (c != '\r')
|
|
||||||
{
|
|
||||||
uint8_t first = pgm_read_byte(&gfxFont->first), last = pgm_read_byte(&gfxFont->last);
|
|
||||||
if ((c >= first) && (c <= last))
|
|
||||||
{
|
|
||||||
GFXglyph *glyph = pgm_read_glyph_ptr(gfxFont, c - first);
|
|
||||||
uint8_t gw = pgm_read_byte(&glyph->width), gh = pgm_read_byte(&glyph->height),
|
|
||||||
xa = pgm_read_byte(&glyph->xAdvance);
|
|
||||||
int8_t xo = pgm_read_byte(&glyph->xOffset), yo = pgm_read_byte(&glyph->yOffset);
|
|
||||||
if (wrap && ((*x + (((int16_t)xo + gw) * textsize_x)) > width()))
|
|
||||||
{
|
|
||||||
*x = 0;
|
|
||||||
*y += textsize_y * (uint8_t)pgm_read_byte(&gfxFont->yAdvance);
|
|
||||||
}
|
|
||||||
int16_t tsx = (int16_t)textsize_x, tsy = (int16_t)textsize_y, x1 = *x + xo * tsx, y1 = *y + yo * tsy,
|
|
||||||
x2 = x1 + gw * tsx - 1, y2 = y1 + gh * tsy - 1;
|
|
||||||
if (x1 < *minx)
|
|
||||||
*minx = x1;
|
|
||||||
if (y1 < *miny)
|
|
||||||
*miny = y1;
|
|
||||||
if (x2 > *maxx)
|
|
||||||
*maxx = x2;
|
|
||||||
if (y2 > *maxy)
|
|
||||||
*maxy = y2;
|
|
||||||
*x += xa * tsx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (c == '\n')
|
|
||||||
{
|
|
||||||
*x = 0;
|
|
||||||
*y += textsize_y * 8;
|
|
||||||
}
|
|
||||||
else if (c != '\r')
|
|
||||||
{
|
|
||||||
if (wrap && ((*x + textsize_x * 6) > width()))
|
|
||||||
{
|
|
||||||
*x = 0;
|
|
||||||
*y += textsize_y * 8;
|
|
||||||
}
|
|
||||||
int x2 = *x + textsize_x * 6 - 1, y2 = *y + textsize_y * 8 - 1;
|
|
||||||
if (x2 > *maxx)
|
|
||||||
*maxx = x2; // Track max x, y
|
|
||||||
if (y2 > *maxy)
|
|
||||||
*maxy = y2;
|
|
||||||
if (*x < *minx)
|
|
||||||
*minx = *x; // Track min x, y
|
|
||||||
if (*y < *miny)
|
|
||||||
*miny = *y;
|
|
||||||
*x += textsize_x * 6; // Advance x one char
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::getTextBounds(const char *str, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h)
|
|
||||||
{
|
|
||||||
uint8_t c;
|
|
||||||
|
|
||||||
*x1 = x;
|
|
||||||
*y1 = y;
|
|
||||||
*w = *h = 0;
|
|
||||||
|
|
||||||
int16_t minx = width(), miny = height(), maxx = -1, maxy = -1;
|
|
||||||
|
|
||||||
while ((c = *str++))
|
|
||||||
charBounds(c, &x, &y, &minx, &miny, &maxx, &maxy);
|
|
||||||
|
|
||||||
if (maxx >= minx)
|
|
||||||
{
|
|
||||||
*x1 = minx;
|
|
||||||
*w = maxx - minx + 1;
|
|
||||||
}
|
|
||||||
if (maxy >= miny)
|
|
||||||
{
|
|
||||||
*y1 = miny;
|
|
||||||
*h = maxy - miny + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::getTextBounds(const String &str, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h)
|
|
||||||
{
|
|
||||||
if (str.length() != 0)
|
|
||||||
{
|
|
||||||
getTextBounds(const_cast<char *>(str.c_str()), x, y, x1, y1, w, h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::getTextBounds(const __FlashStringHelper *str, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w,
|
|
||||||
uint16_t *h)
|
|
||||||
{
|
|
||||||
uint8_t *s = (uint8_t *)str, c;
|
|
||||||
|
|
||||||
*x1 = x;
|
|
||||||
*y1 = y;
|
|
||||||
*w = *h = 0;
|
|
||||||
|
|
||||||
int16_t minx = width(), miny = height(), maxx = -1, maxy = -1;
|
|
||||||
|
|
||||||
while ((c = pgm_read_byte(s++)))
|
|
||||||
charBounds(c, &x, &y, &minx, &miny, &maxx, &maxy);
|
|
||||||
|
|
||||||
if (maxx >= minx)
|
|
||||||
{
|
|
||||||
*x1 = minx;
|
|
||||||
*w = maxx - minx + 1;
|
|
||||||
}
|
|
||||||
if (maxy >= miny)
|
|
||||||
{
|
|
||||||
*y1 = miny;
|
|
||||||
*h = maxy - miny + 1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
#ifndef __FONT_H__
|
|
||||||
#define __FONT_H__
|
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
#include "Print.h"
|
|
||||||
|
|
||||||
#include "../libs/GFXFont/gfxfont.h"
|
|
||||||
#include "../libs/GFXFont/glcdfont.c"
|
|
||||||
|
|
||||||
|
|
||||||
class Font : public Print
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
|
|
||||||
|
|
||||||
virtual int16_t width() = 0;
|
|
||||||
virtual int16_t height() = 0;
|
|
||||||
|
|
||||||
virtual size_t write(uint8_t);
|
|
||||||
|
|
||||||
void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size);
|
|
||||||
void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size_x, uint8_t size_y);
|
|
||||||
|
|
||||||
void getTextBounds(const char *string, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
|
|
||||||
void getTextBounds(const __FlashStringHelper *s, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w,
|
|
||||||
uint16_t *h);
|
|
||||||
void getTextBounds(const String &str, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
|
|
||||||
|
|
||||||
void setTextSize(uint8_t s);
|
|
||||||
void setTextSize(uint8_t sx, uint8_t sy);
|
|
||||||
|
|
||||||
void setFont(const GFXfont *f = NULL);
|
|
||||||
|
|
||||||
int16_t getCursorX();
|
|
||||||
int16_t getCursorY();
|
|
||||||
void setCursor(int16_t x, int16_t y);
|
|
||||||
|
|
||||||
void setTextColor(uint16_t c);
|
|
||||||
void setTextColor(uint16_t c, uint16_t bg);
|
|
||||||
|
|
||||||
void setTextWrap(bool w);
|
|
||||||
void cp437(bool x);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int16_t cursor_x = 0;
|
|
||||||
int16_t cursor_y = 0;
|
|
||||||
uint16_t textcolor, textbgcolor;
|
|
||||||
uint8_t textsize_x, textsize_y;
|
|
||||||
bool wrap, _cp437;
|
|
||||||
|
|
||||||
virtual void startWrite(void) = 0;
|
|
||||||
virtual void writePixel(int16_t x, int16_t y, uint16_t color) = 0;
|
|
||||||
virtual void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) = 0;
|
|
||||||
virtual void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) = 0;
|
|
||||||
virtual void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) = 0;
|
|
||||||
virtual void writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) = 0;
|
|
||||||
virtual void endWrite(void) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
GFXfont *gfxFont;
|
|
||||||
void charBounds(char c, int16_t *x, int16_t *y, int16_t *minx, int16_t *miny, int16_t *maxx, int16_t *maxy);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -13,19 +13,6 @@
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Graphics::Graphics(int16_t w, int16_t h)
|
|
||||||
{
|
|
||||||
_width = WIDTH = w;
|
|
||||||
_height = HEIGHT = h;
|
|
||||||
setRotation(0);
|
|
||||||
setCursor(0, 0);
|
|
||||||
setTextSize(1);
|
|
||||||
setTextColor(0xFFFF, 0xFFFF);
|
|
||||||
setTextWrap(true);
|
|
||||||
cp437(false);
|
|
||||||
gfxFont = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::setRotation(uint8_t x)
|
void Graphics::setRotation(uint8_t x)
|
||||||
{
|
{
|
||||||
rotation = (x & 3);
|
rotation = (x & 3);
|
||||||
|
@ -84,7 +71,7 @@ void Graphics::writePixel(int16_t x0, int16_t y0, uint16_t color)
|
||||||
int x = x0 >> 3;
|
int x = x0 >> 3;
|
||||||
int x_sub = x0 & 7;
|
int x_sub = x0 & 7;
|
||||||
uint8_t temp = *(_partial + 100 * y0 + x);
|
uint8_t temp = *(_partial + 100 * y0 + x);
|
||||||
*(_partial + 100 * y0 + x) = ~pixelMaskLUT[x_sub] & temp | (color ? pixelMaskLUT[x_sub] : 0);
|
*(_partial + 100 * y0 + x) = (~pixelMaskLUT[x_sub] & temp) | (color ? pixelMaskLUT[x_sub] : 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -93,7 +80,7 @@ void Graphics::writePixel(int16_t x0, int16_t y0, uint16_t color)
|
||||||
int x_sub = x0 & 1;
|
int x_sub = x0 & 1;
|
||||||
uint8_t temp;
|
uint8_t temp;
|
||||||
temp = *(D_memory4Bit + 400 * y0 + x);
|
temp = *(D_memory4Bit + 400 * y0 + x);
|
||||||
*(D_memory4Bit + 400 * y0 + x) = pixelMaskGLUT[x_sub] & temp | (x_sub ? color : color << 4);
|
*(D_memory4Bit + 400 * y0 + x) = (pixelMaskGLUT[x_sub] & temp) | (x_sub ? color : color << 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
#ifndef __Graphics_H__
|
#ifndef __GRAPHICS_H__
|
||||||
#define __Graphics_H__
|
#define __GRAPHICS_H__
|
||||||
|
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
|
||||||
#include "Font.h"
|
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
#include "Shapes.h"
|
#include "Shapes.h"
|
||||||
|
|
||||||
|
@ -26,15 +25,15 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class Graphics : public Shapes, public Image, public Font
|
class Graphics : public Shapes, public Image
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Graphics(int16_t w, int16_t h);
|
Graphics(int16_t w, int16_t h) : Adafruit_GFX(w, h), Shapes(w, h), Image(w, h){};
|
||||||
|
|
||||||
void setRotation(uint8_t r);
|
void setRotation(uint8_t r);
|
||||||
uint8_t getRotation();
|
uint8_t getRotation();
|
||||||
|
|
||||||
inline void drawPixel(int16_t x, int16_t y, uint16_t color) override;
|
void drawPixel(int16_t x, int16_t y, uint16_t color) override;
|
||||||
|
|
||||||
void selectDisplayMode(uint8_t _mode);
|
void selectDisplayMode(uint8_t _mode);
|
||||||
|
|
||||||
|
@ -65,7 +64,7 @@ class Graphics : public Shapes, public Image, public Font
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startWrite(void) override;
|
void startWrite(void) override;
|
||||||
inline void writePixel(int16_t x, int16_t y, uint16_t color) override;
|
void writePixel(int16_t x, int16_t y, uint16_t color) override;
|
||||||
void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) override;
|
void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) override;
|
||||||
void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) override;
|
void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) override;
|
||||||
void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) override;
|
void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) override;
|
||||||
|
@ -75,9 +74,6 @@ class Graphics : public Shapes, public Image, public Font
|
||||||
uint8_t _displayMode = 0;
|
uint8_t _displayMode = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int16_t WIDTH, HEIGHT;
|
|
||||||
int16_t _width, _height;
|
|
||||||
uint8_t rotation = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
Image *_imagePtrJpeg = nullptr;
|
Image *_imagePtrJpeg = nullptr;
|
||||||
|
|
||||||
Image::Image()
|
Image::Image(int16_t w, int16_t h) : Adafruit_GFX(w, h)
|
||||||
{
|
{
|
||||||
_imagePtrJpeg = this;
|
_imagePtrJpeg = this;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ bool Image::drawImage(const char *path, int x, int y, bool dither, bool invert)
|
||||||
if (strstr(path, ".jpg") != NULL || strstr(path, ".jpeg") != NULL)
|
if (strstr(path, ".jpg") != NULL || strstr(path, ".jpeg") != NULL)
|
||||||
return drawJpegFromSd(path, x, y, dither, invert);
|
return drawJpegFromSd(path, x, y, dither, invert);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Image::drawImage(const uint8_t *buf, int x, int y, int16_t w, int16_t h, uint8_t c, uint8_t bg)
|
bool Image::drawImage(const uint8_t *buf, int x, int y, int16_t w, int16_t h, uint8_t c, uint8_t bg)
|
||||||
|
@ -45,30 +46,7 @@ bool Image::drawImage(const uint8_t *buf, int x, int y, int16_t w, int16_t h, ui
|
||||||
drawBitmap(x, y, buf, w, h, c, bg);
|
drawBitmap(x, y, buf, w, h, c, bg);
|
||||||
else if (getDisplayMode() == INKPLATE_3BIT)
|
else if (getDisplayMode() == INKPLATE_3BIT)
|
||||||
drawBitmap3Bit(x, y, buf, w, h);
|
drawBitmap3Bit(x, y, buf, w, h);
|
||||||
}
|
return 1;
|
||||||
|
|
||||||
void Image::drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg)
|
|
||||||
{
|
|
||||||
int16_t byteWidth = (w + 7) >> 3; // Bitmap scanline pad = whole byte
|
|
||||||
uint8_t byte = 0;
|
|
||||||
|
|
||||||
startWrite();
|
|
||||||
for (int16_t j = 0; j < h; j++, y++)
|
|
||||||
{
|
|
||||||
for (int16_t i = 0; i < w; i++)
|
|
||||||
{
|
|
||||||
if (i & 7)
|
|
||||||
byte <<= 1;
|
|
||||||
else
|
|
||||||
byte = bitmap[j * byteWidth + (i >> 3)];
|
|
||||||
|
|
||||||
if (byte & 0x80)
|
|
||||||
writePixel(x + i, y, color);
|
|
||||||
else if (bg != 0xFFFF)
|
|
||||||
writePixel(x + i, y, bg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
endWrite();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::drawBitmap3Bit(int16_t _x, int16_t _y, const unsigned char *_p, int16_t _w, int16_t _h)
|
void Image::drawBitmap3Bit(int16_t _x, int16_t _y, const unsigned char *_p, int16_t _w, int16_t _h)
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
#ifndef __IMAGE_H__
|
#ifndef __IMAGE_H__
|
||||||
#define __IMAGE_H__
|
#define __IMAGE_H__
|
||||||
|
|
||||||
|
#include "../libs/Adafruit-GFX-Library/Adafruit_GFX.h"
|
||||||
#include "../libs/SdFat/SdFat.h"
|
#include "../libs/SdFat/SdFat.h"
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "Network.h"
|
#include "Network.h"
|
||||||
#include "WiFiClient.h"
|
#include "WiFiClient.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
class Image : virtual public Network
|
class Image : virtual public Network, virtual public Adafruit_GFX
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Image();
|
Image(int16_t w, int16_t h);
|
||||||
|
|
||||||
virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
|
virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
|
||||||
|
|
||||||
|
@ -23,8 +24,11 @@ class Image : virtual public Network
|
||||||
bool drawImage(const String path, int x, int y, bool dither = 1, bool invert = 0);
|
bool drawImage(const String path, int x, int y, bool dither = 1, bool invert = 0);
|
||||||
bool drawImage(const uint8_t *buf, int x, int y, int16_t w, int16_t h, uint8_t c = BLACK, uint8_t bg = 0xFF);
|
bool drawImage(const uint8_t *buf, int x, int y, int16_t w, int16_t h, uint8_t c = BLACK, uint8_t bg = 0xFF);
|
||||||
|
|
||||||
void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color,
|
// Defined in Adafruit-GFX-Library, but should fit here
|
||||||
uint16_t bg = 0xFFFF);
|
// void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color);
|
||||||
|
// void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color,
|
||||||
|
// uint16_t bg);
|
||||||
|
|
||||||
void drawBitmap3Bit(int16_t _x, int16_t _y, const unsigned char *_p, int16_t _w, int16_t _h);
|
void drawBitmap3Bit(int16_t _x, int16_t _y, const unsigned char *_p, int16_t _w, int16_t _h);
|
||||||
|
|
||||||
bool drawBitmapFromBuffer(uint8_t *buf, int x, int y, bool dither, bool invert);
|
bool drawBitmapFromBuffer(uint8_t *buf, int x, int y, bool dither, bool invert);
|
||||||
|
|
|
@ -116,7 +116,7 @@ bool Image::drawBitmapFromWeb(const char *url, int x, int y, bool dither, bool i
|
||||||
ret = drawBitmapFromBuffer(buf, x, y, dither, invert);
|
ret = drawBitmapFromBuffer(buf, x, y, dither, invert);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
return 1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Image::drawBitmapFromWeb(WiFiClient *s, int x, int y, int32_t len, bool dither, bool invert)
|
bool Image::drawBitmapFromWeb(WiFiClient *s, int x, int y, int32_t len, bool dither, bool invert)
|
||||||
|
@ -127,7 +127,7 @@ bool Image::drawBitmapFromWeb(WiFiClient *s, int x, int y, int32_t len, bool dit
|
||||||
ret = drawBitmapFromBuffer(buf, x, y, dither, invert);
|
ret = drawBitmapFromBuffer(buf, x, y, dither, invert);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
return 1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Image::drawBitmapFromBuffer(uint8_t *buf, int x, int y, bool dither, bool invert)
|
bool Image::drawBitmapFromBuffer(uint8_t *buf, int x, int y, bool dither, bool invert)
|
||||||
|
@ -155,7 +155,7 @@ bool Image::drawBitmapFromBuffer(uint8_t *buf, int x, int y, bool dither, bool i
|
||||||
|
|
||||||
void Image::displayBmpLine(int16_t x, int16_t y, bitmapHeader *bmpHeader, bool dither, bool invert)
|
void Image::displayBmpLine(int16_t x, int16_t y, bitmapHeader *bmpHeader, bool dither, bool invert)
|
||||||
{
|
{
|
||||||
int16_t w = bmpHeader->width, h = bmpHeader->height;
|
int16_t w = bmpHeader->width;
|
||||||
int8_t c = bmpHeader->color;
|
int8_t c = bmpHeader->color;
|
||||||
|
|
||||||
startWrite();
|
startWrite();
|
||||||
|
@ -164,7 +164,7 @@ void Image::displayBmpLine(int16_t x, int16_t y, bitmapHeader *bmpHeader, bool d
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
writePixel(x + j, y, (invert ^ (palette[0] < palette[1])) ^ !!(pixelBuffer[j >> 3] & (1 << (7 - j & 7))));
|
writePixel(x + j, y, (invert ^ (palette[0] < palette[1])) ^ !!(pixelBuffer[j >> 3] & (1 << (7 - (j & 7)))));
|
||||||
break;
|
break;
|
||||||
// as for 2 bit, literally cannot find an example online or in PS, so skipped
|
// as for 2 bit, literally cannot find an example online or in PS, so skipped
|
||||||
case 4: {
|
case 4: {
|
||||||
|
|
|
@ -13,322 +13,6 @@
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Shapes::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)
|
|
||||||
{
|
|
||||||
startWrite();
|
|
||||||
writeFastVLine(x, y, h, color);
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shapes::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color)
|
|
||||||
{
|
|
||||||
startWrite();
|
|
||||||
writeFastHLine(x, y, w, color);
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shapes::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
|
|
||||||
{
|
|
||||||
startWrite();
|
|
||||||
writeFillRect(x, y, w, h, color);
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shapes::fillScreen(uint16_t color)
|
|
||||||
{
|
|
||||||
startWrite();
|
|
||||||
fillRect(0, 0, width(), height(), color);
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shapes::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color)
|
|
||||||
{
|
|
||||||
if (x0 == x1)
|
|
||||||
{
|
|
||||||
if (y0 > y1)
|
|
||||||
{
|
|
||||||
_swap_int16_t(y0, y1);
|
|
||||||
}
|
|
||||||
drawFastVLine(x0, y0, y1 - y0 + 1, color);
|
|
||||||
}
|
|
||||||
else if (y0 == y1)
|
|
||||||
{
|
|
||||||
if (x0 > x1)
|
|
||||||
{
|
|
||||||
_swap_int16_t(x0, x1);
|
|
||||||
}
|
|
||||||
drawFastHLine(x0, y0, x1 - x0 + 1, color);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
startWrite();
|
|
||||||
writeLine(x0, y0, x1, y1, color);
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shapes::drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)
|
|
||||||
{
|
|
||||||
int16_t f = 1 - r;
|
|
||||||
int16_t ddF_x = 1;
|
|
||||||
int16_t ddF_y = -2 * r;
|
|
||||||
int16_t x = 0;
|
|
||||||
int16_t y = r;
|
|
||||||
|
|
||||||
startWrite();
|
|
||||||
writePixel(x0, y0 + r, color);
|
|
||||||
writePixel(x0, y0 - r, color);
|
|
||||||
writePixel(x0 + r, y0, color);
|
|
||||||
writePixel(x0 - r, y0, color);
|
|
||||||
|
|
||||||
while (x < y)
|
|
||||||
{
|
|
||||||
if (f >= 0)
|
|
||||||
{
|
|
||||||
y--;
|
|
||||||
ddF_y += 2;
|
|
||||||
f += ddF_y;
|
|
||||||
}
|
|
||||||
x++;
|
|
||||||
ddF_x += 2;
|
|
||||||
f += ddF_x;
|
|
||||||
|
|
||||||
writePixel(x0 + x, y0 + y, color);
|
|
||||||
writePixel(x0 - x, y0 + y, color);
|
|
||||||
writePixel(x0 + x, y0 - y, color);
|
|
||||||
writePixel(x0 - x, y0 - y, color);
|
|
||||||
writePixel(x0 + y, y0 + x, color);
|
|
||||||
writePixel(x0 - y, y0 + x, color);
|
|
||||||
writePixel(x0 + y, y0 - x, color);
|
|
||||||
writePixel(x0 - y, y0 - x, color);
|
|
||||||
}
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shapes::drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color)
|
|
||||||
{
|
|
||||||
startWrite();
|
|
||||||
int16_t f = 1 - r;
|
|
||||||
int16_t ddF_x = 1;
|
|
||||||
int16_t ddF_y = -2 * r;
|
|
||||||
int16_t x = 0;
|
|
||||||
int16_t y = r;
|
|
||||||
|
|
||||||
while (x < y)
|
|
||||||
{
|
|
||||||
if (f >= 0)
|
|
||||||
{
|
|
||||||
y--;
|
|
||||||
ddF_y += 2;
|
|
||||||
f += ddF_y;
|
|
||||||
}
|
|
||||||
x++;
|
|
||||||
ddF_x += 2;
|
|
||||||
f += ddF_x;
|
|
||||||
if (cornername & 0x4)
|
|
||||||
{
|
|
||||||
writePixel(x0 + x, y0 + y, color);
|
|
||||||
writePixel(x0 + y, y0 + x, color);
|
|
||||||
}
|
|
||||||
if (cornername & 0x2)
|
|
||||||
{
|
|
||||||
writePixel(x0 + x, y0 - y, color);
|
|
||||||
writePixel(x0 + y, y0 - x, color);
|
|
||||||
}
|
|
||||||
if (cornername & 0x8)
|
|
||||||
{
|
|
||||||
writePixel(x0 - y, y0 + x, color);
|
|
||||||
writePixel(x0 - x, y0 + y, color);
|
|
||||||
}
|
|
||||||
if (cornername & 0x1)
|
|
||||||
{
|
|
||||||
writePixel(x0 - y, y0 - x, color);
|
|
||||||
writePixel(x0 - x, y0 - y, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shapes::fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)
|
|
||||||
{
|
|
||||||
startWrite();
|
|
||||||
writeFastVLine(x0, y0 - r, 2 * r + 1, color);
|
|
||||||
fillCircleHelper(x0, y0, r, 3, 0, color);
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shapes::fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t corners, int16_t delta, uint16_t color)
|
|
||||||
{
|
|
||||||
startWrite();
|
|
||||||
int16_t f = 1 - r;
|
|
||||||
int16_t ddF_x = 1;
|
|
||||||
int16_t ddF_y = -2 * r;
|
|
||||||
int16_t x = 0;
|
|
||||||
int16_t y = r;
|
|
||||||
int16_t px = x;
|
|
||||||
int16_t py = y;
|
|
||||||
|
|
||||||
++delta;
|
|
||||||
|
|
||||||
while (x < y)
|
|
||||||
{
|
|
||||||
if (f >= 0)
|
|
||||||
{
|
|
||||||
y--;
|
|
||||||
ddF_y += 2;
|
|
||||||
f += ddF_y;
|
|
||||||
}
|
|
||||||
x++;
|
|
||||||
ddF_x += 2;
|
|
||||||
f += ddF_x;
|
|
||||||
if (x < (y + 1))
|
|
||||||
{
|
|
||||||
if (corners & 1)
|
|
||||||
writeFastVLine(x0 + x, y0 - y, 2 * y + delta, color);
|
|
||||||
if (corners & 2)
|
|
||||||
writeFastVLine(x0 - x, y0 - y, 2 * y + delta, color);
|
|
||||||
}
|
|
||||||
if (y != py)
|
|
||||||
{
|
|
||||||
if (corners & 1)
|
|
||||||
writeFastVLine(x0 + py, y0 - px, 2 * px + delta, color);
|
|
||||||
if (corners & 2)
|
|
||||||
writeFastVLine(x0 - py, y0 - px, 2 * px + delta, color);
|
|
||||||
py = y;
|
|
||||||
}
|
|
||||||
px = x;
|
|
||||||
}
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shapes::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
|
|
||||||
{
|
|
||||||
startWrite();
|
|
||||||
writeFastHLine(x, y, w, color);
|
|
||||||
writeFastHLine(x, y + h - 1, w, color);
|
|
||||||
writeFastVLine(x, y, h, color);
|
|
||||||
writeFastVLine(x + w - 1, y, h, color);
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shapes::drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color)
|
|
||||||
{
|
|
||||||
int16_t max_radius = ((w < h) ? w : h) / 2;
|
|
||||||
if (r > max_radius)
|
|
||||||
r = max_radius;
|
|
||||||
|
|
||||||
startWrite();
|
|
||||||
writeFastHLine(x + r, y, w - 2 * r, color);
|
|
||||||
writeFastHLine(x + r, y + h - 1, w - 2 * r, color);
|
|
||||||
writeFastVLine(x, y + r, h - 2 * r, color);
|
|
||||||
writeFastVLine(x + w - 1, y + r, h - 2 * r, color);
|
|
||||||
endWrite();
|
|
||||||
|
|
||||||
drawCircleHelper(x + r, y + r, r, 1, color);
|
|
||||||
drawCircleHelper(x + w - r - 1, y + r, r, 2, color);
|
|
||||||
drawCircleHelper(x + w - r - 1, y + h - r - 1, r, 4, color);
|
|
||||||
drawCircleHelper(x + r, y + h - r - 1, r, 8, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shapes::fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color)
|
|
||||||
{
|
|
||||||
int16_t max_radius = ((w < h) ? w : h) / 2;
|
|
||||||
if (r > max_radius)
|
|
||||||
r = max_radius;
|
|
||||||
|
|
||||||
startWrite();
|
|
||||||
writeFillRect(x + r, y, w - 2 * r, h, color);
|
|
||||||
endWrite();
|
|
||||||
|
|
||||||
fillCircleHelper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1, color);
|
|
||||||
fillCircleHelper(x + r, y + r, r, 2, h - 2 * r - 1, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shapes::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)
|
|
||||||
{
|
|
||||||
startWrite();
|
|
||||||
writeLine(x0, y0, x1, y1, color);
|
|
||||||
writeLine(x1, y1, x2, y2, color);
|
|
||||||
writeLine(x2, y2, x0, y0, color);
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Shapes::fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
startWrite();
|
|
||||||
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;
|
|
||||||
|
|
||||||
writeFastHLine(a, y0, b - a + 1, color);
|
|
||||||
endWrite();
|
|
||||||
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;
|
|
||||||
else
|
|
||||||
last = y1 - 1;
|
|
||||||
|
|
||||||
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);
|
|
||||||
writeFastHLine(a, y, b - a + 1, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
sa = (int32_t)dx12 * (y - y1);
|
|
||||||
sb = (int32_t)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);
|
|
||||||
writeFastHLine(a, y, b - a + 1, color);
|
|
||||||
}
|
|
||||||
endWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Shapes::drawElipse(int rx, int ry, int xc, int yc, int c)
|
void Shapes::drawElipse(int rx, int ry, int xc, int yc, int c)
|
||||||
{
|
{
|
||||||
float dx, dy, d1, d2, x, y;
|
float dx, dy, d1, d2, x, y;
|
||||||
|
@ -437,7 +121,6 @@ void Shapes::drawThickLine(int x1, int y1, int x2, int y2, int color, float thic
|
||||||
float deg = atan2f((float)(y2 - y1), (float)(x2 - x1));
|
float deg = atan2f((float)(y2 - y1), (float)(x2 - x1));
|
||||||
|
|
||||||
float l1 = tan(deg);
|
float l1 = tan(deg);
|
||||||
float k1 = (float)y1 - l1 * (float)x1;
|
|
||||||
|
|
||||||
float degShift = (l1 < 0 ? M_PI_2 : -M_PI_2);
|
float degShift = (l1 < 0 ? M_PI_2 : -M_PI_2);
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,19 @@
|
||||||
#ifndef __SHAPES_H__
|
#ifndef __SHAPES_H__
|
||||||
#define __SHAPES_H__
|
#define __SHAPES_H__
|
||||||
|
|
||||||
|
#include "../libs/Adafruit-GFX-Library/Adafruit_GFX.h"
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "Triangulate.h"
|
#include "Triangulate.h"
|
||||||
|
|
||||||
class Shapes
|
class Shapes : virtual public Adafruit_GFX
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Shapes(int16_t w, int16_t h) : Adafruit_GFX(w, h){};
|
||||||
|
|
||||||
virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
|
virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
|
||||||
|
|
||||||
virtual void selectDisplayMode(uint8_t _mode) = 0;
|
virtual void selectDisplayMode(uint8_t _mode) = 0;
|
||||||
virtual uint8_t getDisplayMode() = 0;
|
virtual uint8_t getDisplayMode() = 0;
|
||||||
virtual int16_t width() = 0;
|
|
||||||
virtual int16_t height() = 0;
|
|
||||||
|
|
||||||
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
|
||||||
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
|
||||||
void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
|
||||||
void fillScreen(uint16_t color);
|
|
||||||
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
|
|
||||||
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
|
||||||
|
|
||||||
void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
|
|
||||||
void drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color);
|
|
||||||
void fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
|
|
||||||
void fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color);
|
|
||||||
void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
|
|
||||||
void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
|
|
||||||
void drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
|
|
||||||
void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
|
|
||||||
|
|
||||||
void drawElipse(int rx, int ry, int xc, int yc, int c);
|
void drawElipse(int rx, int ry, int xc, int yc, int c);
|
||||||
void fillElipse(int rx, int ry, int xc, int yc, int c);
|
void fillElipse(int rx, int ry, int xc, int yc, int c);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,403 @@
|
||||||
|
#ifndef _ADAFRUIT_GFX_H
|
||||||
|
#define _ADAFRUIT_GFX_H
|
||||||
|
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include "Print.h"
|
||||||
|
#else
|
||||||
|
#include "WProgram.h"
|
||||||
|
#endif
|
||||||
|
#include "gfxfont.h"
|
||||||
|
|
||||||
|
/// A generic graphics superclass that can handle all sorts of drawing. At a
|
||||||
|
/// minimum you can subclass and provide drawPixel(). At a maximum you can do a
|
||||||
|
/// ton of overriding to optimize. Used for any/all Adafruit displays!
|
||||||
|
class Adafruit_GFX : public Print
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
Adafruit_GFX(int16_t w, int16_t h); // Constructor
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Draw to the screen/framebuffer/etc.
|
||||||
|
Must be overridden in subclass.
|
||||||
|
@param x X coordinate in pixels
|
||||||
|
@param y Y coordinate in pixels
|
||||||
|
@param color 16-bit pixel color.
|
||||||
|
*/
|
||||||
|
/**********************************************************************/
|
||||||
|
virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
|
||||||
|
|
||||||
|
// TRANSACTION API / CORE DRAW API
|
||||||
|
// These MAY be overridden by the subclass to provide device-specific
|
||||||
|
// optimized code. Otherwise 'generic' versions are used.
|
||||||
|
virtual void startWrite(void);
|
||||||
|
virtual void writePixel(int16_t x, int16_t y, uint16_t color);
|
||||||
|
virtual void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||||||
|
virtual void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||||
|
virtual void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||||
|
virtual void writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
|
||||||
|
virtual void endWrite(void);
|
||||||
|
|
||||||
|
// CONTROL API
|
||||||
|
// These MAY be overridden by the subclass to provide device-specific
|
||||||
|
// optimized code. Otherwise 'generic' versions are used.
|
||||||
|
virtual void setRotation(uint8_t r);
|
||||||
|
virtual void invertDisplay(bool i);
|
||||||
|
|
||||||
|
// BASIC DRAW API
|
||||||
|
// These MAY be overridden by the subclass to provide device-specific
|
||||||
|
// optimized code. Otherwise 'generic' versions are used.
|
||||||
|
|
||||||
|
// It's good to implement those, even if using transaction API
|
||||||
|
virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||||
|
virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||||
|
virtual void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||||||
|
virtual void fillScreen(uint16_t color);
|
||||||
|
// Optional and probably not necessary to change
|
||||||
|
virtual void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
|
||||||
|
virtual void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
|
||||||
|
|
||||||
|
// These exist only with Adafruit_GFX (no subclass overrides)
|
||||||
|
void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
|
||||||
|
void drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color);
|
||||||
|
void fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
|
||||||
|
void fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color);
|
||||||
|
void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
|
||||||
|
void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
|
||||||
|
void drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
|
||||||
|
void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
|
||||||
|
void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color);
|
||||||
|
void drawBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color, uint16_t bg);
|
||||||
|
void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color);
|
||||||
|
void drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color, uint16_t bg);
|
||||||
|
void drawXBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color);
|
||||||
|
void drawGrayscaleBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h);
|
||||||
|
void drawGrayscaleBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h);
|
||||||
|
void drawGrayscaleBitmap(int16_t x, int16_t y, const uint8_t bitmap[], const uint8_t mask[], int16_t w, int16_t h);
|
||||||
|
void drawGrayscaleBitmap(int16_t x, int16_t y, uint8_t *bitmap, uint8_t *mask, int16_t w, int16_t h);
|
||||||
|
void drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[], int16_t w, int16_t h);
|
||||||
|
void drawRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h);
|
||||||
|
void drawRGBBitmap(int16_t x, int16_t y, const uint16_t bitmap[], const uint8_t mask[], int16_t w, int16_t h);
|
||||||
|
void drawRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, uint8_t *mask, int16_t w, int16_t h);
|
||||||
|
void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size);
|
||||||
|
void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size_x, uint8_t size_y);
|
||||||
|
void getTextBounds(const char *string, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
|
||||||
|
void getTextBounds(const __FlashStringHelper *s, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w,
|
||||||
|
uint16_t *h);
|
||||||
|
void getTextBounds(const String &str, int16_t x, int16_t y, int16_t *x1, int16_t *y1, uint16_t *w, uint16_t *h);
|
||||||
|
void setTextSize(uint8_t s);
|
||||||
|
void setTextSize(uint8_t sx, uint8_t sy);
|
||||||
|
void setFont(const GFXfont *f = NULL);
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Set text cursor location
|
||||||
|
@param x X coordinate in pixels
|
||||||
|
@param y Y coordinate in pixels
|
||||||
|
*/
|
||||||
|
/**********************************************************************/
|
||||||
|
void setCursor(int16_t x, int16_t y)
|
||||||
|
{
|
||||||
|
cursor_x = x;
|
||||||
|
cursor_y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Set text font color with transparant background
|
||||||
|
@param c 16-bit 5-6-5 Color to draw text with
|
||||||
|
@note For 'transparent' background, background and foreground
|
||||||
|
are set to same color rather than using a separate flag.
|
||||||
|
*/
|
||||||
|
/**********************************************************************/
|
||||||
|
void setTextColor(uint16_t c)
|
||||||
|
{
|
||||||
|
textcolor = textbgcolor = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Set text font color with custom background color
|
||||||
|
@param c 16-bit 5-6-5 Color to draw text with
|
||||||
|
@param bg 16-bit 5-6-5 Color to draw background/fill with
|
||||||
|
*/
|
||||||
|
/**********************************************************************/
|
||||||
|
void setTextColor(uint16_t c, uint16_t bg)
|
||||||
|
{
|
||||||
|
textcolor = c;
|
||||||
|
textbgcolor = bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Set whether text that is too long for the screen width should
|
||||||
|
automatically wrap around to the next line (else clip right).
|
||||||
|
@param w true for wrapping, false for clipping
|
||||||
|
*/
|
||||||
|
/**********************************************************************/
|
||||||
|
void setTextWrap(bool w)
|
||||||
|
{
|
||||||
|
wrap = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Enable (or disable) Code Page 437-compatible charset.
|
||||||
|
There was an error in glcdfont.c for the longest time -- one
|
||||||
|
character (#176, the 'light shade' block) was missing -- this
|
||||||
|
threw off the index of every character that followed it.
|
||||||
|
But a TON of code has been written with the erroneous
|
||||||
|
character indices. By default, the library uses the original
|
||||||
|
'wrong' behavior and old sketches will still work. Pass
|
||||||
|
'true' to this function to use correct CP437 character values
|
||||||
|
in your code.
|
||||||
|
@param x true = enable (new behavior), false = disable (old behavior)
|
||||||
|
*/
|
||||||
|
/**********************************************************************/
|
||||||
|
void cp437(bool x = true)
|
||||||
|
{
|
||||||
|
_cp437 = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
using Print::write;
|
||||||
|
#if ARDUINO >= 100
|
||||||
|
virtual size_t write(uint8_t);
|
||||||
|
#else
|
||||||
|
virtual void write(uint8_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Get width of the display, accounting for current rotation
|
||||||
|
@returns Width in pixels
|
||||||
|
*/
|
||||||
|
/************************************************************************/
|
||||||
|
int16_t width(void) const
|
||||||
|
{
|
||||||
|
return _width;
|
||||||
|
};
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Get height of the display, accounting for current rotation
|
||||||
|
@returns Height in pixels
|
||||||
|
*/
|
||||||
|
/************************************************************************/
|
||||||
|
int16_t height(void) const
|
||||||
|
{
|
||||||
|
return _height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Get rotation setting for display
|
||||||
|
@returns 0 thru 3 corresponding to 4 cardinal rotations
|
||||||
|
*/
|
||||||
|
/************************************************************************/
|
||||||
|
uint8_t getRotation(void) const
|
||||||
|
{
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get current cursor position (get rotation safe maximum values,
|
||||||
|
// using: width() for x, height() for y)
|
||||||
|
/************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Get text cursor X location
|
||||||
|
@returns X coordinate in pixels
|
||||||
|
*/
|
||||||
|
/************************************************************************/
|
||||||
|
int16_t getCursorX(void) const
|
||||||
|
{
|
||||||
|
return cursor_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Get text cursor Y location
|
||||||
|
@returns Y coordinate in pixels
|
||||||
|
*/
|
||||||
|
/************************************************************************/
|
||||||
|
int16_t getCursorY(void) const
|
||||||
|
{
|
||||||
|
return cursor_y;
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void charBounds(unsigned char c, int16_t *x, int16_t *y, int16_t *minx, int16_t *miny, int16_t *maxx,
|
||||||
|
int16_t *maxy);
|
||||||
|
int16_t WIDTH; ///< This is the 'raw' display width - never changes
|
||||||
|
int16_t HEIGHT; ///< This is the 'raw' display height - never changes
|
||||||
|
int16_t _width; ///< Display width as modified by current rotation
|
||||||
|
int16_t _height; ///< Display height as modified by current rotation
|
||||||
|
int16_t cursor_x; ///< x location to start print()ing text
|
||||||
|
int16_t cursor_y; ///< y location to start print()ing text
|
||||||
|
uint16_t textcolor; ///< 16-bit background color for print()
|
||||||
|
uint16_t textbgcolor; ///< 16-bit text color for print()
|
||||||
|
uint8_t textsize_x; ///< Desired magnification in X-axis of text to print()
|
||||||
|
uint8_t textsize_y; ///< Desired magnification in Y-axis of text to print()
|
||||||
|
uint8_t rotation; ///< Display rotation (0 thru 3)
|
||||||
|
bool wrap; ///< If set, 'wrap' text at right edge of display
|
||||||
|
bool _cp437; ///< If set, use correct CP437 charset (default is off)
|
||||||
|
GFXfont *gfxFont; ///< Pointer to special font
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A simple drawn button UI element
|
||||||
|
class Adafruit_GFX_Button
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
Adafruit_GFX_Button(void);
|
||||||
|
// "Classic" initButton() uses center & size
|
||||||
|
void initButton(Adafruit_GFX *gfx, int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t outline, uint16_t fill,
|
||||||
|
uint16_t textcolor, char *label, uint8_t textsize);
|
||||||
|
void initButton(Adafruit_GFX *gfx, int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t outline, uint16_t fill,
|
||||||
|
uint16_t textcolor, char *label, uint8_t textsize_x, uint8_t textsize_y);
|
||||||
|
// New/alt initButton() uses upper-left corner & size
|
||||||
|
void initButtonUL(Adafruit_GFX *gfx, int16_t x1, int16_t y1, uint16_t w, uint16_t h, uint16_t outline,
|
||||||
|
uint16_t fill, uint16_t textcolor, char *label, uint8_t textsize);
|
||||||
|
void initButtonUL(Adafruit_GFX *gfx, int16_t x1, int16_t y1, uint16_t w, uint16_t h, uint16_t outline,
|
||||||
|
uint16_t fill, uint16_t textcolor, char *label, uint8_t textsize_x, uint8_t textsize_y);
|
||||||
|
void drawButton(bool inverted = false);
|
||||||
|
bool contains(int16_t x, int16_t y);
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Sets button state, should be done by some touch function
|
||||||
|
@param p True for pressed, false for not.
|
||||||
|
*/
|
||||||
|
/**********************************************************************/
|
||||||
|
void press(bool p)
|
||||||
|
{
|
||||||
|
laststate = currstate;
|
||||||
|
currstate = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool justPressed();
|
||||||
|
bool justReleased();
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Query whether the button is currently pressed
|
||||||
|
@returns True if pressed
|
||||||
|
*/
|
||||||
|
/**********************************************************************/
|
||||||
|
bool isPressed(void)
|
||||||
|
{
|
||||||
|
return currstate;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
Adafruit_GFX *_gfx;
|
||||||
|
int16_t _x1, _y1; // Coordinates of top-left corner
|
||||||
|
uint16_t _w, _h;
|
||||||
|
uint8_t _textsize_x;
|
||||||
|
uint8_t _textsize_y;
|
||||||
|
uint16_t _outlinecolor, _fillcolor, _textcolor;
|
||||||
|
char _label[10];
|
||||||
|
|
||||||
|
bool currstate, laststate;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A GFX 1-bit canvas context for graphics
|
||||||
|
class GFXcanvas1 : public Adafruit_GFX
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GFXcanvas1(uint16_t w, uint16_t h);
|
||||||
|
~GFXcanvas1(void);
|
||||||
|
void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||||
|
void fillScreen(uint16_t color);
|
||||||
|
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||||
|
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||||
|
bool getPixel(int16_t x, int16_t y) const;
|
||||||
|
/**********************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Get a pointer to the internal buffer memory
|
||||||
|
@returns A pointer to the allocated buffer
|
||||||
|
*/
|
||||||
|
/**********************************************************************/
|
||||||
|
uint8_t *getBuffer(void) const
|
||||||
|
{
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool getRawPixel(int16_t x, int16_t y) const;
|
||||||
|
void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||||
|
void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t *buffer;
|
||||||
|
|
||||||
|
#ifdef __AVR__
|
||||||
|
// Bitmask tables of 0x80>>X and ~(0x80>>X), because X>>Y is slow on AVR
|
||||||
|
static const uint8_t PROGMEM GFXsetBit[], GFXclrBit[];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A GFX 8-bit canvas context for graphics
|
||||||
|
class GFXcanvas8 : public Adafruit_GFX
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GFXcanvas8(uint16_t w, uint16_t h);
|
||||||
|
~GFXcanvas8(void);
|
||||||
|
void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||||
|
void fillScreen(uint16_t color);
|
||||||
|
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||||
|
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||||
|
uint8_t getPixel(int16_t x, int16_t y) const;
|
||||||
|
/**********************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Get a pointer to the internal buffer memory
|
||||||
|
@returns A pointer to the allocated buffer
|
||||||
|
*/
|
||||||
|
/**********************************************************************/
|
||||||
|
uint8_t *getBuffer(void) const
|
||||||
|
{
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint8_t getRawPixel(int16_t x, int16_t y) const;
|
||||||
|
void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||||
|
void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t *buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A GFX 16-bit canvas context for graphics
|
||||||
|
class GFXcanvas16 : public Adafruit_GFX
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GFXcanvas16(uint16_t w, uint16_t h);
|
||||||
|
~GFXcanvas16(void);
|
||||||
|
void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||||
|
void fillScreen(uint16_t color);
|
||||||
|
void byteSwap(void);
|
||||||
|
void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||||
|
void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||||
|
uint16_t getPixel(int16_t x, int16_t y) const;
|
||||||
|
/**********************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Get a pointer to the internal buffer memory
|
||||||
|
@returns A pointer to the allocated buffer
|
||||||
|
*/
|
||||||
|
/**********************************************************************/
|
||||||
|
uint16_t *getBuffer(void) const
|
||||||
|
{
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint16_t getRawPixel(int16_t x, int16_t y) const;
|
||||||
|
void drawFastRawVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
|
||||||
|
void drawFastRawHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint16_t *buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _ADAFRUIT_GFX_H
|
Loading…
Reference in New Issue