CFrameBuffer: Add functions to draw color gradients

This commit is contained in:
M. Liebmann
2014-09-20 21:33:48 +02:00
committed by [CST] Focus
parent 98511b686d
commit a428a1f583
2 changed files with 158 additions and 1 deletions

View File

@@ -47,6 +47,7 @@
#include <gui/audiomute.h> #include <gui/audiomute.h>
#include <gui/color.h> #include <gui/color.h>
#include <gui/pictureviewer.h> #include <gui/pictureviewer.h>
#include <system/debug.h>
#include <global.h> #include <global.h>
#include <video.h> #include <video.h>
#include <cs_api.h> #include <cs_api.h>
@@ -660,6 +661,114 @@ 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);
int line = 0;
while (line < dy) {
int ofl, ofr;
calcCorners(NULL, &ofl, &ofr, dy, line, radius, type);
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) 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) */ /* draw a filled rectangle (with additional round corners) */
@@ -1826,6 +1935,30 @@ void CFrameBuffer::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32
} }
} }
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 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; void *fbbuff = NULL;

View File

@@ -40,6 +40,14 @@
typedef struct fb_var_screeninfo t_fb_var_screeninfo; 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_TOP_LEFT 0x1 #define CORNER_TOP_LEFT 0x1
#define CORNER_TOP_RIGHT 0x2 #define CORNER_TOP_RIGHT 0x2
#define CORNER_TOP 0x3 #define CORNER_TOP 0x3
@@ -131,6 +139,7 @@ class CFrameBuffer
void paintHLineRelInternal(int x, int dx, int y, const fb_pixel_t col); void paintHLineRelInternal(int x, int dx, int y, const fb_pixel_t col);
void paintVLineRelInternal(int x, int y, int dy, const fb_pixel_t col); void paintVLineRelInternal(int x, int y, int dy, const fb_pixel_t col);
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); void paintShortHLineRelInternal(const int& x, const int& dx, const int& y, const fb_pixel_t& col);
int limitRadius(const int& dx, const int& dy, int& radius); int limitRadius(const int& dx, const int& dy, int& radius);
void setCornerFlags(const int& type); void setCornerFlags(const int& type);
@@ -139,6 +148,18 @@ class CFrameBuffer
bool calcCorners(int *ofs, int *ofl, int *ofr, const int& dy, const int& line, const int& radius, const int& type); bool calcCorners(int *ofs, int *ofl, int *ofr, const int& dy, const int& line, const int& radius, const int& type);
public: public:
enum {
gradientHorizontal,
gradientVertical
};
enum {
pbrg_noOption = 0x00,
pbrg_noPaint = 0x01,
pbrg_noFree = 0x02
};
fb_pixel_t realcolor[256]; fb_pixel_t realcolor[256];
~CFrameBuffer(); ~CFrameBuffer();
@@ -184,6 +205,9 @@ class CFrameBuffer
}; };
void paintPixel(int x, int y, const fb_pixel_t col); 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); 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) { 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); } 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); }
@@ -245,7 +269,7 @@ class CFrameBuffer
void* convertRGBA2FB(unsigned char *rgbbuff, unsigned long x, unsigned long y); 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 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); 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);
enum enum
{ {