diff --git a/makefile b/makefile index e134b76..beea043 100644 --- a/makefile +++ b/makefile @@ -45,8 +45,10 @@ else endif X11DIR= $(shell pkg-config --libs-only-L x11 xpm) # for macOS -CFLAGS= -c -std=gnu11 $(OPT) $(GPROF) $(W) $(GDB) -OFLAGS= -lm $(GPROF) -lX11 -lXpm $(X11DIR) +XFTLIB= $(shell pkg-config --libs xft) +XFTCFLAGS= $(shell pkg-config --cflags xft) +CFLAGS= -c -std=gnu11 $(OPT) $(GPROF) $(W) $(GDB) $(XFTCFLAGS) +OFLAGS= -lm $(GPROF) -lX11 -lXpm $(X11DIR) $(XFTLIB) SRCDIR=src OBJDIR=obj diff --git a/src/mol/common.h b/src/mol/common.h index f25a54e..87f2b17 100644 --- a/src/mol/common.h +++ b/src/mol/common.h @@ -25,11 +25,11 @@ #define printalive {printf("alive @ %s:%d\n", __FILE__, __LINE__); fflush(stdout);} #define PRINT_ERR(...) {\ - fprintf(stderr, "\e[1;31m" "error: " "\e[0m" "\e[1;30m" "[%s:%d]" "\e[0m ", __FILE__, __LINE__);\ + fprintf(stderr, "\e[1;31m" "error: " "\e[0m" "\e[1;37m" "[%s:%d]" "\e[0m ", __FILE__, __LINE__);\ fprintf(stderr, __VA_ARGS__ );\ } #define PRINT_WARN(...) {\ - fprintf(stderr, "\e[1;35m" "warning: " "\e[0m" "\e[1;30m" "[%s:%d]" "\e[0m ", __FILE__, __LINE__);\ + fprintf(stderr, "\e[1;33m" "warning: " "\e[0m" "\e[1;37m" "[%s:%d]" "\e[0m ", __FILE__, __LINE__);\ fprintf(stderr, __VA_ARGS__ );\ } diff --git a/src/v/ac3_draw.c b/src/v/ac3_draw.c index 450b0d4..20a6fe4 100644 --- a/src/v/ac3_draw.c +++ b/src/v/ac3_draw.c @@ -4,10 +4,20 @@ #define EPS 1e-15 #define BOND_OFFSET 0.666 // bond line starts this fraction of the atom radius away from the atom center #define RESOL_SCALE (128.0/768.0) // reference resolution for atom sizes -#define XDRAWSTRING XDrawImageString // change to XDrawString to remove white boxes behind atom/bond labels extern draw_world_t world; +static void draw_label(int x, int y, const char *text) { + XGlyphInfo extents; + XftTextExtentsUtf8(world.dis, world.font_info, (const FcChar8*) text, + strlen(text), &extents); + + XftDrawStringUtf8(world.xft_draw, &world.xft_color, world.font_info, + x - extents.xOff / 2, y + extents.height / 2, + (const FcChar8 *)text, strlen(text)); + return; +} + static inline int getgci(int q){ return abs(q)num == SHOW_NUMBERS){ char text[16]; snprintf(text, sizeof(text), "%d", k+1); - XDRAWSTRING(world.dis, world.canv, world.gc_black, x, y, text, strlen(text)); + draw_label(x, y, text); } else if(rend->num == SHOW_TYPES){ char text[16]; const char * s = get_name(q); s ? snprintf(text, sizeof(text), "%s", s) : snprintf(text, sizeof(text), "%d", q ); - XDRAWSTRING(world.dis, world.canv, world.gc_black, x, y, text, strlen(text)); + draw_label(x, y, text); } if(rend->bonds>0){ @@ -97,7 +107,7 @@ void ac3_draw(atcoord * ac, rendpars * rend){ if(rend->bonds==SHOW_LENGTHS){ char text[16]; snprintf(text, sizeof(text), "%.3lf", ac->bonds.r[j]); - XDRAWSTRING(world.dis, world.canv, world.gc_black, x+dx/2, y+dy/2, text, strlen(text)); + draw_label(x+dx/2, y+dy/2, text); } } } diff --git a/src/v/x.c b/src/v/x.c index 3e8ab90..7a203f5 100644 --- a/src/v/x.c +++ b/src/v/x.c @@ -14,8 +14,11 @@ void close_x(void) { } XDestroyWindow (world.dis, world.win); XFreePixmap (world.dis, world.px); - if(world.fontInfo){ - XFreeFont (world.dis, world.fontInfo); + if(world.font_info){ + XftFontClose (world.dis, world.font_info); + } + if (world.xft_draw) { + XftDrawDestroy(world.xft_draw); } XCloseDisplay (world.dis); }; @@ -103,49 +106,37 @@ void init_x(const char * const capt, const colorscheme_t colorscheme){ return; }; -static void autosize_font(char * fontname){ - const int screen_sizes[] = {1200, 1080, 960, 900, 840, 768}; - const int font_sizes[] = { 24, 20, 18, 16, 15, 14}; // font_size='ceil'(world.size) / 60 - int font_size = 13; - for(int i=0; iscreen_sizes[i]){ - font_size = font_sizes[i]; - break; - } - } - sprintf(fontname, "*x%d", font_size); - return; -} - void init_font(char * fontname){ - styp s; if(!fontname){ - fontname = s; - autosize_font(fontname); + PRINT_WARN("using system default monospace font\n"); + world.font_info = XftFontOpenName(world.dis, DefaultScreen(world.dis), "monospace:size=12"); + } else { + world.font_info = XftFontOpenName(world.dis, DefaultScreen(world.dis), fontname); } - world.fontInfo = XLoadQueryFont(world.dis, fontname); - if(world.fontInfo){ - XSetFont (world.dis, world.gc_black, world.fontInfo->fid); - XSetFont (world.dis, world.gc_red, world.fontInfo->fid); - } - else{ - PRINT_WARN("cannot load font '%s'\n", fontname); + + if(!world.font_info){ + PRINT_ERR("cannot load font %s\n", fontname); + exit(1); } - XCharStruct _o; - int _d, font_ascent, font_descent; - XQueryTextExtents(world.dis, XGContextFromGC(world.gc_black), ".", 1, &_d, &font_ascent, &font_descent, &_o); - world.font_height = font_ascent + font_descent; + world.xft_draw = XftDrawCreate(world.dis, world.canv, DefaultVisual(world.dis, DefaultScreen(world.dis)), DefaultColormap(world.dis, DefaultScreen(world.dis))); + XRenderColor color = {0, 0, 0, 65535}; + XftColorAllocValue(world.dis, DefaultVisual(world.dis, DefaultScreen(world.dis)), DefaultColormap(world.dis, DefaultScreen(world.dis)), &color, &world.xft_color); + XGlyphInfo extents; + XftTextExtentsUtf8(world.dis, world.font_info, (const FcChar8 *)".", 1, &extents); return; } void put_text(const char * const lines[MAX_LINES], const int red[MAX_LINES]){ - int voffset = world.font_height + 5; - int hoffset = 10; + int voffset = world.font_info->height; + int hoffset = 16; for(int i=0; iascent; + XftDrawStringUtf8(world.xft_draw, &(world.xft_color), world.font_info, x, y, (const FcChar8 *)lines[i], strlen(lines[i])); } + voffset += world.font_info->height; } return; } diff --git a/src/v/x.h b/src/v/x.h index 792647c..dc1a3d4 100644 --- a/src/v/x.h +++ b/src/v/x.h @@ -1,3 +1,4 @@ +#include #include #include #include @@ -16,7 +17,8 @@ typedef struct { GC gc_white, gc_black, gc_red, gc_dot[2], gcc[NCOLORS]; Pixmap px; Drawable canv; - XFontStruct * fontInfo; - int font_height; + XftFont * font_info; + XftDraw * xft_draw; + XftColor xft_color; int W, H, size; } draw_world_t;