Add scalable font support.

This commit is contained in:
John Vogel 2015-05-26 22:29:18 -04:00
parent a9f285fd28
commit 4eba66912f
2 changed files with 92 additions and 8 deletions

View File

@ -6,7 +6,7 @@ lemonbar - Featherweight lemon-scented bar
=head1 SYNOPSIS
I<lemonbar> [-h | -g I<width>B<x>I<height>B<+>I<x>B<+>I<y> | -b | -d | -f I<font> | -p | -u I<pixel> | -B I<color> | -F I<color>]
I<lemonbar> [-h | -g I<width>B<x>I<height>B<+>I<x>B<+>I<y> | -b | -d | -s | -f I<font> | -p | -u I<pixel> | -B I<color> | -F I<color>]
=head1 DESCRIPTION
@ -32,6 +32,10 @@ Dock the bar at the bottom of the screen.
Force docking without asking the window manager. This is needed if the window manager isn't EWMH compliant.
=item B<-s>
Scale fonts. Must be ahead of any I<font> that should be scaled. A way to scale some but not all fonts is to put unscaled fonts before using I<-s>, then place all scaled fonts after using I<-s>.
=item B<-f> I<font>
Define the font to load into one of the five slots (the number of slots is hardcoded and can be tweaked by

View File

@ -88,6 +88,7 @@ static monitor_t *monhead, *montail;
static font_t *font_list[MAX_FONT_COUNT];
static int font_count = 0;
static int font_index = -1;
static int scale_fonts = 0;
static uint32_t attrs = 0;
static bool dock = false;
static bool topbar = true;
@ -609,6 +610,68 @@ parse (char *text)
}
}
char *
scale_font(const char *name)
{
char *newname;
size_t sz;
int i, j, field;
int res_x, res_y;
unsigned long pixel_size = 0L;
if (!name || !*name)
return NULL;
sz = strlen(name) * 2; /* make big enough to avoid overflows */
newname = malloc(sz+1);
if (!newname) {
fprintf(stderr, "Failed to allocate new scalable fontname\n");
exit(EXIT_FAILURE);
}
/* calculate our screen resolution in dots per inch */
res_x = scr->width_in_pixels / (scr->width_in_millimeters / 25.4);
res_y = scr->height_in_pixels / (scr->height_in_millimeters / 25.4);
/* copy the font name, changing the scalable fields as we go */
for (i = j = field = 0; name[i] && field <= 14; i++) {
newname[j++] = name[i];
if (name[i] == '-') {
field++;
switch (field) {
case 7: /* pixel size */
pixel_size = strtoul(&name[i+1], NULL, 10);
case 12: /* average width */
newname[j] = '*';
j++;
while (name[i+1] != '-' && name[i+1] != '\0') i++;
break;
case 8: /* point size */
snprintf(&newname[j], sz-j, "%ld", pixel_size * 10);
while (newname[j] != '\0') j++;
while (name[i+1] != '-' && name[i+1] != '\0') i++;
break;
case 9: /* x resolution */
case 10: /* y resolution */
/* change from an unspecified resolution to res_x or res_y */
snprintf(&newname[j], sz-j, "%d", (field == 9) ? res_x : res_y);
while (newname[j] != '\0') j++;
while (name[i+1] != '-' && name[i+1] != '\0') i++;
break;
}
}
}
if (field != 14) {
printf("font name has invalid number of fields(%d): %s\n", field, name);
return NULL;
}
newname[j] = '\0';
return newname;
}
void
font_load (const char *pattern)
{
@ -616,19 +679,32 @@ font_load (const char *pattern)
xcb_query_font_reply_t *font_info;
xcb_void_cookie_t cookie;
xcb_font_t font;
int is_scaled = false;
char *fontname = NULL;
if (scale_fonts)
fontname = scale_font(pattern);
if (fontname)
is_scaled = true;
else
fontname = (char *)pattern;
font = xcb_generate_id(c);
cookie = xcb_open_font_checked(c, font, strlen(pattern), pattern);
cookie = xcb_open_font_checked(c, font, strlen(fontname), fontname);
if (xcb_request_check (c, cookie)) {
fprintf(stderr, "Could not load font \"%s\"\n", pattern);
fprintf(stderr, "Could not load font \"%s\"\n", fontname);
if (is_scaled)
free(fontname);
return;
}
font_t *ret = calloc(1, sizeof(font_t));
if (!ret)
return;
if (!ret) {
fprintf(stderr, "Failed to allocate space for font\n");
exit(EXIT_FAILURE);
}
queryreq = xcb_query_font(c, font);
font_info = xcb_query_font_reply(c, queryreq, NULL);
@ -648,6 +724,8 @@ font_load (const char *pattern)
}
free(font_info);
if (is_scaled)
free(fontname);
font_list[font_count++] = ret;
}
@ -1214,15 +1292,16 @@ main (int argc, char **argv)
ugc = fgc;
while ((ch = getopt(argc, argv, "hg:bdf:a:pu:B:F:")) != -1) {
while ((ch = getopt(argc, argv, "hg:bdsf:a:pu:B:F:")) != -1) {
switch (ch) {
case 'h':
printf ("lemonbar version %s\n", VERSION);
printf ("usage: %s [-h | -g | -b | -d | -f | -a | -p | -u | -B | -F]\n"
printf ("usage: %s [-h | -g | -b | -d | -s | -f | -a | -p | -u | -B | -F]\n"
"\t-h Show this help\n"
"\t-g Set the bar geometry {width}x{height}+{xoffset}+{yoffset}\n"
"\t-b Put the bar at the bottom of the screen\n"
"\t-d Force docking (use this if your WM isn't EWMH compliant)\n"
"\t-s Scale fonts\n"
"\t-f Set the font name to use\n"
"\t-p Don't close after the data ends\n"
"\t-u Set the underline/overline height in pixels\n"
@ -1233,6 +1312,7 @@ main (int argc, char **argv)
case 'p': permanent = true; break;
case 'b': topbar = false; break;
case 'd': dock = true; break;
case 's': scale_fonts = 1; break;
case 'f': font_load(optarg); break;
case 'u': bu = strtoul(optarg, NULL, 10); break;
case 'B': dbgc = bgc = parse_color(optarg, NULL, (rgba_t)scr->black_pixel); break;