1616#include <X11/Xlib.h>
1717
1818typedef struct XFont XFont ;
19+ #ifdef NK_XLIB_USE_XFT
20+ NK_API struct nk_context * nk_xlib_init (XFont * , Display * , int scrn , Window root , Visual * vis , Colormap cmap , unsigned w , unsigned h );
21+ #else
1922NK_API struct nk_context * nk_xlib_init (XFont * , Display * , int scrn , Window root , unsigned w , unsigned h );
23+ #endif
2024NK_API int nk_xlib_handle_event (Display * , int scrn , Window , XEvent * );
2125NK_API void nk_xlib_render (Drawable screen , struct nk_color clear );
2226NK_API void nk_xlib_shutdown (void );
@@ -53,6 +57,10 @@ NK_API void nk_xfont_del(Display *dpy, XFont *font);
5357#include <X11/Xlocale.h>
5458#include <X11/Xatom.h>
5559
60+ #ifdef NK_XLIB_USE_XFT
61+ #include <X11/Xft/Xft.h>
62+ #endif
63+
5664#include <sys/time.h>
5765#include <unistd.h>
5866#include <time.h>
@@ -80,8 +88,12 @@ struct XFont {
8088 int ascent ;
8189 int descent ;
8290 int height ;
91+ #ifdef NK_XLIB_USE_XFT
92+ XftFont * ft ;
93+ #else
8394 XFontSet set ;
8495 XFontStruct * xfont ;
96+ #endif
8597 struct nk_user_font handle ;
8698};
8799struct XSurface {
@@ -91,6 +103,9 @@ struct XSurface {
91103 Window root ;
92104 Drawable drawable ;
93105 unsigned int w , h ;
106+ #ifdef NK_XLIB_USE_XFT
107+ XftDraw * ftdraw ;
108+ #endif
94109};
95110struct XImageWithAlpha {
96111 XImage * ximage ;
@@ -112,6 +127,10 @@ static struct {
112127 Cursor cursor ;
113128 Display * dpy ;
114129 Window root ;
130+ #ifdef NK_XLIB_USE_XFT
131+ Visual * vis ;
132+ Colormap cmap ;
133+ #endif
115134 double last_button_click ;
116135 double time_of_last_frame ;
117136} xlib ;
@@ -147,6 +166,10 @@ nk_xsurf_create(int screen, unsigned int w, unsigned int h)
147166 XSetLineAttributes (xlib .dpy , surface -> gc , 1 , LineSolid , CapButt , JoinMiter );
148167 surface -> drawable = XCreatePixmap (xlib .dpy , xlib .root , w , h ,
149168 (unsigned int )DefaultDepth (xlib .dpy , screen ));
169+ #ifdef NK_XLIB_USE_XFT
170+ surface -> ftdraw = XftDrawCreate (xlib .dpy , surface -> drawable ,
171+ xlib .vis , xlib .cmap );
172+ #endif
150173 return surface ;
151174}
152175
@@ -159,6 +182,9 @@ nk_xsurf_resize(XSurface *surf, unsigned int w, unsigned int h)
159182 if (surf -> drawable ) XFreePixmap (surf -> dpy , surf -> drawable );
160183 surf -> drawable = XCreatePixmap (surf -> dpy , surf -> root , w , h ,
161184 (unsigned int )DefaultDepth (surf -> dpy , surf -> screen ));
185+ #ifdef NK_XLIB_USE_XFT
186+ XftDrawChange (surf -> ftdraw , surf -> drawable );
187+ #endif
162188}
163189
164190NK_INTERN void
@@ -170,6 +196,10 @@ nk_xsurf_scissor(XSurface *surf, float x, float y, float w, float h)
170196 clip_rect .width = (unsigned short )(w + 2 );
171197 clip_rect .height = (unsigned short )(h + 2 );
172198 XSetClipRectangles (surf -> dpy , surf -> gc , 0 , 0 , & clip_rect , 1 , Unsorted );
199+
200+ #ifdef NK_XLIB_USE_XFT
201+ XftDrawSetClipRectangles (surf -> ftdraw , 0 , 0 , & clip_rect , 1 );
202+ #endif
173203}
174204
175205NK_INTERN void
@@ -416,16 +446,31 @@ nk_xsurf_draw_text(XSurface *surf, short x, short y, const char *text, int len,
416446 XFont * font , struct nk_color cfg )
417447{
418448 int tx , ty ;
449+ #ifdef NK_XLIB_USE_XFT
450+ XRenderColor xrc ;
451+ XftColor color ;
452+ #else
419453 unsigned long fg = nk_color_from_byte (& cfg .r );
454+ #endif
420455
421456 if (!text || !font || !len ) return ;
422457
423458 tx = (int )x ;
424459 ty = (int )y + font -> ascent ;
460+ #ifdef NK_XLIB_USE_XFT
461+ xrc .red = cfg .r * 257 ;
462+ xrc .green = cfg .g * 257 ;
463+ xrc .blue = cfg .b * 257 ;
464+ xrc .alpha = cfg .a * 257 ;
465+ XftColorAllocValue (surf -> dpy , xlib .vis , xlib .cmap , & xrc , & color );
466+ XftDrawStringUtf8 (surf -> ftdraw , & color , font -> ft , tx , ty , (FcChar8 * )text , len );
467+ XftColorFree (surf -> dpy , xlib .vis , xlib .cmap , & color );
468+ #else
425469 XSetForeground (surf -> dpy , surf -> gc , fg );
426470 if (font -> set )
427471 XmbDrawString (surf -> dpy ,surf -> drawable ,font -> set ,surf -> gc ,tx ,ty ,(const char * )text ,(int )len );
428472 else XDrawString (surf -> dpy , surf -> drawable , surf -> gc , tx , ty , (const char * )text , (int )len );
473+ #endif
429474}
430475
431476
@@ -563,6 +608,9 @@ nk_xsurf_blit(Drawable target, XSurface *surf, unsigned int w, unsigned int h)
563608NK_INTERN void
564609nk_xsurf_del (XSurface * surf )
565610{
611+ #ifdef NK_XLIB_USE_XFT
612+ XftDrawDestroy (surf -> ftdraw );
613+ #endif
566614 XFreePixmap (surf -> dpy , surf -> drawable );
567615 XFreeGC (surf -> dpy , surf -> gc );
568616 free (surf );
@@ -571,6 +619,17 @@ nk_xsurf_del(XSurface *surf)
571619NK_API XFont *
572620nk_xfont_create (Display * dpy , const char * name )
573621{
622+ #ifdef NK_XLIB_USE_XFT
623+ XFont * font = (XFont * )calloc (1 , sizeof (XFont ));
624+ font -> ft = XftFontOpenName (dpy , XDefaultScreen (dpy ), name );
625+ if (!font -> ft ) {
626+ fprintf (stderr , "missing font: %s\n" , name );
627+ return font ;
628+ }
629+ font -> ascent = font -> ft -> ascent ;
630+ font -> descent = font -> ft -> descent ;
631+ font -> height = font -> ft -> height ;
632+ #else
574633 int n ;
575634 char * def , * * missing ;
576635 XFont * font = (XFont * )calloc (1 , sizeof (XFont ));
@@ -600,13 +659,26 @@ nk_xfont_create(Display *dpy, const char *name)
600659 font -> descent = font -> xfont -> descent ;
601660 }
602661 font -> height = font -> ascent + font -> descent ;
662+ #endif
603663 return font ;
604664}
605665
606666NK_INTERN float
607667nk_xfont_get_text_width (nk_handle handle , float height , const char * text , int len )
608668{
609669 XFont * font = (XFont * )handle .ptr ;
670+
671+ #ifdef NK_XLIB_USE_XFT
672+ XGlyphInfo g ;
673+
674+ NK_UNUSED (height );
675+
676+ if (!font || !text )
677+ return 0 ;
678+
679+ XftTextExtentsUtf8 (xlib .dpy , font -> ft , (FcChar8 * )text , len , & g );
680+ return g .xOff ;
681+ #else
610682 XRectangle r ;
611683
612684 NK_UNUSED (height );
@@ -621,21 +693,29 @@ nk_xfont_get_text_width(nk_handle handle, float height, const char *text, int le
621693 int w = XTextWidth (font -> xfont , (const char * )text , len );
622694 return (float )w ;
623695 }
696+ #endif
624697}
625698
626699NK_API void
627700nk_xfont_del (Display * dpy , XFont * font )
628701{
629702 if (!font ) return ;
703+ #ifdef NK_XLIB_USE_XFT
704+ XftFontClose (dpy , font -> ft );
705+ #else
630706 if (font -> set )
631707 XFreeFontSet (dpy , font -> set );
632708 else
633709 XFreeFont (dpy , font -> xfont );
710+ #endif
634711 free (font );
635712}
636713
637714NK_API struct nk_context *
638715nk_xlib_init (XFont * xfont , Display * dpy , int screen , Window root ,
716+ #ifdef NK_XLIB_USE_XFT
717+ Visual * vis , Colormap cmap ,
718+ #endif
639719 unsigned int w , unsigned int h )
640720{
641721 struct nk_user_font * font = & xfont -> handle ;
@@ -644,6 +724,10 @@ nk_xlib_init(XFont *xfont, Display *dpy, int screen, Window root,
644724 font -> width = nk_xfont_get_text_width ;
645725 xlib .dpy = dpy ;
646726 xlib .root = root ;
727+ #ifdef NK_XLIB_USE_XFT
728+ xlib .vis = vis ;
729+ xlib .cmap = cmap ;
730+ #endif
647731
648732 if (!setlocale (LC_ALL ,"" )) return 0 ;
649733 if (!XSupportsLocale ()) return 0 ;
0 commit comments