From ab0c6edc63fa0dceac7a847ca276910a03119b12 Mon Sep 17 00:00:00 2001 From: Jiri Kalvoda <jirikalvoda@kam.mff.cuni.cz> Date: Mon, 8 Feb 2021 19:41:11 +0100 Subject: [PATCH] Add support of alternatives fonts --- display.c | 91 +++++++++++++++++++++++++++++++++++++------------------ osdd-run | 2 +- 2 files changed, 63 insertions(+), 30 deletions(-) diff --git a/display.c b/display.c index 29426c4..6069b25 100644 --- a/display.c +++ b/display.c @@ -39,12 +39,13 @@ struct display_line { int slider_unit; int slider_space; int slider_units; + XftFont *font; }; struct osd_abstract display_state_new_arg(int argc, char ** argv,Display * dpy); -struct osd_abstract display_state_new(Display *dpy,int width,int height,int x,int y, char * font_name, double line_spacing); +struct osd_abstract display_state_new(Display *dpy,int width,int height,int x,int y, char * font_name,VECTOR(char *) alternative_fonts, double line_spacing); void display_free(struct display_state *display); -void display_set_font(struct display_state *display, char *font_name, double line_spacing); +void display_set_font(struct display_state *display, char *font_name, VECTOR(char *) alternative_fonts_name, double line_spacing); struct display_line *display_add_line(struct display_state *display, struct osd_line * line); void display_show(struct display_state *display, struct osd_line * lines, int num_lines); void display_hide(struct display_state *display); @@ -78,7 +79,8 @@ struct display_state { GC mask_gc; // Xft state - XftFont *font; + XftFont **font; + int num_font; XftDraw *mask_draw; XftDraw *image_draw; @@ -154,6 +156,7 @@ void display_state_new_arg_help(FILE * f) { fprintf(f,"Module DISPLAY help:\n\ -f, --font=<f>\t\tFont to use for the OSD\n\ +-F, --alternative-font=<f>\tFont to use when line is too big\n\ -s, --line-spacing=<n>\tSet line spacing factor (decimal fraction, default=0.2)\n\ -x, --x=<px>\t\tLeft up corner positing (move right, default=0)\n\ -y, --y=<px>\t\tLeft up corner positing (move down, default=0)\n\ @@ -164,9 +167,10 @@ void display_state_new_arg_help(FILE * f) struct osd_abstract display_state_new_arg(int argc, char ** argv,Display *dpy) { -static const char short_opts[] = "f:s:x:y:h:w:"; +static const char short_opts[] = "f:F:s:x:y:h:w:"; static const struct option long_opts[] = { { "font", required_argument, NULL, 'f' }, + { "alternative-font", required_argument, NULL, 'F' }, { "line-spacing", required_argument, NULL, 's' }, { "x", required_argument, NULL, 'x' }, { "y", required_argument, NULL, 'y' }, @@ -177,6 +181,7 @@ static const struct option long_opts[] = { //fprintf(stderr,"NEW DISPLAY:\n"); //for(int i=0;i<argc;i++) fprintf(stderr,"\t%s\n",argv[i]); char *font_name = "times-64:bold"; + VECTOR(char *) alternative_fonts = 0; double line_spacing = 0.2; int opt; int x=0,y=0; @@ -189,7 +194,9 @@ static const struct option long_opts[] = { { case 'f': font_name = optarg; - fprintf(stderr,"FONT SET\n"); + break; + case 'F': + VPB(alternative_fonts, optarg); break; case 's': line_spacing = atof(optarg); @@ -211,7 +218,7 @@ static const struct option long_opts[] = { exit(0); } } - return display_state_new(dpy,width,height,x,y,font_name,line_spacing); + return display_state_new(dpy,width,height,x,y,font_name,alternative_fonts,line_spacing); } struct osd_creator_abstract display_creator_new(void) @@ -233,6 +240,7 @@ void display_state_new_by_outputs_help(FILE * f) { fprintf(f,"Module DISPLAY_BY_OUTPUTS help:\n\ -f, --font=<f>\t\tFont to use for the OSD\n\ +-F, --alternative-font=<f>\tFont to use when line is too big\n\ -s, --line-spacing=<n>\tSet line spacing factor (decimal fraction, default=0.2)\n\ -n, --name=<s>\t\tname with expansion %%d to display number (expanded by printf)\n\ \n"); @@ -241,9 +249,10 @@ void display_state_new_by_outputs_help(FILE * f) static void display_state_new_by_outputs(struct osd_set *set, int argc, char ** argv,Display *dpy,int names_len, char ** names) { -static const char short_opts[] = "f:s:n:"; +static const char short_opts[] = "f:F:s:n:"; static const struct option long_opts[] = { { "font", required_argument, NULL, 'f' }, + { "alternative-font", required_argument, NULL, 'F' }, { "line-spacing", required_argument, NULL, 's' }, { "name", required_argument, NULL, 'n' }, { NULL, 0, NULL, 0 }, @@ -252,6 +261,7 @@ static const struct option long_opts[] = { //for(int i=0;i<argc;i++) fprintf(stderr,"\t%s\n",argv[i]); char * expanding_name = ""; char *font_name = "times-64:bold"; + VECTOR(char *) alternative_fonts = 0; double line_spacing = 0.2; int opt; optind = 0; @@ -261,7 +271,9 @@ static const struct option long_opts[] = { { case 'f': font_name = optarg; - fprintf(stderr,"FONT SET\n"); + break; + case 'F': + VPB(alternative_fonts, optarg); break; case 's': line_spacing = atof(optarg); @@ -291,7 +303,7 @@ static const struct option long_opts[] = { DBG("ADD screen %dx%d on %d,%d\n",width,height,x,y); sprintf(new_names[names_len],expanding_name,i,i,i,i,i,i); - osd_set_add(set,display_state_new(dpy,width,height,x,y,font_name,line_spacing),names_len+(bool)expanding_name[0],new_names); + osd_set_add(set,display_state_new(dpy,width,height,x,y,font_name,alternative_fonts,line_spacing),names_len+(bool)expanding_name[0],new_names); i++; } } @@ -312,7 +324,7 @@ struct osd_creator_abstract display_by_outputs_creator_new(void) // **************************************************************************************** -struct osd_abstract display_state_new(Display *dpy,int width,int height,int x,int y, char * font_name, double line_spacing) +struct osd_abstract display_state_new(Display *dpy,int width,int height,int x,int y, char * font_name, VECTOR(char *) alternative_fonts, double line_spacing) { struct display_state *display = xmalloc(sizeof(*display)); memset(display, 0, sizeof(*display)); @@ -339,7 +351,7 @@ struct osd_abstract display_state_new(Display *dpy,int width,int height,int x,in display->num_lines = 0; display->lines = xmalloc(sizeof(struct display_line) * display->max_lines); - display_set_font(display, font_name, line_spacing); + display_set_font(display, font_name, alternative_fonts, line_spacing); struct osd_abstract r; memset(&r, 0, sizeof(r)); @@ -357,26 +369,41 @@ void display_free(struct display_state *display) { display_hide(display); - if (display->font) - XftFontClose(display->dpy, display->font); + if(display->font) + { + for(int i=0;i<display->num_font;i++) + if (display->font[i]) + XftFontClose(display->dpy, display->font[i]); + free(display->font); + } free(display->lines); free(display); } -void display_set_font(struct display_state *display, char *font_name, double line_spacing) +void display_set_font(struct display_state *display, char *font_name, VECTOR(char *) alternative_fonts_name, double line_spacing) { - if (display->font) - XftFontClose(display->dpy, display->font); + if(display->font) + { + for(int i=0;i<display->num_font;i++) + if (display->font[i]) + XftFontClose(display->dpy, display->font[i]); + free(display->font); + } DBG("Using font %s\n", font_name); - display->font = XftFontOpenName(display->dpy, display->screen, font_name); - if (!display->font) - die("Cannot open font %s", font_name); - DBG("Font: asc=%d desc=%d ht=%d\n", display->font->ascent, display->font->descent, display->font->height); + display->num_font = 1 + VSIZE(alternative_fonts_name); + display->font = malloc(sizeof(display->font[0])*display->num_font); + for(int i=0;i<display->num_font;i++) + { + display->font[i] = XftFontOpenName(display->dpy, display->screen, i?alternative_fonts_name[i-1]:font_name); + if (!display->font[0]) + die("Cannot open font %s", font_name); + DBG("Font: asc=%d desc=%d ht=%d\n", display->font->ascent, display->font->descent, display->font->height); + } - display->line_distance = display->font->height; - display->line_height = display->font->ascent; + display->line_distance = display->font[0]->height; + display->line_height = display->font[0]->ascent; display->line_skip = display->line_distance * line_spacing; DBG("Line: distance=%d height=%d skip=%d\n", display->line_distance, display->line_height, display->line_skip); } @@ -402,11 +429,17 @@ static void display_prepare_line(struct display_state *display, int i) { case OSD_TYPE_TEXT: { - XGlyphInfo gi; - XftTextExtentsUtf8(display->dpy, display->font, (unsigned char *) line->line->u.text, strlen(line->line->u.text), &gi); - DBG("Line #%d: Glyph info: (%d,%d)+(%d,%d) off (%d,%d)\n", i, gi.x, gi.y, gi.width, gi.height, gi.xOff, gi.yOff); - line->width = gi.width + 2*line->line->outline_width; - line->height = display->line_distance + 2*line->line->outline_width; + for(int j=0;j<display->num_font;j++) + { + XGlyphInfo gi; + XftTextExtentsUtf8(display->dpy, display->font[j], (unsigned char *) line->line->u.text, strlen(line->line->u.text), &gi); + DBG("Line #%d: Glyph info: (%d,%d)+(%d,%d) off (%d,%d)\n", i, gi.x, gi.y, gi.width, gi.height, gi.xOff, gi.yOff); + line->width = gi.width + 2*line->line->outline_width; + line->height = display->line_distance + 2*line->line->outline_width; + line->font = display->font[j]; + //fprintf(stderr,"i%d j%d L %d S %d\n", i,j, line->width, display->screen_width); + if(line->width < display->screen_width - 10) break; + } break; } case OSD_TYPE_PERCENTAGE: @@ -510,14 +543,14 @@ static void display_draw_line(struct display_state *display, int i) unsigned char *text = (unsigned char *) line->line->u.text; int text_len = strlen(line->line->u.text); - XftDrawStringUtf8(display->image_draw, &display->fg_color, display->font, x, y, text, text_len); + XftDrawStringUtf8(display->image_draw, &display->fg_color, line->font, x, y, text, text_len); // This is slow, but unlike the method used by libxosd, the result isn't ugly. int outline = line->line->outline_width; for (int dx = -outline; dx <= outline; dx++) for (int dy = -outline; dy <= outline; dy++) if (dx*dx + dy*dy <= outline*outline) - XftDrawStringUtf8(display->mask_draw, &display->mask_color, display->font, x + dx, y + dy, text, text_len); + XftDrawStringUtf8(display->mask_draw, &display->mask_color, line->font, x + dx, y + dy, text, text_len); break; } diff --git a/osdd-run b/osdd-run index fd179e7..aa31d48 100755 --- a/osdd-run +++ b/osdd-run @@ -8,7 +8,7 @@ tmp=$(mktemp) echo "Xft.render: False" > $tmp XENVIRONMENT=$tmp \ ./osdd -D \ - DISPLAY_BY_OUTPUTS default nolog display [ -n d%d ] \ + DISPLAY_BY_OUTPUTS default nolog display [ -n d%d -Ftimes-48:bold -Ftimes-32:bold ] \ FILE default log loglog [ -b -l' ' -m'\n' -T' ' -tiso -cterm ~/.osdd_log ] \ FILE default log loglast [ -l'\n' -tunix -T'\n' -crgbHEX -r ~/.osdd_last ] \ FILE stdout [ -A -l' ' -m'\n' /dev/stdout ] \ -- GitLab