On Sun, Feb 08, 2026 at 01:34:37AM +0800, 406643764 wrote:
> I find that XftDrawStringUtf8 can not draw color emoji. I test it with those 
> code:

bug reports go here:

https://gitlab.freedesktop.org/xorg/lib/libxft/-/issues
 
> #include <stdio.h>
> #include <stdint.h>
> #include <X11/Xlib.h>
> #include <X11/Xft/Xft.h>
> 
> Display *display;
> int screen;
> Window root_win, win;
> Colormap colormap;
> Visual *visual;
> 
> int get_utf8_codepoint(const char *str, uint32_t *codepoint)
> {
>     const uint8_t *p=(const uint8_t*)str;
>     int len=0;
>     
>     if(*p < 0x80) // 1 byte char
>         len=1, *codepoint=*p;
>     else if((*p>>5) == 0x06) // 2 bytes char
>         len=2, *codepoint=(*p & 0x1F)<<6 | (*(p+1) & 0x3F);
>     else if((*p>>4) == 0x0E) // 3 bytes char
>         len=3, *codepoint=(*p & 0x0F)<<12 | (*(p+1) & 0x3F)<<6 | (*(p+2) & 
> 0x3F);
>     else if((*p>>3) == 0x1E) // 4 bytes char
>         len=4, *codepoint=(*p & 0x07)<<18 | (*(p+1) & 0x3F)<<12 | (*(p+2) & 
> 0x3F)<<6 | (*(p+3) & 0x3F);
>     else // not utf8 char
>         len=0;
> 
>     return len;
> }
> 
> void draw_utf8_char(XftFont *font, const char *s, uint32_t codepoint, int len)
> {
>     XftColor color;
>     XftColorAllocName(display, visual, colormap, "red", &color);
>     XftDraw *draw=XftDrawCreate(display, win, visual, colormap);
>     XftDrawStringUtf8(draw, &color, font, 50, 50, s, len);
>     XftDrawDestroy(draw);
> }
> 
> void check_font(const char *s, const char *fontname)
> {
>     XftFont *font=XftFontOpenName(display, screen, fontname);
>     if(font == NULL)
>     {
>         fprintf(stderr, "%s not exsit", fontname);
>         return;
>     }
> 
>     uint32_t codepoint;
>     int len=get_utf8_codepoint(s, &codepoint);
>     if(XftCharExists(display, font, codepoint))
>     {
>         printf("'%s' in %s\n", s, fontname);
>         draw_utf8_char(font, s, codepoint, len);
>     }
>     else
>         printf("'%s' not in %s\n", s, fontname);
> }
> 
> int main(int argc, char **argv)
> {
>     display=XOpenDisplay(NULL);
>     screen=DefaultScreen(display);
>     root_win=RootWindow(display, screen);
>     visual=DefaultVisual(display, screen);
>     colormap=DefaultColormap(display, screen);
>     win=XCreateSimpleWindow(display, root_win, 0, 0, 100, 100, 2, 0x00ff00, 
> 0);
>     XSelectInput(display, win, ExposureMask);
>     XMapWindow(display, win);
>     if(argc != 3)
>     {
>         fprintf(stderr, "usage: %s <char> [fontname]\n", argv[0]);
>         exit(1);
>     }
> 
>     XEvent e;
>     while(!XNextEvent(display, &e))
>         if(e.type == Expose)
>             check_font(argv[1], argv[2]);
> 
> 
>     return 0;
> }
> 
> 
> I tested it like that:
>      ./a.out 🌐 "Noto Color Emoji"
> 
> 
> And can not draw 🌐.

...that's done in a terminal (which one, and which version is not specified)

> 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

I had a Fedora 41, with these versions:

libX11-devel-1.8.11-1.fc41.x86_64
libXft-2.3.8-7.fc41.x86_64
libXft-devel-2.3.8-7.fc41.x86_64
google-noto-color-emoji-fonts-20241008-1.fc41.noarch
 
> And the test code can draw color emoji at Fedora 41 and older version.

perhaps the defect is in the font, since it's likely either the font or Xft.
Also, since the version of Xft is the same (2.3.8), the font is suspect.

-- 
Thomas E. Dickey <[email protected]>
https://invisible-island.net

Attachment: signature.asc
Description: PGP signature

Reply via email to