mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-30 08:51:10 +02:00
Fontrenderer: Use real color values for Renderstring()
This commit is contained in:
@@ -37,10 +37,6 @@
|
|||||||
#include <system/debug.h>
|
#include <system/debug.h>
|
||||||
#include <global.h>
|
#include <global.h>
|
||||||
|
|
||||||
/* Drawing pixels is actually faster without the GXA accelerator (wich OTOH is
|
|
||||||
faster for drawing lines, so disable it here. */
|
|
||||||
#undef USE_NEVIS_GXA
|
|
||||||
|
|
||||||
FT_Error FBFontRenderClass::myFTC_Face_Requester(FTC_FaceID face_id,
|
FT_Error FBFontRenderClass::myFTC_Face_Requester(FTC_FaceID face_id,
|
||||||
FT_Library /*library*/,
|
FT_Library /*library*/,
|
||||||
FT_Pointer request_data,
|
FT_Pointer request_data,
|
||||||
@@ -367,7 +363,21 @@ int UTF8ToUnicode(const char * &text, const bool utf8_encoded) // returns -1 on
|
|||||||
return unicode_value;
|
return unicode_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::RenderString(int x, int y, const int width, const char *text, const unsigned char color, const int boxheight, const bool utf8_encoded)
|
#define F_MUL 0x7FFF
|
||||||
|
|
||||||
|
void Font::paintFontPixel(fb_pixel_t *td, uint8_t fg_red, uint8_t fg_green, uint8_t fg_blue, fb_pixel_t bg_col, int faktor, fb_pixel_t fg_trans)
|
||||||
|
{
|
||||||
|
int korr_r = ((bg_col & 0x00FF0000) >> 16) - fg_red;
|
||||||
|
int korr_g = ((bg_col & 0x0000FF00) >> 8) - fg_green;
|
||||||
|
int korr_b = (bg_col & 0x000000FF) - fg_blue;
|
||||||
|
|
||||||
|
*td = fg_trans |
|
||||||
|
(((fg_red + ((korr_r*faktor)/F_MUL)) << 16) & 0x00FF0000) |
|
||||||
|
(((fg_green + ((korr_g*faktor)/F_MUL)) << 8) & 0x0000FF00) |
|
||||||
|
((fg_blue + ((korr_b*faktor)/F_MUL)) & 0x000000FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Font::RenderString(int x, int y, const int width, const char *text, const fb_pixel_t color, const int boxheight, const bool utf8_encoded, const bool useFullBg)
|
||||||
{
|
{
|
||||||
if (!frameBuffer->getActive())
|
if (!frameBuffer->getActive())
|
||||||
return;
|
return;
|
||||||
@@ -430,57 +440,61 @@ void Font::RenderString(int x, int y, const int width, const char *text, const u
|
|||||||
int lastindex=0; // 0 == missing glyph (never has kerning values)
|
int lastindex=0; // 0 == missing glyph (never has kerning values)
|
||||||
FT_Vector kerning;
|
FT_Vector kerning;
|
||||||
int pen1=-1; // "pen" positions for kerning, pen2 is "x"
|
int pen1=-1; // "pen" positions for kerning, pen2 is "x"
|
||||||
|
static fb_pixel_t old_bgcolor = 0, old_fgcolor = 0;
|
||||||
|
static uint8_t fg_red = 0, fg_green = 0, fg_blue = 0;
|
||||||
|
static bool olduseFullBg = false;
|
||||||
|
static fb_pixel_t colors[256] = {0};
|
||||||
|
static fb_pixel_t fg_trans[256] = {0};
|
||||||
|
static int faktor[256] = {0};
|
||||||
|
static bool fontRecsInit = false;
|
||||||
|
fb_pixel_t bg_color = 1;
|
||||||
|
fb_pixel_t fg_color = color;
|
||||||
|
|
||||||
static fb_pixel_t oldbgcolor = 0, oldfgcolor = 0;
|
if (!useFullBg) {
|
||||||
static fb_pixel_t colors[256]={0};
|
|
||||||
|
|
||||||
// fb_pixel_t bgcolor = frameBuffer->realcolor[color];
|
|
||||||
uint8_t fgindex = color; /* index of font color in the palette */
|
|
||||||
if (color > COL_BLACK0 && color < 254) /* bigger than 254 would result in > 255 */
|
|
||||||
fgindex = ((((int)color) + 2) | 7) - 2; /* no idea what this does exactly... */
|
|
||||||
fb_pixel_t fgcolor = frameBuffer->realcolor[fgindex];
|
|
||||||
#ifndef USE_NEVIS_GXA
|
|
||||||
/* the GXA seems to do it's job asynchonously, so we need to wait until
|
/* the GXA seems to do it's job asynchonously, so we need to wait until
|
||||||
it's ready, otherwise the font will sometimes "be overwritten" with
|
it's ready, otherwise the font will sometimes "be overwritten" with
|
||||||
background color or bgcolor will be wrong */
|
background color or bgcolor will be wrong */
|
||||||
frameBuffer->waitForIdle("Font::RenderString");
|
frameBuffer->waitForIdle("Font::RenderString 1");
|
||||||
#endif
|
|
||||||
/* fetch bgcolor from framebuffer, using lower left edge of the font... */
|
/* fetch bgcolor from framebuffer, using lower left edge of the font... */
|
||||||
fb_pixel_t bgcolor = *(frameBuffer->getFrameBufferPointer() + x +
|
bg_color = *(frameBuffer->getFrameBufferPointer() + x +
|
||||||
y * frameBuffer->getStride() / sizeof(fb_pixel_t));
|
y * frameBuffer->getStride() / sizeof(fb_pixel_t));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bg_color = 0;
|
||||||
|
|
||||||
if((oldbgcolor != bgcolor) || (oldfgcolor != fgcolor)) {
|
if ((old_fgcolor != fg_color) || (old_bgcolor != bg_color) || (olduseFullBg != useFullBg) || !fontRecsInit) {
|
||||||
|
old_bgcolor = bg_color;
|
||||||
|
old_fgcolor = fg_color;
|
||||||
|
olduseFullBg = useFullBg;
|
||||||
|
fontRecsInit = true;
|
||||||
|
|
||||||
oldbgcolor = bgcolor;
|
uint8_t fgt;
|
||||||
oldfgcolor = fgcolor;
|
fgt = (fg_color & 0xFF000000) >> 24;
|
||||||
t_fb_var_screeninfo * screeninfo = frameBuffer->getScreenInfo();
|
fg_red = (fg_color & 0x00FF0000) >> 16;
|
||||||
int rl = screeninfo->red.length;
|
fg_green = (fg_color & 0x0000FF00) >> 8;
|
||||||
int ro = screeninfo->red.offset;
|
fg_blue = fg_color & 0x000000FF;
|
||||||
int gl = screeninfo->green.length;
|
|
||||||
int go = screeninfo->green.offset;
|
|
||||||
int bl = screeninfo->blue.length;
|
|
||||||
int bo = screeninfo->blue.offset;
|
|
||||||
int tl = screeninfo->transp.length;
|
|
||||||
int to = screeninfo->transp.offset;
|
|
||||||
int fgr = (((int)fgcolor >> ro) & ((1 << rl) - 1));
|
|
||||||
int fgg = (((int)fgcolor >> go) & ((1 << gl) - 1));
|
|
||||||
int fgb = (((int)fgcolor >> bo) & ((1 << bl) - 1));
|
|
||||||
int fgt = (((int)fgcolor >> to) & ((1 << tl) - 1));
|
|
||||||
int deltar = (((int)bgcolor >> ro) & ((1 << rl) - 1)) - fgr;
|
|
||||||
int deltag = (((int)bgcolor >> go) & ((1 << gl) - 1)) - fgg;
|
|
||||||
int deltab = (((int)bgcolor >> bo) & ((1 << bl) - 1)) - fgb;
|
|
||||||
int deltat = (((int)bgcolor >> to) & ((1 << tl) - 1)) - fgt;
|
|
||||||
|
|
||||||
|
int korr_r=0, korr_g=0, korr_b=0;
|
||||||
|
if (!useFullBg) {
|
||||||
|
korr_r = ((bg_color & 0x00FF0000) >> 16) - fg_red;
|
||||||
|
korr_g = ((bg_color & 0x0000FF00) >> 8) - fg_green;
|
||||||
|
korr_b = (bg_color & 0x000000FF) - fg_blue;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i <= 0xFF; i++) {
|
||||||
colors[255 - i] =
|
int _faktor = ((0xFF - i) * F_MUL) / 0xFF;
|
||||||
((((fgr + deltar * i / 255) & ((1 << rl) - 1)) << ro) |
|
fb_pixel_t _fg_trans = (g_settings.contrast_fonts && (i > 128)) ? 0xFF000000 : (fgt << 24) & 0xFF000000;
|
||||||
(((fgg + deltag * i / 255) & ((1 << gl) - 1)) << go) |
|
|
||||||
(((fgb + deltab * i / 255) & ((1 << bl) - 1)) << bo) |
|
if (useFullBg) {
|
||||||
(((fgt + deltat * i / 255) & ((1 << tl) - 1)) << to));
|
faktor[i] = _faktor;
|
||||||
/* FIXME must be better solution */
|
fg_trans[i] = _fg_trans;
|
||||||
if(g_settings.contrast_fonts && ((255-i) > 128))
|
}
|
||||||
colors[255 - i] |= 0xFF << to;
|
else {
|
||||||
|
colors[i] = (_fg_trans |
|
||||||
|
(((fg_red + ((korr_r*_faktor)/F_MUL)) << 16) & 0x00FF0000) |
|
||||||
|
(((fg_green + ((korr_g*_faktor)/F_MUL)) << 8) & 0x0000FF00) |
|
||||||
|
((fg_blue + ((korr_b*_faktor)/F_MUL)) & 0x000000FF));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,98 +550,83 @@ void Font::RenderString(int x, int y, const int width, const char *text, const u
|
|||||||
if (x + glyph->xadvance + spread_by > left + width)
|
if (x + glyph->xadvance + spread_by > left + width)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifndef USE_NEVIS_GXA
|
|
||||||
int stride = frameBuffer->getStride();
|
int stride = frameBuffer->getStride();
|
||||||
int ap=(x + glyph->left) * sizeof(fb_pixel_t) + stride * (y - glyph->top);
|
int ap=(x + glyph->left) * sizeof(fb_pixel_t) + stride * (y - glyph->top);
|
||||||
uint8_t * d = ((uint8_t *)frameBuffer->getFrameBufferPointer()) + ap;
|
uint8_t * d = ((uint8_t *)frameBuffer->getFrameBufferPointer()) + ap;
|
||||||
#endif
|
|
||||||
uint8_t * s = glyph->buffer;
|
uint8_t * s = glyph->buffer;
|
||||||
int w = glyph->width;
|
int w = glyph->width;
|
||||||
int h = glyph->height;
|
int h = glyph->height;
|
||||||
int pitch = glyph->pitch;
|
int pitch = glyph->pitch;
|
||||||
#ifndef USE_NEVIS_GXA
|
if (ap>-1) {
|
||||||
if(ap>-1){
|
fb_pixel_t *bg_buf = NULL;
|
||||||
#endif
|
if (useFullBg) {
|
||||||
for (int ay=0; ay<h; ay++)
|
// save background of the char
|
||||||
{
|
bg_buf = new fb_pixel_t[h * (w+spread_by)];
|
||||||
#ifndef USE_NEVIS_GXA
|
uint8_t *pos = d;
|
||||||
fb_pixel_t * td = (fb_pixel_t *)d;
|
fb_pixel_t *bkpos = bg_buf;
|
||||||
#endif
|
/* the GXA seems to do it's job asynchonously, so we need to wait until
|
||||||
|
it's ready, otherwise the font will sometimes "be overwritten" with
|
||||||
int ax;
|
background color or bgcolor will be wrong */
|
||||||
for (ax=0; ax < w + spread_by; ax++)
|
frameBuffer->waitForIdle("Font::RenderString 2");
|
||||||
{
|
for (int j = 0; j < h; j++) {
|
||||||
if (stylemodifier != Font::Embolden)
|
fb_pixel_t *dest = (fb_pixel_t*)pos;
|
||||||
{
|
for (int i = 0; i < (w + spread_by); i++)
|
||||||
#ifdef USE_NEVIS_GXA
|
*(bkpos++) = *(dest++);
|
||||||
/* not nice (and also slower), but currently the easiest way to prevent visible errors */
|
pos += stride;
|
||||||
frameBuffer->paintPixel(x + glyph->left + ax, y - glyph->top + ay, colors[*s++]);
|
|
||||||
#else
|
|
||||||
/* do not paint the backgroundcolor, see below */
|
|
||||||
//if (colors[*s] != bgcolor)
|
|
||||||
// from code above bgcolor index should be always 0
|
|
||||||
if(*s != 0)
|
|
||||||
*td = colors[*s];
|
|
||||||
td++; s++;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int ay = 0; ay < h; ay++) {
|
||||||
|
fb_pixel_t * td = (fb_pixel_t *)d;
|
||||||
|
int ax;
|
||||||
|
for (ax = 0; ax < w + spread_by; ax++) {
|
||||||
|
if (stylemodifier != Font::Embolden) {
|
||||||
|
/* do not paint the backgroundcolor (*s = 0) */
|
||||||
|
if(*s != 0) {
|
||||||
|
if (useFullBg)
|
||||||
|
paintFontPixel(td, fg_red, fg_green, fg_blue, bg_buf[ax*ay], faktor[*s], fg_trans[*s]);
|
||||||
else
|
else
|
||||||
{
|
*td = colors[*s];
|
||||||
int start, end;
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
int lcolor = -1;
|
int lcolor = -1;
|
||||||
|
int start = (ax < w) ? 0 : ax - w + 1;
|
||||||
if (ax < w)
|
int end = (ax < spread_by) ? ax + 1 : spread_by + 1;
|
||||||
start = 0;
|
|
||||||
else
|
|
||||||
start = ax - w + 1;
|
|
||||||
|
|
||||||
if (ax < spread_by)
|
|
||||||
end = ax + 1;
|
|
||||||
else
|
|
||||||
end = spread_by + 1;
|
|
||||||
|
|
||||||
for (int i = start; i < end; i++)
|
for (int i = start; i < end; i++)
|
||||||
if (lcolor < *(s - i))
|
if (lcolor < *(s - i))
|
||||||
lcolor = *(s - i);
|
lcolor = *(s - i);
|
||||||
#ifdef USE_NEVIS_GXA
|
/* do not paint the backgroundcolor (lcolor = 0) */
|
||||||
frameBuffer->paintPixel(x + glyph->left + ax, y - glyph->top + ay, colors[lcolor]);
|
if(lcolor != 0) {
|
||||||
#else
|
if (useFullBg)
|
||||||
/* we make the font "transparent" by not painting the background color
|
paintFontPixel(td, fg_red, fg_green, fg_blue, bg_buf[ax*ay], faktor[lcolor], fg_trans[lcolor]);
|
||||||
colored boxes are painted beneath the fonts anyway
|
else
|
||||||
note that this is not totally correct, because of subpixel hinting etc,
|
|
||||||
but that should be barely visible in reality ;) */
|
|
||||||
//if (colors[lcolor] != bgcolor)
|
|
||||||
// from code above bgcolor index should be always 0
|
|
||||||
if (lcolor != 0)
|
|
||||||
*td = colors[lcolor];
|
*td = colors[lcolor];
|
||||||
td++;
|
|
||||||
#endif
|
|
||||||
s++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s += pitch- ax;
|
td++; s++;
|
||||||
#ifndef USE_NEVIS_GXA
|
}
|
||||||
|
s += pitch - ax;
|
||||||
d += stride;
|
d += stride;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#ifndef USE_NEVIS_GXA
|
if (bg_buf != NULL)
|
||||||
|
delete[] bg_buf;
|
||||||
|
bg_buf = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
x += glyph->xadvance + 1;
|
||||||
x+=glyph->xadvance+1;
|
if (pen1 > x)
|
||||||
//x+=glyph->xadvance;
|
x = pen1;
|
||||||
if(pen1>x)
|
pen1 = x;
|
||||||
x=pen1;
|
lastindex = index;
|
||||||
pen1=x;
|
|
||||||
lastindex=index;
|
|
||||||
}
|
}
|
||||||
//printf("RenderStat: %d %d %d \n", renderer->cacheManager->num_nodes, renderer->cacheManager->num_bytes, renderer->cacheManager->max_bytes);
|
//printf("RenderStat: %d %d %d \n", renderer->cacheManager->num_nodes, renderer->cacheManager->num_bytes, renderer->cacheManager->max_bytes);
|
||||||
pthread_mutex_unlock( &renderer->render_mutex );
|
pthread_mutex_unlock( &renderer->render_mutex );
|
||||||
frameBuffer->checkFbArea(x, y-height, width, height, false);
|
frameBuffer->checkFbArea(x, y-height, width, height, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::RenderString(int x, int y, const int width, const std::string & text, const unsigned char color, const int boxheight, const bool utf8_encoded)
|
void Font::RenderString(int x, int y, const int width, const std::string & text, const fb_pixel_t color, const int boxheight, const bool utf8_encoded, const bool useFullBg)
|
||||||
{
|
{
|
||||||
RenderString(x, y, width, text.c_str(), color, boxheight, utf8_encoded);
|
RenderString(x, y, width, text.c_str(), color, boxheight, utf8_encoded, useFullBg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Font::getRenderWidth(const char *text, const bool utf8_encoded)
|
int Font::getRenderWidth(const char *text, const bool utf8_encoded)
|
||||||
|
@@ -54,6 +54,8 @@ class Font
|
|||||||
int height,DigitHeight,DigitOffset,ascender,descender,upper,lower;
|
int height,DigitHeight,DigitOffset,ascender,descender,upper,lower;
|
||||||
int fontwidth;
|
int fontwidth;
|
||||||
|
|
||||||
|
inline void paintFontPixel(fb_pixel_t *td, uint8_t fg_red, uint8_t fg_green, uint8_t fg_blue, fb_pixel_t bg_col, int faktor, fb_pixel_t fg_trans);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum fontmodifier
|
enum fontmodifier
|
||||||
{
|
{
|
||||||
@@ -62,8 +64,8 @@ class Font
|
|||||||
};
|
};
|
||||||
fontmodifier stylemodifier;
|
fontmodifier stylemodifier;
|
||||||
|
|
||||||
void RenderString(int x, int y, const int width, const char * text, const unsigned char color, const int boxheight = 0, const bool utf8_encoded = false);
|
void RenderString(int x, int y, const int width, const char * text, const fb_pixel_t color, const int boxheight = 0, const bool utf8_encoded = false, const bool useFullBg = false);
|
||||||
void RenderString(int x, int y, const int width, const std::string & text, const unsigned char color, const int boxheight = 0, const bool utf8_encoded = false);
|
void RenderString(int x, int y, const int width, const std::string & text, const fb_pixel_t color, const int boxheight = 0, const bool utf8_encoded = false, const bool useFullBg = false);
|
||||||
|
|
||||||
int getRenderWidth(const char * text, const bool utf8_encoded = false);
|
int getRenderWidth(const char * text, const bool utf8_encoded = false);
|
||||||
int getRenderWidth(const std::string & text, const bool utf8_encoded = false);
|
int getRenderWidth(const std::string & text, const bool utf8_encoded = false);
|
||||||
|
Reference in New Issue
Block a user