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);
+/* TIZEN_ONLY(20191112): content fit feature */
+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);
+/* END */
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);
{"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},
+ /* TIZEN_ONLY(20191112): content fit feature */
+ {"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},
+ /* END */
{"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},
ed->text.fit_y = parse_bool(1);
}
+/* TIZEN_ONLY(20191112): content fit feature */
+/**
+ @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);
+ }
+}
+
+/* END */
+
/**
@page edcref
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);
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);
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)
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);
+ /* TIZEN_ONLY(20191112): content fit feature */
+ 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);
+ /* END */
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);
int id_text_source; /* -1 if none */
int size_range_min;
int size_range_max; /* -1 means, no bound. */
+ /* TIZEN_ONLY(20191112): content fit feature */
+ unsigned int fit_step;
+ /*FIXME THIS SHOULD BE EINA_LIST*/
+ Eina_List *fit_size_array;
+ /* END */
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 */
#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.
if (chosen_desc)
{
- Evas_Coord tw, th;
const char *text = "";
const char *style = "";
Evas_Textblock_Style *stl = NULL;
evas_object_textblock_text_markup_set(ep->object, text);
}
- /*****************************************************************************
- * TIZEN_ONLY(20170920): Calculate text.fit for multiline Textblock properly *
- *****************************************************************************
if ((chosen_desc->text.fit_x) || (chosen_desc->text.fit_y))
{
- double base_s = 1.0;
- double orig_s;
- double s = base_s;
-
- if (ep->part->scale) base_s = TO_DOUBLE(sc);
- efl_gfx_entity_scale_set(ep->object, base_s);
- efl_canvas_text_size_native_get(ep->object, &tw, &th);
-
- 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) / tw);
- efl_gfx_entity_scale_set(ep->object, orig_s);
- efl_canvas_text_size_native_get(ep->object, &tw, &th);
- }
- if (chosen_desc->text.fit_x)
- {
- if (tw > 0)
- {
- s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
- orig_s * TO_INT(params->eval.w) / tw);
- efl_gfx_entity_scale_set(ep->object, s);
- efl_canvas_text_size_native_get(ep->object, NULL, NULL);
- }
- }
- if (chosen_desc->text.fit_y)
+ 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)
{
- if (th > 0)
- {
- double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, base_s,
- orig_s * TO_INT(params->eval.h) / th);
- // 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_text_size_native_get(ep->object, NULL, NULL);
- }
+ size_array[size_array_len++] = *value;
}
- // 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.
- Evas_Coord fw, fh;
- efl_canvas_text_size_native_get(ep->object, &fw, &fh);
-
- // If we are still too big, try reducing the size to
- // 95% each try.
- while ((i > 0) &&
- ((chosen_desc->text.fit_x && (fw > TO_INT(params->eval.w))) ||
- (chosen_desc->text.fit_y && (fh > 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);
- efl_canvas_text_size_native_get(ep->object, &fw, &fh);
- i--;
- }
- }
- }
- */
- /**
- * FIXME: "size_range" option is not proper option for Textblock.
- * Textblock can have multiple font size. We need to support "fit_range"
- * to give size limitation as percentage.
- * ex) fit_range: 0.7 2.5; // 70% ~ 250%
- */
- if ((chosen_desc->text.fit_x) || (chosen_desc->text.fit_y))
- {
- double orig_scale = 1.0;
- double result_scale;
- double fit_x_scale;
- double fit_y_scale;
- int given_w, given_h;
-
- given_w = TO_INT(params->eval.w);
- given_h = TO_INT(params->eval.h);
-
- if (minw && *minw > given_w)
- given_w = *minw;
-
- if (minh && *minh > given_h)
- given_h = *minh;
-
- if (ep->part->scale) orig_scale = TO_DOUBLE(sc);
- efl_gfx_entity_scale_set(ep->object, orig_scale);
- evas_object_textblock_ellipsis_disabled_set(ep->object, EINA_TRUE);
- efl_gfx_entity_size_set(ep->object, EINA_SIZE2D(given_w, given_h));
-
- result_scale = 0.0;
- fit_x_scale = orig_scale;
- fit_y_scale = orig_scale;
+ unsigned int mode = TEXTBLOCK_FIT_MODE_NONE;
if (chosen_desc->text.fit_x)
- {
- efl_canvas_text_size_native_get(ep->object, &tw, NULL);
- if (tw > 0)
- {
- fit_x_scale = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, orig_scale,
- orig_scale * (double)given_w / tw);
- }
-
- result_scale = fit_x_scale;
- }
+ 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)
{
- efl_canvas_text_size_formatted_get(ep->object, NULL, &th);
- if (th > 0)
- {
- double given_size = (double)given_w * (double)given_w + (double)given_h * (double)given_h;
- double current_size = (double)given_w * (double)given_w + (double)th * (double)th;
-
- fit_y_scale = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, orig_scale,
- orig_scale * given_size / current_size);
- }
-
- if (!chosen_desc->text.fit_x)
- result_scale = fit_y_scale;
- else if (fit_y_scale < result_scale)
- result_scale = fit_y_scale;
- }
-
- efl_gfx_entity_scale_set(ep->object, result_scale);
- efl_canvas_text_size_native_get(ep->object, &tw, NULL);
- efl_canvas_text_size_formatted_get(ep->object, NULL, &th);
-
- /* Final tuning, try going down/up by 5% at a time, hoping it'll
- * actually end up being correct. */
- if (((chosen_desc->text.fit_x && (tw > given_w))) ||
- (chosen_desc->text.fit_y && (th > given_h)))
- {
- int i = 5; /* Tries before we give up. */
-
- while ((i > 0) &&
- ((chosen_desc->text.fit_x && (tw > given_w)) ||
- (chosen_desc->text.fit_y && (th > given_h))))
- {
- double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, orig_scale, result_scale * 0.95);
-
- /* Break if we are not making any progress. */
- if (fabs(tmp_s - result_scale) <= DBL_EPSILON)
- break;
- result_scale = tmp_s;
-
- efl_gfx_entity_scale_set(ep->object, result_scale);
- efl_canvas_text_size_native_get(ep->object, &tw, NULL);
- efl_canvas_text_size_formatted_get(ep->object, NULL, &th);
- i--;
- }
- }
- else if (((chosen_desc->text.fit_x && (tw < given_w)) ||
- (chosen_desc->text.fit_y && (th < given_h))))
- {
- int i = 5; /* Tries before we give up. */
-
- while ((i > 0) &&
- ((chosen_desc->text.fit_x && (tw < given_w)) ||
- (chosen_desc->text.fit_y && (th < given_h))))
- {
- double tmp_s = _edje_part_recalc_single_textblock_scale_range_adjust(chosen_desc, orig_scale, result_scale * 1.05);
-
- /* Break if we are not making any progress. */
- if (fabs(tmp_s - result_scale) <= DBL_EPSILON)
- break;
-
- efl_gfx_entity_scale_set(ep->object, tmp_s);
- efl_canvas_text_size_native_get(ep->object, &tw, NULL);
- efl_canvas_text_size_formatted_get(ep->object, NULL, &th);
-
- /* It can't be bigger than given size.
- * Restore scale for the object. */
- if (((chosen_desc->text.fit_x && (tw > given_w)) ||
- (chosen_desc->text.fit_y && (th > given_h))))
- {
- efl_gfx_entity_scale_set(ep->object, result_scale);
- break;
- }
-
- result_scale = tmp_s;
- i--;
- }
+ evas_textblock_fit_size_array_set(ep->object,size_array,size_array_len);
}
-
- evas_object_textblock_ellipsis_disabled_set(ep->object, EINA_FALSE);
}
- /*******
- * END *
- *******/
/* TIZEN_ONLY(20180103): don't run legacy calculation for Textblock parts
if ((ed->file->efl_version.major >= 1) && (ed->file->efl_version.minor >= 19))
0, /* 0, */ NULL, NULL); \
} while (0)
+/* TIZEN_ONLY(20191112): content fit feature */
+/**
+ * @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)
+/* END */
+
/**
* @ingroup Eet_Data_Group
* @brief Adds a hash type to a data descriptor.
* Text item filter properties (run context, output buffer, ...)
*/
typedef struct _Text_Item_Filter Text_Item_Filter;
+
+/* TIZEN_ONLY(20191112): content fit feature */
+/**
+ * @internal
+ * @typedef TEXT_FIT_CONTENT_CONFIG
+ * Configurations used to fit content inside Textblock
+ */
+typedef struct _TEXT_FIT_CONTENT_CONFIG TEXT_FIT_CONTENT_CONFIG;
+/* END */
+
/**
* @internal
* @def IS_AT_END(ti, ind)
Eina_Bool is_item : 1; /**< indicates it is an item/object placeholder */
};
+/* TIZEN_ONLY(20191112): content fit feature */
+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];
+};
+/* END */
+
#define _FMT(x) (o->default_format.format.x)
#define _FMT_INFO(x) (o->default_format.info.x)
Eina_Bool ellipsis_disabled : 1;
/* END */
+ /* TIZEN_ONLY(20191112): content fit feature */
+ TEXT_FIT_CONTENT_CONFIG fit_content_config;
+ Eina_Bool fit_in_progress : 1;
+ /* END */
Eina_Bool redraw : 1;
Eina_Bool changed : 1;
Eina_Bool pause_change : 1;
static void
_textblock_style_generic_set(Evas_Object *eo_obj, Evas_Textblock_Style *ts, const char *key);
+
+/* TIZEN_ONLY(20191112): content fit feature */
+/*********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;
+
+
+static void _canvas_text_format_changed(Eo *eo_obj, Efl_Canvas_Text_Data *o);
+/* END */
+
/** selection iterator */
/**
* @internal
finalize = EINA_TRUE;
}
}
+ /* TIZEN_ONLY(20191112): content fit feature */
+ /* 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);
+ }
+ /* END */
if (finalize)
_format_finalize(c->obj, c->fmt);
if (obj->delete_me) return EINA_TRUE;
/* XXX const */
- evas_object_textblock_coords_recalc((Evas_Object *)eo_obj, obj, obj->private_data);
+ /* TIZEN_ONLY(20191112): content fit feature */
+ if(!fit_is_fitting(eo_obj))
+ evas_object_textblock_coords_recalc((Evas_Object *)eo_obj, obj, obj->private_data);
+ /* END */
+
if (o->formatted.valid)
{
return EINA_TRUE;
_FMT(ellipsis) = -1;
_FMT_INFO(bitmap_scalable) = EFL_TEXT_FONT_BITMAP_SCALABLE_COLOR;
+ /* TIZEN_ONLY(20191112): content fit feature */
+ /* Fit default properties*/
+ evas_textblock_fit_size_range_set(eo_obj,1,255);
+ evas_textblock_fit_step_size_set(eo_obj,1);
+ /* END */
+
o->auto_styles = EINA_TRUE;
return eo_obj;
o->formatted.valid = 0;
o->native.valid = 0;
o->content_changed = 1;
- if (o->markup_text)
+ /* TIZEN_ONLY(20191112): content fit feature */
+ 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;
+ }
}
+ /* END */
// FIXME: emit ONCE after this following checks
_cursor_emit_if_changed(o->cursor);
_cursor_emit_if_changed(data_obj);
}
+ /* TIZEN_ONLY(20191112): content fit feature */
+ /*
+ 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);
+ }
+ /* END */
evas_object_change(eo_obj, obj);
}
/* remove obstacles */
_obstacles_free(eo_obj, o);
+ /* TIZEN_ONLY(20191112): content fit feature */
+ if (o->fit_content_config.p_size_array)
+ {
+ free(o->fit_content_config.p_size_array);
+ o->fit_content_config.p_size_array = NULL;
+ }
+ /* END */
#ifdef HAVE_HYPHEN
/* Hyphenation */
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,
o->formatted.valid = 0;
o->changed = 1;
}
+
+ /* TIZEN_ONLY(20191112): content fit feature */
+ 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);
+ }
+ /* END */
}
static void
eo_obj, is_v, was_v);
}
+/* TIZEN_ONLY(20191112): content fit feature */
+void fit_style_update(Evas_Object *object, int i_font_size, Eina_Bool disable_ellipsis, Eina_Bool disable_wrap)
+{
+ Efl_Canvas_Text_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);
+}
+/* END */
+
static void
evas_object_textblock_render_post(Evas_Object *eo_obj EINA_UNUSED,
Evas_Object_Protected_Data *obj,
/* END */
/*******/
+
+
+/* TIZEN_ONLY(20191112): content fit feature */
+/* 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_Text_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_Text_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_Text_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_Text_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);
+ efl_canvas_text_size_formatted_get(eo_obj, &wf_new, &hf_new);
+ 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_Text_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_Text_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_Text_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_Text_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_Text_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_Text_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_Text_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_Text_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;
+}
+/* END */
+
#include "canvas/efl_canvas_text.eo.c"
#include "canvas/efl_canvas_text_eo.legacy.c"
#include "canvas/efl_canvas_text_factory.eo.c" // interface
*/
EAPI Evas_Textblock_Cursor *evas_object_textblock_cursor_get(const Evas_Object *obj);
+
+
+/* TIZEN_ONLY(20191112): content fit feature */
+/* 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);
+/* END */
+
+
+
+
+
+
+
+
+
#include "canvas/efl_canvas_text_eo.legacy.h"
/* TIZEN_ONLY(20180709): fix build failure caused by missing legacy types */