text: Unify 'ellipsify' implementation in text library
This commit is contained in:
parent
cb51bff817
commit
aae9596888
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
24
apps/panel.c
24
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);
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
26
lib/text.c
26
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user