ngl: Make the coloring shader more versatile

When the color passed is transparent black, use
the color from the texture as source, instead of
as mask. This lets use use the coloring program
both for regular and color glyphs, avoiding
program changes in text with Emoji.
This commit is contained in:
Matthias Clasen 2021-03-12 01:27:19 -05:00
parent 06d5c8e72d
commit 6a30c6b01c
2 changed files with 46 additions and 28 deletions

View File

@ -2703,15 +2703,20 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob *job,
guint last_texture = 0;
GskNglDrawVertex *vertices;
guint used = 0;
GdkRGBA c;
if (num_glyphs == 0)
return;
/* If the font has color glyphs, we don't need to recolor anything */
program = CHOOSE_PROGRAM (job, coloring);
/* If the font has color glyphs, we don't need to recolor anything.
* We tell the shader by setting the color to vec4(-1).
*/
if (!force_color && gsk_text_node_has_color_glyphs (node))
program = CHOOSE_PROGRAM (job, blit);
c = (GdkRGBA) { -1.f, -1.f, -1.f, -1.f };
else
program = CHOOSE_PROGRAM (job, coloring);
c = *color;
lookup.font = (PangoFont *)font;
lookup.scale = (guint) (text_scale * 1024);
@ -2786,55 +2791,55 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob *job,
vertices[base+0].position[1] = glyph_y;
vertices[base+0].uv[0] = tx;
vertices[base+0].uv[1] = ty;
vertices[base+0].color[0] = color->red;
vertices[base+0].color[1] = color->green;
vertices[base+0].color[2] = color->blue;
vertices[base+0].color[3] = color->alpha;
vertices[base+0].color[0] = c.red;
vertices[base+0].color[1] = c.green;
vertices[base+0].color[2] = c.blue;
vertices[base+0].color[3] = c.alpha;
vertices[base+1].position[0] = glyph_x;
vertices[base+1].position[1] = glyph_y2;
vertices[base+1].uv[0] = tx;
vertices[base+1].uv[1] = ty2;
vertices[base+1].color[0] = color->red;
vertices[base+1].color[1] = color->green;
vertices[base+1].color[2] = color->blue;
vertices[base+1].color[3] = color->alpha;
vertices[base+1].color[0] = c.red;
vertices[base+1].color[1] = c.green;
vertices[base+1].color[2] = c.blue;
vertices[base+1].color[3] = c.alpha;
vertices[base+2].position[0] = glyph_x2;
vertices[base+2].position[1] = glyph_y;
vertices[base+2].uv[0] = tx2;
vertices[base+2].uv[1] = ty;
vertices[base+2].color[0] = color->red;
vertices[base+2].color[1] = color->green;
vertices[base+2].color[2] = color->blue;
vertices[base+2].color[3] = color->alpha;
vertices[base+2].color[0] = c.red;
vertices[base+2].color[1] = c.green;
vertices[base+2].color[2] = c.blue;
vertices[base+2].color[3] = c.alpha;
vertices[base+3].position[0] = glyph_x2;
vertices[base+3].position[1] = glyph_y2;
vertices[base+3].uv[0] = tx2;
vertices[base+3].uv[1] = ty2;
vertices[base+3].color[0] = color->red;
vertices[base+3].color[1] = color->green;
vertices[base+3].color[2] = color->blue;
vertices[base+3].color[3] = color->alpha;
vertices[base+3].color[0] = c.red;
vertices[base+3].color[1] = c.green;
vertices[base+3].color[2] = c.blue;
vertices[base+3].color[3] = c.alpha;
vertices[base+4].position[0] = glyph_x;
vertices[base+4].position[1] = glyph_y2;
vertices[base+4].uv[0] = tx;
vertices[base+4].uv[1] = ty2;
vertices[base+4].color[0] = color->red;
vertices[base+4].color[1] = color->green;
vertices[base+4].color[2] = color->blue;
vertices[base+4].color[3] = color->alpha;
vertices[base+4].color[0] = c.red;
vertices[base+4].color[1] = c.green;
vertices[base+4].color[2] = c.blue;
vertices[base+4].color[3] = c.alpha;
vertices[base+5].position[0] = glyph_x2;
vertices[base+5].position[1] = glyph_y;
vertices[base+5].uv[0] = tx2;
vertices[base+5].uv[1] = ty;
vertices[base+5].color[0] = color->red;
vertices[base+5].color[1] = color->green;
vertices[base+5].color[2] = color->blue;
vertices[base+5].color[3] = color->alpha;
vertices[base+5].color[0] = c.red;
vertices[base+5].color[1] = c.green;
vertices[base+5].color[2] = c.blue;
vertices[base+5].color[3] = c.alpha;
batch->draw.vbo_count += GSK_NGL_N_VERTICES;
used++;

View File

@ -1,20 +1,33 @@
// VERTEX_SHADER:
_OUT_ vec4 final_color;
flat _OUT_ int use_color;
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
// We use this shader for both plain glyphs (used as mask)
// and color glpyhs (used as source). The renderer sets
// aColor to vec4(-1) for color glyhs.
if (distance(aColor, vec4(-1)) < 0.001)
use_color = 0;
else
use_color = 1;
final_color = gsk_premultiply(aColor) * u_alpha;
}
// FRAGMENT_SHADER:
_IN_ vec4 final_color;
flat _IN_ int use_color;
void main() {
vec4 diffuse = GskTexture(u_source, vUv);
gskSetOutputColor(final_color * diffuse.a);
if (use_color == 1)
gskSetOutputColor(final_color * diffuse.a);
else
gskSetOutputColor(diffuse * u_alpha);
}