diff --git a/apps/cpuwidget.c b/apps/cpuwidget.c index 25ff9d18..afa92c8c 100644 --- a/apps/cpuwidget.c +++ b/apps/cpuwidget.c @@ -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)); } diff --git a/apps/file-browser.c b/apps/file-browser.c index 47ee63e0..77223093 100644 --- a/apps/file-browser.c +++ b/apps/file-browser.c @@ -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); diff --git a/apps/panel.c b/apps/panel.c index 3c07382c..cf66ead9 100644 --- a/apps/panel.c +++ b/apps/panel.c @@ -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); diff --git a/base/usr/include/toaru/panel.h b/base/usr/include/toaru/panel.h index 2feec29f..c2248fe2 100644 --- a/base/usr/include/toaru/panel.h +++ b/base/usr/include/toaru/panel.h @@ -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); diff --git a/base/usr/include/toaru/text.h b/base/usr/include/toaru/text.h index 831dd7e4..b8b57c67 100644 --- a/base/usr/include/toaru/text.h +++ b/base/usr/include/toaru/text.h @@ -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. */ diff --git a/lib/decor-fancy.c b/lib/decor-fancy.c index e743b95d..0c105c52 100644 --- a/lib/decor-fancy.c +++ b/lib/decor-fancy.c @@ -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); diff --git a/lib/kuroko/_yutani2.c b/lib/kuroko/_yutani2.c index 5aa723a9..40c3dccc 100644 --- a/lib/kuroko/_yutani2.c +++ b/lib/kuroko/_yutani2.c @@ -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); diff --git a/lib/panel_windowlist.c b/lib/panel_windowlist.c index 857f0acd..ab9e53b1 100644 --- a/lib/panel_windowlist.c +++ b/lib/panel_windowlist.c @@ -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); diff --git a/lib/text.c b/lib/text.c index 979b73ed..8ffe5fd4 100644 --- a/lib/text.c +++ b/lib/text.c @@ -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; +}