Refactor text rendering

This commit is contained in:
o9000 2017-06-05 16:12:37 +02:00
parent 59c3761455
commit 948bf10bad
3 changed files with 168 additions and 292 deletions

View file

@ -278,156 +278,55 @@ int update_battery()
battery_state.percentage = 100;
}
snprintf(buf_bat_percentage, sizeof(buf_bat_percentage), "%d%%", battery_state.percentage);
if (battery_state.state == BATTERY_FULL) {
strcpy(buf_bat_time, "Full");
} else {
snprintf(buf_bat_time, sizeof(buf_bat_time), "%02d:%02d", battery_state.time.hours, battery_state.time.minutes);
}
return err;
}
int battery_compute_desired_size(void *obj)
{
Battery *battery = (Battery *)obj;
Panel *panel = (Panel *)battery->area.panel;
int bat_percentage_height, bat_percentage_width, bat_percentage_height_ink;
int bat_time_height, bat_time_width, bat_time_height_ink;
snprintf(buf_bat_percentage, sizeof(buf_bat_percentage), "%d%%", battery_state.percentage);
if (battery_state.state == BATTERY_FULL) {
strcpy(buf_bat_time, "Full");
} else {
snprintf(buf_bat_time, sizeof(buf_bat_time), "%02d:%02d", battery_state.time.hours, battery_state.time.minutes);
}
get_text_size2(bat1_font_desc,
&bat_percentage_height_ink,
&bat_percentage_height,
&bat_percentage_width,
panel->area.height,
panel->area.width,
buf_bat_percentage,
strlen(buf_bat_percentage),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
get_text_size2(bat2_font_desc,
&bat_time_height_ink,
&bat_time_height,
&bat_time_width,
panel->area.height,
panel->area.width,
buf_bat_time,
strlen(buf_bat_time),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
if (panel_horizontal) {
int new_size = (bat_percentage_width > bat_time_width) ? bat_percentage_width : bat_time_width;
new_size += 2 * battery->area.paddingxlr + left_right_border_width(&battery->area);
return new_size;
} else {
int new_size = bat_percentage_height + bat_time_height + 2 * battery->area.paddingxlr +
top_bottom_border_width(&battery->area);
return new_size;
}
return text_area_compute_desired_size(&battery->area,
buf_bat_percentage,
buf_bat_time,
bat1_font_desc,
bat2_font_desc);
}
gboolean resize_battery(void *obj)
{
Battery *battery = (Battery *)obj;
Panel *panel = (Panel *)battery->area.panel;
int bat_percentage_height, bat_percentage_width, bat_percentage_height_ink;
int bat_time_height, bat_time_width, bat_time_height_ink;
int ret = 0;
snprintf(buf_bat_percentage, sizeof(buf_bat_percentage), "%d%%", battery_state.percentage);
if (battery_state.state == BATTERY_FULL) {
strcpy(buf_bat_time, "Full");
} else {
snprintf(buf_bat_time, sizeof(buf_bat_time), "%02d:%02d", battery_state.time.hours, battery_state.time.minutes);
}
get_text_size2(bat1_font_desc,
&bat_percentage_height_ink,
&bat_percentage_height,
&bat_percentage_width,
panel->area.height,
panel->area.width,
buf_bat_percentage,
strlen(buf_bat_percentage),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
get_text_size2(bat2_font_desc,
&bat_time_height_ink,
&bat_time_height,
&bat_time_width,
panel->area.height,
panel->area.width,
buf_bat_time,
strlen(buf_bat_time),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
if (panel_horizontal) {
int new_size = (bat_percentage_width > bat_time_width) ? bat_percentage_width : bat_time_width;
new_size += 2 * battery->area.paddingxlr + left_right_border_width(&battery->area);
if (new_size > battery->area.width || new_size < battery->area.width - 2) {
// we try to limit the number of resize
battery->area.width = new_size;
battery->bat1_posy = (battery->area.height - bat_percentage_height - bat_time_height) / 2;
battery->bat2_posy = battery->bat1_posy + bat_percentage_height;
ret = 1;
}
} else {
int new_size = bat_percentage_height + bat_time_height + 2 * battery->area.paddingxlr +
top_bottom_border_width(&battery->area);
if (new_size > battery->area.height || new_size < battery->area.height - 2) {
battery->area.height = new_size;
battery->bat1_posy = (battery->area.height - bat_percentage_height - bat_time_height - 2) / 2;
battery->bat2_posy = battery->bat1_posy + bat_percentage_height + 2;
ret = 1;
}
}
schedule_redraw(&battery->area);
return ret;
return resize_text_area(&battery->area,
buf_bat_percentage,
buf_bat_time,
bat1_font_desc,
bat2_font_desc,
&battery->bat1_posy,
&battery->bat2_posy);
}
void draw_battery(void *obj, cairo_t *c)
{
Battery *battery = obj;
PangoLayout *layout = pango_cairo_create_layout(c);
pango_layout_set_font_description(layout, bat1_font_desc);
pango_layout_set_width(layout, battery->area.width * PANGO_SCALE);
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
pango_layout_set_text(layout, buf_bat_percentage, strlen(buf_bat_percentage));
cairo_set_source_rgba(c,
battery->font_color.rgb[0],
battery->font_color.rgb[1],
battery->font_color.rgb[2],
battery->font_color.alpha);
pango_cairo_update_layout(c, layout);
draw_text(layout, c, 0, battery->bat1_posy, &battery->font_color, ((Panel *)battery->area.panel)->font_shadow);
pango_layout_set_font_description(layout, bat2_font_desc);
pango_layout_set_indent(layout, 0);
pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
pango_layout_set_text(layout, buf_bat_time, strlen(buf_bat_time));
pango_layout_set_width(layout, battery->area.width * PANGO_SCALE);
pango_cairo_update_layout(c, layout);
draw_text(layout, c, 0, battery->bat2_posy, &battery->font_color, ((Panel *)battery->area.panel)->font_shadow);
pango_cairo_show_layout(c, layout);
g_object_unref(layout);
Battery *battery = (Battery *)obj;
draw_text_area(&battery->area,
c,
buf_bat_percentage,
buf_bat_time,
bat1_font_desc,
bat2_font_desc,
battery->bat1_posy,
battery->bat2_posy,
&battery->font_color);
}
void battery_dump_geometry(void *obj, int indent)
{
Battery *battery = obj;
Battery *battery = (Battery *)obj;
fprintf(stderr, "%*sText 1: y = %d, text = %s\n", indent, "", battery->bat1_posy, buf_bat_percentage);
fprintf(stderr, "%*sText 2: y = %d, text = %s\n", indent, "", battery->bat2_posy, buf_bat_time);
}

View file

@ -337,6 +337,7 @@ gboolean resize_button(void *obj)
{
Button *button = (Button *)obj;
Panel *panel = (Panel *)button->area.panel;
Area *area = &button->area;
int horiz_padding = (panel_horizontal ? button->area.paddingxlr : button->area.paddingy);
int vert_padding = (panel_horizontal ? button->area.paddingy : button->area.paddingxlr);
int interior_padding = button->area.paddingx;
@ -360,34 +361,29 @@ gboolean resize_button(void *obj)
if (button->frontend->icon_load_size != button->frontend->iconw)
button_reload_icon(button);
int available_w, available_h;
if (panel_horizontal) {
available_w = panel->area.width;
available_h = area->height - 2 * area->paddingy - left_right_border_width(area);
} else {
available_w =
area->width - icon_w - (icon_w ? interior_padding : 0) - 2 * horiz_padding - left_right_border_width(area);
available_h = panel->area.height;
}
int txt_height_ink, txt_height, txt_width;
if (button->backend->text) {
if (panel_horizontal) {
get_text_size2(button->backend->font_desc,
&txt_height_ink,
&txt_height,
&txt_width,
panel->area.height,
panel->area.width,
button->backend->text,
strlen(button->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
} else {
get_text_size2(button->backend->font_desc,
&txt_height_ink,
&txt_height,
&txt_width,
panel->area.height,
button->area.width - icon_w - (icon_w ? interior_padding : 0) - 2 * horiz_padding -
left_right_border_width(&button->area),
button->backend->text,
strlen(button->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
}
get_text_size2(button->backend->font_desc,
&txt_height_ink,
&txt_height,
&txt_width,
available_h,
available_w,
button->backend->text,
strlen(button->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
FALSE);
} else {
txt_height_ink = txt_height = txt_width = 0;
}

View file

@ -290,156 +290,138 @@ gboolean reload_icon(Execp *execp)
return FALSE;
}
int execp_compute_desired_size(void *obj)
void execp_compute_icon_text_geometry(Execp *execp,
int *horiz_padding,
int *vert_padding,
int *interior_padding,
int *icon_w,
int *icon_h,
gboolean *text_next_line,
int *txt_height_ink,
int *txt_height,
int *txt_width,
int *new_size,
gboolean *resized)
{
Execp *execp = (Execp *)obj;
Panel *panel = (Panel *)execp->area.panel;
int horiz_padding = (panel_horizontal ? execp->area.paddingxlr : execp->area.paddingy);
int vert_padding = (panel_horizontal ? execp->area.paddingy : execp->area.paddingxlr);
int interior_padding = execp->area.paddingx;
Area *area = &execp->area;
*horiz_padding = (panel_horizontal ? area->paddingxlr : area->paddingy);
*vert_padding = (panel_horizontal ? area->paddingy : area->paddingxlr);
*interior_padding = area->paddingx;
int icon_w, icon_h;
if (reload_icon(execp)) {
if (execp->backend->icon) {
imlib_context_set_image(execp->backend->icon);
icon_w = imlib_image_get_width();
icon_h = imlib_image_get_height();
*icon_w = imlib_image_get_width();
*icon_h = imlib_image_get_height();
} else {
icon_w = icon_h = 0;
*icon_w = *icon_h = 0;
}
} else {
icon_w = icon_h = 0;
*icon_w = *icon_h = 0;
}
int text_next_line = !panel_horizontal && icon_w > execp->area.width / 2;
*text_next_line = !panel_horizontal && *icon_w > area->width / 2;
int available_w, available_h;
if (panel_horizontal) {
available_w = panel->area.width;
available_h = area->height - 2 * area->paddingy - left_right_border_width(area);
} else {
available_w = !text_next_line
? area->width - *icon_w - (*icon_w ? *interior_padding : 0) - 2 * *horiz_padding -
left_right_border_width(area)
: area->width - 2 * *horiz_padding - left_right_border_width(area);
available_h = panel->area.height;
}
get_text_size2(execp->backend->font_desc,
txt_height_ink,
txt_height,
txt_width,
available_h,
available_w,
execp->backend->text,
strlen(execp->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
execp->backend->has_markup);
*resized = FALSE;
if (panel_horizontal) {
*new_size = *txt_width;
if (*icon_w)
*new_size += *interior_padding + *icon_w;
*new_size += 2 * *horiz_padding + left_right_border_width(area);
if (*new_size > area->width || *new_size < (area->width - 6)) {
// we try to limit the number of resize
*new_size += 1;
*resized = TRUE;
}
} else {
if (!*text_next_line) {
*new_size = *txt_height + 2 * *vert_padding + top_bottom_border_width(area);
*new_size = MAX(*new_size, *icon_h + 2 * *vert_padding + top_bottom_border_width(area));
} else {
*new_size = *icon_h + *interior_padding + *txt_height + 2 * *vert_padding + top_bottom_border_width(area);
}
if (*new_size != area->height) {
*resized = TRUE;
}
}
}
int execp_compute_desired_size(void *obj)
{
Execp *execp = (Execp *)obj;
int horiz_padding, vert_padding, interior_padding;
int icon_w, icon_h;
gboolean text_next_line;
int txt_height_ink, txt_height, txt_width;
if (panel_horizontal) {
get_text_size2(execp->backend->font_desc,
&txt_height_ink,
&txt_height,
&txt_width,
panel->area.height,
panel->area.width,
execp->backend->text,
strlen(execp->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
execp->backend->has_markup);
} else {
get_text_size2(execp->backend->font_desc,
&txt_height_ink,
&txt_height,
&txt_width,
panel->area.height,
!text_next_line
? execp->area.width - icon_w - (icon_w ? interior_padding : 0) - 2 * horiz_padding -
left_right_border_width(&execp->area)
: execp->area.width - 2 * horiz_padding - left_right_border_width(&execp->area),
execp->backend->text,
strlen(execp->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
execp->backend->has_markup);
}
int new_size;
gboolean resized;
execp_compute_icon_text_geometry(execp,
&horiz_padding,
&vert_padding,
&interior_padding,
&icon_w,
&icon_h,
&text_next_line,
&txt_height_ink,
&txt_height,
&txt_width,
&new_size,
&resized);
if (panel_horizontal) {
int new_size = txt_width;
if (icon_w)
new_size += interior_padding + icon_w;
new_size += 2 * horiz_padding + left_right_border_width(&execp->area);
return new_size;
} else {
int new_size;
if (!text_next_line) {
new_size = txt_height + 2 * vert_padding + top_bottom_border_width(&execp->area);
new_size = MAX(new_size, icon_h + 2 * vert_padding + top_bottom_border_width(&execp->area));
} else {
new_size =
icon_h + interior_padding + txt_height + 2 * vert_padding + top_bottom_border_width(&execp->area);
}
return new_size;
}
return new_size;
}
gboolean resize_execp(void *obj)
{
Execp *execp = (Execp *)obj;
Panel *panel = (Panel *)execp->area.panel;
int horiz_padding = (panel_horizontal ? execp->area.paddingxlr : execp->area.paddingy);
int vert_padding = (panel_horizontal ? execp->area.paddingy : execp->area.paddingxlr);
int interior_padding = execp->area.paddingx;
int horiz_padding, vert_padding, interior_padding;
int icon_w, icon_h;
if (reload_icon(execp)) {
if (execp->backend->icon) {
imlib_context_set_image(execp->backend->icon);
icon_w = imlib_image_get_width();
icon_h = imlib_image_get_height();
} else {
icon_w = icon_h = 0;
}
} else {
icon_w = icon_h = 0;
}
int text_next_line = !panel_horizontal && icon_w > execp->area.width / 2;
gboolean text_next_line;
int txt_height_ink, txt_height, txt_width;
if (panel_horizontal) {
get_text_size2(execp->backend->font_desc,
&txt_height_ink,
&txt_height,
&txt_width,
panel->area.height,
panel->area.width,
execp->backend->text,
strlen(execp->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
execp->backend->has_markup);
} else {
get_text_size2(execp->backend->font_desc,
&txt_height_ink,
&txt_height,
&txt_width,
panel->area.height,
!text_next_line
? execp->area.width - icon_w - (icon_w ? interior_padding : 0) - 2 * horiz_padding -
left_right_border_width(&execp->area)
: execp->area.width - 2 * horiz_padding - left_right_border_width(&execp->area),
execp->backend->text,
strlen(execp->backend->text),
PANGO_WRAP_WORD_CHAR,
PANGO_ELLIPSIZE_NONE,
execp->backend->has_markup);
}
int new_size;
gboolean resized;
execp_compute_icon_text_geometry(execp,
&horiz_padding,
&vert_padding,
&interior_padding,
&icon_w,
&icon_h,
&text_next_line,
&txt_height_ink,
&txt_height,
&txt_width,
&new_size,
&resized);
if (panel_horizontal)
execp->area.width = new_size;
else
execp->area.height = new_size;
gboolean result = FALSE;
if (panel_horizontal) {
int new_size = txt_width;
if (icon_w)
new_size += interior_padding + icon_w;
new_size += 2 * horiz_padding + left_right_border_width(&execp->area);
if (new_size > execp->area.width || new_size < (execp->area.width - 6)) {
// we try to limit the number of resize
execp->area.width = new_size + 1;
result = TRUE;
}
} else {
int new_size;
if (!text_next_line) {
new_size = txt_height + 2 * vert_padding + top_bottom_border_width(&execp->area);
new_size = MAX(new_size, icon_h + 2 * vert_padding + top_bottom_border_width(&execp->area));
} else {
new_size =
icon_h + interior_padding + txt_height + 2 * vert_padding + top_bottom_border_width(&execp->area);
}
if (new_size != execp->area.height) {
execp->area.height = new_size;
result = TRUE;
}
}
execp->frontend->textw = txt_width;
execp->frontend->texth = txt_height;
if (execp->backend->centered) {
@ -479,13 +461,12 @@ gboolean resize_execp(void *obj)
}
schedule_redraw(&execp->area);
return result;
return resized;
}
void draw_execp(void *obj, cairo_t *c)
{
Execp *execp = obj;
Execp *execp = (Execp *)obj;
PangoLayout *layout = pango_cairo_create_layout(c);
if (execp->backend->has_icon && execp->backend->icon) {
@ -518,7 +499,7 @@ void draw_execp(void *obj, cairo_t *c)
void execp_dump_geometry(void *obj, int indent)
{
Execp *execp = obj;
Execp *execp = (Execp *)obj;
if (execp->backend->has_icon && execp->backend->icon) {
Imlib_Image tmp = imlib_context_get_image();
@ -559,7 +540,7 @@ void execp_force_update(Execp *execp)
void execp_action(void *obj, int button, int x, int y, Time time)
{
Execp *execp = obj;
Execp *execp = (Execp *)obj;
char *command = NULL;
switch (button) {
case 1:
@ -603,7 +584,7 @@ void execp_cmd_completed(Execp *execp, pid_t pid)
void execp_timer_callback(void *arg)
{
Execp *execp = arg;
Execp *execp = (Execp *)arg;
if (!execp->backend->command)
return;
@ -802,7 +783,7 @@ const char *time_to_string(int seconds, char *buffer)
char *execp_get_tooltip(void *obj)
{
Execp *execp = obj;
Execp *execp = (Execp *)obj;
if (execp->backend->tooltip) {
if (strlen(execp->backend->tooltip) > 0)