forked from enlightenment/efl
evas_textblock: content fit feature
Summary: **Content Fit Feature for Evas_Object_Textblock** This Feature is available at **Evas **object level. And **Edje **level (where it is internally use evas functionality) This feature will allow text block to fit its content font size to proper size to fit its area. **Main Properties:** Fit Modes : None=Default, Width, Height, All [Width+Height] Fit Size Range : Contains maximum and minimum font size to be used (and in between). Fit Step Size : Step(Jump) value when trying fonts sizes between Size_Range max and min. Fit Size Array : Other way to resize font, where you explicitly select font sizes to be uses (for example [20, 50, 100] it will try 3 sizes only) Text Fit feature was available in Edje but: 1- It doesn't effected by ellipsis or warping in font style (or do not handle the in right way) 2- Accuracy is not good (specially if you have fix pixel size elements (spaces,tabs,items)) 3- No (Step size, Size Array) available. Test Plan: To check the Feature > elementary_test > fit > textbock fit You can modify all the modes and properties These are two examples, One using Evas other uses Edje **Evas** ``` #include <Elementary.h> enum BUTTON{ BUTTON_MODE = 0, BUTTON_MAX = 1, BUTTON_MIN = 2, BUTTON_STEP = 3, BUTTON_ARRAY = 4, BUTTON_CONTENT = 5, BUTTON_STYLE = 6, BUTTON_ALL = BUTTON_STYLE+1, }; char* BUTTON_STR[BUTTON_ALL] ={ "MODE", "MAX", "MIN", "STEP", "ARRAY", "CONTENT", "STYLE", }; char *contents[] = { "Hello World", "This is Line<br>THis is other Line", "This text contains <font_size=20 color=#F00>SPECIFIC SIZE</font_size> that does not effected by fit mode" }; char *styles[] = { "DEFAULT='font=sans font_size=30 color=#000 wrap=mixed ellipsis=1.0'", "DEFAULT='font=sans font_size=30 color=#000 wrap=mixed'", "DEFAULT='font=sans font_size=30 color=#000 ellipsis=1.0'", "DEFAULT='font=sans font_size=30 color=#000'", }; char *styles_names[] = { "wrap=<color=#F00>mixed</color> ellipsis=<color=#F00>1.0</color>", "wrap=<color=#F00>mixed</color> ellipsis=<color=#F00>NONE</color>", "wrap=<color=#F00>NONE</color> ellipsis=<color=#F00>1.0</color>", "wrap=<color=#F00>NONE</color> ellipsis=<color=#F00>NONE</color>", }; typedef struct _APP { Evas_Object *win, *box, *txtblock,*bg, *boxHor, *boxHor2; Eo *btn[BUTTON_ALL]; Eo *lbl_status; char * str; unsigned int i_contnet, i_style; } APP; APP *app; char * get_fit_status(Eo * textblock); static void _btn_clicked(void *data EINA_UNUSED, Eo *obj, void *eventInfo EINA_UNUSED){ if (obj == app->btn[BUTTON_MODE]) { unsigned int options; evas_textblock_fit_options_get(app->txtblock, &options); if (options == TEXTBLOCK_FIT_MODE_NONE) evas_textblock_fit_options_set(app->txtblock, TEXTBLOCK_FIT_MODE_HEIGHT); else if (options == TEXTBLOCK_FIT_MODE_HEIGHT) evas_textblock_fit_options_set(app->txtblock, TEXTBLOCK_FIT_MODE_WIDTH); else if (options == TEXTBLOCK_FIT_MODE_WIDTH) evas_textblock_fit_options_set(app->txtblock, TEXTBLOCK_FIT_MODE_ALL); else if (options == TEXTBLOCK_FIT_MODE_ALL) evas_textblock_fit_options_set(app->txtblock, TEXTBLOCK_FIT_MODE_NONE); } else if (obj == app->btn[BUTTON_MAX]) { unsigned int min, max; evas_textblock_fit_size_range_get(app->txtblock, &min, &max); max -= 5; evas_textblock_fit_size_range_set(app->txtblock, min, max); } else if (obj == app->btn[BUTTON_MIN]) { unsigned int min, max; evas_textblock_fit_size_range_get(app->txtblock, &min, &max); min += 5; evas_textblock_fit_size_range_set(app->txtblock, min, max); } else if (obj == app->btn[BUTTON_STEP]) { unsigned int step; evas_textblock_fit_step_size_get(app->txtblock, &step); step++; evas_textblock_fit_step_size_set(app->txtblock, step); } else if (obj == app->btn[BUTTON_ARRAY]) { unsigned int font_size[] = {10, 50, 100 ,150}; evas_textblock_fit_size_array_set(app->txtblock,font_size,4); } else if (obj == app->btn[BUTTON_CONTENT]) { app->i_contnet++; if(app->i_contnet>=sizeof(contents)/sizeof(char*)) app->i_contnet=0; evas_object_textblock_text_markup_set(app->txtblock,contents[app->i_contnet]); } else if (obj == app->btn[BUTTON_STYLE]) { app->i_style++; if(app->i_style>=sizeof(styles)/sizeof(char*)) app->i_style=0; Evas_Textblock_Style *style = evas_object_textblock_style_get(app->txtblock); evas_textblock_style_set(style,styles[app->i_style]); } elm_object_text_set(app->lbl_status, get_fit_status(app->txtblock)); } char * get_fit_status(Eo * textblock) { static char status[0xFFF]; unsigned int options,min,max,step,size_array[256]; size_t size_array_len; evas_textblock_fit_options_get(textblock,&options); evas_textblock_fit_size_range_get(textblock,&min,&max); evas_textblock_fit_step_size_get(textblock,&step); evas_textblock_fit_size_array_get(textblock,NULL,&size_array_len,0); if (size_array_len>255) size_array_len = 255; evas_textblock_fit_size_array_get(textblock,size_array,NULL,size_array_len); strcpy(status,"Mode : "); if (options == TEXTBLOCK_FIT_MODE_NONE) strcat(status,"MODE_NONE"); else if (options == TEXTBLOCK_FIT_MODE_HEIGHT) strcat(status,"MODE_HEIGHT"); else if (options == TEXTBLOCK_FIT_MODE_WIDTH) strcat(status,"MODE_WIDTH"); else if (options == TEXTBLOCK_FIT_MODE_ALL) strcat(status,"MODE_ALL"); strcat(status,"<br>"); sprintf(status + strlen(status),"Max : %d<br>",max); sprintf(status + strlen(status),"Min : %d<br>",min); sprintf(status + strlen(status),"Step : %d<br>",step); sprintf(status + strlen(status),"Array : [ "); for (size_t i = 0 ; i < 10 ; i++) { if(i<size_array_len) sprintf(status + strlen(status)," %d,",size_array[i]); } if(10<size_array_len) sprintf(status + strlen(status)," ... "); sprintf(status + strlen(status)," ]"); sprintf(status + strlen(status),"<br>"); sprintf(status + strlen(status),"%s",styles_names[app->i_style]); return status; } int elm_main(int argc, char **argv) { app = calloc(sizeof(APP), 1); elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); app->win = elm_win_util_standard_add("Main", "App"); elm_win_autodel_set(app->win, EINA_TRUE); app->box = elm_box_add(app->win); app->boxHor = elm_box_add(app->box); app->boxHor2 = elm_box_add(app->box); app->txtblock = evas_object_textblock_add(app->box); app->bg = elm_bg_add(app->box); elm_bg_color_set(app->bg,255,255,255); Evas_Textblock_Style *style = evas_textblock_style_new(); evas_textblock_style_set(style,styles[0]); evas_object_textblock_style_set(app->txtblock,style); evas_object_textblock_text_markup_set(app->txtblock,contents[0]); elm_box_horizontal_set(app->boxHor, EINA_TRUE); elm_box_horizontal_set(app->boxHor2, EINA_TRUE); evas_object_size_hint_weight_set(app->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(app->box, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_size_hint_weight_set(app->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(app->box, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(app->txtblock); evas_object_show(app->bg); evas_object_show(app->box); evas_object_show(app->boxHor); evas_object_show(app->boxHor2); elm_box_pack_end(app->box, app->bg); elm_box_pack_end(app->box, app->boxHor); elm_box_pack_end(app->box, app->boxHor2); elm_object_content_set(app->bg,app->txtblock); elm_win_resize_object_add(app->win, app->box); evas_object_resize(app->win, 320, 480); for(int i = 0 ; i < BUTTON_ALL ; i++) { app->btn[i] = elm_button_add(app->boxHor); evas_object_smart_callback_add(app->btn[i], "clicked", _btn_clicked, NULL); elm_object_text_set(app->btn[i], BUTTON_STR[i]); elm_box_pack_end(app->boxHor, app->btn[i]); evas_object_show(app->btn[i]); } app->lbl_status = elm_label_add(app->boxHor2); elm_object_text_set(app->lbl_status, get_fit_status(app->txtblock)); elm_box_pack_end(app->boxHor2, app->lbl_status); evas_object_show(app->lbl_status); evas_object_size_hint_weight_set(app->txtblock, EVAS_HINT_EXPAND,EVAS_HINT_EXPAND); evas_object_size_hint_align_set(app->txtblock, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_size_hint_weight_set(app->bg, EVAS_HINT_EXPAND,EVAS_HINT_EXPAND); evas_object_size_hint_align_set(app->bg, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(app->win); elm_run(); return 0; } ELM_MAIN() ``` **Edje** ``` // compile: edje_cc source.edc // run: edje_player source.edje collections { styles { style { name: "text_style"; base: "font=sans font_size=30 color=#FFF wrap=mixed ellipsis=1.0"; tag: "br" "\n"; tag: "ps" "ps"; tag: "tab" "\t"; tag: "b" "+ font_weight=Bold"; } } group { name: "my_group"; // must be the same as in source.c parts { part { name: "background"; type: RECT; scale: 1; description { color: 0 0 0 0; rel1.relative: 0.0 0.0; rel2.relative: 1.0 1.0; } } part { name: "text"; type: TEXTBLOCK; scale: 1; entry_mode: NONE; effect: OUTLINE_SHADOW; description { state: "default" 0.0; rel1.to : "background"; rel1.relative: 0.0 0.0; rel2.to : "background"; rel2.relative: 1.0 1.0; text { style: "text_style"; align: 0.0 0.0; text: "Hello World This is Me"; fit: 1 1; fit_step: 1; size_range: 30 200; //fit_size_array: 20 40 60 80 100 200; } } } } } } ``` Found Task T5724 relative to this Feature Reviewers: woohyun, bowonryu, cedric, raster Reviewed By: woohyun Subscribers: a.srour, #committers, #reviewers, cedric Tags: #efl Differential Revision: https://phab.enlightenment.org/D9280
This commit is contained in:
parent
8fabc422b6
commit
8f87a2411a
|
@ -419,6 +419,8 @@ static void st_collections_group_parts_part_description_text_repch(void);
|
|||
static void st_collections_group_parts_part_description_text_size(void);
|
||||
static void st_collections_group_parts_part_description_text_size_range(void);
|
||||
static void st_collections_group_parts_part_description_text_fit(void);
|
||||
static void st_collections_group_parts_part_description_text_fit_step(void);
|
||||
static void st_collections_group_parts_part_description_text_fit_size_array(void);
|
||||
static void st_collections_group_parts_part_description_text_min(void);
|
||||
static void st_collections_group_parts_part_description_text_max(void);
|
||||
static void st_collections_group_parts_part_description_text_align(void);
|
||||
|
@ -952,6 +954,8 @@ New_Statement_Handler statement_handlers[] =
|
|||
{"collections.group.parts.part.description.text.size", st_collections_group_parts_part_description_text_size},
|
||||
{"collections.group.parts.part.description.text.size_range", st_collections_group_parts_part_description_text_size_range},
|
||||
{"collections.group.parts.part.description.text.fit", st_collections_group_parts_part_description_text_fit},
|
||||
{"collections.group.parts.part.description.text.fit_step", st_collections_group_parts_part_description_text_fit_step},
|
||||
{"collections.group.parts.part.description.text.fit_size_array", st_collections_group_parts_part_description_text_fit_size_array},
|
||||
{"collections.group.parts.part.description.text.min", st_collections_group_parts_part_description_text_min},
|
||||
{"collections.group.parts.part.description.text.max", st_collections_group_parts_part_description_text_max},
|
||||
{"collections.group.parts.part.description.text.align", st_collections_group_parts_part_description_text_align},
|
||||
|
@ -11654,6 +11658,83 @@ st_collections_group_parts_part_description_text_fit(void)
|
|||
ed->text.fit_y = parse_bool(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@page edcref
|
||||
|
||||
@property
|
||||
fit_step
|
||||
@parameters
|
||||
[font step size in points (pt)]
|
||||
@effect
|
||||
Sets the font step size for the text part. when fitting text
|
||||
|
||||
Defaults: 1
|
||||
@since 1.24.0
|
||||
@endproperty
|
||||
*/
|
||||
static void
|
||||
st_collections_group_parts_part_description_text_fit_step(void)
|
||||
{
|
||||
Edje_Part_Description_Text *ed;
|
||||
|
||||
check_arg_count(1);
|
||||
|
||||
if (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)
|
||||
{
|
||||
ERR("parse error %s:%i. text attributes in non-TEXTBLOCK part.",
|
||||
file_in, line - 1);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
ed = (Edje_Part_Description_Text *)current_desc;
|
||||
|
||||
ed->text.fit_step = parse_int(0);
|
||||
|
||||
if (ed->text.fit_step < 1)
|
||||
{
|
||||
ERR("parse error %s:%i. fit step less than 1.",
|
||||
file_in, line - 1);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@page edcref
|
||||
|
||||
@property
|
||||
fit
|
||||
@parameters
|
||||
[Array of font sizes in points]
|
||||
@effect
|
||||
Sets the allowed font sizes array for the text part.
|
||||
@since 1.24.0
|
||||
@endproperty
|
||||
*/
|
||||
static void
|
||||
st_collections_group_parts_part_description_text_fit_size_array(void)
|
||||
{
|
||||
int n, argc;
|
||||
Edje_Part_Description_Text *ed;
|
||||
|
||||
if (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)
|
||||
{
|
||||
ERR("parse error %s:%i. text attributes in non-TEXTBLOCK part.",
|
||||
file_in, line - 1);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
ed = (Edje_Part_Description_Text *)current_desc;
|
||||
check_min_arg_count(1);
|
||||
|
||||
for (n = 0, argc = get_arg_count(); n < argc; n++)
|
||||
{
|
||||
unsigned int *value = malloc(sizeof(unsigned int));
|
||||
*value = (unsigned int) parse_int(n);
|
||||
ed->text.fit_size_array = eina_list_append(ed->text.fit_size_array, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@page edcref
|
||||
|
||||
|
|
|
@ -240,6 +240,7 @@ void test_flip_page_eo(void *data, Evas_Object *obj, void *event_info);
|
|||
void test_label(void *data, Evas_Object *obj, void *event_info);
|
||||
void test_label_slide(void *data, Evas_Object *obj, void *event_info);
|
||||
void test_label_wrap(void *data, Evas_Object *obj, void *event_info);
|
||||
void test_textblock_fit(void *data, Evas_Object *obj, void *event_info);
|
||||
void test_label_ellipsis(void *data, Evas_Object *obj, void *event_info);
|
||||
void test_label_colors(void *data, Evas_Object *obj, void *event_info);
|
||||
void test_label_emoji(void *data, Evas_Object *obj, void *event_info);
|
||||
|
@ -1206,6 +1207,7 @@ add_tests:
|
|||
ADD_TEST(NULL, "Text", "Label", test_label);
|
||||
ADD_TEST(NULL, "Text", "Label Slide", test_label_slide);
|
||||
ADD_TEST(NULL, "Text", "Label Wrap", test_label_wrap);
|
||||
ADD_TEST(NULL, "Text", "Textblock Fit", test_textblock_fit);
|
||||
ADD_TEST(NULL, "Text", "Label Ellipsis", test_label_ellipsis);
|
||||
ADD_TEST(NULL, "Text", "Label Colors", test_label_colors);
|
||||
ADD_TEST(NULL, "Text", "Label Emoji", test_label_emoji);
|
||||
|
|
|
@ -309,6 +309,238 @@ test_label_slide(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
|
|||
evas_object_show(win);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*** FIT TEXT **************************************************************/
|
||||
enum BUTTON{
|
||||
BUTTON_MODE = 0,
|
||||
BUTTON_MAX = 1,
|
||||
BUTTON_MIN = 2,
|
||||
BUTTON_STEP = 3,
|
||||
BUTTON_ARRAY = 4,
|
||||
BUTTON_CONTENT = 5,
|
||||
BUTTON_STYLE = 6,
|
||||
BUTTON_ALL = BUTTON_STYLE+1,
|
||||
};
|
||||
|
||||
char* BUTTON_STR[BUTTON_ALL] ={
|
||||
"MODE",
|
||||
"MAX",
|
||||
"MIN",
|
||||
"STEP",
|
||||
"ARRAY",
|
||||
"CONTENT",
|
||||
"STYLE",
|
||||
};
|
||||
|
||||
char *contents[] = {
|
||||
"Hello World",
|
||||
"This is Line<br>THis is other Line",
|
||||
"This text contains <font_size=20 color=#F00>SPECIFIC SIZE</font_size>that does not effected by fit mode"
|
||||
};
|
||||
|
||||
char *styles[] = {
|
||||
"DEFAULT='font=sans font_size=30 color=#000 wrap=mixed ellipsis=1.0'",
|
||||
"DEFAULT='font=sans font_size=30 color=#000 wrap=mixed'",
|
||||
"DEFAULT='font=sans font_size=30 color=#000 ellipsis=1.0'",
|
||||
"DEFAULT='font=sans font_size=30 color=#000'",
|
||||
};
|
||||
|
||||
char *styles_names[] = {
|
||||
"wrap=<color=#F00>mixed</color> ellipsis=<color=#F00>1.0</color>",
|
||||
"wrap=<color=#F00>mixed</color> ellipsis=<color=#F00>NONE</color>",
|
||||
"wrap=<color=#F00>NONE</color> ellipsis=<color=#F00>1.0</color>",
|
||||
"wrap=<color=#F00>NONE</color> ellipsis=<color=#F00>NONE</color>",
|
||||
};
|
||||
|
||||
typedef struct _APP
|
||||
{
|
||||
Evas_Object *win, *box, *txtblock,*bg, *boxHor, *boxHor2;
|
||||
Eo *btn[BUTTON_ALL];
|
||||
Eo *lbl_status;
|
||||
char * str;
|
||||
unsigned int i_contnet, i_style;
|
||||
} APP;
|
||||
APP *app;
|
||||
|
||||
char * get_fit_status(Eo * textblock);
|
||||
|
||||
static void _btn_clicked(void *data EINA_UNUSED, Eo *obj, void *eventInfo EINA_UNUSED){
|
||||
if (obj == app->btn[BUTTON_MODE])
|
||||
{
|
||||
unsigned int options;
|
||||
evas_textblock_fit_options_get(app->txtblock, &options);
|
||||
if (options == TEXTBLOCK_FIT_MODE_NONE)
|
||||
evas_textblock_fit_options_set(app->txtblock, TEXTBLOCK_FIT_MODE_HEIGHT);
|
||||
else if (options == TEXTBLOCK_FIT_MODE_HEIGHT)
|
||||
evas_textblock_fit_options_set(app->txtblock, TEXTBLOCK_FIT_MODE_WIDTH);
|
||||
else if (options == TEXTBLOCK_FIT_MODE_WIDTH)
|
||||
evas_textblock_fit_options_set(app->txtblock, TEXTBLOCK_FIT_MODE_ALL);
|
||||
else if (options == TEXTBLOCK_FIT_MODE_ALL)
|
||||
evas_textblock_fit_options_set(app->txtblock, TEXTBLOCK_FIT_MODE_NONE);
|
||||
}
|
||||
else if (obj == app->btn[BUTTON_MAX])
|
||||
{
|
||||
unsigned int min, max;
|
||||
evas_textblock_fit_size_range_get(app->txtblock, &min, &max);
|
||||
max -= 5;
|
||||
evas_textblock_fit_size_range_set(app->txtblock, min, max);
|
||||
}
|
||||
else if (obj == app->btn[BUTTON_MIN])
|
||||
{
|
||||
unsigned int min, max;
|
||||
evas_textblock_fit_size_range_get(app->txtblock, &min, &max);
|
||||
min += 5;
|
||||
evas_textblock_fit_size_range_set(app->txtblock, min, max);
|
||||
}
|
||||
else if (obj == app->btn[BUTTON_STEP])
|
||||
{
|
||||
unsigned int step;
|
||||
evas_textblock_fit_step_size_get(app->txtblock, &step);
|
||||
step++;
|
||||
evas_textblock_fit_step_size_set(app->txtblock, step);
|
||||
}
|
||||
else if (obj == app->btn[BUTTON_ARRAY])
|
||||
{
|
||||
unsigned int font_size[] = {10, 50, 100 ,150};
|
||||
evas_textblock_fit_size_array_set(app->txtblock,font_size,4);
|
||||
}
|
||||
else if (obj == app->btn[BUTTON_CONTENT])
|
||||
{
|
||||
app->i_contnet++;
|
||||
if(app->i_contnet>=sizeof(contents)/sizeof(char*))
|
||||
app->i_contnet=0;
|
||||
evas_object_textblock_text_markup_set(app->txtblock,contents[app->i_contnet]);
|
||||
}
|
||||
else if (obj == app->btn[BUTTON_STYLE])
|
||||
{
|
||||
app->i_style++;
|
||||
if(app->i_style>=sizeof(styles)/sizeof(char*))
|
||||
app->i_style=0;
|
||||
|
||||
Evas_Textblock_Style *style = evas_object_textblock_style_get(app->txtblock);
|
||||
evas_textblock_style_set(style,styles[app->i_style]);
|
||||
}
|
||||
|
||||
elm_object_text_set(app->lbl_status, get_fit_status(app->txtblock));
|
||||
}
|
||||
|
||||
char * get_fit_status(Eo * textblock)
|
||||
{
|
||||
static char status[0xFFF];
|
||||
unsigned int options,min,max,step,size_array[256];
|
||||
size_t size_array_len;
|
||||
evas_textblock_fit_options_get(textblock,&options);
|
||||
evas_textblock_fit_size_range_get(textblock,&min,&max);
|
||||
evas_textblock_fit_step_size_get(textblock,&step);
|
||||
evas_textblock_fit_size_array_get(textblock,NULL,&size_array_len,0);
|
||||
if (size_array_len>255)
|
||||
size_array_len = 255;
|
||||
evas_textblock_fit_size_array_get(textblock,size_array,NULL,size_array_len);
|
||||
|
||||
strcpy(status,"Mode : ");
|
||||
if (options == TEXTBLOCK_FIT_MODE_NONE)
|
||||
strcat(status,"MODE_NONE");
|
||||
else if (options == TEXTBLOCK_FIT_MODE_HEIGHT)
|
||||
strcat(status,"MODE_HEIGHT");
|
||||
else if (options == TEXTBLOCK_FIT_MODE_WIDTH)
|
||||
strcat(status,"MODE_WIDTH");
|
||||
else if (options == TEXTBLOCK_FIT_MODE_ALL)
|
||||
strcat(status,"MODE_ALL");
|
||||
|
||||
strcat(status,"<br>");
|
||||
sprintf(status + strlen(status),"Max : %d<br>",max);
|
||||
sprintf(status + strlen(status),"Min : %d<br>",min);
|
||||
sprintf(status + strlen(status),"Step : %d<br>",step);
|
||||
sprintf(status + strlen(status),"Array : [ ");
|
||||
for (size_t i = 0 ; i < 10 ; i++)
|
||||
{
|
||||
if(i<size_array_len)
|
||||
sprintf(status + strlen(status)," %d,",size_array[i]);
|
||||
}
|
||||
|
||||
if(10<size_array_len)
|
||||
sprintf(status + strlen(status)," ... ");
|
||||
sprintf(status + strlen(status)," ]");
|
||||
|
||||
sprintf(status + strlen(status),"<br>");
|
||||
sprintf(status + strlen(status),"%s",styles_names[app->i_style]);
|
||||
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
test_textblock_fit(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
app = calloc(sizeof(APP), 1);
|
||||
|
||||
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
|
||||
|
||||
app->win = elm_win_util_standard_add("Main", "App");
|
||||
elm_win_autodel_set(app->win, EINA_TRUE);
|
||||
|
||||
app->box = elm_box_add(app->win);
|
||||
app->boxHor = elm_box_add(app->box);
|
||||
app->boxHor2 = elm_box_add(app->box);
|
||||
app->txtblock = evas_object_textblock_add(app->box);
|
||||
app->bg = elm_bg_add(app->box);
|
||||
elm_bg_color_set(app->bg,255,255,255);
|
||||
|
||||
Evas_Textblock_Style *style = evas_textblock_style_new();
|
||||
evas_textblock_style_set(style,styles[0]);
|
||||
evas_object_textblock_style_set(app->txtblock,style);
|
||||
evas_object_textblock_text_markup_set(app->txtblock,contents[0]);
|
||||
|
||||
elm_box_horizontal_set(app->boxHor, EINA_TRUE);
|
||||
elm_box_horizontal_set(app->boxHor2, EINA_TRUE);
|
||||
|
||||
evas_object_size_hint_weight_set(app->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(app->box, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
|
||||
|
||||
evas_object_size_hint_weight_set(app->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(app->box, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
|
||||
evas_object_show(app->txtblock);
|
||||
evas_object_show(app->bg);
|
||||
evas_object_show(app->box);
|
||||
evas_object_show(app->boxHor);
|
||||
evas_object_show(app->boxHor2);
|
||||
|
||||
elm_box_pack_end(app->box, app->bg);
|
||||
elm_box_pack_end(app->box, app->boxHor);
|
||||
elm_box_pack_end(app->box, app->boxHor2);
|
||||
|
||||
elm_object_content_set(app->bg,app->txtblock);
|
||||
|
||||
elm_win_resize_object_add(app->win, app->box);
|
||||
evas_object_resize(app->win, 320, 480);
|
||||
|
||||
for(int i = 0 ; i < BUTTON_ALL ; i++)
|
||||
{
|
||||
app->btn[i] = elm_button_add(app->boxHor);
|
||||
evas_object_smart_callback_add(app->btn[i], "clicked", _btn_clicked, NULL);
|
||||
elm_object_text_set(app->btn[i], BUTTON_STR[i]);
|
||||
elm_box_pack_end(app->boxHor, app->btn[i]);
|
||||
evas_object_show(app->btn[i]);
|
||||
}
|
||||
|
||||
app->lbl_status = elm_label_add(app->boxHor2);
|
||||
elm_object_text_set(app->lbl_status, get_fit_status(app->txtblock));
|
||||
elm_box_pack_end(app->boxHor2, app->lbl_status);
|
||||
evas_object_show(app->lbl_status);
|
||||
|
||||
evas_object_size_hint_weight_set(app->txtblock, EVAS_HINT_EXPAND,EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(app->txtblock, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
|
||||
evas_object_size_hint_weight_set(app->bg, EVAS_HINT_EXPAND,EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(app->bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
|
||||
evas_object_show(app->win);
|
||||
}
|
||||
|
||||
/*** Label Wrap **************************************************************/
|
||||
void
|
||||
test_label_wrap(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
|
|
|
@ -1188,6 +1188,8 @@ _edje_edd_init(void)
|
|||
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.size_range_max", text.size_range_max, EET_T_INT);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.fit_x", text.fit_x, EET_T_UCHAR);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.fit_y", text.fit_y, EET_T_UCHAR);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.fit_step", text.fit_step, EET_T_UINT);
|
||||
EET_DATA_DESCRIPTOR_ADD_LIST_UINT(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.fit_size_array", text.fit_size_array);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.min_x", text.min_x, EET_T_UCHAR);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.min_y", text.min_y, EET_T_UCHAR);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.max_x", text.max_x, EET_T_UCHAR);
|
||||
|
|
|
@ -1460,6 +1460,9 @@ struct _Edje_Part_Description_Spec_Text
|
|||
int id_text_source; /* -1 if none */
|
||||
int size_range_min;
|
||||
int size_range_max; /* -1 means, no bound. */
|
||||
unsigned int fit_step;
|
||||
/*FIXME THIS SHOULD BE EINA_LIST*/
|
||||
Eina_List *fit_size_array;
|
||||
|
||||
unsigned char fit_x; /* resize font size down to fit in x dir */
|
||||
unsigned char fit_y; /* resize font size down to fit in y dir */
|
||||
|
|
|
@ -1,25 +1,5 @@
|
|||
#include "edje_private.h"
|
||||
|
||||
static double
|
||||
_edje_part_recalc_single_textblock_scale_range_adjust(Edje_Part_Description_Text *chosen_desc, double base_scale, double scale)
|
||||
{
|
||||
double size, min, max;
|
||||
|
||||
if (chosen_desc->text.size == 0)
|
||||
return scale;
|
||||
|
||||
min = base_scale * chosen_desc->text.size_range_min;
|
||||
max = chosen_desc->text.size_range_max * base_scale;
|
||||
size = chosen_desc->text.size * scale;
|
||||
|
||||
if ((size > max) && (max > 0))
|
||||
scale = max / (double)chosen_desc->text.size;
|
||||
else if (size < min)
|
||||
scale = min / (double)chosen_desc->text.size;
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
/*
|
||||
* Legacy function for min/max calculation of textblock part.
|
||||
* It can't calculate min/max properly in many cases.
|
||||
|
@ -528,7 +508,6 @@ _edje_part_recalc_single_textblock(FLOAT_T sc,
|
|||
|
||||
if (chosen_desc)
|
||||
{
|
||||
Eina_Size2D size;
|
||||
|
||||
if (ep->part->scale)
|
||||
evas_object_scale_set(ep->object, TO_DOUBLE(sc));
|
||||
|
@ -539,76 +518,28 @@ _edje_part_recalc_single_textblock(FLOAT_T sc,
|
|||
{
|
||||
if ((chosen_desc->text.fit_x) || (chosen_desc->text.fit_y))
|
||||
{
|
||||
double base_s = 1.0;
|
||||
double orig_s;
|
||||
double s = base_s;
|
||||
unsigned int size_array[255];
|
||||
size_t size_array_len = 0;
|
||||
Eina_List *l;
|
||||
unsigned int *value;
|
||||
EINA_LIST_FOREACH(chosen_desc->text.fit_size_array, l, value)
|
||||
{
|
||||
size_array[size_array_len++] = *value;
|
||||
}
|
||||
unsigned int mode = TEXTBLOCK_FIT_MODE_NONE;
|
||||
|
||||
if (ep->part->scale) base_s = TO_DOUBLE(sc);
|
||||
efl_gfx_entity_scale_set(ep->object, base_s);
|
||||
size = efl_canvas_textblock_size_native_get(ep->object);
|
||||
|
||||
orig_s = base_s;
|
||||
/* Now make it bigger so calculations will be more accurate
|
||||
* and less influenced by hinting... */
|
||||
{
|
||||
orig_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
|
||||
orig_s * TO_INT(params->eval.w) / size.w);
|
||||
efl_gfx_entity_scale_set(ep->object, orig_s);
|
||||
size = efl_canvas_textblock_size_native_get(ep->object);
|
||||
}
|
||||
if (chosen_desc->text.fit_x)
|
||||
{
|
||||
if (size.w > 0)
|
||||
{
|
||||
s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
|
||||
orig_s * TO_INT(params->eval.w) / size.w);
|
||||
efl_gfx_entity_scale_set(ep->object, s);
|
||||
efl_canvas_textblock_size_native_get(ep->object);
|
||||
}
|
||||
}
|
||||
mode |= TEXTBLOCK_FIT_MODE_WIDTH;
|
||||
if (chosen_desc->text.fit_y)
|
||||
mode |= TEXTBLOCK_FIT_MODE_HEIGHT;
|
||||
evas_textblock_fit_options_set(ep->object, mode);
|
||||
evas_textblock_fit_step_size_set(ep->object, chosen_desc->text.fit_step);
|
||||
if ( chosen_desc->text.size_range_min || chosen_desc->text.size_range_max)
|
||||
evas_textblock_fit_size_range_set(ep->object, chosen_desc->text.size_range_min, chosen_desc->text.size_range_max);
|
||||
if (size_array_len>0)
|
||||
{
|
||||
if (size.h > 0)
|
||||
{
|
||||
double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
|
||||
orig_s * TO_INT(params->eval.h) / size.h);
|
||||
/* If we already have X fit, restrict Y to be no bigger
|
||||
* than what we got with X. */
|
||||
if (!((chosen_desc->text.fit_x) && (tmp_s > s)))
|
||||
{
|
||||
s = tmp_s;
|
||||
}
|
||||
|
||||
efl_gfx_entity_scale_set(ep->object, s);
|
||||
efl_canvas_textblock_size_native_get(ep->object);
|
||||
}
|
||||
evas_textblock_fit_size_array_set(ep->object,size_array,size_array_len);
|
||||
}
|
||||
|
||||
/* Final tuning, try going down 90% at a time, hoping it'll
|
||||
* actually end up being correct. */
|
||||
{
|
||||
int i = 5; /* Tries before we give up. */
|
||||
Eina_Size2D size;
|
||||
size = efl_canvas_textblock_size_native_get(ep->object);
|
||||
|
||||
/* If we are still too big, try reducing the size to
|
||||
* 95% each try. */
|
||||
while ((i > 0) &&
|
||||
((chosen_desc->text.fit_x && (size.w > TO_INT(params->eval.w))) ||
|
||||
(chosen_desc->text.fit_y && (size.h > TO_INT(params->eval.h)))))
|
||||
{
|
||||
double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s, s * 0.95);
|
||||
|
||||
/* Break if we are not making any progress. */
|
||||
if (EQ(tmp_s, s))
|
||||
break;
|
||||
s = tmp_s;
|
||||
|
||||
efl_gfx_entity_scale_set(ep->object, s);
|
||||
size = efl_canvas_textblock_size_native_get(ep->object);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((ed->file->efl_version.major >= 1) && (ed->file->efl_version.minor >= 19))
|
||||
|
|
|
@ -3536,6 +3536,29 @@ eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
|
|||
0, /* 0, */ NULL, NULL); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @ingroup Eet_Data_Group
|
||||
* @brief Adds a linked list of unsigned integers to a data descriptor.
|
||||
* @param edd The data descriptor to add the type to.
|
||||
* @param struct_type The type of the struct.
|
||||
* @param name The string name to use to encode/decode this member
|
||||
* (must be a constant global and never change).
|
||||
* @param member The struct member itself to be encoded.
|
||||
*
|
||||
* This macro lets you easily add a linked list of unsigned int. All the
|
||||
* parameters are the same as for EET_DATA_DESCRIPTOR_ADD_BASIC().
|
||||
*
|
||||
* @since 1.24.0
|
||||
*/
|
||||
#define EET_DATA_DESCRIPTOR_ADD_LIST_UINT(edd, struct_type, name, member) \
|
||||
do { \
|
||||
struct_type ___ett; \
|
||||
eet_data_descriptor_element_add(edd, name, EET_T_UINT, EET_G_LIST, \
|
||||
(char *)(& (___ett.member)) - \
|
||||
(char *)(& (___ett)), \
|
||||
0, /* 0, */ NULL, NULL); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @ingroup Eet_Data_Group
|
||||
* @brief Adds a hash type to a data descriptor.
|
||||
|
|
|
@ -139,6 +139,12 @@ static const char o_type[] = "textblock";
|
|||
#define EINA_INLIST_REMOVE(l,i) do { l = (__typeof__(l)) eina_inlist_remove(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0)
|
||||
#define EINA_INLIST_APPEND(l,i) do { l = (__typeof__(l)) eina_inlist_append(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0)
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @typedef TEXT_FIT_CONTENT_CONFIG
|
||||
* Configurations used to fit content inside Textblock
|
||||
*/
|
||||
typedef struct _TEXT_FIT_CONTENT_CONFIG TEXT_FIT_CONTENT_CONFIG;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
@ -420,6 +426,20 @@ typedef struct _User_Style_Entry
|
|||
const char *key;
|
||||
} User_Style_Entry;
|
||||
|
||||
struct _TEXT_FIT_CONTENT_CONFIG
|
||||
{
|
||||
unsigned int options;
|
||||
unsigned int min_font_size,max_font_size;
|
||||
unsigned int step_size;
|
||||
unsigned int *p_size_array;
|
||||
size_t size_list_length;
|
||||
Eina_Size2D size_cache[256+1]; /** used hash font sizes 1-255 */
|
||||
Eina_Size2D last_size;
|
||||
int last_size_index;
|
||||
Eina_Bool force_refit;
|
||||
char fit_style[256];
|
||||
};
|
||||
|
||||
#define _FMT(x) (o->default_format.format.x)
|
||||
#define _FMT_INFO(x) (o->default_format.info.x)
|
||||
|
||||
|
@ -495,6 +515,7 @@ struct _Evas_Object_Textblock
|
|||
Eina_Hash *sources;
|
||||
Text_Item_Filter *text_items; // inlist
|
||||
} gfx_filter;
|
||||
TEXT_FIT_CONTENT_CONFIG fit_content_config;
|
||||
Eina_Bool redraw : 1;
|
||||
Eina_Bool changed : 1;
|
||||
Eina_Bool pause_change : 1;
|
||||
|
@ -509,6 +530,7 @@ struct _Evas_Object_Textblock
|
|||
Eina_Bool multiline : 1;
|
||||
Eina_Bool wrap_changed : 1;
|
||||
Eina_Bool auto_styles : 1;
|
||||
Eina_Bool fit_in_progress : 1;
|
||||
};
|
||||
|
||||
struct _Evas_Textblock_Selection_Iterator
|
||||
|
@ -619,6 +641,19 @@ static void _evas_textblock_cursor_copy(Efl_Text_Cursor_Handle *dst, const Efl_T
|
|||
static void
|
||||
_textblock_style_generic_set(Evas_Object *eo_obj, Evas_Textblock_Style *ts, const char *key);
|
||||
|
||||
|
||||
/*********Internal fitting Functions and Defines*********/
|
||||
int fit_cache_clear(TEXT_FIT_CONTENT_CONFIG *fc,const unsigned int fit_cache_flags);
|
||||
int fit_text_block(Evas_Object *eo_obj);
|
||||
int fit_fill_internal_list(TEXT_FIT_CONTENT_CONFIG *fc);
|
||||
int fit_start_fitting(Evas_Object *eo_obj);
|
||||
int fit_finish_fitting(Evas_Object *eo_obj);
|
||||
Eina_Bool fit_is_fitting(const Evas_Object *eo_obj);
|
||||
const unsigned int FIT_CACHE_CANVAS_SIZE = 0x0001;
|
||||
const unsigned int FIT_CACHE_INTERNAL_SIZE_ARRAY = 0x0002;
|
||||
const unsigned int FIT_CACHE_FORCE_REFIT = 0x0004;
|
||||
const unsigned int FIT_CACHE_ALL = 0x000F;
|
||||
|
||||
/** selection iterator */
|
||||
/**
|
||||
* @internal
|
||||
|
@ -7369,6 +7404,11 @@ _layout_setup(Ctxt *c, const Eo *eo_obj, Evas_Coord w, Evas_Coord h)
|
|||
finalize = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
/* Extra Style used by fitting configure*/
|
||||
if (*o->fit_content_config.fit_style)
|
||||
{
|
||||
_format_fill(c->obj, c->fmt, o->fit_content_config.fit_style, EINA_FALSE);
|
||||
}
|
||||
|
||||
if (finalize)
|
||||
_format_finalize(c->obj, c->fmt);
|
||||
|
@ -7463,7 +7503,9 @@ _relayout_if_needed(const Evas_Object *eo_obj, Efl_Canvas_Textblock_Data *o)
|
|||
if (obj->delete_me) return EINA_TRUE;
|
||||
|
||||
/* XXX const */
|
||||
evas_object_textblock_coords_recalc((Evas_Object *)eo_obj, obj, obj->private_data);
|
||||
if(!fit_is_fitting(eo_obj))
|
||||
evas_object_textblock_coords_recalc((Evas_Object *)eo_obj, obj, obj->private_data);
|
||||
|
||||
if (o->formatted.valid)
|
||||
{
|
||||
return EINA_TRUE;
|
||||
|
@ -7621,6 +7663,10 @@ _efl_canvas_textblock_efl_object_constructor(Eo *eo_obj, Efl_Canvas_Textblock_Da
|
|||
_FMT(ellipsis) = -1;
|
||||
_FMT_INFO(bitmap_scalable) = EFL_TEXT_FONT_BITMAP_SCALABLE_COLOR;
|
||||
|
||||
/* Fit default properties*/
|
||||
evas_textblock_fit_size_range_set(eo_obj,1,255);
|
||||
evas_textblock_fit_step_size_set(eo_obj,1);
|
||||
|
||||
o->auto_styles = EINA_TRUE;
|
||||
|
||||
return eo_obj;
|
||||
|
@ -11311,10 +11357,13 @@ _evas_textblock_changed(Efl_Canvas_Textblock_Data *o, Evas_Object *eo_obj)
|
|||
o->formatted.valid = 0;
|
||||
o->native.valid = 0;
|
||||
o->content_changed = 1;
|
||||
if (o->markup_text)
|
||||
if (!fit_is_fitting(eo_obj))
|
||||
{
|
||||
eina_stringshare_del(o->markup_text);
|
||||
o->markup_text = NULL;
|
||||
if (o->markup_text)
|
||||
{
|
||||
eina_stringshare_del(o->markup_text);
|
||||
o->markup_text = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: emit ONCE after this following checks
|
||||
|
@ -11324,6 +11373,15 @@ _evas_textblock_changed(Efl_Canvas_Textblock_Data *o, Evas_Object *eo_obj)
|
|||
_cursor_emit_if_changed(data_obj);
|
||||
}
|
||||
|
||||
/*
|
||||
If format changed we need to refit content again.
|
||||
If content already fitting then ignore fitting (fitting cause fall to this callback)
|
||||
*/
|
||||
if (!fit_is_fitting(eo_obj))
|
||||
{
|
||||
fit_cache_clear(&o->fit_content_config, FIT_CACHE_ALL);
|
||||
fit_text_block(eo_obj);
|
||||
}
|
||||
evas_object_change(eo_obj, obj);
|
||||
}
|
||||
|
||||
|
@ -14264,6 +14322,11 @@ evas_object_textblock_free(Evas_Object *eo_obj)
|
|||
|
||||
/* remove obstacles */
|
||||
_obstacles_free(eo_obj, o);
|
||||
if (o->fit_content_config.p_size_array)
|
||||
{
|
||||
free(o->fit_content_config.p_size_array);
|
||||
o->fit_content_config.p_size_array = NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_HYPHEN
|
||||
/* Hyphenation */
|
||||
|
@ -15350,6 +15413,7 @@ _efl_canvas_textblock_efl_gfx_filter_filter_source_get(const Eo *obj EINA_UNUSED
|
|||
return eina_hash_find(pd->gfx_filter.sources, name);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
evas_object_textblock_coords_recalc(Evas_Object *eo_obj,
|
||||
Evas_Object_Protected_Data *obj,
|
||||
|
@ -15407,6 +15471,17 @@ evas_object_textblock_coords_recalc(Evas_Object *eo_obj,
|
|||
o->formatted.valid = 0;
|
||||
o->changed = 1;
|
||||
}
|
||||
|
||||
Evas_Coord x,y,w,h;
|
||||
evas_object_geometry_get(eo_obj, &x, &y, &w, &h);
|
||||
if (
|
||||
(w!=o->fit_content_config.last_size.w || h!=o->fit_content_config.last_size.h) &&
|
||||
(o->fit_content_config.options & TEXTBLOCK_FIT_MODE_ALL) != TEXTBLOCK_FIT_MODE_NONE
|
||||
)
|
||||
{
|
||||
fit_cache_clear(&o->fit_content_config, FIT_CACHE_INTERNAL_SIZE_ARRAY);
|
||||
fit_text_block(eo_obj);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -15534,6 +15609,54 @@ done:
|
|||
eo_obj, is_v, was_v);
|
||||
}
|
||||
|
||||
void fit_style_update(Evas_Object *object, int i_font_size, Eina_Bool disable_ellipsis, Eina_Bool disable_wrap)
|
||||
{
|
||||
Efl_Canvas_Textblock_Data *o = efl_data_scope_get(object, MY_CLASS);
|
||||
TEXT_FIT_CONTENT_CONFIG * fc = &o->fit_content_config;
|
||||
memset(fc->fit_style,0,sizeof(fc->fit_style));
|
||||
char * fit_style = fc->fit_style;
|
||||
if (i_font_size >= 0)
|
||||
{
|
||||
char font_size[0xF] = {0};
|
||||
char *pfont = font_size;
|
||||
sprintf(font_size, "font_size=%i ", i_font_size);
|
||||
while (*pfont)
|
||||
{
|
||||
*fit_style = *pfont;
|
||||
pfont++;
|
||||
fit_style++;
|
||||
}
|
||||
}
|
||||
|
||||
if (disable_ellipsis == EINA_TRUE)
|
||||
{
|
||||
*fit_style = ' ';
|
||||
fit_style++;
|
||||
char *p = "ellipsis=2.0";
|
||||
while (*p)
|
||||
{
|
||||
*fit_style = *p;
|
||||
p++;
|
||||
fit_style++;
|
||||
}
|
||||
}
|
||||
|
||||
if (disable_wrap == EINA_TRUE)
|
||||
{
|
||||
*fit_style = ' ';
|
||||
fit_style++;
|
||||
char *p = "wrap=none";
|
||||
while (*p)
|
||||
{
|
||||
*fit_style = *p;
|
||||
p++;
|
||||
fit_style++;
|
||||
}
|
||||
}
|
||||
|
||||
_canvas_text_format_changed(object,o);
|
||||
}
|
||||
|
||||
static void
|
||||
evas_object_textblock_render_post(Evas_Object *eo_obj EINA_UNUSED,
|
||||
Evas_Object_Protected_Data *obj,
|
||||
|
@ -17026,6 +17149,371 @@ _efl_canvas_textblock_async_layout(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Textblock_
|
|||
NULL, ctx);
|
||||
return f;
|
||||
}
|
||||
/* Fitting Internal Functions*/
|
||||
|
||||
int fit_cache_clear(TEXT_FIT_CONTENT_CONFIG *fc, unsigned int fit_cache_flags)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(fc, EVAS_ERROR_INVALID_PARAM);
|
||||
if ((fit_cache_flags&FIT_CACHE_CANVAS_SIZE) == FIT_CACHE_CANVAS_SIZE)
|
||||
fc->last_size = EINA_SIZE2D(0, 0);
|
||||
if ((fit_cache_flags&FIT_CACHE_INTERNAL_SIZE_ARRAY) == FIT_CACHE_INTERNAL_SIZE_ARRAY)
|
||||
for(int i = 0 ; i < 255 ; i++) fc->size_cache[i] = EINA_SIZE2D(0,0);
|
||||
if ((fit_cache_flags&FIT_CACHE_FORCE_REFIT) == FIT_CACHE_FORCE_REFIT)
|
||||
fc->force_refit = EINA_TRUE;
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
int fit_start_fitting(Evas_Object *eo_obj)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(eo_obj, EVAS_ERROR_INVALID_PARAM);
|
||||
Efl_Canvas_Textblock_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
|
||||
if (o->fit_in_progress == EINA_TRUE)
|
||||
return EVAS_ERROR_INVALID_OPERATION;
|
||||
|
||||
o->fit_in_progress = EINA_TRUE;
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
int fit_finish_fitting(Evas_Object *eo_obj)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(eo_obj, EVAS_ERROR_INVALID_PARAM);
|
||||
Efl_Canvas_Textblock_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
|
||||
if (o->fit_in_progress == EINA_FALSE)
|
||||
return EVAS_ERROR_INVALID_OPERATION;
|
||||
|
||||
o->fit_in_progress = EINA_FALSE;
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
Eina_Bool fit_is_fitting(const Evas_Object *eo_obj)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(eo_obj, EVAS_ERROR_INVALID_PARAM);
|
||||
Efl_Canvas_Textblock_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
|
||||
return o->fit_in_progress;
|
||||
}
|
||||
|
||||
int fit_text_block(Evas_Object *eo_obj)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(eo_obj, EVAS_ERROR_INVALID_PARAM);
|
||||
Efl_Canvas_Textblock_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
|
||||
Evas_Coord x,y,w,h;
|
||||
Evas_Coord wf_new,hf_new;
|
||||
|
||||
TEXT_FIT_CONTENT_CONFIG * fc = &o->fit_content_config;
|
||||
|
||||
if (fc->options == TEXTBLOCK_FIT_MODE_NONE && !fc->force_refit)
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
|
||||
|
||||
if (fc->options == TEXTBLOCK_FIT_MODE_NONE)
|
||||
{
|
||||
fit_start_fitting(eo_obj);
|
||||
fc->force_refit = 0;
|
||||
fit_style_update(eo_obj,-1, EINA_FALSE, EINA_FALSE);
|
||||
fit_finish_fitting(eo_obj);
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
evas_object_geometry_get(eo_obj, &x, &y, &w, &h);
|
||||
|
||||
if (w > 0 && h > 0)
|
||||
{
|
||||
Eina_Bool b_fit_width = ((fc->options & TEXTBLOCK_FIT_MODE_WIDTH) == TEXTBLOCK_FIT_MODE_WIDTH);
|
||||
Eina_Bool b_fit_height = ((fc->options & TEXTBLOCK_FIT_MODE_HEIGHT) == TEXTBLOCK_FIT_MODE_HEIGHT);
|
||||
//FIXME uncomment condition when style is not warp
|
||||
if ( fc->force_refit || /*(w != fc->last_size.w && b_fit_width) || (h != fc->last_size.h && b_fit_height)*/ EINA_TRUE)
|
||||
{
|
||||
/* Extra Check to reduce recalculate */
|
||||
Eina_Bool b_max_reached = (fc->last_size_index == ((int)fc->size_list_length) - 1);
|
||||
Eina_Bool b_min_reached = (fc->last_size_index == 0);
|
||||
/* 1 - If max font size reached and text block size increased*/
|
||||
if (!fc->force_refit && b_max_reached && ((b_fit_width ? (w >= fc->last_size.w) : EINA_TRUE) && (b_fit_height ? (h >= fc->last_size.h) : EINA_TRUE)))
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
/* 2- If min font size reached and text block size decreased*/
|
||||
if (!fc->force_refit && b_min_reached && ((b_fit_width ? (w <= fc->last_size.w) : EINA_TRUE) && (b_fit_height ? (h <= fc->last_size.h) : EINA_TRUE)))
|
||||
{
|
||||
/*This is needed to recalculate ellipsis, inside fitting to avoid losing markup_text*/
|
||||
fit_start_fitting(eo_obj);
|
||||
_canvas_text_format_changed(eo_obj, o);
|
||||
fit_finish_fitting(eo_obj);
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
fit_start_fitting(eo_obj);
|
||||
|
||||
fc->force_refit = EINA_FALSE;
|
||||
fc->last_size.w = w;
|
||||
fc->last_size.h = h;
|
||||
|
||||
int r = fc->size_list_length;
|
||||
int l = 0;
|
||||
|
||||
Eina_Bool bwrap = EINA_FALSE;
|
||||
if (fc->options == TEXTBLOCK_FIT_MODE_WIDTH)
|
||||
{
|
||||
bwrap = EINA_TRUE;
|
||||
}
|
||||
|
||||
while(r > l)
|
||||
{
|
||||
int mid = (r + l) / 2;
|
||||
/*cache font sizes vaules from 0-255 in size_cache array*/
|
||||
size_t font_size = fc->p_size_array[mid];
|
||||
if (font_size <= 0xFF && (fc->size_cache[font_size].w != 0 && fc->size_cache[font_size].h != 0))
|
||||
{
|
||||
wf_new = fc->size_cache[font_size].w;
|
||||
hf_new = fc->size_cache[font_size].h;
|
||||
}
|
||||
else
|
||||
{
|
||||
fit_style_update(eo_obj,fc->p_size_array[mid],EINA_TRUE,bwrap);
|
||||
Eina_Size2D size = efl_canvas_textblock_size_formatted_get(eo_obj);
|
||||
wf_new = size.w;
|
||||
hf_new = size.h;
|
||||
if (fc->p_size_array[mid]<255)
|
||||
{
|
||||
fc->size_cache[font_size].w = wf_new;
|
||||
fc->size_cache[font_size].h = hf_new;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
((wf_new > w) & ((fc->options & TEXTBLOCK_FIT_MODE_WIDTH) == TEXTBLOCK_FIT_MODE_WIDTH)) ||
|
||||
((hf_new > h) & ((fc->options & TEXTBLOCK_FIT_MODE_HEIGHT) == TEXTBLOCK_FIT_MODE_HEIGHT)))
|
||||
{
|
||||
r = mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*Lower bound founded, subtract one to move for nearest value*/
|
||||
fc->last_size_index = MAX(l-1, 0);
|
||||
fit_style_update(eo_obj,fc->p_size_array[fc->last_size_index],(fc->last_size_index != 0) && fc->options != TEXTBLOCK_FIT_MODE_HEIGHT ,EINA_FALSE);
|
||||
fit_finish_fitting(eo_obj);
|
||||
}
|
||||
}
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
int fit_fill_internal_list(TEXT_FIT_CONTENT_CONFIG *fc)
|
||||
{
|
||||
int diff = (fc->max_font_size - fc->min_font_size);
|
||||
if (fc->p_size_array)
|
||||
{
|
||||
free(fc->p_size_array);
|
||||
fc->p_size_array = NULL;
|
||||
}
|
||||
if (diff == 0)
|
||||
{
|
||||
fc->size_list_length = 1;
|
||||
fc->p_size_array = malloc(sizeof(unsigned int) * fc->size_list_length);
|
||||
if (!fc->p_size_array)
|
||||
return EVAS_ERROR_NO_MEMORY;
|
||||
fc->p_size_array[0] = fc->max_font_size;
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
fc->size_list_length = 2 + diff / MAX(fc->step_size, 1);
|
||||
fc->p_size_array = malloc(sizeof(unsigned int) * fc->size_list_length);
|
||||
if (!fc->p_size_array)
|
||||
return EVAS_ERROR_NO_MEMORY;
|
||||
|
||||
size_t i ;
|
||||
for (i = 0 ; i < fc->size_list_length - 1; i++)
|
||||
{
|
||||
fc->p_size_array[i] = fc->min_font_size + i * MAX(fc->step_size, 1);
|
||||
}
|
||||
fc->p_size_array[fc->size_list_length - 1] = fc->max_font_size;
|
||||
fc->last_size_index = -1;
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EAPI int evas_textblock_fit_options_set(Evas_Object *obj, unsigned int options)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EVAS_ERROR_INVALID_PARAM);
|
||||
Efl_Canvas_Textblock_Data *o = efl_data_scope_get(obj, MY_CLASS);
|
||||
TEXT_FIT_CONTENT_CONFIG * fc = &o->fit_content_config;
|
||||
if (fc->options == options)
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
|
||||
fc->options = options;
|
||||
fit_cache_clear(fc, FIT_CACHE_ALL);
|
||||
fit_text_block(obj);
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
EAPI int evas_textblock_fit_options_get(const Evas_Object *obj, unsigned int *p_options)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EVAS_ERROR_INVALID_PARAM);
|
||||
Efl_Canvas_Textblock_Data *o = efl_data_scope_get(obj, MY_CLASS);
|
||||
TEXT_FIT_CONTENT_CONFIG * fc = &o->fit_content_config;
|
||||
if (p_options)
|
||||
*p_options = fc->options;
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
EAPI int evas_textblock_fit_size_range_set(Evas_Object *obj, unsigned int min_font_size, unsigned int max_font_size)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EVAS_ERROR_INVALID_PARAM);
|
||||
Efl_Canvas_Textblock_Data *o = efl_data_scope_get(obj, MY_CLASS);
|
||||
TEXT_FIT_CONTENT_CONFIG * fc = &o->fit_content_config;
|
||||
|
||||
Eina_Bool max_changed = fc->max_font_size != max_font_size;
|
||||
Eina_Bool min_changed = fc->min_font_size != min_font_size;
|
||||
|
||||
/* last_selected_size used for optimization calculations
|
||||
* If last_size_index already recach last element in p_size_array
|
||||
* Skip optimization by setting last_selected_size to -1
|
||||
*/
|
||||
int last_selected_size = fc->last_size_index;
|
||||
if (last_selected_size == ((int)fc->size_list_length-1))
|
||||
last_selected_size = -1;
|
||||
|
||||
if (!max_changed && !min_changed)
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
|
||||
if (min_font_size < 0 || max_font_size <0)
|
||||
return EVAS_ERROR_INVALID_PARAM;
|
||||
|
||||
if (max_font_size < min_font_size)
|
||||
return EVAS_ERROR_INVALID_PARAM;
|
||||
|
||||
fc->max_font_size = max_font_size;
|
||||
fc->min_font_size = min_font_size;
|
||||
|
||||
int n_ret = EVAS_ERROR_SUCCESS;
|
||||
n_ret = fit_cache_clear(fc,FIT_CACHE_FORCE_REFIT);
|
||||
if (n_ret) return n_ret;
|
||||
n_ret = fit_fill_internal_list(fc);
|
||||
if (n_ret) return n_ret;
|
||||
|
||||
/* Optimization to reduce calculations
|
||||
* If only max size changed and last fit size index is still valid, then no need to recalculation
|
||||
* Where changing max font size will not change content of p_size_array for sizes < max_size
|
||||
*/
|
||||
if (min_changed || (last_selected_size == -1 || last_selected_size > ((int)fc->size_list_length-1)))
|
||||
{
|
||||
n_ret = fit_text_block(obj);
|
||||
if (n_ret) return n_ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Keep fit size index */
|
||||
fc->last_size_index = last_selected_size;
|
||||
}
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
EAPI int evas_textblock_fit_size_range_get(const Evas_Object *obj, unsigned int *p_min_font_size, unsigned int *p_max_font_size)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EVAS_ERROR_INVALID_PARAM);
|
||||
Efl_Canvas_Textblock_Data *o = efl_data_scope_get(obj, MY_CLASS);
|
||||
TEXT_FIT_CONTENT_CONFIG * fc = &o->fit_content_config;
|
||||
|
||||
if (p_min_font_size)
|
||||
*p_min_font_size = fc->min_font_size;
|
||||
|
||||
if (p_max_font_size)
|
||||
*p_max_font_size = fc->max_font_size;
|
||||
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
EAPI int evas_textblock_fit_step_size_set(Evas_Object *obj, unsigned int step_size)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EVAS_ERROR_INVALID_PARAM);
|
||||
Efl_Canvas_Textblock_Data *o = efl_data_scope_get(obj, MY_CLASS);
|
||||
TEXT_FIT_CONTENT_CONFIG * fc = &o->fit_content_config;
|
||||
if (fc->step_size == step_size)
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
|
||||
if (step_size == 0)
|
||||
return EVAS_ERROR_INVALID_PARAM;
|
||||
|
||||
fc->step_size = step_size;
|
||||
int n_ret = EVAS_ERROR_SUCCESS;
|
||||
n_ret = fit_cache_clear(fc, FIT_CACHE_FORCE_REFIT);
|
||||
if (n_ret) return n_ret;
|
||||
n_ret = fit_fill_internal_list(fc);
|
||||
if (n_ret) return n_ret;
|
||||
n_ret = fit_text_block(obj);
|
||||
if (n_ret) return n_ret;
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
EAPI int evas_textblock_fit_step_size_get(const Evas_Object *obj, unsigned int * p_step_size)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EVAS_ERROR_INVALID_PARAM);
|
||||
Efl_Canvas_Textblock_Data *o = efl_data_scope_get(obj, MY_CLASS);
|
||||
TEXT_FIT_CONTENT_CONFIG * fc = &o->fit_content_config;
|
||||
if (p_step_size)
|
||||
*p_step_size = fc->step_size;
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
int compareUINT(const void * a, const void * b)
|
||||
{
|
||||
unsigned int a_value = *(const unsigned int*)a;
|
||||
unsigned int b_value = *(const unsigned int*)b;
|
||||
|
||||
if(a_value > b_value) return 1;
|
||||
else if(a_value < b_value) return -1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
EAPI int evas_textblock_fit_size_array_set(Evas_Object *obj, const unsigned int *p_size_array, size_t size_array_len)
|
||||
{
|
||||
int n_ret = EVAS_ERROR_SUCCESS;
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EVAS_ERROR_INVALID_PARAM);
|
||||
Efl_Canvas_Textblock_Data *o = efl_data_scope_get(obj, MY_CLASS);
|
||||
TEXT_FIT_CONTENT_CONFIG * fc = &o->fit_content_config;
|
||||
if (size_array_len == 0)
|
||||
return EVAS_ERROR_INVALID_PARAM;
|
||||
|
||||
if (fc->p_size_array)
|
||||
{
|
||||
free(fc->p_size_array);
|
||||
fc->p_size_array = NULL;
|
||||
fc->size_list_length = 0;
|
||||
}
|
||||
|
||||
fc->p_size_array = malloc(sizeof(unsigned int) * size_array_len);
|
||||
if (!fc->p_size_array) return EVAS_ERROR_NO_MEMORY;
|
||||
memcpy(fc->p_size_array,p_size_array,sizeof(unsigned int) * size_array_len);
|
||||
fc->size_list_length = size_array_len;
|
||||
|
||||
fc->last_size_index = -1;
|
||||
|
||||
qsort(fc->p_size_array,fc->size_list_length,sizeof(unsigned int),compareUINT);
|
||||
|
||||
n_ret = fit_cache_clear(fc, FIT_CACHE_FORCE_REFIT);
|
||||
if (n_ret) return n_ret;
|
||||
n_ret = fit_text_block(obj);
|
||||
if (n_ret) return n_ret;
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
EAPI int evas_textblock_fit_size_array_get(const Evas_Object *obj, unsigned int *p_size_array, size_t *p_size_array_len, size_t passed_array_size)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EVAS_ERROR_INVALID_PARAM);
|
||||
Efl_Canvas_Textblock_Data *o = efl_data_scope_get(obj, MY_CLASS);
|
||||
TEXT_FIT_CONTENT_CONFIG * fc = &o->fit_content_config;
|
||||
if (p_size_array)
|
||||
{
|
||||
size_t num = MIN(passed_array_size,fc->size_list_length);
|
||||
memcpy(p_size_array,fc->p_size_array,sizeof(unsigned int)* num);
|
||||
}
|
||||
if (p_size_array_len)
|
||||
{
|
||||
*p_size_array_len = fc->size_list_length;
|
||||
}
|
||||
return EVAS_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
#include "canvas/efl_canvas_textblock.eo.c"
|
||||
#include "canvas/efl_canvas_textblock_eo.legacy.c"
|
||||
|
|
|
@ -1056,6 +1056,106 @@ EAPI void evas_textblock_cursor_char_delete(Evas_Textblock_Cursor *cur);
|
|||
* @ingroup Evas_Textblock
|
||||
*/
|
||||
EAPI Evas_Textblock_Cursor *evas_object_textblock_cursor_get(const Evas_Object *obj);
|
||||
|
||||
|
||||
|
||||
/* TEXT BLOCK FIT OPTIONS FLAGS*/
|
||||
#define TEXTBLOCK_FIT_MODE_NONE 0x0000
|
||||
#define TEXTBLOCK_FIT_MODE_WIDTH 0x0001
|
||||
#define TEXTBLOCK_FIT_MODE_HEIGHT 0x0002
|
||||
#define TEXTBLOCK_FIT_MODE_ALL 0x0003
|
||||
|
||||
/* TEXT BLOCK ERROR CODES*/
|
||||
/* FIXME this hould go to other public place*/
|
||||
#define EVAS_ERROR_SUCCESS 0x0000
|
||||
#define EVAS_ERROR_INVALID_PARAM 0x0001
|
||||
#define EVAS_ERROR_NO_MEMORY 0x0002
|
||||
#define EVAS_ERROR_INVALID_OPERATION 0x0003
|
||||
|
||||
|
||||
/** Get the object's content it options.
|
||||
*
|
||||
* @param obj The textblock object.
|
||||
* @param[out] options content fitting options.
|
||||
* @return Returns error code.
|
||||
*/
|
||||
EAPI int evas_textblock_fit_options_get(const Evas_Object *obj, unsigned int * p_options);
|
||||
|
||||
/** Set the object's content it options.
|
||||
*
|
||||
* @param obj The textblock object.
|
||||
* @param[in] options content fitting options.
|
||||
* @return Returns error code.
|
||||
*/
|
||||
EAPI int evas_textblock_fit_options_set(Evas_Object *obj, unsigned int options);
|
||||
|
||||
/** Get the object's max and min font sizes used for fitting content.
|
||||
*
|
||||
* @param obj The textblock object.
|
||||
* @param[out] p_min_font_size min font size used when fitting content.
|
||||
* @param[out] p_max_font_size max font size used when fitting content.
|
||||
* @return Returns error code.
|
||||
*/
|
||||
EAPI int evas_textblock_fit_size_range_get(const Evas_Object *obj, unsigned int *p_min_font_size, unsigned int *p_max_font_size);
|
||||
|
||||
/** Set the object's max and min font sizes used for fitting content.
|
||||
*
|
||||
* @param obj The textblock object.
|
||||
* @param[in] min_font_size min font size used when fitting content.
|
||||
* @param[in] max_font_size max font size used when fitting content.
|
||||
* @return Returns error code.
|
||||
*/
|
||||
EAPI int evas_textblock_fit_size_range_set(Evas_Object *obj, unsigned int min_font_size, unsigned int max_font_size);
|
||||
|
||||
|
||||
/** Get the object's fitting step size when trying fonts between min font size and
|
||||
* max font size.
|
||||
*
|
||||
* @param obj The textblock object.
|
||||
* @param[out] p_step_size step jumps between min and max font size.
|
||||
* @return Returns error code.
|
||||
*/
|
||||
EAPI int evas_textblock_fit_step_size_get(const Evas_Object *obj, unsigned int *p_step_size);
|
||||
|
||||
|
||||
/** Set the object's fitting step size when trying fonts between min font size and
|
||||
* max font size.
|
||||
*
|
||||
* @param obj The textblock object.
|
||||
* @param[out] step_size step jumps between min and max font size.
|
||||
* @return Returns error code.
|
||||
*/
|
||||
EAPI int evas_textblock_fit_step_size_set(Evas_Object *obj, unsigned int step_size);
|
||||
|
||||
/** Get copy of the object's fitting font size array used internally
|
||||
*
|
||||
* @param obj The textblock object.
|
||||
* @param[out] p_size_array pointer to size array (passing NULL will ignore filling array).
|
||||
* @param[out] p_size_array_len the length of internall font sizes array.
|
||||
* @param[out] request_size_array request to fill specific amount in p_size_array.
|
||||
* @return Returns error code.
|
||||
*/
|
||||
EAPI int evas_textblock_fit_size_array_get(const Evas_Object *obj, unsigned int *p_size_array, size_t *p_size_array_len,size_t request_size_array);
|
||||
|
||||
/** Set the object's fitting font size array that will be used internally
|
||||
* Changing fitting step_size,min_font_size,max_font size will generate new array
|
||||
* Internall array will be sorted
|
||||
*
|
||||
* @param obj The textblock object.
|
||||
* @param[in] p_size_array pointer to font sizes array.
|
||||
* @param[in] size_array_len the length passed font sizes array.
|
||||
* @return Returns error code.
|
||||
*/
|
||||
EAPI int evas_textblock_fit_size_array_set(Evas_Object *obj, const unsigned int *p_size_array, size_t size_array_len);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "canvas/efl_canvas_textblock_eo.legacy.h"
|
||||
/**
|
||||
* @}
|
||||
|
|
|
@ -4134,6 +4134,32 @@ EFL_START_TEST(evas_textblock_obstacle)
|
|||
}
|
||||
EFL_END_TEST;
|
||||
|
||||
EFL_START_TEST(evas_textblock_fit)
|
||||
{
|
||||
START_TB_TEST();
|
||||
Evas_Coord fw, fh,fw_new, fh_new;
|
||||
int n_ret;
|
||||
const char *buf =
|
||||
"This is an example text to demonstrate the textblock object"
|
||||
" with content fit feature.";
|
||||
evas_object_textblock_text_markup_set(tb, buf);
|
||||
evas_object_resize(tb, 300, 300);
|
||||
evas_object_textblock_size_formatted_get(tb, &fw, &fh);
|
||||
n_ret = evas_textblock_fit_options_set(tb,TEXTBLOCK_FIT_MODE_ALL);
|
||||
fail_if(n_ret != EVAS_ERROR_SUCCESS);
|
||||
n_ret = evas_textblock_fit_size_range_set(tb,1,50);
|
||||
fail_if(n_ret != EVAS_ERROR_SUCCESS);
|
||||
evas_object_textblock_size_formatted_get(tb, &fw_new, &fh_new);
|
||||
fail_if(fw_new == fw && fh_new == fh);
|
||||
unsigned int size_array[3] = {150,200,250};
|
||||
n_ret = evas_textblock_fit_size_array_set(tb,size_array,3);
|
||||
fail_if(n_ret != EVAS_ERROR_SUCCESS);
|
||||
evas_object_textblock_size_formatted_get(tb, &fw, &fh);
|
||||
fail_if(fw_new == fw && fh_new == fh);
|
||||
END_TB_TEST();
|
||||
}
|
||||
EFL_END_TEST;
|
||||
|
||||
#ifdef HAVE_HYPHEN
|
||||
static void
|
||||
_hyphenation_width_stress(Evas_Object *tb, Evas_Textblock_Cursor *cur)
|
||||
|
@ -4654,6 +4680,7 @@ void evas_test_textblock(TCase *tc)
|
|||
tcase_add_test(tc, evas_textblock_items);
|
||||
tcase_add_test(tc, evas_textblock_delete);
|
||||
tcase_add_test(tc, evas_textblock_obstacle);
|
||||
tcase_add_test(tc, evas_textblock_fit);
|
||||
#ifdef HAVE_HYPHEN
|
||||
tcase_add_test(tc, evas_textblock_hyphenation);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue