mirror of
https://github.com/adafruit/Adafruit-GFX-Library.git
synced 2026-07-27 20:05:52 +00:00
Initial file reorg, and set cp437 true by default
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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); }
|
||||
@@ -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_
|
||||
@@ -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_
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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,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
|
||||
Reference in New Issue
Block a user