summaryrefslogtreecommitdiff
path: root/src/xftrender.c
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2019-10-22 22:46:49 +1100
committerThomas E. Dickey <dickey@invisible-island.net>2022-07-09 10:12:35 -0400
commit6a08279ee80dbd1a226592d7f18c862c2e4a7d3a (patch)
tree1b1e5e999dc93aadb34ea3246c8de58fd8df6d87 /src/xftrender.c
parent2cbb9597e0b10d87fa9fc506910f69b9199320f0 (diff)
downloadxorg-lib-libXft-6a08279ee80dbd1a226592d7f18c862c2e4a7d3a.tar.gz
Add support for BGRA glyphs display and scaling
Display is done using an XRender Picture, as XRender glyphs are incompatible with BGRA rendering due to their use of the glyph bitmap as a mask. Scaling is done by averaging all relevant pixel, which gives much better result than nearest pixel sampling while staying simple enough and not too computationally expensive. This enables color emoji rendering support. Fixes: #6 Signed-off-by: Maxime Coste <mawww@kakoune.org> Signed-off-by: Thomas E. Dickey <dickey@invisible-island.net>
Diffstat (limited to 'src/xftrender.c')
-rw-r--r--src/xftrender.c69
1 files changed, 56 insertions, 13 deletions
diff --git a/src/xftrender.c b/src/xftrender.c
index aad5431..721cae0 100644
--- a/src/xftrender.c
+++ b/src/xftrender.c
@@ -84,12 +84,14 @@ XftGlyphRender (Display *dpy,
int nglyphs)
{
XftFontInt *font = (XftFontInt *) pub;
- int i;
+ int i, j;
FT_UInt missing[XFT_NMISSING];
int nmissing;
FT_UInt g, max;
int size, width;
+ int dstx, dsty;
Glyph wire;
+ XftGlyph* glyph;
char *char8;
unsigned short *char16;
unsigned int *char32;
@@ -141,22 +143,46 @@ XftGlyphRender (Display *dpy,
if (!chars)
goto bail1;
}
+ dstx = x;
+ dsty = y;
char8 = (char *) chars;
char16 = (unsigned short *) chars;
char32 = (unsigned int *) chars;
- for (i = 0; i < nglyphs; i++)
+ for (i = 0, j = 0; i < nglyphs; i++)
{
wire = (Glyph) glyphs[i];
if (wire >= (Glyph) font->num_glyphs || !font->glyphs[wire])
wire = 0;
- switch (width) {
- case 1: char8[i] = (char) wire; break;
- case 2: char16[i] = (unsigned short) wire; break;
- case 4: char32[i] = (unsigned int) wire; break;
+ glyph = font->glyphs[wire];
+ if (glyph->picture)
+ {
+ _XftCompositeString(dpy, op, src, dst, font->format, font->glyphset,
+ srcx, srcy, x, y, width, chars, j);
+ XRenderComposite(dpy, PictOpOver, glyph->picture, None,
+ dst, 0, 0, 0, 0, dstx, dsty - glyph->metrics.y,
+ glyph->metrics.width, glyph->metrics.height);
+
+ dstx += glyph->metrics.xOff;
+ dsty += glyph->metrics.yOff;
+
+ x = dstx;
+ y = dsty;
+ j = 0;
+ }
+ else
+ {
+ switch (width) {
+ case 1: char8[j] = (char) wire; break;
+ case 2: char16[j] = (unsigned short) wire; break;
+ case 4: char32[j] = (unsigned int) wire; break;
+ }
+ dstx += glyph->metrics.xOff;
+ dsty += glyph->metrics.yOff;
+ ++j;
}
}
_XftCompositeString(dpy, op, src, dst, font->format, font->glyphset,
- srcx, srcy, x, y, width, chars, nglyphs);
+ srcx, srcy, x, y, width, chars, j);
if (chars != char_local)
free (chars);
bail1:
@@ -319,9 +345,10 @@ XftGlyphSpecRender (Display *dpy,
g = 0;
/*
* check to see if the glyph is placed where it would
- * fall using the normal spacing
+ * fall using the normal spacing and if it would render
+ * as a XRender glyph
*/
- if ((glyph = font->glyphs[g]))
+ if ((glyph = font->glyphs[g]) && !glyph->picture)
{
if (x != glyphs[i].x || y != glyphs[i].y)
{
@@ -335,7 +362,7 @@ XftGlyphSpecRender (Display *dpy,
}
elts = elts_local;
- if (nelt > NUM_ELT_LOCAL)
+ if (!font->info.color && nelt > NUM_ELT_LOCAL)
{
elts = AllocGlyphElt8Array (nelt);
if (!elts)
@@ -343,7 +370,7 @@ XftGlyphSpecRender (Display *dpy,
}
/*
- * Generate the list of glyph elts
+ * Generate the list of glyph elts or render color glyphs
*/
nelt = 0;
x = y = 0;
@@ -357,6 +384,14 @@ XftGlyphSpecRender (Display *dpy,
g = 0;
if ((glyph = font->glyphs[g]))
{
+ if (glyph->picture)
+ {
+ XRenderComposite(dpy, PictOpOver, glyph->picture, None,
+ dst, 0, 0, 0, 0,
+ glyphs[i].x, glyphs[i].y - glyph->metrics.y,
+ glyph->metrics.width, glyph->metrics.height);
+ continue;
+ }
if (!i || x != glyphs[i].x || y != glyphs[i].y)
{
if (n)
@@ -592,7 +627,7 @@ XftGlyphFontSpecRender (Display *dpy,
* check to see if the glyph is placed where it would
* fall using the normal spacing
*/
- if ((glyph = font->glyphs[g]))
+ if ((glyph = font->glyphs[g]) && !glyph->picture)
{
if (pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
{
@@ -617,7 +652,7 @@ XftGlyphFontSpecRender (Display *dpy,
}
/*
- * Generate the list of glyph elts
+ * Generate the list of glyph elts and render color glyphs
*/
nelt = 0;
x = y = 0;
@@ -635,6 +670,14 @@ XftGlyphFontSpecRender (Display *dpy,
g = 0;
if ((glyph = font->glyphs[g]))
{
+ if (glyph->picture)
+ {
+ XRenderComposite(dpy, PictOpOver, glyph->picture, None,
+ dst, 0, 0, 0, 0,
+ glyphs[i].x, glyphs[i].y - glyph->metrics.y,
+ glyph->metrics.width, glyph->metrics.height);
+ continue;
+ }
if (!i || pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
{
if (n)