Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text blending #4069

Merged
merged 3 commits into from
Sep 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 98 additions & 57 deletions lib/gdi/font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,7 @@ nprint: isprintable=0;
return 0;
}

void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, const gRGB &foreground, bool border)
void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &cbackground, const gRGB &foreground, bool border)
{
if (glyphs.empty()) return;

Expand All @@ -939,6 +939,7 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons
dc.getPixmap(target);
gUnmanagedSurface *surface = target->surface;
gRGB currentforeground = foreground;
const gRGB background = (m_blend && surface->bpp == 32) ? gRGB(currentforeground.r, currentforeground.g, currentforeground.b, 200) : cbackground;

int opcode = -1;

Expand Down Expand Up @@ -995,15 +996,16 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons
opcode=0;
} else
opcode=1;
} else if (surface->bpp == 32)
}
else if (surface->bpp == 32)
{
opcode=3;
opcode = (m_blend) ? 4 : 3;

for (int i=0; i<16; ++i)
{
unsigned char da = background.a, dr = background.r, dg = background.g, db = background.b;
#define BLEND(y, x, a) (y + (((x-y) * a)>>8))

unsigned char da = background.a, dr = background.r, dg = background.g, db = background.b;
int sa = i * 16;
if (sa < 256)
{
Expand All @@ -1018,7 +1020,8 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons
}
for (int i=0; i<16; ++i)
lookup32_invert[i]=lookup32_normal[i^0xF];
} else if (surface->bpp == 16)
}
else if (surface->bpp == 16)
{
opcode=2;
for (int i = 0; i != 16; ++i)
Expand All @@ -1042,7 +1045,8 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons
}
for (int i=0; i<16; ++i)
lookup16_invert[i]=lookup16_normal[i^0xF];
} else
}
else
{
eWarning("[eTextPara] Can't render to %dbpp!", surface->bpp);
return;
Expand All @@ -1056,7 +1060,8 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons
lookup8 = lookup8_normal;
lookup16 = lookup16_normal;
lookup32 = lookup32_normal;
} else
}
else
{
lookup8 = lookup8_invert;
lookup16 = lookup16_invert;
Expand Down Expand Up @@ -1128,77 +1133,113 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons
{
case 0: // 4bit lookup to 8bit
{
int extra_buffer_stride = buffer_stride - sx;
__u8 *td=d;
for (int ay = 0; ay < sy; ay++)
{
int ax;

for (ax=0; ax<sx; ax++)
int extra_buffer_stride = buffer_stride - sx;
__u8 *td=d;
for (int ay = 0; ay < sy; ay++)
{
int b=(*s++)>>4;
if(b)
*td=lookup8[b];
++td;
int ax;

for (ax=0; ax<sx; ax++)
{
int b=(*s++)>>4;
if(b)
*td=lookup8[b];
++td;
}
s += extra_source_stride;
td += extra_buffer_stride;
}
s += extra_source_stride;
td += extra_buffer_stride;
}
}
break;
case 1: // 8bit direct
{
int extra_buffer_stride = buffer_stride - sx;
__u8 *td=d;
for (int ay = 0; ay < sy; ay++)
{
int ax;
for (ax=0; ax<sx; ax++)
int extra_buffer_stride = buffer_stride - sx;
__u8 *td=d;
for (int ay = 0; ay < sy; ay++)
{
int b=*s++;
*td++^=b;
int ax;
for (ax=0; ax<sx; ax++)
{
int b=*s++;
*td++^=b;
}
s += extra_source_stride;
td += extra_buffer_stride;
}
s += extra_source_stride;
td += extra_buffer_stride;
}
}
break;
case 2: // 16bit
{
int extra_buffer_stride = (buffer_stride >> 1) - sx;
__u16 *td = (__u16*)d;
for (int ay = 0; ay != sy; ay++)
{
int ax;
for (ax = 0; ax != sx; ax++)
int extra_buffer_stride = (buffer_stride >> 1) - sx;
__u16 *td = (__u16*)d;
for (int ay = 0; ay != sy; ay++)
{
int b = (*s++) >> 4;
if (b)
*td = lookup16[b];
++td;
int ax;
for (ax = 0; ax != sx; ax++)
{
int b = (*s++) >> 4;
if (b)
*td = lookup16[b];
++td;
}
s += extra_source_stride;
td += extra_buffer_stride;
}
s += extra_source_stride;
td += extra_buffer_stride;
}
}
break;
case 3: // 32bit
{
int extra_buffer_stride = (buffer_stride >> 2) - sx;
__u32 *td=(__u32*)d;
for (int ay = 0; ay < sy; ay++)
{
int ax;
for (ax=0; ax<sx; ax++)
int extra_buffer_stride = (buffer_stride >> 2) - sx;
__u32 *td=(__u32*)d;
for (int ay = 0; ay < sy; ay++)
{
int b=(*s++)>>4;
if(b)
*td=lookup32[b];
++td;
int ax;
for (ax=0; ax<sx; ax++)
{
int b=(*s++)>>4;
if(b)
*td=lookup32[b];
++td;
}
s += extra_source_stride;
td += extra_buffer_stride;
}
s += extra_source_stride;
td += extra_buffer_stride;
}
break;
case 4: // 32-bit blend
{
int extra_buffer_stride = (buffer_stride >> 2) - sx;
__u32 *td = (__u32 *)d;
for (int ay = 0; ay < sy; ay++)
{
int ax;
for (ax = 0; ax < sx; ax++)
{
int b = (*s++) >> 4;
if (b)
{
// unsigned char frame_a = (*td) >> 24 & 0xFF;
unsigned char frame_r = (*td) >> 16 & 0xFF;
unsigned char frame_g = (*td) >> 8 & 0xFF;
unsigned char frame_b = (*td) & 0xFF;

unsigned char da = lookup32[b] >> 24 & 0xFF;
unsigned char dr = lookup32[b] >> 16 & 0xFF;
unsigned char dg = lookup32[b] >> 8 & 0xFF;
unsigned char db = lookup32[b] & 0xFF;

#define BLEND(y, x, a) (y + (((x-y) * a)>>8))
frame_r = BLEND(frame_r, dr, da) & 0xFF;
frame_g = BLEND(frame_g, dg, da) & 0xFF;
frame_b = BLEND(frame_b, db, da) & 0xFF;
#undef BLEND
*td = ((currentforeground.a ^ 0xFF) << 24) | (frame_r << 16) | (frame_g << 8) | frame_b;
}
++td;
}
s += extra_source_stride;
td += extra_buffer_stride;
}
}
break;
}
Expand Down
7 changes: 5 additions & 2 deletions lib/gdi/font.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class eTextPara: public iObject
int bboxValid;
eRect boundBox;
bool doTopBottomReordering;
bool m_blend;

int appendGlyph(Font *current_font, FT_Face current_face, FT_UInt glyphIndex, int flags, int rflags, int border, bool last,
bool activate_newcolor, unsigned long newcolor);
Expand All @@ -156,7 +157,7 @@ class eTextPara: public iObject
: current_font(0), replacement_font(0), fallback_font(0),
current_face(0), replacement_face(0), fallback_face(0),
area(area), cursor(start), maximum(0, 0), left(start.x()), charCount(0), totalheight(0),
bboxValid(0), doTopBottomReordering(false)
bboxValid(0), doTopBottomReordering(false), m_blend(false)
{
}
virtual ~eTextPara();
Expand All @@ -171,7 +172,9 @@ class eTextPara: public iObject

void clear();

void blit(gDC &dc, const ePoint &offset, const gRGB &background, const gRGB &foreground, bool border = false);
void setBlend(bool blend) { m_blend = blend; }

void blit(gDC &dc, const ePoint &offset, const gRGB &cbackground, const gRGB &foreground, bool border = false);

enum
{
Expand Down
3 changes: 3 additions & 0 deletions lib/gdi/grc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,9 @@ void gDC::exec(const gOpcode *o)
int correction = o->parm.renderText->area.height() - bbox.height() - 2;
offset += ePoint(0, correction);
}

para->setBlend(flags & gPainter::RT_BLEND);

if (o->parm.renderText->border)
{
para->blit(*this, offset, m_background_color_rgb, o->parm.renderText->bordercolor, true);
Expand Down
13 changes: 13 additions & 0 deletions lib/gui/elabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ int eLabel::event(int event, void *data, void *data2)
if (!m_nowrap)
flags |= gPainter::RT_WRAP;

if (m_blend)
flags |= gPainter::RT_BLEND;

/* if we don't have shadow, m_shadow_offset will be 0,0 */
painter.renderText(eRect(-m_shadow_offset.x(), -m_shadow_offset.y(), size().width(), size().height()), m_text, flags, m_border_color, m_border_size);

Expand Down Expand Up @@ -222,6 +225,16 @@ void eLabel::setNoWrap(int nowrap)
}
}

void eLabel::setAlphatest(int alphatest)
{
bool blend = (alphatest > 0); // blend if BT_ALPHATEST or BT_ALPHABLEND
if (m_blend != blend)
{
m_blend = blend;
invalidate();
}
}

void eLabel::clearForegroundColor()
{
if (m_have_foreground_color)
Expand Down
2 changes: 2 additions & 0 deletions lib/gui/elabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class eLabel: public eWidget
void setBorderColor(const gRGB &col);
void setBorderWidth(int size);
void setNoWrap(int nowrap);
void setAlphatest(int alphatest);
void clearForegroundColor();
int getNoWrap() { return m_nowrap; }

Expand All @@ -49,6 +50,7 @@ class eLabel: public eWidget
ePoint m_shadow_offset;
int m_border_size;
int m_nowrap;
bool m_blend = false;

enum eLabelEvent
{
Expand Down
17 changes: 11 additions & 6 deletions lib/gui/elistboxcontent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style,
int border_size = 0;
int radius = 0;
int edges = 0;
bool alphablendtext = true;

/* get local listbox style, if present */
if (m_listbox)
Expand Down Expand Up @@ -309,6 +310,8 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style,
painter.setForegroundColor(gRGB(0x808080));

int flags = 0;
if (alphablendtext)
flags |= gPainter::RT_BLEND;
if (local_style)
{
style_text_offset = local_style->m_text_offset;
Expand Down Expand Up @@ -420,6 +423,7 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
int border_size = 0;
int radius = 0;
int edges = 0;
bool alphablendtext = true;

painter.clip(itemrect);
style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
Expand Down Expand Up @@ -498,6 +502,7 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,

if (m_list && cursorValid)
{
int alphablendflag = (alphablendtext) ? gPainter::RT_BLEND : 0;
/* get current list item */
ePyObject item = PyList_GET_ITEM(m_list, m_cursor); // borrowed reference!
ePyObject text, value;
Expand Down Expand Up @@ -533,7 +538,7 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
//eDebug("[CONFIGCONTENT] Go to step 1 fill line thick: %d; at pos x: %d, y: %d, w: %d, h: %d", m_sepline_thickness, offset.x() + 15, offset.y() + (m_itemsize.height() - m_sepline_thickness)/2, m_itemsize.width() - 30, m_sepline_thickness);
painter.fill(eRect(offset.x()+15, offset.y() + (m_itemsize.height() - m_sepline_thickness)/2, m_itemsize.width() - 30, m_sepline_thickness));
} else {
painter.renderText(eRect(ePoint(offset.x()+15, offset.y()), m_itemsize), string, gPainter::RT_HALIGN_LEFT | gPainter::RT_VALIGN_CENTER, border_color, border_size);
painter.renderText(eRect(ePoint(offset.x()+15, offset.y()), m_itemsize), string, alphablendflag | gPainter::RT_HALIGN_LEFT | gPainter::RT_VALIGN_CENTER, border_color, border_size);
}
Py_XDECREF(text);
if (!sep) {
Expand Down Expand Up @@ -563,7 +568,7 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
/* check if this is really a tuple */
if (value && PyTuple_Check(value))
{
/* convert type to string */
/* convert type to string */
ePyObject type = PyTuple_GET_ITEM(value, 0);
const char *atype = (type && PyUnicode_Check(type)) ? PyUnicode_AsUTF8(type) : 0;

Expand All @@ -575,9 +580,9 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
const char *value = (pvalue && PyUnicode_Check(pvalue)) ? PyUnicode_AsUTF8(pvalue) : "<not-a-string>";
painter.setFont(fnt2);
if (value_alignment_left)
painter.renderText(eRect(ePoint(offset.x()-15, offset.y()), m_itemsize), value, gPainter::RT_HALIGN_LEFT | gPainter::RT_VALIGN_CENTER, border_color, border_size);
painter.renderText(eRect(ePoint(offset.x()-15, offset.y()), m_itemsize), value, alphablendflag | gPainter::RT_HALIGN_LEFT | gPainter::RT_VALIGN_CENTER, border_color, border_size);
else
painter.renderText(eRect(ePoint(offset.x()-15, offset.y()), m_itemsize), value, gPainter::RT_HALIGN_RIGHT| gPainter::RT_VALIGN_CENTER, border_color, border_size);
painter.renderText(eRect(ePoint(offset.x()-15, offset.y()), m_itemsize), value, alphablendflag | gPainter::RT_HALIGN_RIGHT| gPainter::RT_VALIGN_CENTER, border_color, border_size);

/* pvalue is borrowed */
} else if (!strcmp(atype, "slider"))
Expand Down Expand Up @@ -709,9 +714,9 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
const char *value = (ppixmap && PyUnicode_Check(ppixmap)) ? PyUnicode_AsUTF8(ppixmap) : "<not-a-string>";
painter.setFont(fnt2);
if (value_alignment_left)
painter.renderText(eRect(ePoint(offset.x()-15, offset.y()), m_itemsize), value, gPainter::RT_HALIGN_LEFT | gPainter::RT_VALIGN_CENTER, border_color, border_size);
painter.renderText(eRect(ePoint(offset.x()-15, offset.y()), m_itemsize), value, alphablendflag | gPainter::RT_HALIGN_LEFT | gPainter::RT_VALIGN_CENTER, border_color, border_size);
else
painter.renderText(eRect(ePoint(offset.x()-15, offset.y()), m_itemsize), value, gPainter::RT_HALIGN_RIGHT| gPainter::RT_VALIGN_CENTER, border_color, border_size);
painter.renderText(eRect(ePoint(offset.x()-15, offset.y()), m_itemsize), value, alphablendflag | gPainter::RT_HALIGN_RIGHT| gPainter::RT_VALIGN_CENTER, border_color, border_size);
}
else
{
Expand Down
Loading
Loading