I find that XftDrawStringUtf8 can not draw color emoji. I test it with 
those code:


#include <stdio.h&gt;
#include <stdint.h&gt;
#include <X11/Xlib.h&gt;
#include <X11/Xft/Xft.h&gt;

Display *display;
int screen;
Window root_win, win;
Colormap colormap;
Visual *visual;

int get_utf8_codepoint(const char *str, uint32_t *codepoint)
{
&nbsp; &nbsp; const uint8_t *p=(const uint8_t*)str;
&nbsp; &nbsp; int len=0;
&nbsp; &nbsp;&nbsp;
&nbsp; &nbsp; if(*p < 0x80) // 1 byte char
&nbsp; &nbsp; &nbsp; &nbsp; len=1, *codepoint=*p;
&nbsp; &nbsp; else if((*p&gt;&gt;5) == 0x06) // 2 bytes char
&nbsp; &nbsp; &nbsp; &nbsp; len=2, *codepoint=(*p &amp; 0x1F)<<6 | (*(p+1) 
&amp; 0x3F);
&nbsp; &nbsp; else if((*p&gt;&gt;4) == 0x0E) // 3 bytes char
&nbsp; &nbsp; &nbsp; &nbsp; len=3, *codepoint=(*p &amp; 0x0F)<<12 | (*(p+1) 
&amp; 0x3F)<<6 | (*(p+2) &amp; 0x3F);
&nbsp; &nbsp; else if((*p&gt;&gt;3) == 0x1E) // 4 bytes char
&nbsp; &nbsp; &nbsp; &nbsp; len=4, *codepoint=(*p &amp; 0x07)<<18 | (*(p+1) 
&amp; 0x3F)<<12 | (*(p+2) &amp; 0x3F)<<6 | (*(p+3) &amp; 0x3F);
&nbsp; &nbsp; else // not&nbsp;utf8 char
&nbsp; &nbsp; &nbsp; &nbsp; len=0;

&nbsp; &nbsp; return len;
}

void draw_utf8_char(XftFont *font, const char *s, uint32_t codepoint, int len)
{
&nbsp; &nbsp; XftColor color;
&nbsp; &nbsp; XftColorAllocName(display, visual, colormap, "red", &amp;color);
&nbsp; &nbsp; XftDraw *draw=XftDrawCreate(display, win, visual, colormap);
&nbsp; &nbsp; XftDrawStringUtf8(draw, &amp;color, font, 50, 50, s, len);
&nbsp; &nbsp; XftDrawDestroy(draw);
}

void check_font(const char *s, const char *fontname)
{
&nbsp; &nbsp; XftFont *font=XftFontOpenName(display, screen, fontname);
&nbsp; &nbsp; if(font == NULL)
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; fprintf(stderr, "%s not exsit", fontname);
&nbsp; &nbsp; &nbsp; &nbsp; return;
&nbsp; &nbsp; }

&nbsp; &nbsp; uint32_t codepoint;
&nbsp; &nbsp; int len=get_utf8_codepoint(s, &amp;codepoint);
&nbsp; &nbsp; if(XftCharExists(display, font, codepoint))
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; printf("'%s' in %s\n", s, fontname);
&nbsp; &nbsp; &nbsp; &nbsp; draw_utf8_char(font, s, codepoint, len);
&nbsp; &nbsp; }
&nbsp; &nbsp; else
&nbsp; &nbsp; &nbsp; &nbsp; printf("'%s' not in %s\n", s, fontname);
}

int main(int argc, char **argv)
{
&nbsp; &nbsp; display=XOpenDisplay(NULL);
&nbsp; &nbsp; screen=DefaultScreen(display);
&nbsp; &nbsp; root_win=RootWindow(display, screen);
&nbsp; &nbsp; visual=DefaultVisual(display, screen);
&nbsp; &nbsp; colormap=DefaultColormap(display, screen);
&nbsp; &nbsp; win=XCreateSimpleWindow(display, root_win, 0, 0, 100, 100, 2, 
0x00ff00, 0);
&nbsp; &nbsp; XSelectInput(display, win, ExposureMask);
&nbsp; &nbsp; XMapWindow(display, win);
&nbsp; &nbsp; if(argc != 3)
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; fprintf(stderr, "usage: %s <char&gt; [fontname]\n", 
argv[0]);
&nbsp; &nbsp; &nbsp; &nbsp; exit(1);
&nbsp; &nbsp; }

&nbsp; &nbsp; XEvent e;
&nbsp; &nbsp; while(!XNextEvent(display, &amp;e))
&nbsp; &nbsp; &nbsp; &nbsp; if(e.type == Expose)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; check_font(argv[1], argv[2]);


&nbsp; &nbsp; return 0;
}


I tested it like that:
&nbsp; &nbsp; &nbsp;./a.out ?9?4 "Noto Color Emoji"


And can not draw&nbsp;?9?4.


Those are software info:
libX11-devel-1.8.12-1.fc43.x86_64
libXft-devel-2.3.8-9.fc43.x86_64
google-noto-color-emoji-fonts-20250623-2.fc43.noarch


And the test code can draw color emoji at Fedora 41 and older version.


406643764
[email protected]



&nbsp;

Reply via email to