Skip to content

Commit 5003938

Browse files
Laurence BankLaurence Bank
authored andcommitted
Added fractional scaling to G5 bitmap drawing
1 parent 384c552 commit 5003938

File tree

3 files changed

+48
-24
lines changed

3 files changed

+48
-24
lines changed

src/FastEPD.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ int FASTEPD::loadBMP(const uint8_t *pBMP, int x, int y, int iFG, int iBG)
5353
return bbepLoadBMP(&_state, pBMP, x, y, iFG, iBG);
5454
} /* loadBMP() */
5555

56+
int FASTEPD::loadG5Image(const uint8_t *pG5, int x, int y, int iFG, int iBG, float fScale)
57+
{
58+
return bbepLoadG5(&_state, pG5, x, y, iFG, iBG, fScale);
59+
}
60+
5661
int FASTEPD::setRotation(int iAngle)
5762
{
5863
return bbepSetRotation(&_state, iAngle);

src/FastEPD.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ class FASTEPD
211211
void setTextColor(int iFG, int iBG = BBEP_TRANSPARENT);
212212
void setCursor(int x, int y) {_state.iCursorX = x; _state.iCursorY = y;}
213213
int loadBMP(const uint8_t *pBMP, int x, int y, int iFG, int iBG);
214-
int loadG5Image(const uint8_t *pG5, int x, int y, int iFG, int iBG);
214+
int loadG5Image(const uint8_t *pG5, int x, int y, int iFG, int iBG, float fScale = 1.0f);
215215
void setFont(int iFont);
216216
void setFont(const void *pFont);
217217
void drawLine(int x1, int y1, int x2, int y2, int iColor);

src/bb_ep_gfx.inl

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -514,46 +514,65 @@ void InvertBytes(uint8_t *pData, uint8_t bLen)
514514
}
515515
} /* InvertBytes() */
516516
//
517-
// Load a 1-bpp Group5 compressed bitmap
517+
// Load a 1-bpp Group5 compressed bitmap at the given scale
518518
// Pass the pointer to the beginning of the G5 file
519-
// If the FG == BG color, and there is a back buffer, it will
520-
// draw the 1's bits as the FG color and leave
521-
// the background (0 pixels) unchanged - aka transparent.
519+
// If the FG == BG color, it will draw the 1's bits
520+
// as the FG color and leave the background (0 bits)
521+
// unchanged - aka transparent.
522522
//
523-
int bbepLoadG5(FASTEPDSTATE *pBBEP, const uint8_t *pG5, int x, int y, int iFG, int iBG)
523+
int bbepLoadG5(FASTEPDSTATE *pBBEP, const uint8_t *pG5, int x, int y, int iFG, int iBG, float fScale)
524524
{
525-
uint16_t rc, tx, ty, cx, cy, size;
525+
uint16_t rc, tx, ty, dx, dy, cx, cy, size;
526+
uint16_t width, height;
526527
BB_BITMAP *pbbb;
527-
528-
if (pBBEP == NULL || pG5 == NULL) return BBEP_ERROR_BAD_PARAMETER;
528+
uint32_t u32Frac, u32XAcc, u32YAcc; // integer fraction vars
529+
530+
if (pBBEP == NULL || pG5 == NULL || fScale < 0.01) return BBEP_ERROR_BAD_PARAMETER;
531+
u32Frac = (uint32_t)(65536.0f / fScale); // calculate the fraction to advance the destination x/y
529532
pbbb = (BB_BITMAP *)pG5;
530533
if (pgm_read_word(&pbbb->u16Marker) != BB_BITMAP_MARKER) return BBEP_ERROR_BAD_DATA;
534+
width = pBBEP->width;
535+
height = pBBEP->height;
531536
cx = pgm_read_word(&pbbb->width);
532537
cy = pgm_read_word(&pbbb->height);
538+
// Calculate scaled destination size
539+
dx = (int)(fScale * (float)cx);
540+
dy = (int)(fScale * (float)cy);
533541
size = pgm_read_word(&pbbb->size);
534542
if (iFG == -1) iFG = BBEP_WHITE;
535543
if (iBG == -1) iBG = BBEP_BLACK;
536544
rc = g5_decode_init(&g5dec, cx, cy, (uint8_t *)&pbbb[1], size);
537545
if (rc != G5_SUCCESS) return BBEP_ERROR_BAD_DATA; // corrupt data?
538-
for (ty=y; ty<y+cy && ty < pBBEP->height; ty++) {
546+
u32YAcc = 65536; // force first line to get decoded
547+
for (ty=y; ty<y+dy && ty < height; ty++) {
539548
uint8_t u8, *s, src_mask;
540-
g5_decode_line(&g5dec, u8Cache);
541-
src_mask = 0; // make it read a byte to start
542-
s = u8Cache;
543-
for (tx=x; tx<x+cx; tx++) {
549+
while (u32YAcc >= 65536) { // advance to next source line
550+
g5_decode_line(&g5dec, u8Cache);
551+
u32YAcc -= 65536;
552+
}
553+
s = u8Cache;
554+
u32XAcc = 0;
555+
u8 = *s++; // grab first source byte (8 pixels)
556+
src_mask = 0x80; // MSB on left
557+
for (tx=x; tx<x+dx && tx < width; tx++) {
558+
if (u8 & src_mask) {
559+
if (iFG != BBEP_TRANSPARENT)
560+
(*pBBEP->pfnSetPixelFast)(pBBEP, tx, ty, (uint8_t)iFG);
561+
} else {
562+
if (iBG != BBEP_TRANSPARENT)
563+
(*pBBEP->pfnSetPixelFast)(pBBEP, tx, ty, (uint8_t)iBG);
564+
}
565+
u32XAcc += u32Frac;
566+
while (u32XAcc >= 65536) {
567+
u32XAcc -= 65536; // whole source pixel horizontal movement
568+
src_mask >>= 1;
544569
if (src_mask == 0) { // need to load the next byte
545570
u8 = *s++;
546-
src_mask = 0x80; // MSB on left
547-
}
548-
if (u8 & src_mask) {
549-
if (iFG != BBEP_TRANSPARENT)
550-
(*pBBEP->pfnSetPixelFast)(pBBEP, tx, ty, (uint8_t)iFG);
551-
} else {
552-
if (iBG != BBEP_TRANSPARENT)
553-
(*pBBEP->pfnSetPixelFast)(pBBEP, tx, ty, (uint8_t)iBG);
571+
src_mask = 0x80;
554572
}
555-
src_mask >>= 1;
556-
} // for tx
573+
}
574+
} // for tx
575+
u32YAcc += u32Frac;
557576
} // for y
558577
return BBEP_SUCCESS;
559578
} /* bbepLoadG5() */

0 commit comments

Comments
 (0)