From 2da46b868c0f6d8ab31605b50b7ddca13d30473c Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Thu, 25 Dec 2014 18:06:03 +0100 Subject: [PATCH] framebuffer_ng: add color gradient function Basically implement commit 9fc90622 to allow build to succeed. These are all unaccelerated so should not be used at all :-( Origin commit data ------------------ Commit: https://github.com/neutrino-images/ni-neutrino/commit/b6d5b8396bd6d86174a5ca22e2c46bd38a8d9a86 Author: Stefan Seyfried Date: 2014-12-25 (Thu, 25 Dec 2014) --- src/driver/framebuffer_ng.cpp | 139 ++++++++++++++++++++++++++++++++++ src/driver/framebuffer_ng.h | 31 +++++++- 2 files changed, 169 insertions(+), 1 deletion(-) diff --git a/src/driver/framebuffer_ng.cpp b/src/driver/framebuffer_ng.cpp index 5ce43e2f5..7502dccd4 100644 --- a/src/driver/framebuffer_ng.cpp +++ b/src/driver/framebuffer_ng.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -506,6 +507,120 @@ void CFrameBuffer::paletteSet(struct fb_cmap *map) } } +void CFrameBuffer::paintHLineRelInternal2Buf(const int& x, const int& dx, const int& y, const int& box_dx, const fb_pixel_t& col, fb_pixel_t* buf) +{ + uint8_t * pos = ((uint8_t *)buf) + x * sizeof(fb_pixel_t) + box_dx * sizeof(fb_pixel_t) * y; + fb_pixel_t * dest = (fb_pixel_t *)pos; + for (int i = 0; i < dx; i++) + *(dest++) = col; +} + +fb_pixel_t* CFrameBuffer::paintBoxRel2Buf(const int dx, const int dy, const fb_pixel_t col, fb_pixel_t* buf/* = NULL*/, int radius/* = 0*/, int type/* = CORNER_ALL*/) +{ + if (!getActive()) + return buf; + if (dx == 0 || dy == 0) { + dprintf(DEBUG_INFO, "[%s - %d]: radius %d, dx %d dy %d\n", __func__, __LINE__, radius, dx, dy); + return buf; + } + + fb_pixel_t* pixBuf = buf; + if (pixBuf == NULL) { + pixBuf = (fb_pixel_t*) cs_malloc_uncached(dx*dy*sizeof(fb_pixel_t)); + if (pixBuf == NULL) { + dprintf(DEBUG_NORMAL, "[%s #%d] Error cs_malloc_uncached\n", __func__, __LINE__); + return NULL; + } + } + memset((void*)pixBuf, '\0', dx*dy*sizeof(fb_pixel_t)); + + if (type && radius) { + //setCornerFlags(type); + radius = limitRadius(dx, dy, radius); + + bool corner_tl = !!(type & CORNER_TOP_LEFT); + bool corner_tr = !!(type & CORNER_TOP_RIGHT); + bool corner_bl = !!(type & CORNER_BOTTOM_LEFT); + bool corner_br = !!(type & CORNER_BOTTOM_RIGHT); + + int line = 0; + while (line < dy) { + int ofl, ofr; + calcCorners(NULL, &ofl, &ofr, dy, line, radius, + corner_tl, corner_tr, corner_bl, corner_br); + if (dx-ofr-ofl < 1) { + if (dx-ofr-ofl == 0) { + dprintf(DEBUG_INFO, "[%s - %d]: radius %d, end x %d y %d\n", __func__, __LINE__, radius, dx-ofr-ofl, line); + } + else { + dprintf(DEBUG_INFO, "[%s - %04d]: Calculated width: %d\n (radius %d, dx %d, offsetLeft %d, offsetRight %d).\n Width can not be less than 0, abort.\n", + __func__, __LINE__, dx-ofr-ofl, radius, dx, ofl, ofr); + } + line++; + continue; + } + paintHLineRelInternal2Buf(ofl, dx-ofl-ofr, line, dx, col, pixBuf); + line++; + } + } else { + fb_pixel_t *bp = pixBuf; + int line = 0; + while (line < dy) { + for (int pos = 0; pos < dx; pos++) + *(bp + pos) = col; + bp += dx; + line++; + } + } + return pixBuf; +} + +fb_pixel_t* CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int dy, + const fb_pixel_t /*col*/, gradientData_t *gradientData, + int radius, int type) +{ +#define MASK 0xFFFFFFFF + + fb_pixel_t* boxBuf = paintBoxRel2Buf(dx, dy, MASK, NULL, radius, type); + fb_pixel_t *bp = boxBuf; + fb_pixel_t *gra = gradientData->gradientBuf; + gradientData->boxBuf = boxBuf; + + if (gradientData->direction == gradientVertical) { + // vertical + for (int pos = 0; pos < dx; pos++) { + for(int count = 0; count < dy; count++) { + if (*(bp + pos) == MASK) + *(bp + pos) = (fb_pixel_t)(*(gra + count)); + bp += dx; + } + bp = boxBuf; + } + } else { + // horizontal + for (int line = 0; line < dy; line++) { + for (int pos = 0; pos < dx; pos++) { + if (*(bp + pos) == MASK) + *(bp + pos) = (fb_pixel_t)(*(gra + pos)); + } + bp += dx; + } + } + + if ((gradientData->mode & pbrg_noPaint) == pbrg_noPaint) + return boxBuf; + +// blit2FB(boxBuf, dx, dy, x, y); + blitBox2FB(boxBuf, dx, dy, x, y); + + if ((gradientData->mode & pbrg_noFree) == pbrg_noFree) + return boxBuf; + + cs_free_uncached(boxBuf); + + return NULL; +} + void CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int dy, const fb_pixel_t col, int radius, int type) { /* draw a filled rectangle (with additional round corners) */ @@ -1089,6 +1204,30 @@ void CFrameBuffer::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32 accel->blit2FB(fbbuff, width, height, xoff, yoff, xp, yp, transp); } +void CFrameBuffer::blitBox2FB(const fb_pixel_t* boxBuf, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff) +{ + checkFbArea(xoff, yoff, width, height, true); + + uint32_t swidth = stride / sizeof(fb_pixel_t); + fb_pixel_t *fbp = getFrameBufferPointer() + (swidth * yoff); + fb_pixel_t* data = (fb_pixel_t*)boxBuf; + + uint32_t line = 0; + while (line < height) { + fb_pixel_t *pixpos = &data[line * width]; + for (uint32_t pos = xoff; pos < xoff + width; pos++) { + //don't paint backgroundcolor (*pixpos = 0x00000000) + if (*pixpos) + *(fbp + pos) = *pixpos; + pixpos++; + } + fbp += swidth; + line++; + } + + checkFbArea(xoff, yoff, width, height, false); +} + void CFrameBuffer::displayRGB(unsigned char *rgbbuff, int x_size, int y_size, int x_pan, int y_pan, int x_offs, int y_offs, bool clearfb, int transp) { void *fbbuff = NULL; diff --git a/src/driver/framebuffer_ng.h b/src/driver/framebuffer_ng.h index 11949a197..02c3597bd 100644 --- a/src/driver/framebuffer_ng.h +++ b/src/driver/framebuffer_ng.h @@ -39,6 +39,15 @@ typedef struct fb_var_screeninfo t_fb_var_screeninfo; +typedef struct gradientData_t +{ + fb_pixel_t* gradientBuf; + fb_pixel_t* boxBuf; + bool direction; + int mode; +} gradientData_struct_t; + +#define CORNER_NONE 0x0 #define CORNER_TOP_LEFT 0x1 #define CORNER_TOP_RIGHT 0x2 #define CORNER_TOP 0x3 @@ -123,6 +132,12 @@ class CFrameBuffer int m_transparent_default, m_transparent; CFbAccel *accel; + inline void paintHLineRelInternal2Buf(const int& x, const int& dx, const int& y, const int& box_dx, const fb_pixel_t& col, fb_pixel_t* buf); + void paintShortHLineRelInternal(const int& x, const int& dx, const int& y, const fb_pixel_t& col); +#if 0 + int limitRadius(const int& dx, const int& dy, int& radius); + void setCornerFlags(const int& type); +#endif public: fb_pixel_t realcolor[256]; @@ -136,6 +151,16 @@ class CFrameBuffer void init(const char * const fbDevice = "/dev/fb0"); int setMode(unsigned int xRes, unsigned int yRes, unsigned int bpp); + enum { + gradientHorizontal, + gradientVertical + }; + + enum { + pbrg_noOption = 0x00, + pbrg_noPaint = 0x01, + pbrg_noFree = 0x02 + }; int getFileHandle() const; //only used for plugins (games) !! t_fb_var_screeninfo *getScreenInfo(); @@ -170,6 +195,9 @@ class CFrameBuffer }; void paintPixel(int x, int y, const fb_pixel_t col); + fb_pixel_t* paintBoxRel2Buf(const int dx, const int dy, const fb_pixel_t col, fb_pixel_t* buf = NULL, int radius = 0, int type = CORNER_ALL); + fb_pixel_t* paintBoxRel(const int x, const int y, const int dx, const int dy, const fb_pixel_t col, gradientData_t *gradientData, int radius = 0, int type = CORNER_ALL); + void paintBoxRel(const int x, const int y, const int dx, const int dy, const fb_pixel_t col, int radius = 0, int type = CORNER_ALL); inline void paintBox(int xa, int ya, int xb, int yb, const fb_pixel_t col) { paintBoxRel(xa, ya, xb - xa, yb - ya, col); } inline void paintBox(int xa, int ya, int xb, int yb, const fb_pixel_t col, int radius, int type) { paintBoxRel(xa, ya, xb - xa, yb - ya, col, radius, type); } @@ -185,6 +213,7 @@ class CFrameBuffer void setIconBasePath(const std::string & iconPath); + std::string getIconBasePath(){return iconBasePath;}; void getIconSize(const char * const filename, int* width, int *height); /* h is the height of the target "window", if != 0 the icon gets centered in that window */ @@ -226,7 +255,7 @@ class CFrameBuffer void* convertRGBA2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y); void displayRGB(unsigned char *rgbbuff, int x_size, int y_size, int x_pan, int y_pan, int x_offs, int y_offs, bool clearfb = true, int transp = 0xFF); void blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff, uint32_t xp = 0, uint32_t yp = 0, bool transp = false); - bool blitToPrimary(unsigned int * data, int dx, int dy, int sw, int sh); + void blitBox2FB(const fb_pixel_t* boxBuf, uint32_t width, uint32_t height, uint32_t xoff, uint32_t yoff); void mark(int x, int y, int dx, int dy); void paintMuteIcon(bool paint, int ax, int ay, int dx, int dy, bool paintFrame=true);