add font.family=<string>, font.style=<string>, font.size=<float> subdomains to texts for better font handling

This commit is contained in:
Felix Kratz 2023-03-26 23:44:00 +02:00
parent 6d2b3c2a34
commit e7461b4bb5
7 changed files with 202 additions and 85 deletions

View file

@ -4,8 +4,8 @@ ODIR = bin
SRC = src
_OBJ = alias.o background.o bar_item.o custom_events.o event.o graph.o \
image.o mouse.o shadow.o text.o message.o mouse.o bar.o window.o \
bar_manager.o display.o event_loop.o group.o mach.o popup.o \
image.o mouse.o shadow.o font.o text.o message.o mouse.o bar.o \
window.o bar_manager.o display.o event_loop.o group.o mach.o popup.o \
animation.o workspace.om volume.o slider.o power.o wifi.om
OBJ = $(patsubst %, $(ODIR)/%, $(_OBJ))

View file

@ -670,16 +670,9 @@ void bar_item_inherit_from_item(struct bar_item* bar_item, struct bar_item* ance
bar_item->script = script;
bar_item->click_script = click_script;
text_set_font(&bar_item->icon, string_copy(ancestor->icon.font_name), true);
text_set_font(&bar_item->label, string_copy(ancestor->label.font_name),true);
text_set_string(&bar_item->icon, string_copy(ancestor->icon.string), true);
text_set_string(&bar_item->label, string_copy(ancestor->label.string), true);
text_set_font(&bar_item->slider.knob,
string_copy(ancestor->slider.knob.font_name), true);
text_set_string(&bar_item->slider.knob,
string_copy(ancestor->slider.knob.string), true);
text_copy(&bar_item->icon, &ancestor->icon);
text_copy(&bar_item->label, &ancestor->label);
text_copy(&bar_item->slider.knob, &ancestor->slider.knob);
if (ancestor->script)
bar_item_set_script(bar_item, string_copy(ancestor->script));

137
src/font.c Normal file
View file

@ -0,0 +1,137 @@
#include "font.h"
#include "animation.h"
#include "bar_manager.h"
void font_create_ctfont(struct font* font) {
CFStringRef family_ref = CFStringCreateWithCString(NULL,
font->family,
kCFStringEncodingUTF8);
CFStringRef style_ref = CFStringCreateWithCString(NULL,
font->style,
kCFStringEncodingUTF8);
CFNumberRef size_ref = CFNumberCreate(NULL,
kCFNumberFloat32Type,
&font->size );
const void *keys[] = { kCTFontFamilyNameAttribute,
kCTFontStyleNameAttribute,
kCTFontSizeAttribute };
const void *values[] = { family_ref, style_ref, size_ref };
CFDictionaryRef attr = CFDictionaryCreate(NULL,
keys,
values,
array_count(keys),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes(attr);
if (font->ct_font) CFRelease(font->ct_font);
font->ct_font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL);
CFRelease(descriptor);
CFRelease(attr);
CFRelease(size_ref);
CFRelease(style_ref);
CFRelease(family_ref);
}
void font_init(struct font* font) {
font->size = 14.f;
font->style = string_copy("Bold");
font->family = string_copy("Hack Nerd Font");
font_create_ctfont(font);
}
bool font_set_style(struct font* font, char* style, bool forced) {
if (!style) return false;
if (!forced && font->style && string_equals(font->style, style)) {
free(style);
return false;
}
if (font->style && style != font->style) free(font->style);
font->style = style;
font->font_changed = true;
return true;
}
bool font_set_family(struct font* font, char* family, bool forced) {
if (!family) return false;
if (!forced && font->family && string_equals(font->family, family)) {
free(family);
return false;
}
if (font->family) free(font->family);
font->family = family;
font->font_changed = true;
return true;
}
bool font_set_size(struct font* font, float size) {
if (font->size == size) return false;
font->size = size;
font->font_changed = true;
return true;
}
bool font_set(struct font* font, char* font_string, bool forced) {
if (!font_string) return false;
float size = 10.0f;
char font_properties[2][255] = { {}, {} };
sscanf(font_string,
"%254[^:]:%254[^:]:%f",
font_properties[0],
font_properties[1],
&size );
free(font_string);
bool change = font_set_family(font, string_copy(font_properties[0]), forced);
change |= font_set_style(font, string_copy(font_properties[1]), forced);
change |= font_set_size(font, size);
return change;
}
void font_clear_pointers(struct font* font) {
font->ct_font = NULL;
font->family = NULL;
font->style = NULL;
}
void font_destroy(struct font* font) {
if (font->style) free(font->style);
if (font->family) free(font->family);
if (font->ct_font) CFRelease(font->ct_font);
font_clear_pointers(font);
}
bool font_parse_sub_domain(struct font* font, FILE* rsp, struct token property, char* message) {
bool needs_refresh = false;
if (token_equals(property, PROPERTY_FONT_SIZE)) {
struct token token = get_token(&message);
ANIMATE_FLOAT(font_set_size,
font,
font->size,
token_to_float(token));
} else if (token_equals(property, PROPERTY_FONT_FAMILY)) {
struct token token = get_token(&message);
needs_refresh = font_set_family(font, token_to_string(token), false);
} else if (token_equals(property, PROPERTY_FONT_STYLE)) {
struct token token = get_token(&message);
needs_refresh = font_set_style(font, token_to_string(token), false);
} else {
respond(rsp, "[!] Text: Invalid property '%s'\n", property.text);
}
return needs_refresh;
}

23
src/font.h Normal file
View file

@ -0,0 +1,23 @@
#pragma once
#include <CoreText/CoreText.h>
#include "misc/helpers.h"
struct font {
CTFontRef ct_font;
bool font_changed;
float size;
char* family;
char* style;
};
void font_init(struct font* font);
void font_destroy(struct font* font);
bool font_set(struct font* font, char* font_string, bool forced);
bool font_set_size(struct font* font, float size);
bool font_set_family(struct font* font, char* family, bool forced);
bool font_set_style(struct font* font, char* style, bool forced);
void font_create_ctfont(struct font* font);
void font_clear_pointers(struct font* font);
bool font_parse_sub_domain(struct font* font, FILE* rsp, struct token property, char* message);

View file

@ -40,6 +40,7 @@
#define SUB_DOMAIN_IMAGE "image"
#define SUB_DOMAIN_KNOB "knob"
#define SUB_DOMAIN_SLIDER "slider"
#define SUB_DOMAIN_FONT "font"
#define PROPERTY_FONT "font"
#define PROPERTY_COLOR "color"
@ -61,6 +62,10 @@
#define PROPERTY_SCALE "scale"
#define PROPERTY_STRING "string"
#define PROPERTY_FONT_FAMILY "family"
#define PROPERTY_FONT_STYLE "style"
#define PROPERTY_FONT_SIZE "size"
#define PROPERTY_UPDATES "updates"
#define PROPERTY_POSITION "position"
#define PROPERTY_ASSOCIATED_DISPLAY "associated_display"

View file

@ -1,54 +1,15 @@
#include "text.h"
#include "bar_manager.h"
static CTFontRef text_create_font(char *cstring) {
float size = 10.0f;
char font_properties[2][255] = { {}, {} };
sscanf(cstring,
"%254[^:]:%254[^:]:%f",
font_properties[0],
font_properties[1],
&size );
CFStringRef font_family_name = CFStringCreateWithCString(NULL,
font_properties[0],
kCFStringEncodingUTF8);
CFStringRef font_style_name = CFStringCreateWithCString(NULL,
font_properties[1],
kCFStringEncodingUTF8);
CFNumberRef font_size = CFNumberCreate(NULL, kCFNumberFloat32Type, &size);
const void *keys[] = { kCTFontFamilyNameAttribute,
kCTFontStyleNameAttribute,
kCTFontSizeAttribute };
const void *values[] = { font_family_name, font_style_name, font_size };
CFDictionaryRef attributes = CFDictionaryCreate(NULL,
keys,
values,
array_count(keys),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes(attributes);
CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL);
CFRelease(descriptor);
CFRelease(attributes);
CFRelease(font_size);
CFRelease(font_style_name);
CFRelease(font_family_name);
return font;
}
static void text_prepare_line(struct text* text) {
const void *keys[] = { kCTFontAttributeName,
kCTForegroundColorFromContextAttributeName };
const void *values[] = { text->font, kCFBooleanTrue };
if (text->font.font_changed) {
font_create_ctfont(&text->font);
text->font.font_changed = false;
}
const void *values[] = { text->font.ct_font, kCFBooleanTrue };
CFDictionaryRef attributes = CFDictionaryCreate(NULL,
keys,
values,
@ -107,21 +68,16 @@ bool text_set_string(struct text* text, char* string, bool forced) {
return true;
}
void text_copy(struct text* text, struct text* source) {
font_set_family(&text->font, string_copy(source->font.family), true);
font_set_style(&text->font, string_copy(source->font.style), true);
font_set_size(&text->font, source->font.size);
text_set_string(text, string_copy(source->string), true);
}
bool text_set_font(struct text* text, char* font_string, bool forced) {
if (!font_string) return false;
if (!forced && text->font_name
&& strcmp(text->font_name, font_string) == 0) {
free(font_string);
return false;
}
if (font_string != text->font_name && text->font_name)
free(text->font_name);
if (text->font) CFRelease(text->font);
text->font = text_create_font(font_string);
text->font_name = font_string;
return text_set_string(text, text->string, true);
bool changed = font_set(&text->font, font_string, forced);
return changed;
}
void text_init(struct text* text) {
@ -137,13 +93,11 @@ void text_init(struct text* text) {
text->color = rgba_color_from_hex(0xffffffff);
text->highlight_color = rgba_color_from_hex(0xff000000);
text->font = NULL;
text->string = string_copy("");
text->font_name = string_copy("Hack Nerd Font:Bold:14.0");
text_set_font(text, text->font_name, true);
text_set_string(text, text->string, false);
shadow_init(&text->shadow);
background_init(&text->background);
font_init(&text->font);
}
static bool text_update_color(struct text* text) {
@ -205,14 +159,18 @@ static bool text_set_width(struct text* text, int width) {
void text_clear_pointers(struct text* text) {
text->string = NULL;
text->font_name = NULL;
text->font = NULL;
text->line.line = NULL;
background_clear_pointers(&text->background);
font_clear_pointers(&text->font);
}
uint32_t text_get_length(struct text* text, bool override) {
if (!text->drawing) return 0;
if (text->font.font_changed) {
text_set_string(text, text->string, true);
}
int len = text->bounds.size.width + text->padding_left + text->padding_right;
if ((!text->has_const_width || override)
&& text->background.enabled
@ -232,9 +190,9 @@ uint32_t text_get_height(struct text* text) {
void text_destroy(struct text* text) {
background_destroy(&text->background);
font_destroy(&text->font);
if (text->string) free(text->string);
if (text->font_name) free(text->font_name);
if (text->font) CFRelease(text->font);
text_destroy_line(text);
text_clear_pointers(text);
}
@ -327,7 +285,7 @@ void text_serialize(struct text* text, char* indent, FILE* rsp) {
"%s\"padding_left\": %d,\n"
"%s\"padding_right\": %d,\n"
"%s\"y_offset\": %d,\n"
"%s\"font\": \"%s\",\n"
"%s\"font\": \"%s:%s:%.2f\",\n"
"%s\"width\": %d,\n"
"%s\"align\": \"%s\",\n"
"%s\"background\": {\n",
@ -339,9 +297,9 @@ void text_serialize(struct text* text, char* indent, FILE* rsp) {
indent, text->padding_left,
indent, text->padding_right,
indent, text->y_offset,
indent, text->font_name,
indent, text->font.family, text->font.style, text->font.size,
indent, text->custom_width,
indent, align, indent );
indent, align, indent );
char deeper_indent[strlen(indent) + 2];
snprintf(deeper_indent, strlen(indent) + 2, "%s\t", indent);
@ -461,9 +419,10 @@ bool text_parse_sub_domain(struct text* text, FILE* rsp, struct token property,
return background_parse_sub_domain(&text->background, rsp, entry, message);
else if (token_equals(subdom, SUB_DOMAIN_SHADOW))
return shadow_parse_sub_domain(&text->shadow, rsp, entry, message);
else {
else if (token_equals(subdom, SUB_DOMAIN_FONT))
return font_parse_sub_domain(&text->font, rsp, entry, message);
else
respond(rsp, "[!] Text: Invalid subdomain '%s' \n", subdom.text);
}
}
else {
respond(rsp, "[!] Text: Invalid property '%s'\n", property.text);

View file

@ -1,7 +1,7 @@
#pragma once
#include <CoreText/CoreText.h>
#include "background.h"
#include "misc/helpers.h"
#include "font.h"
struct text_line {
CTLineRef line;
@ -17,7 +17,6 @@ struct text {
char align;
char* string;
char* font_name;
int y_offset;
int padding_left;
@ -25,8 +24,8 @@ struct text {
uint32_t custom_width;
CGRect bounds;
CTFontRef font;
struct font font;
struct text_line line;
struct rgba_color color;
struct rgba_color highlight_color;
@ -41,6 +40,7 @@ uint32_t text_get_length(struct text* text, bool override);
uint32_t text_get_height(struct text* text);
bool text_set_string(struct text* text, char* string, bool forced);
bool text_set_font(struct text* text, char* font_string, bool forced);
void text_copy(struct text* text, struct text* source);
void text_calculate_bounds(struct text* text, uint32_t x, uint32_t y);
void text_draw(struct text* text, CGContextRef context);