From d9ca3d7e4eeca5417b7be4421371344c96e4e3c7 Mon Sep 17 00:00:00 2001 From: Laurence Bank Date: Wed, 13 Nov 2024 17:16:50 +0000 Subject: [PATCH] Fixed drawSprite method and added 2x scale with optional smoothing --- .../images_and_icons/images_and_icons.ino | 18 ++- src/bb_ep_gfx.inl | 111 ++++++++++++------ src/bb_epaper.cpp | 8 +- src/bb_epaper.h | 4 +- 4 files changed, 92 insertions(+), 49 deletions(-) diff --git a/examples/images_and_icons/images_and_icons.ino b/examples/images_and_icons/images_and_icons.ino index 59c2634..488911c 100644 --- a/examples/images_and_icons/images_and_icons.ino +++ b/examples/images_and_icons/images_and_icons.ino @@ -8,12 +8,18 @@ BBEPAPER bbep(EP295_128x296); // Mike Rankin's C3 e-ink PCB -#define PIN_DC 3 -#define PIN_BUSY 1 -#define PIN_RST 10 -#define PIN_CS 7 -#define PIN_MOSI 6 -#define PIN_SCK 4 +//#define PIN_DC 3 +//#define PIN_BUSY 1 +//#define PIN_RST 10 +//#define PIN_CS 7 +//#define PIN_MOSI 6 +//#define PIN_SCK 4 +#define PIN_DC 16 +#define PIN_BUSY 15 +#define PIN_RST 14 +#define PIN_CS 10 +#define PIN_MOSI MOSI +#define PIN_SCK SCK void setup() { diff --git a/src/bb_ep_gfx.inl b/src/bb_ep_gfx.inl index 7c82369..5615267 100644 --- a/src/bb_ep_gfx.inl +++ b/src/bb_ep_gfx.inl @@ -25,6 +25,7 @@ static G5DECIMAGE g5dec; // forward declarations void InvertBytes(uint8_t *pData, uint8_t bLen); +int bbepSetPixel(BBEPDISP *pBBEP, int x, int y, unsigned char ucColor); const uint8_t ucFont[]PROGMEM = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x5f,0x5f,0x06,0x00, @@ -186,9 +187,7 @@ const uint8_t ucSmallFont[] PROGMEM = { void bbepDrawSprite(BBEPDISP *pBBEP, const uint8_t *pSprite, int cx, int cy, int iPitch, int x, int y, uint8_t iColor) { int tx, ty, dx, dy, iStartX; - uint8_t *s, *d, uc, pix, ucSrcMask, ucDstMask; - int iLocalPitch; - iLocalPitch = pBBEP->width; + uint8_t *s, pix, ucSrcMask; if (pBBEP == NULL) return; if (x+cx < 0 || y+cy < 0 || x >= pBBEP->native_width || y >= pBBEP->native_height) { @@ -266,43 +265,18 @@ void bbepDrawSprite(BBEPDISP *pBBEP, const uint8_t *pSprite, int cx, int cy, int for (ty=0; ty> 3)]; - d = &pBBEP->ucScreen[(dy>>3) * iLocalPitch + dx]; ucSrcMask = 0x80 >> (iStartX & 7); pix = *s++; - ucDstMask = 1 << (dy & 7); - if (iColor) // priority color is 1 - { - for (tx=0; tx>= 1; - if (ucSrcMask == 0) // read next byte - { - ucSrcMask = 0x80; - pix = *s++; - } - } // for tx - } // priorty color 1 - else - { - for (tx=0; tx>= 1; - if (ucSrcMask == 0) // read next byte - { - ucSrcMask = 0x80; - pix = *s++; - } - } // for tx - } // priority color 0 - dy++; + for (tx=0; tx>= 1; + if (ucSrcMask == 0) { // read next byte + ucSrcMask = 0x80; + pix = *s++; + } + } // for tx pSprite += iPitch; } // for ty #endif // NO_RAM @@ -857,6 +831,67 @@ void RotateCharBox(uint8_t *pSrc) memcpy(pSrc, ucDest, 8); // rotate "in-place" } /* RotateCharBox() */ // +// Double the size of a 1-bpp image and smooth the jaggies +// +void bbepStretchAndSmooth(uint8_t *pSrc, uint8_t *pDest, int w, int h, int bSmooth) +{ +uint8_t c, uc1, uc2, *s, *d, ucMask; +int tx, ty, iPitch, iDestPitch; + + iPitch = (w+7)>>3; + iDestPitch = ((w*2)+7)>>3; +// First, double the size of the source bitmap into the destination + uc1 = uc2 = 0; + memset(pDest, 0, iDestPitch * h*2); + for (ty=0; ty>= 2; + c <<= 1; + if (ucMask == 0) { + c = *s++; + d[0] = d[iDestPitch] = uc1; + d[1] = d[iDestPitch+1] = uc2; + d += 2; + ucMask = 0xc0; + tx += 4; + uc1 = uc2 = 0; + } + } // for tx + } // for ty + if (!bSmooth) return; + // Now that the image is stretched, go through it and fill in corners + // to smooth the blockiness + for (ty = 0; ty < h; ty ++) { + s = &pSrc[ty * iPitch]; + d = &pDest[ty*2 * iDestPitch]; + for (tx=0; tx>3] & (0x80 >> (tx & 7)); + c10 = s[(tx+1)>>3] & (0x80 >> ((tx+1) & 7)); + c01 = s[iPitch + (tx>>3)] & (0x80 >> (tx & 7)); + c11 = s[iPitch + ((tx+1)>>3)] & (0x80 >> ((tx+1) & 7)); + if (c00 && c11 && (!c10 || !c01)) { + // fill in the 'hole' + d[(dx>>3)+iDestPitch*2] |= (0x80 >> (dx & 7)); + d[((dx+1)>>3) + iDestPitch] |= (0x80 >> ((dx+1) & 7)); + } + if (c10 && c01 && (!c11 || !c00)) { + d[(dx>>3)+iDestPitch] |= (0x80 >> (dx & 7)); + d[((dx+1)>>3)+iDestPitch*2] |= (0x80 >> ((dx+1) & 7)); + } + } // for tx + } // for ty +} /* bbepStretchAndSmooth() */ +// // Draw a string of normal (8x8), small (6x8) or large (16x32) characters // At the given col+row // diff --git a/src/bb_epaper.cpp b/src/bb_epaper.cpp index fa08c6e..c367a95 100644 --- a/src/bb_epaper.cpp +++ b/src/bb_epaper.cpp @@ -128,6 +128,10 @@ void BBEPAPER::setBuffer(uint8_t *pBuffer) _bbep.ucScreen = pBuffer; } +void BBEPAPER::stretchAndSmooth(uint8_t *pSrc, uint8_t *pDest, int w, int h, int bSmooth) +{ + bbepStretchAndSmooth(pSrc, pDest, w, h, bSmooth); +} void BBEPAPER::backupPlane(void) { int iSize = ((_bbep.native_width+7)>>3) * _bbep.native_height; @@ -367,7 +371,7 @@ char ucTemp[4]; #ifndef __AVR__ size_t BBEPAPER::write(uint8_t c) { char szTemp[2]; // used to draw 1 character at a time to the C methods -int rc, w=8, h=8; +int w=8, h=8; szTemp[0] = c; szTemp[1] = 0; if (_bbep.pFont == NULL) { // use built-in fonts @@ -405,7 +409,7 @@ int rc, w=8, h=8; _bbep.iCursorX = 0; _bbep.iCursorY += h; } - rc = bbepWriteStringCustom(&_bbep, (BB_FONT *)_bbep.pFont, -1, -1, szTemp, _bbep.iFG, _bbep.iPlane); + bbepWriteStringCustom(&_bbep, (BB_FONT *)_bbep.pFont, -1, -1, szTemp, _bbep.iFG, _bbep.iPlane); } } } diff --git a/src/bb_epaper.h b/src/bb_epaper.h index b2822ba..c10a69a 100644 --- a/src/bb_epaper.h +++ b/src/bb_epaper.h @@ -144,9 +144,6 @@ enum { EPD583R_600x448, EPD74R_640x384, EPD583_648x480, // DEPG0583BN - EPD29_BWYR_128x296, // GDEY029F51 - EPD29_BWYR_168x384, // GDEY029F51H - EPD266_BWYR_184x360, // GDEY0266F51 EPD30_BWYR_168x400, // Waveshare 3" B/W/Y/R EPD164_BWYR_168x168, // Waveshare 1.64" B/W/Y/R EPD236_BWYR_168x296, // Waveshare 2.36" B/W/Y/R @@ -350,6 +347,7 @@ class BBEPAPER void fillCircle(int32_t x, int32_t y, int32_t r, uint32_t color); void drawEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color); void fillEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color); + void stretchAndSmooth(uint8_t *pSrc, uint8_t *pDest, int w, int h, int bSmooth = 1); void sleep(int bDeep); void wait(bool bQuick = false); void drawString(const char *pText, int x, int y);