text: Unify 'ellipsify' implementation in text library

This commit is contained in:
K. Lange 2023-06-07 10:15:31 +09:00
parent cb51bff817
commit aae9596888
9 changed files with 60 additions and 92 deletions

View File

@ -358,25 +358,6 @@ static void next_net(gfx_context_t * ctx) {
ticks_last = ticks_now;
}
static char * ellipsify(char * input, int font_size, struct TT_Font * font, int max_width, int * out_width) {
int len = strlen(input);
char * out = malloc(len + 4);
memcpy(out, input, len + 1);
int width;
tt_set_size(font, font_size);
while ((width = tt_string_width(font, out)) > max_width) {
len--;
out[len+0] = '.';
out[len+1] = '.';
out[len+2] = '.';
out[len+3] = '\0';
}
if (out_width) *out_width = width;
return out;
}
static void draw_legend_element(int which, int count, int index, uint32_t color, char * label) {
struct decor_bounds bounds;
decor_get_bounds(wina, &bounds);
@ -399,7 +380,7 @@ static void draw_legend_element(int which, int count, int index, uint32_t color,
unit_x, y, 20, 20, 5, color);
if (unit_width > 22) {
char * label_cropped = ellipsify(label, 12, tt_thin, unit_width - 22, NULL);
char * label_cropped = tt_ellipsify(label, 12, tt_thin, unit_width - 22, NULL);
tt_draw_string(ctx_base, tt_thin, 22 + unit_x, y + 14, label_cropped, rgb(0,0,0));
}

View File

@ -210,28 +210,6 @@ static int print_human_readable_size(char * _out, uint64_t s) {
#define HILIGHT_GRADIENT_BOTTOM rgb(56,137,220)
#define HILIGHT_BORDER_BOTTOM rgb(47,106,167)
/**
* Clip text and add ellipsis to fit a specified display width.
*/
static char * ellipsify(char * input, int font_size, struct TT_Font * font, int max_width, int * out_width) {
int len = strlen(input);
char * out = malloc(len + 4);
memcpy(out, input, len + 1);
int width;
tt_set_size(font, font_size);
while ((width = tt_string_width(font, out)) > max_width) {
len--;
out[len+0] = '.';
out[len+1] = '.';
out[len+2] = '.';
out[len+3] = '\0';
}
if (out_width) *out_width = width;
return out;
}
/**
* Draw an icon view entry
*/
@ -249,7 +227,7 @@ static void draw_file(struct File * f, int offset) {
/* If the display name is too long to fit, cut it with an ellipsis. */
int name_width;
char * name = ellipsify(f->name, 13, tt_font_thin, FILE_WIDTH - 8, &name_width);
char * name = tt_ellipsify(f->name, 13, tt_font_thin, FILE_WIDTH - 8, &name_width);
/* Draw the icon */
int center_x_icon = (FILE_WIDTH - icon->width) / 2;
@ -309,8 +287,8 @@ static void draw_file(struct File * f, int offset) {
draw_sprite_alpha_paint(contents, icon, x + 11, y + 11, 0.3, rgb(255,255,255));
}
char * name = ellipsify(f->name, 13, tt_font_bold, FILE_WIDTH - 81, NULL);
char * type = ellipsify(f->filetype, 13, tt_font_thin, FILE_WIDTH - 81, NULL);
char * name = tt_ellipsify(f->name, 13, tt_font_bold, FILE_WIDTH - 81, NULL);
char * type = tt_ellipsify(f->filetype, 13, tt_font_thin, FILE_WIDTH - 81, NULL);
if (f->type == 0) {
tt_set_size(tt_font_bold, 13);
@ -356,7 +334,7 @@ static void draw_file(struct File * f, int offset) {
draw_sprite(contents, icon, x + 4, y + 4);
}
char * name = ellipsify(f->name, 13, tt_font_thin, FILE_WIDTH - 26, NULL);
char * name = tt_ellipsify(f->name, 13, tt_font_thin, FILE_WIDTH - 26, NULL);
tt_set_size(tt_font_thin, 13);
tt_draw_string(contents, tt_font_thin, x + 24, y + 15, name, text_color);
@ -961,7 +939,7 @@ static void _draw_nav_bar(struct decor_bounds bounds) {
/* Draw the nav bar text, ellipsified if needed */
int max_width = main_window->width - bounds.width - x - 12;
char * name = ellipsify(nav_bar, 13, tt_font_thin, max_width, NULL);
char * name = tt_ellipsify(nav_bar, 13, tt_font_thin, max_width, NULL);
tt_draw_string(ctx, tt_font_thin, bounds.left_width + 2 + x + 5, bounds.top_height + menu_bar_height + 8 + 13, name, rgb(0,0,0));
free(name);

View File

@ -91,28 +91,6 @@ static int new_focused = -1;
static void widgets_layout(void);
/**
* Clip text and add ellipsis to fit a specified display width.
*/
char * ellipsify(char * input, int font_size, struct TT_Font * font, int max_width, int * out_width) {
int len = strlen(input);
char * out = malloc(len + 4);
memcpy(out, input, len + 1);
int width;
tt_set_size(font, font_size);
while ((width = tt_string_width(font, out)) > max_width) {
len--;
out[len+0] = '.';
out[len+1] = '.';
out[len+2] = '.';
out[len+3] = '\0';
}
if (out_width) *out_width = width;
return out;
}
static int _close_enough(struct yutani_msg_window_mouse_event * me) {
if (me->command == YUTANI_MOUSE_EVENT_RAISE && sqrt(pow(me->new_x - me->old_x, 2) + pow(me->new_y - me->old_y, 2)) < 10) {
return 1;
@ -342,7 +320,7 @@ static void redraw_alttab(void) {
{
struct window_ad * ad = ads_by_z[new_focused];
int t;
char * title = ellipsify(ad->name, 16, panel_context.font, alttab->width - 20, &t);
char * title = tt_ellipsify(ad->name, 16, panel_context.font, alttab->width - 20, &t);
tt_set_size(panel_context.font, 16);
tt_draw_string(actx, panel_context.font, center_x_a(t), rows * (ALTTAB_WIN_SIZE + 20) + 44, title, rgb(255,255,255));
free(title);

View File

@ -75,7 +75,6 @@ struct window_ad {
extern struct window_ad * ads_by_z[];
extern list_t * window_list;
extern void redraw(void);
extern char * ellipsify(char * input, int font_size, struct TT_Font * font, int max_width, int * out_width);
extern int panel_menu_show(struct PanelWidget * this, struct MenuList * menu);
extern int panel_menu_show_at(struct MenuList * menu, int x);
extern void panel_highlight_widget(struct PanelWidget * this, gfx_context_t * ctx, int active);

View File

@ -55,6 +55,9 @@ extern struct TT_Contour * tt_prepare_string_into(struct TT_Contour * contour, s
extern void tt_path_paint_sprite(gfx_context_t * ctx, const struct TT_Shape * shape, sprite_t * sprite, gfx_matrix_t matrix);
extern void tt_path_paint_sprite_options(gfx_context_t * ctx, const struct TT_Shape * shape, sprite_t * sprite, gfx_matrix_t matrix, int filter, int wrap);
/* Truncate text with an ellipsis to fit a requested width. */
extern char * tt_ellipsify(const char * input, int font_size, struct TT_Font * font, int max_width, int * out_width);
/* Path painting options */
#define TT_PATH_FILTER_BILINEAR 0 /* Bilinear filter. Good quality, slow. Default. */
#define TT_PATH_FILTER_NEAREST 1 /* Nearest neighbor. Low quality, fast. */

View File

@ -121,25 +121,6 @@ static int get_bounds_fancy(yutani_window_t * window, struct decor_bounds * boun
return 0;
}
static char * ellipsify(char * input, int font_size, struct TT_Font * font, int max_width, int * out_width) {
int len = strlen(input);
char * out = malloc(len + 4);
memcpy(out, input, len + 1);
int width;
tt_set_size(font, font_size);
while ((width = tt_string_width(font, out)) > max_width) {
len--;
out[len+0] = '.';
out[len+1] = '.';
out[len+2] = '.';
out[len+3] = '\0';
}
if (out_width) *out_width = width;
return out;
}
#define BUTTON_PAD 5
static void render_decorations_fancy(yutani_window_t * window, gfx_context_t * ctx, char * title, int decors_active) {
@ -231,7 +212,7 @@ static void render_decorations_fancy(yutani_window_t * window, gfx_context_t * c
if (title_width > usable_width) {
usable_width += buttons_width * TOTAL_SCALE;
if (usable_width > 0) {
char * tmp_title = ellipsify(title, 12 * TOTAL_SCALE, _tt_font, usable_width, &title_width);
char * tmp_title = tt_ellipsify(title, 12 * TOTAL_SCALE, _tt_font, usable_width, &title_width);
int title_offset = bounds.left_width + 10 * TOTAL_SCALE;
tt_draw_string(ctx, _tt_font, title_offset, (TEXT_OFFSET + 14) * TOTAL_SCALE, tmp_title, title_color);
free(tmp_title);

View File

@ -1128,6 +1128,27 @@ KRK_Method(Font,prepare_string) {
return krk_pop();
}
KRK_Method(Font,ellipsify) {
const char * s;
int max_width;
if (!krk_parseArgs(".si", (const char*[]){"s","w"},
&s, &max_width)) return NONE_VAL();
int out_width = 0;
char * out = tt_ellipsify(s, self->fontSize, self->fontData, max_width, &out_width);
KrkTuple * out_tuple = krk_newTuple(2);
krk_push(OBJECT_VAL(out_tuple));
out_tuple->values.values[out_tuple->values.count++] = OBJECT_VAL(krk_copyString(out, strlen(out)));
out_tuple->values.values[out_tuple->values.count++] = INTEGER_VAL(out_width);
free(out);
return krk_pop();
}
#undef CURRENT_CTYPE
WRAP_TYPE(MenuBar,struct menu_bar,menuBar);
@ -2086,6 +2107,7 @@ KrkValue krk_module_onload__yutani2(void) {
BIND_METHOD(Font,measure);
BIND_METHOD(Font,draw_glyph_into);
BIND_METHOD(Font,prepare_string);
BIND_METHOD(Font,ellipsify);
BIND_PROP(Font,size);
krk_finalizeClass(Font);

View File

@ -92,7 +92,7 @@ static int widget_draw_windowlist(struct PanelWidget * this, gfx_context_t * ctx
if (title_width >= MIN_TEXT_WIDTH) {
/* Ellipsifiy the title */
char * s = ellipsify(ad->name, 14, this->pctx->font, title_width - 4, NULL);
char * s = tt_ellipsify(ad->name, 14, this->pctx->font, title_width - 4, NULL);
sprite_t * icon = icon_get_48(ad->icon);
gfx_context_t * subctx = init_graphics_subregion(ctx, i, 0, w, ctx->height-1);
draw_sprite_scaled_alpha(subctx, icon, w - 48 - 2, 0, 48, 48, (ad->flags & 1) ? 1.0 : 0.7);

View File

@ -1424,3 +1424,29 @@ void tt_path_paint_sprite_options(gfx_context_t * ctx, const struct TT_Shape * s
tt_path_paint_sprite_internal(ctx,shape,sprite,matrix,sprite_interp,pixel_getter);
}
char * tt_ellipsify(const char * input, int font_size, struct TT_Font * font, int max_width, int * out_width) {
int width;
int len = strlen(input);
char * out = malloc(len + 4);
if (max_width <= 0) {
out[0] = '\0';
width = 0;
goto _finish;
}
memcpy(out, input, len + 1);
tt_set_size(font, font_size);
while ((width = tt_string_width(font, out)) > max_width) {
len--;
if (len+0>=0) out[len+0] = '.';
if (len+1>=0) out[len+1] = '.';
if (len+2>=0) out[len+2] = '.';
out[len+3] = '\0';
}
_finish:
if (out_width) *out_width = width;
return out;
}