Initial file reorg, and set cp437 true by default

This commit is contained in:
Phillip Burgess
2022-07-20 14:23:16 -07:00
parent 91d916deeb
commit 5b16fa5484
17 changed files with 1297 additions and 1307 deletions
File diff suppressed because it is too large Load Diff
+10 -158
View File
@@ -1,5 +1,4 @@
#ifndef _ADAFRUIT_GFX_H
#define _ADAFRUIT_GFX_H
#pragma once
#if ARDUINO >= 100
#include "Arduino.h"
@@ -166,15 +165,15 @@ public:
/**********************************************************************/
/*!
@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.
@brief Enable or disable Code Page 437-compatible charset.
There was a bug in glcdfont.c for years -- 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 now uses the correct charset. Old code
relying on the prior 'wrong' behavior really should update any
upper char indices its using, but can still work as-is by
adding an initial call to cp437(false).
@param x true = enable (new behavior), false = disable (old behavior)
*/
/**********************************************************************/
@@ -247,150 +246,3 @@ protected:
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
+183
View File
@@ -0,0 +1,183 @@
#include "Adafruit_GFX_Button.h"
/**************************************************************************/
/*!
@brief Create a simple drawn button UI element
*/
/**************************************************************************/
Adafruit_GFX_Button::Adafruit_GFX_Button(void) { _gfx = 0; }
/**************************************************************************/
/*!
@brief Initialize button with our desired color/size/settings
@param gfx Pointer to our display so we can draw to it!
@param x The X coordinate of the center of the button
@param y The Y coordinate of the center of the button
@param w Width of the buttton
@param h Height of the buttton
@param outline Color of the outline (16-bit 5-6-5 standard)
@param fill Color of the button fill (16-bit 5-6-5 standard)
@param textcolor Color of the button label (16-bit 5-6-5 standard)
@param label Ascii string of the text inside the button
@param textsize The font magnification of the label text
*/
/**************************************************************************/
// Classic initButton() function: pass center & size
void Adafruit_GFX_Button::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) {
// Tweak arguments and pass to the newer initButtonUL() function...
initButtonUL(gfx, x - (w / 2), y - (h / 2), w, h, outline, fill, textcolor,
label, textsize);
}
/**************************************************************************/
/*!
@brief Initialize button with our desired color/size/settings
@param gfx Pointer to our display so we can draw to it!
@param x The X coordinate of the center of the button
@param y The Y coordinate of the center of the button
@param w Width of the buttton
@param h Height of the buttton
@param outline Color of the outline (16-bit 5-6-5 standard)
@param fill Color of the button fill (16-bit 5-6-5 standard)
@param textcolor Color of the button label (16-bit 5-6-5 standard)
@param label Ascii string of the text inside the button
@param textsize_x The font magnification in X-axis of the label text
@param textsize_y The font magnification in Y-axis of the label text
*/
/**************************************************************************/
// Classic initButton() function: pass center & size
void Adafruit_GFX_Button::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) {
// Tweak arguments and pass to the newer initButtonUL() function...
initButtonUL(gfx, x - (w / 2), y - (h / 2), w, h, outline, fill, textcolor,
label, textsize_x, textsize_y);
}
/**************************************************************************/
/*!
@brief Initialize button with our desired color/size/settings, with
upper-left coordinates
@param gfx Pointer to our display so we can draw to it!
@param x1 The X coordinate of the Upper-Left corner of the button
@param y1 The Y coordinate of the Upper-Left corner of the button
@param w Width of the buttton
@param h Height of the buttton
@param outline Color of the outline (16-bit 5-6-5 standard)
@param fill Color of the button fill (16-bit 5-6-5 standard)
@param textcolor Color of the button label (16-bit 5-6-5 standard)
@param label Ascii string of the text inside the button
@param textsize The font magnification of the label text
*/
/**************************************************************************/
void Adafruit_GFX_Button::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) {
initButtonUL(gfx, x1, y1, w, h, outline, fill, textcolor, label, textsize,
textsize);
}
/**************************************************************************/
/*!
@brief Initialize button with our desired color/size/settings, with
upper-left coordinates
@param gfx Pointer to our display so we can draw to it!
@param x1 The X coordinate of the Upper-Left corner of the button
@param y1 The Y coordinate of the Upper-Left corner of the button
@param w Width of the buttton
@param h Height of the buttton
@param outline Color of the outline (16-bit 5-6-5 standard)
@param fill Color of the button fill (16-bit 5-6-5 standard)
@param textcolor Color of the button label (16-bit 5-6-5 standard)
@param label Ascii string of the text inside the button
@param textsize_x The font magnification in X-axis of the label text
@param textsize_y The font magnification in Y-axis of the label text
*/
/**************************************************************************/
void Adafruit_GFX_Button::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) {
_x1 = x1;
_y1 = y1;
_w = w;
_h = h;
_outlinecolor = outline;
_fillcolor = fill;
_textcolor = textcolor;
_textsize_x = textsize_x;
_textsize_y = textsize_y;
_gfx = gfx;
strncpy(_label, label, 9);
_label[9] = 0; // strncpy does not place a null at the end.
// When 'label' is >9 characters, _label is not terminated.
}
/**************************************************************************/
/*!
@brief Draw the button on the screen
@param inverted Whether to draw with fill/text swapped to indicate
'pressed'
*/
/**************************************************************************/
void Adafruit_GFX_Button::drawButton(bool inverted) {
uint16_t fill, outline, text;
if (!inverted) {
fill = _fillcolor;
outline = _outlinecolor;
text = _textcolor;
} else {
fill = _textcolor;
outline = _outlinecolor;
text = _fillcolor;
}
uint8_t r = min(_w, _h) / 4; // Corner radius
_gfx->fillRoundRect(_x1, _y1, _w, _h, r, fill);
_gfx->drawRoundRect(_x1, _y1, _w, _h, r, outline);
_gfx->setCursor(_x1 + (_w / 2) - (strlen(_label) * 3 * _textsize_x),
_y1 + (_h / 2) - (4 * _textsize_y));
_gfx->setTextColor(text);
_gfx->setTextSize(_textsize_x, _textsize_y);
_gfx->print(_label);
}
/**************************************************************************/
/*!
@brief Helper to let us know if a coordinate is within the bounds of the
button
@param x The X coordinate to check
@param y The Y coordinate to check
@returns True if within button graphics outline
*/
/**************************************************************************/
bool Adafruit_GFX_Button::contains(int16_t x, int16_t y) {
return ((x >= _x1) && (x < (int16_t)(_x1 + _w)) && (y >= _y1) &&
(y < (int16_t)(_y1 + _h)));
}
/**************************************************************************/
/*!
@brief Query whether the button was pressed since we last checked state
@returns True if was not-pressed before, now is.
*/
/**************************************************************************/
bool Adafruit_GFX_Button::justPressed() { return (currstate && !laststate); }
/**************************************************************************/
/*!
@brief Query whether the button was released since we last checked state
@returns True if was pressed before, now is not.
*/
/**************************************************************************/
bool Adafruit_GFX_Button::justReleased() { return (!currstate && laststate); }
+61
View File
@@ -0,0 +1,61 @@
#pragma once
#include "Adafruit_GFX.h"
/// 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;
};
@@ -18,7 +18,6 @@
#if !defined(__AVR_ATtiny85__) // Not for ATtiny, at all
#include "Adafruit_GrayOLED.h"
#include <Adafruit_GFX.h>
// SOME DEFINES AND STATIC VARIABLES USED INTERNALLY -----------------------
@@ -418,4 +417,4 @@ void Adafruit_GrayOLED::setContrast(uint8_t level) {
oled_commandList(cmd, 2);
}
#endif /* ATTIN85 not supported */
#endif // end !__AVR_ATtiny85__
@@ -21,12 +21,11 @@
*
*/
#ifndef _Adafruit_GRAYOLED_H_
#define _Adafruit_GRAYOLED_H_
#pragma once
#if !defined(__AVR_ATtiny85__) // Not for ATtiny, at all
#include <Adafruit_GFX.h>
#include "Adafruit_GFX.h"
#include <Adafruit_I2CDevice.h>
#include <Adafruit_SPIDevice.h>
#include <SPI.h>
@@ -97,4 +96,3 @@ private:
};
#endif // end __AVR_ATtiny85__
#endif // _Adafruit_GrayOLED_H_
+1 -3
View File
@@ -17,8 +17,7 @@
* BSD license, all text here must be included in any redistribution.
*/
#ifndef _ADAFRUIT_SPITFT_H_
#define _ADAFRUIT_SPITFT_H_
#pragma once
#if !defined(__AVR_ATtiny85__) // Not for ATtiny, at all
@@ -527,4 +526,3 @@ protected:
};
#endif // end __AVR_ATtiny85__
#endif // end _ADAFRUIT_SPITFT_H_
+359
View File
@@ -0,0 +1,359 @@
#include "GFXcanvas1.h"
// GFXcanvas1, GFXcanvas8 and GFXcanvas16 (currently a WIP, don't get too
// comfy with the implementation) provide 1-, 8- and 16-bit offscreen
// canvases, the address of which can be passed to drawBitmap() or
// pushColors() (the latter appears only in a couple of GFX-subclassed TFT
// libraries at this time). This is here mostly to help with the recently-
// added proportionally-spaced fonts; adds a way to refresh a section of the
// screen without a massive flickering clear-and-redraw...but maybe you'll
// find other uses too. VERY RAM-intensive, since the buffer is in MCU
// memory and not the display driver...GXFcanvas1 might be minimally useful
// on an Uno-class board, but this and the others are much more likely to
// require at least a Mega or various recent ARM-type boards (recommended,
// as the text+bitmap draw can be pokey). GFXcanvas1 requires 1 bit per
// pixel (rounded up to nearest byte per scanline), GFXcanvas8 is 1 byte
// per pixel (no scanline pad), and GFXcanvas16 uses 2 bytes per pixel (no
// scanline pad).
// NOT EXTENSIVELY TESTED YET. MAY CONTAIN WORST BUGS KNOWN TO HUMANKIND.
#ifdef __AVR__
// Bitmask tables of 0x80>>X and ~(0x80>>X), because X>>Y is slow on AVR
const uint8_t PROGMEM GFXcanvas1::GFXsetBit[] = {0x80, 0x40, 0x20, 0x10,
0x08, 0x04, 0x02, 0x01};
const uint8_t PROGMEM GFXcanvas1::GFXclrBit[] = {0x7F, 0xBF, 0xDF, 0xEF,
0xF7, 0xFB, 0xFD, 0xFE};
#endif
/**************************************************************************/
/*!
@brief Instatiate a GFX 1-bit canvas context for graphics
@param w Display width, in pixels
@param h Display height, in pixels
*/
/**************************************************************************/
GFXcanvas1::GFXcanvas1(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
uint16_t bytes = ((w + 7) / 8) * h;
if ((buffer = (uint8_t *)malloc(bytes))) {
memset(buffer, 0, bytes);
}
}
/**************************************************************************/
/*!
@brief Delete the canvas, free memory
*/
/**************************************************************************/
GFXcanvas1::~GFXcanvas1(void) {
if (buffer)
free(buffer);
}
/**************************************************************************/
/*!
@brief Draw a pixel to the canvas framebuffer
@param x x coordinate
@param y y coordinate
@param color Binary (on or off) color to fill with
*/
/**************************************************************************/
void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint16_t color) {
if (buffer) {
if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height))
return;
int16_t t;
switch (rotation) {
case 1:
t = x;
x = WIDTH - 1 - y;
y = t;
break;
case 2:
x = WIDTH - 1 - x;
y = HEIGHT - 1 - y;
break;
case 3:
t = x;
x = y;
y = HEIGHT - 1 - t;
break;
}
uint8_t *ptr = &buffer[(x / 8) + y * ((WIDTH + 7) / 8)];
#ifdef __AVR__
if (color)
*ptr |= pgm_read_byte(&GFXsetBit[x & 7]);
else
*ptr &= pgm_read_byte(&GFXclrBit[x & 7]);
#else
if (color)
*ptr |= 0x80 >> (x & 7);
else
*ptr &= ~(0x80 >> (x & 7));
#endif
}
}
bool GFXcanvas1::getPixel(int16_t x, int16_t y) const {
int16_t t;
switch (rotation) {
case 1:
t = x;
x = WIDTH - 1 - y;
y = t;
break;
case 2:
x = WIDTH - 1 - x;
y = HEIGHT - 1 - y;
break;
case 3:
t = x;
x = y;
y = HEIGHT - 1 - t;
break;
}
return getRawPixel(x, y);
}
bool GFXcanvas1::getRawPixel(int16_t x, int16_t y) const {
if ((x < 0) || (y < 0) || (x >= WIDTH) || (y >= HEIGHT))
return 0;
if (buffer) {
uint8_t *ptr = &buffer[(x / 8) + y * ((WIDTH + 7) / 8)];
#ifdef __AVR__
return ((*ptr) & pgm_read_byte(&GFXsetBit[x & 7])) != 0;
#else
return ((*ptr) & (0x80 >> (x & 7))) != 0;
#endif
}
return 0;
}
/**************************************************************************/
/*!
@brief Fill the framebuffer completely with one color
@param color Binary (on or off) color to fill with
*/
/**************************************************************************/
void GFXcanvas1::fillScreen(uint16_t color) {
if (buffer) {
uint16_t bytes = ((WIDTH + 7) / 8) * HEIGHT;
memset(buffer, color ? 0xFF : 0x00, bytes);
}
}
/**************************************************************************/
/*!
@brief Speed optimized vertical line drawing
@param x Line horizontal start point
@param y Line vertical start point
@param h Length of vertical line to be drawn, including first point
@param color Color to fill with
*/
/**************************************************************************/
void GFXcanvas1::drawFastVLine(int16_t x, int16_t y, int16_t h,
uint16_t color) {
if (h < 0) { // Convert negative heights to positive equivalent
h *= -1;
y -= h - 1;
if (y < 0) {
h += y;
y = 0;
}
}
// Edge rejection (no-draw if totally off canvas)
if ((x < 0) || (x >= width()) || (y >= height()) || ((y + h - 1) < 0)) {
return;
}
if (y < 0) { // Clip top
h += y;
y = 0;
}
if (y + h > height()) { // Clip bottom
h = height() - y;
}
if (getRotation() == 0) {
drawFastRawVLine(x, y, h, color);
} else if (getRotation() == 1) {
int16_t t = x;
x = WIDTH - 1 - y;
y = t;
x -= h - 1;
drawFastRawHLine(x, y, h, color);
} else if (getRotation() == 2) {
x = WIDTH - 1 - x;
y = HEIGHT - 1 - y;
y -= h - 1;
drawFastRawVLine(x, y, h, color);
} else if (getRotation() == 3) {
int16_t t = x;
x = y;
y = HEIGHT - 1 - t;
drawFastRawHLine(x, y, h, color);
}
}
/**************************************************************************/
/*!
@brief Speed optimized horizontal line drawing
@param x Line horizontal start point
@param y Line vertical start point
@param w Length of horizontal line to be drawn, including first point
@param color Color to fill with
*/
/**************************************************************************/
void GFXcanvas1::drawFastHLine(int16_t x, int16_t y, int16_t w,
uint16_t color) {
if (w < 0) { // Convert negative widths to positive equivalent
w *= -1;
x -= w - 1;
if (x < 0) {
w += x;
x = 0;
}
}
// Edge rejection (no-draw if totally off canvas)
if ((y < 0) || (y >= height()) || (x >= width()) || ((x + w - 1) < 0)) {
return;
}
if (x < 0) { // Clip left
w += x;
x = 0;
}
if (x + w >= width()) { // Clip right
w = width() - x;
}
if (getRotation() == 0) {
drawFastRawHLine(x, y, w, color);
} else if (getRotation() == 1) {
int16_t t = x;
x = WIDTH - 1 - y;
y = t;
drawFastRawVLine(x, y, w, color);
} else if (getRotation() == 2) {
x = WIDTH - 1 - x;
y = HEIGHT - 1 - y;
x -= w - 1;
drawFastRawHLine(x, y, w, color);
} else if (getRotation() == 3) {
int16_t t = x;
x = y;
y = HEIGHT - 1 - t;
y -= w - 1;
drawFastRawVLine(x, y, w, color);
}
}
/**************************************************************************/
/*!
@brief Speed optimized vertical line drawing into the raw canvas buffer
@param x Line horizontal start point
@param y Line vertical start point
@param h length of vertical line to be drawn, including first point
@param color Binary (on or off) color to fill with
*/
/**************************************************************************/
void GFXcanvas1::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
uint16_t color) {
// x & y already in raw (rotation 0) coordinates, no need to transform.
int16_t row_bytes = ((WIDTH + 7) / 8);
uint8_t *ptr = &buffer[(x / 8) + y * row_bytes];
if (color > 0) {
#ifdef __AVR__
uint8_t bit_mask = pgm_read_byte(&GFXsetBit[x & 7]);
#else
uint8_t bit_mask = (0x80 >> (x & 7));
#endif
for (int16_t i = 0; i < h; i++) {
*ptr |= bit_mask;
ptr += row_bytes;
}
} else {
#ifdef __AVR__
uint8_t bit_mask = pgm_read_byte(&GFXclrBit[x & 7]);
#else
uint8_t bit_mask = ~(0x80 >> (x & 7));
#endif
for (int16_t i = 0; i < h; i++) {
*ptr &= bit_mask;
ptr += row_bytes;
}
}
}
/**************************************************************************/
/*!
@brief Speed optimized horizontal line drawing into the raw canvas buffer
@param x Line horizontal start point
@param y Line vertical start point
@param w length of horizontal line to be drawn, including first point
@param color Binary (on or off) color to fill with
*/
/**************************************************************************/
void GFXcanvas1::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
uint16_t color) {
// x & y already in raw (rotation 0) coordinates, no need to transform.
int16_t rowBytes = ((WIDTH + 7) / 8);
uint8_t *ptr = &buffer[(x / 8) + y * rowBytes];
size_t remainingWidthBits = w;
// check to see if first byte needs to be partially filled
if ((x & 7) > 0) {
// create bit mask for first byte
uint8_t startByteBitMask = 0x00;
for (int8_t i = (x & 7); ((i < 8) && (remainingWidthBits > 0)); i++) {
#ifdef __AVR__
startByteBitMask |= pgm_read_byte(&GFXsetBit[i]);
#else
startByteBitMask |= (0x80 >> i);
#endif
remainingWidthBits--;
}
if (color > 0) {
*ptr |= startByteBitMask;
} else {
*ptr &= ~startByteBitMask;
}
ptr++;
}
// do the next remainingWidthBits bits
if (remainingWidthBits > 0) {
size_t remainingWholeBytes = remainingWidthBits / 8;
size_t lastByteBits = remainingWidthBits % 8;
uint8_t wholeByteColor = color > 0 ? 0xFF : 0x00;
memset(ptr, wholeByteColor, remainingWholeBytes);
if (lastByteBits > 0) {
uint8_t lastByteBitMask = 0x00;
for (size_t i = 0; i < lastByteBits; i++) {
#ifdef __AVR__
lastByteBitMask |= pgm_read_byte(&GFXsetBit[i]);
#else
lastByteBitMask |= (0x80 >> i);
#endif
}
ptr += remainingWholeBytes;
if (color > 0) {
*ptr |= lastByteBitMask;
} else {
*ptr &= ~lastByteBitMask;
}
}
}
}
+47
View File
@@ -0,0 +1,47 @@
#pragma once
#include "Adafruit_GFX.h"
/// 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);
/*!
@brief Get the pixel color value at a given coordinate
@param x x coordinate
@param y y coordinate
@returns The pixel's binary color value, either 0x1 (on) or 0x0 (off)
*/
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:
/*!
@brief Get the pixel color value at a given, unrotated coordinate.
This method is intended for hardware drivers to get pixel value
in native physical coordinates.
@param x x coordinate
@param y y coordinate
@returns The pixel's binary color value, either 0x1 (on) or 0x0 (off)
*/
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
};
+295
View File
@@ -0,0 +1,295 @@
#include "GFXcanvas16.h"
/**************************************************************************/
/*!
@brief Instatiate a GFX 16-bit canvas context for graphics
@param w Display width, in pixels
@param h Display height, in pixels
*/
/**************************************************************************/
GFXcanvas16::GFXcanvas16(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
uint32_t bytes = w * h * 2;
if ((buffer = (uint16_t *)malloc(bytes))) {
memset(buffer, 0, bytes);
}
}
/**************************************************************************/
/*!
@brief Delete the canvas, free memory
*/
/**************************************************************************/
GFXcanvas16::~GFXcanvas16(void) {
if (buffer)
free(buffer);
}
/**************************************************************************/
/*!
@brief Draw a pixel to the canvas framebuffer
@param x x coordinate
@param y y coordinate
@param color 16-bit 5-6-5 Color to fill with
*/
/**************************************************************************/
void GFXcanvas16::drawPixel(int16_t x, int16_t y, uint16_t color) {
if (buffer) {
if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height))
return;
int16_t t;
switch (rotation) {
case 1:
t = x;
x = WIDTH - 1 - y;
y = t;
break;
case 2:
x = WIDTH - 1 - x;
y = HEIGHT - 1 - y;
break;
case 3:
t = x;
x = y;
y = HEIGHT - 1 - t;
break;
}
buffer[x + y * WIDTH] = color;
}
}
/**********************************************************************/
/*!
@brief Get the pixel color value at a given coordinate
@param x x coordinate
@param y y coordinate
@returns The desired pixel's 16-bit 5-6-5 color value
*/
/**********************************************************************/
uint16_t GFXcanvas16::getPixel(int16_t x, int16_t y) const {
int16_t t;
switch (rotation) {
case 1:
t = x;
x = WIDTH - 1 - y;
y = t;
break;
case 2:
x = WIDTH - 1 - x;
y = HEIGHT - 1 - y;
break;
case 3:
t = x;
x = y;
y = HEIGHT - 1 - t;
break;
}
return getRawPixel(x, y);
}
/**********************************************************************/
/*!
@brief Get the pixel color value at a given, unrotated coordinate.
This method is intended for hardware drivers to get pixel value
in physical coordinates.
@param x x coordinate
@param y y coordinate
@returns The desired pixel's 16-bit 5-6-5 color value
*/
/**********************************************************************/
uint16_t GFXcanvas16::getRawPixel(int16_t x, int16_t y) const {
if ((x < 0) || (y < 0) || (x >= WIDTH) || (y >= HEIGHT))
return 0;
if (buffer) {
return buffer[x + y * WIDTH];
}
return 0;
}
/**************************************************************************/
/*!
@brief Fill the framebuffer completely with one color
@param color 16-bit 5-6-5 Color to fill with
*/
/**************************************************************************/
void GFXcanvas16::fillScreen(uint16_t color) {
if (buffer) {
uint8_t hi = color >> 8, lo = color & 0xFF;
if (hi == lo) {
memset(buffer, lo, WIDTH * HEIGHT * 2);
} else {
uint32_t i, pixels = WIDTH * HEIGHT;
for (i = 0; i < pixels; i++)
buffer[i] = color;
}
}
}
/**************************************************************************/
/*!
@brief Reverses the "endian-ness" of each 16-bit pixel within the
canvas; little-endian to big-endian, or big-endian to little.
Most microcontrollers (such as SAMD) are little-endian, while
most displays tend toward big-endianness. All the drawing
functions (including RGB bitmap drawing) take care of this
automatically, but some specialized code (usually involving
DMA) can benefit from having pixel data already in the
display-native order. Note that this does NOT convert to a
SPECIFIC endian-ness, it just flips the bytes within each word.
*/
/**************************************************************************/
void GFXcanvas16::byteSwap(void) {
if (buffer) {
uint32_t i, pixels = WIDTH * HEIGHT;
for (i = 0; i < pixels; i++)
buffer[i] = __builtin_bswap16(buffer[i]);
}
}
/**************************************************************************/
/*!
@brief Speed optimized vertical line drawing
@param x Line horizontal start point
@param y Line vertical start point
@param h length of vertical line to be drawn, including first point
@param color color 16-bit 5-6-5 Color to draw line with
*/
/**************************************************************************/
void GFXcanvas16::drawFastVLine(int16_t x, int16_t y, int16_t h,
uint16_t color) {
if (h < 0) { // Convert negative heights to positive equivalent
h *= -1;
y -= h - 1;
if (y < 0) {
h += y;
y = 0;
}
}
// Edge rejection (no-draw if totally off canvas)
if ((x < 0) || (x >= width()) || (y >= height()) || ((y + h - 1) < 0)) {
return;
}
if (y < 0) { // Clip top
h += y;
y = 0;
}
if (y + h > height()) { // Clip bottom
h = height() - y;
}
if (getRotation() == 0) {
drawFastRawVLine(x, y, h, color);
} else if (getRotation() == 1) {
int16_t t = x;
x = WIDTH - 1 - y;
y = t;
x -= h - 1;
drawFastRawHLine(x, y, h, color);
} else if (getRotation() == 2) {
x = WIDTH - 1 - x;
y = HEIGHT - 1 - y;
y -= h - 1;
drawFastRawVLine(x, y, h, color);
} else if (getRotation() == 3) {
int16_t t = x;
x = y;
y = HEIGHT - 1 - t;
drawFastRawHLine(x, y, h, color);
}
}
/**************************************************************************/
/*!
@brief Speed optimized horizontal line drawing
@param x Line horizontal start point
@param y Line vertical start point
@param w Length of horizontal line to be drawn, including 1st point
@param color Color 16-bit 5-6-5 Color to draw line with
*/
/**************************************************************************/
void GFXcanvas16::drawFastHLine(int16_t x, int16_t y, int16_t w,
uint16_t color) {
if (w < 0) { // Convert negative widths to positive equivalent
w *= -1;
x -= w - 1;
if (x < 0) {
w += x;
x = 0;
}
}
// Edge rejection (no-draw if totally off canvas)
if ((y < 0) || (y >= height()) || (x >= width()) || ((x + w - 1) < 0)) {
return;
}
if (x < 0) { // Clip left
w += x;
x = 0;
}
if (x + w >= width()) { // Clip right
w = width() - x;
}
if (getRotation() == 0) {
drawFastRawHLine(x, y, w, color);
} else if (getRotation() == 1) {
int16_t t = x;
x = WIDTH - 1 - y;
y = t;
drawFastRawVLine(x, y, w, color);
} else if (getRotation() == 2) {
x = WIDTH - 1 - x;
y = HEIGHT - 1 - y;
x -= w - 1;
drawFastRawHLine(x, y, w, color);
} else if (getRotation() == 3) {
int16_t t = x;
x = y;
y = HEIGHT - 1 - t;
y -= w - 1;
drawFastRawVLine(x, y, w, color);
}
}
/**************************************************************************/
/*!
@brief Speed optimized vertical line drawing into the raw canvas buffer
@param x Line horizontal start point
@param y Line vertical start point
@param h length of vertical line to be drawn, including first point
@param color color 16-bit 5-6-5 Color to draw line with
*/
/**************************************************************************/
void GFXcanvas16::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
uint16_t color) {
// x & y already in raw (rotation 0) coordinates, no need to transform.
uint16_t *buffer_ptr = buffer + y * WIDTH + x;
for (int16_t i = 0; i < h; i++) {
(*buffer_ptr) = color;
buffer_ptr += WIDTH;
}
}
/**************************************************************************/
/*!
@brief Speed optimized horizontal line drawing into the raw canvas buffer
@param x Line horizontal start point
@param y Line vertical start point
@param w length of horizontal line to be drawn, including first point
@param color color 16-bit 5-6-5 Color to draw line with
*/
/**************************************************************************/
void GFXcanvas16::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
uint16_t color) {
// x & y already in raw (rotation 0) coordinates, no need to transform.
uint32_t buffer_index = y * WIDTH + x;
for (uint32_t i = buffer_index; i < buffer_index + w; i++) {
buffer[i] = color;
}
}
+31
View File
@@ -0,0 +1,31 @@
#pragma once
#include "Adafruit_GFX.h"
/// 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;
};
+269
View File
@@ -0,0 +1,269 @@
#include "GFXcanvas8.h"
/**************************************************************************/
/*!
@brief Instatiate a GFX 8-bit canvas context for graphics
@param w Display width, in pixels
@param h Display height, in pixels
*/
/**************************************************************************/
GFXcanvas8::GFXcanvas8(uint16_t w, uint16_t h) : Adafruit_GFX(w, h) {
uint32_t bytes = w * h;
if ((buffer = (uint8_t *)malloc(bytes))) {
memset(buffer, 0, bytes);
}
}
/**************************************************************************/
/*!
@brief Delete the canvas, free memory
*/
/**************************************************************************/
GFXcanvas8::~GFXcanvas8(void) {
if (buffer)
free(buffer);
}
/**************************************************************************/
/*!
@brief Draw a pixel to the canvas framebuffer
@param x x coordinate
@param y y coordinate
@param color 8-bit Color to fill with. Only lower byte of uint16_t is used.
*/
/**************************************************************************/
void GFXcanvas8::drawPixel(int16_t x, int16_t y, uint16_t color) {
if (buffer) {
if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height))
return;
int16_t t;
switch (rotation) {
case 1:
t = x;
x = WIDTH - 1 - y;
y = t;
break;
case 2:
x = WIDTH - 1 - x;
y = HEIGHT - 1 - y;
break;
case 3:
t = x;
x = y;
y = HEIGHT - 1 - t;
break;
}
buffer[x + y * WIDTH] = color;
}
}
/**********************************************************************/
/*!
@brief Get the pixel color value at a given coordinate
@param x x coordinate
@param y y coordinate
@returns The desired pixel's 8-bit color value
*/
/**********************************************************************/
uint8_t GFXcanvas8::getPixel(int16_t x, int16_t y) const {
int16_t t;
switch (rotation) {
case 1:
t = x;
x = WIDTH - 1 - y;
y = t;
break;
case 2:
x = WIDTH - 1 - x;
y = HEIGHT - 1 - y;
break;
case 3:
t = x;
x = y;
y = HEIGHT - 1 - t;
break;
}
return getRawPixel(x, y);
}
/**********************************************************************/
/*!
@brief Get the pixel color value at a given, unrotated coordinate.
This method is intended for hardware drivers to get pixel value
in physical coordinates.
@param x x coordinate
@param y y coordinate
@returns The desired pixel's 8-bit color value
*/
/**********************************************************************/
uint8_t GFXcanvas8::getRawPixel(int16_t x, int16_t y) const {
if ((x < 0) || (y < 0) || (x >= WIDTH) || (y >= HEIGHT))
return 0;
if (buffer) {
return buffer[x + y * WIDTH];
}
return 0;
}
/**************************************************************************/
/*!
@brief Fill the framebuffer completely with one color
@param color 8-bit Color to fill with. Only lower byte of uint16_t is used.
*/
/**************************************************************************/
void GFXcanvas8::fillScreen(uint16_t color) {
if (buffer) {
memset(buffer, color, WIDTH * HEIGHT);
}
}
/**************************************************************************/
/*!
@brief Speed optimized vertical line drawing
@param x Line horizontal start point
@param y Line vertical start point
@param h Length of vertical line to be drawn, including first point
@param color 8-bit Color to fill with. Only lower byte of uint16_t is
used.
*/
/**************************************************************************/
void GFXcanvas8::drawFastVLine(int16_t x, int16_t y, int16_t h,
uint16_t color) {
if (h < 0) { // Convert negative heights to positive equivalent
h *= -1;
y -= h - 1;
if (y < 0) {
h += y;
y = 0;
}
}
// Edge rejection (no-draw if totally off canvas)
if ((x < 0) || (x >= width()) || (y >= height()) || ((y + h - 1) < 0)) {
return;
}
if (y < 0) { // Clip top
h += y;
y = 0;
}
if (y + h > height()) { // Clip bottom
h = height() - y;
}
if (getRotation() == 0) {
drawFastRawVLine(x, y, h, color);
} else if (getRotation() == 1) {
int16_t t = x;
x = WIDTH - 1 - y;
y = t;
x -= h - 1;
drawFastRawHLine(x, y, h, color);
} else if (getRotation() == 2) {
x = WIDTH - 1 - x;
y = HEIGHT - 1 - y;
y -= h - 1;
drawFastRawVLine(x, y, h, color);
} else if (getRotation() == 3) {
int16_t t = x;
x = y;
y = HEIGHT - 1 - t;
drawFastRawHLine(x, y, h, color);
}
}
/**************************************************************************/
/*!
@brief Speed optimized horizontal line drawing
@param x Line horizontal start point
@param y Line vertical start point
@param w Length of horizontal line to be drawn, including 1st point
@param color 8-bit Color to fill with. Only lower byte of uint16_t is
used.
*/
/**************************************************************************/
void GFXcanvas8::drawFastHLine(int16_t x, int16_t y, int16_t w,
uint16_t color) {
if (w < 0) { // Convert negative widths to positive equivalent
w *= -1;
x -= w - 1;
if (x < 0) {
w += x;
x = 0;
}
}
// Edge rejection (no-draw if totally off canvas)
if ((y < 0) || (y >= height()) || (x >= width()) || ((x + w - 1) < 0)) {
return;
}
if (x < 0) { // Clip left
w += x;
x = 0;
}
if (x + w >= width()) { // Clip right
w = width() - x;
}
if (getRotation() == 0) {
drawFastRawHLine(x, y, w, color);
} else if (getRotation() == 1) {
int16_t t = x;
x = WIDTH - 1 - y;
y = t;
drawFastRawVLine(x, y, w, color);
} else if (getRotation() == 2) {
x = WIDTH - 1 - x;
y = HEIGHT - 1 - y;
x -= w - 1;
drawFastRawHLine(x, y, w, color);
} else if (getRotation() == 3) {
int16_t t = x;
x = y;
y = HEIGHT - 1 - t;
y -= w - 1;
drawFastRawVLine(x, y, w, color);
}
}
/**************************************************************************/
/*!
@brief Speed optimized vertical line drawing into the raw canvas buffer
@param x Line horizontal start point
@param y Line vertical start point
@param h length of vertical line to be drawn, including first point
@param color 8-bit Color to fill with. Only lower byte of uint16_t is
used.
*/
/**************************************************************************/
void GFXcanvas8::drawFastRawVLine(int16_t x, int16_t y, int16_t h,
uint16_t color) {
// x & y already in raw (rotation 0) coordinates, no need to transform.
uint8_t *buffer_ptr = buffer + y * WIDTH + x;
for (int16_t i = 0; i < h; i++) {
(*buffer_ptr) = color;
buffer_ptr += WIDTH;
}
}
/**************************************************************************/
/*!
@brief Speed optimized horizontal line drawing into the raw canvas buffer
@param x Line horizontal start point
@param y Line vertical start point
@param w length of horizontal line to be drawn, including first point
@param color 8-bit Color to fill with. Only lower byte of uint16_t is
used.
*/
/**************************************************************************/
void GFXcanvas8::drawFastRawHLine(int16_t x, int16_t y, int16_t w,
uint16_t color) {
// x & y already in raw (rotation 0) coordinates, no need to transform.
memset(buffer + y * WIDTH + x, color, w);
}
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#include "Adafruit_GFX.h"
/// 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;
};
+1 -4
View File
@@ -4,8 +4,7 @@
// file and pass address of GFXfont struct to setFont(). Pass NULL to
// revert to 'classic' fixed-space bitmap font.
#ifndef _GFXFONT_H_
#define _GFXFONT_H_
#pragma once
/// Font data stored PER GLYPH
typedef struct {
@@ -25,5 +24,3 @@ typedef struct {
uint16_t last; ///< ASCII extents (last char)
uint8_t yAdvance; ///< Newline distance (y axis)
} GFXfont;
#endif // _GFXFONT_H_
+1 -4
View File
@@ -1,8 +1,7 @@
// This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0.
// See gfxfont.h for newer custom bitmap font info.
#ifndef FONT5X7_H
#define FONT5X7_H
#pragma once
#ifdef __AVR__
#include <avr/io.h>
@@ -139,5 +138,3 @@ static const unsigned char font[] PROGMEM = {
static inline void avoid_unused_const_variable_compiler_warning(void) {
(void)font;
}
#endif // FONT5X7_H