summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Faure <billiob@gmail.com>2015-09-02 23:02:29 +0200
committerBoris Faure <billiob@gmail.com>2016-03-12 18:42:50 +0100
commitb0d039aa02471c342523d11755dbb933f0ef5c83 (patch)
tree0383beb1b5b66532d53ce56e8faf725d225630f8
parentf3dc094310d794435a9c7beceef760d1ea913a39 (diff)
downloadefl-b0d039aa02471c342523d11755dbb933f0ef5c83.tar.gz
evas_text_grid: display bold/italic/bolditalic fonts if available
-rw-r--r--src/lib/evas/canvas/evas_object_textgrid.c420
1 files changed, 310 insertions, 110 deletions
diff --git a/src/lib/evas/canvas/evas_object_textgrid.c b/src/lib/evas/canvas/evas_object_textgrid.c
index 45aeab620b..75ac501552 100644
--- a/src/lib/evas/canvas/evas_object_textgrid.c
+++ b/src/lib/evas/canvas/evas_object_textgrid.c
@@ -36,7 +36,7 @@ struct _Evas_Textgrid_Data
const char *font_source;
const char *font_name;
Evas_Font_Size font_size;
- Evas_Font_Description *font_description;
+ Evas_Font_Description *font_description_normal;
Eina_Array palette_standard;
Eina_Array palette_extended;
@@ -44,7 +44,10 @@ struct _Evas_Textgrid_Data
int ascent;
- Evas_Font_Set *font;
+ Evas_Font_Set *font_normal;
+ Evas_Font_Set *font_bold;
+ Evas_Font_Set *font_italic;
+ Evas_Font_Set *font_bolditalic;
unsigned int changed : 1;
unsigned int core_change : 1;
@@ -75,9 +78,11 @@ struct _Evas_Object_Textgrid_Rect
struct _Evas_Object_Textgrid_Text
{
- unsigned char r, g, b, a;
- int x;
Evas_Text_Props text_props;
+ unsigned char r, g, b, a;
+ int x : 30;
+ unsigned char bold : 1;
+ unsigned char italic : 1;
};
struct _Evas_Object_Textgrid_Line
@@ -216,8 +221,14 @@ evas_object_textgrid_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
if (o->cur.rows) free(o->cur.rows);
if (o->cur.font_name) eina_stringshare_del(o->cur.font_name);
if (o->cur.font_source) eina_stringshare_del(o->cur.font_source);
- if (o->cur.font_description) evas_font_desc_unref(o->cur.font_description);
- if (o->font) evas_font_free(obj->layer->evas->evas, o->font);
+
+ if (o->cur.font_description_normal)
+ evas_font_desc_unref(o->cur.font_description_normal);
+ if (o->font_normal) evas_font_free(obj->layer->evas->evas, o->font_normal);
+ if (o->font_bold) evas_font_free(obj->layer->evas->evas, o->font_bold);
+ if (o->font_italic) evas_font_free(obj->layer->evas->evas, o->font_italic);
+ if (o->font_bolditalic) evas_font_free(obj->layer->evas->evas, o->font_bolditalic);
+
if (o->cur.cells) free(o->cur.cells);
while ((c = eina_array_pop(&o->cur.palette_standard)))
free(c);
@@ -265,17 +276,58 @@ evas_object_textgrid_row_rect_append(Evas_Object_Textgrid_Row *row,
row->rects[row->rects_num - 1].a = a;
}
+static Evas_Font_Set *
+_textgrid_font_get(Evas_Textgrid_Data *o,
+ Eina_Bool is_bold,
+ Eina_Bool is_italic)
+{
+ if ((!is_bold) && (!is_italic))
+ return o->font_normal;
+ /* bold */
+ else if ((is_bold) && (!is_italic))
+ {
+ if (o->font_bold)
+ return o->font_bold;
+ else
+ return o->font_normal;
+ }
+ /* italic */
+ else if ((!is_bold) && (is_italic))
+ {
+ if (o->font_italic)
+ return o->font_italic;
+ else
+ return o->font_normal;
+ }
+ /* bolditalic */
+ else
+ {
+ if (o->font_bolditalic)
+ return o->font_bolditalic;
+ else if (o->font_italic)
+ return o->font_italic;
+ else if (o->font_bold)
+ return o->font_bold;
+ else
+ return o->font_normal;
+ }
+}
+
static void
evas_object_textgrid_row_text_append(Evas_Object_Textgrid_Row *row,
Evas_Object_Protected_Data *obj,
Evas_Textgrid_Data *o,
int x,
Eina_Unicode codepoint,
- int r, int g, int b, int a)
+ int r, int g, int b, int a,
+ Eina_Bool is_bold,
+ Eina_Bool is_italic)
{
Evas_Script_Type script;
Evas_Font_Instance *script_fi = NULL;
Evas_Font_Instance *cur_fi = NULL;
+ Evas_Object_Textgrid_Text *text;
+ Evas_Font_Set *font;
row->texts_num++;
if (row->texts_num > row->texts_alloc)
@@ -293,23 +345,24 @@ evas_object_textgrid_row_text_append(Evas_Object_Textgrid_Row *row,
}
script = evas_common_language_script_type_get(&codepoint, 1);
- ENFN->font_run_end_get(ENDT, o->font, &script_fi, &cur_fi,
+ text = &row->texts[row->texts_num - 1];
+ text->bold = is_bold;
+ text->italic = is_italic;
+ font = _textgrid_font_get(o, is_bold, is_italic);
+ ENFN->font_run_end_get(ENDT, font, &script_fi, &cur_fi,
script, &codepoint, 1);
- memset(&(row->texts[row->texts_num - 1].text_props), 0,
- sizeof(Evas_Text_Props));
- evas_common_text_props_script_set
- (&(row->texts[row->texts_num - 1].text_props), script);
- ENFN->font_text_props_info_create
- (ENDT, script_fi, &codepoint,
- &(row->texts[row->texts_num - 1].text_props), NULL, 0, 1,
- EVAS_TEXT_PROPS_MODE_NONE,
- o->cur.font_description->lang);
-
- row->texts[row->texts_num - 1].x = x;
- row->texts[row->texts_num - 1].r = r;
- row->texts[row->texts_num - 1].g = g;
- row->texts[row->texts_num - 1].b = b;
- row->texts[row->texts_num - 1].a = a;
+ memset(&(text->text_props), 0, sizeof(Evas_Text_Props));
+ evas_common_text_props_script_set(&(text->text_props), script);
+ ENFN->font_text_props_info_create(ENDT, script_fi, &codepoint,
+ &(text->text_props), NULL, 0, 1,
+ EVAS_TEXT_PROPS_MODE_NONE,
+ o->cur.font_description_normal->lang);
+
+ text->x = x;
+ text->r = r;
+ text->g = g;
+ text->b = b;
+ text->a = a;
}
static void
@@ -352,9 +405,10 @@ _drop_glyphs_ref(const void *container EINA_UNUSED, void *data, void *fdata)
static void
evas_object_textgrid_render(Evas_Object *eo_obj EINA_UNUSED,
- Evas_Object_Protected_Data *obj,
- void *type_private_data,
- void *output, void *context, void *surface, int x, int y, Eina_Bool do_async)
+ Evas_Object_Protected_Data *obj,
+ void *type_private_data,
+ void *output, void *context, void *surface,
+ int x, int y, Eina_Bool do_async)
{
Evas_Textgrid_Cell *cells;
Evas_Object_Textgrid_Color *c;
@@ -367,7 +421,7 @@ evas_object_textgrid_render(Evas_Object *eo_obj EINA_UNUSED,
ENFN->context_multiplier_unset(output, context);
ENFN->context_render_op_set(output, context, obj->cur->render_op);
- if (!(o->font) || (!o->cur.cells)) return;
+ if (!(o->font_normal) || (!o->cur.cells)) return;
w = o->cur.char_width;
h = o->cur.char_height;
@@ -439,7 +493,9 @@ evas_object_textgrid_render(Evas_Object *eo_obj EINA_UNUSED,
evas_object_textgrid_row_text_append(row, obj,
o, xp,
cells->codepoint,
- c->r, c->g, c->b, c->a);
+ c->r, c->g, c->b, c->a,
+ cells->bold,
+ cells->italic);
// XXX: underlines and strikethroughs dont get
// merged into horizontal runs like bg rects above
if (cells->underline)
@@ -484,57 +540,82 @@ evas_object_textgrid_render(Evas_Object *eo_obj EINA_UNUSED,
{
if ((do_async) && (ENFN->multi_font_draw))
{
+ Evas_Font_Set *font, *current_font;
Eina_Bool async_unref;
- Evas_Font_Array_Data *fad;
-
- texts = malloc(sizeof(*texts));
- texts->array = eina_inarray_new(sizeof(Evas_Font_Array_Data), 1); /* FIXME: Wasting 1 int here */
- texts->refcount = 1;
+ Evas_Object_Textgrid_Text *text;
- fad = eina_inarray_grow(texts->array, row->texts_num);
- if (!fad)
- {
- ERR("Failed to allocate Evas_Font_Array_Data.");
- eina_inarray_free(texts->array);
- free(texts);
- return;
- }
-
- for (xx = 0; xx < row->texts_num; xx++)
+ xx = 0;
+ do
{
- Evas_Text_Props *props;
-
- props = &row->texts[xx].text_props;
-
- evas_common_font_draw_prepare(props);
-
- evas_common_font_glyphs_ref(props->glyphs);
- evas_unref_queue_glyph_put(obj->layer->evas,
- props->glyphs);
-
- fad->color.r = row->texts[xx].r;
- fad->color.g = row->texts[xx].g;
- fad->color.b = row->texts[xx].b;
- fad->color.a = row->texts[xx].a;
- fad->x = row->texts[xx].x;
- fad->glyphs = props->glyphs;
-
- fad++;
- }
-
- async_unref =
- ENFN->multi_font_draw(output, context, surface,
- o->font, xp, yp + o->ascent,
- ww, hh, ww, hh, texts, do_async);
- if (async_unref)
- evas_unref_queue_texts_put(obj->layer->evas, texts);
- else
- {
- eina_inarray_foreach(texts->array, _drop_glyphs_ref,
- obj->layer->evas);
- eina_inarray_free(texts->array);
- free(texts);
+ texts = malloc(sizeof(*texts));
+ if (!texts)
+ {
+ ERR("Failed to allocate Evas_Font_Array.");
+ return;
+ }
+ texts->array = eina_inarray_new(sizeof(Evas_Font_Array_Data), 1);
+ texts->refcount = 1;
+
+ text = &row->texts[xx];
+ font = _textgrid_font_get(o, text->bold, text->italic);
+
+ do
+ {
+ Evas_Font_Array_Data *fad;
+ Evas_Text_Props *props;
+
+ current_font = font;
+
+ props = &text->text_props;
+ evas_common_font_draw_prepare(props);
+
+ evas_common_font_glyphs_ref(props->glyphs);
+ evas_unref_queue_glyph_put(obj->layer->evas,
+ props->glyphs);
+
+ fad = eina_inarray_grow(texts->array, 1);
+ if (!fad)
+ {
+ ERR("Failed to allocate Evas_Font_Array_Data.");
+ eina_inarray_free(texts->array);
+ free(texts);
+ return;
+ }
+ fad->color.r = text->r;
+ fad->color.g = text->g;
+ fad->color.b = text->b;
+ fad->color.a = text->a;
+ fad->x = text->x;
+ fad->glyphs = props->glyphs;
+
+ fad++;
+
+ xx++;
+ if (xx >= row->texts_num)
+ break;
+ text = &row->texts[xx];
+ font = _textgrid_font_get(o, text->bold,
+ text->italic);
+ }
+ while (font == current_font);
+
+ async_unref =
+ ENFN->multi_font_draw(output, context, surface,
+ current_font,
+ xp,
+ yp + o->ascent,
+ ww, hh, ww, hh, texts, do_async);
+ if (async_unref)
+ evas_unref_queue_texts_put(obj->layer->evas, texts);
+ else
+ {
+ eina_inarray_foreach(texts->array, _drop_glyphs_ref,
+ obj->layer->evas);
+ eina_inarray_free(texts->array);
+ free(texts);
+ }
}
+ while (xx < row->texts_num);
}
else
{
@@ -542,20 +623,23 @@ evas_object_textgrid_render(Evas_Object *eo_obj EINA_UNUSED,
{
Evas_Text_Props *props;
unsigned int r, g, b, a;
- int tx = xp + row->texts[xx].x;
+ Evas_Object_Textgrid_Text *text = &row->texts[xx];
+ int tx = xp + text->x;
int ty = yp + o->ascent;
+ Evas_Font_Set *font;
- props = &row->texts[xx].text_props;
+ props = &text->text_props;
- r = row->texts[xx].r;
- g = row->texts[xx].g;
- b = row->texts[xx].b;
- a = row->texts[xx].a;
+ r = text->r;
+ g = text->g;
+ b = text->b;
+ a = text->a;
ENFN->context_color_set(output, context,
r, g, b, a);
+ font = _textgrid_font_get(o, text->bold, text->italic);
evas_font_draw_async_check(obj, output, context, surface,
- o->font, tx, ty, ww, hh,
+ font, tx, ty, ww, hh,
ww, hh, props, do_async);
}
}
@@ -758,7 +842,7 @@ evas_object_textgrid_engine_data_get(Evas_Object *eo_obj)
{
Evas_Textgrid_Data *o = eo_data_scope_get(eo_obj, MY_CLASS);
if (!o) return NULL;
- return o->font;
+ return o->font_normal; /* TODO: why ? */
}
static int
@@ -899,35 +983,89 @@ _evas_textgrid_efl_text_properties_font_source_get(Eo *eo_obj EINA_UNUSED, Evas_
return o->cur.font_source;
}
+static int
+_alternate_font_weight_slant(Evas_Object_Protected_Data *obj,
+ Evas_Textgrid_Data *o,
+ Evas_Font_Set **fontp,
+ Evas_Font_Description *fdesc)
+{
+ int ret = -1;
+ Evas_Font_Set *font;
+
+ font = evas_font_load(obj->layer->evas->evas,
+ fdesc,
+ o->cur.font_source,
+ (int)(((double) o->cur.font_size) *
+ obj->cur->scale));
+ if (font)
+ {
+ Eina_Unicode W[2] = { 'O', 0 };
+ Evas_Font_Instance *script_fi = NULL;
+ Evas_Font_Instance *cur_fi = NULL;
+ Evas_Text_Props text_props;
+ Evas_Script_Type script;
+ int advance, vadvance, ascent;
+
+ script = evas_common_language_script_type_get(W, 1);
+ ENFN->font_run_end_get(ENDT, font, &script_fi, &cur_fi,
+ script, W, 1);
+ memset(&text_props, 0, sizeof(Evas_Text_Props));
+ evas_common_text_props_script_set(&text_props, script);
+ ENFN->font_text_props_info_create(ENDT, script_fi, W, &text_props,
+ NULL, 0, 1,
+ EVAS_TEXT_PROPS_MODE_NONE,
+ fdesc->lang);
+ advance = ENFN->font_h_advance_get(ENDT, font, &text_props);
+ vadvance = ENFN->font_v_advance_get(ENDT, font, &text_props);
+ ascent = ENFN->font_ascent_get(ENDT, font);
+ if ((o->cur.char_width != advance) ||
+ (o->cur.char_height != vadvance) ||
+ (o->ascent != ascent))
+ {
+ evas_font_free(obj->layer->evas->evas, font);
+ }
+ else
+ {
+ *fontp = font;
+ ret = 0;
+ }
+ evas_common_text_props_content_unref(&text_props);
+ }
+ return ret;
+}
+
EOLIAN static void
-_evas_textgrid_efl_text_properties_font_set(Eo *eo_obj, Evas_Textgrid_Data *o, const char *font_name, Evas_Font_Size font_size)
+_evas_textgrid_efl_text_properties_font_set(Eo *eo_obj,
+ Evas_Textgrid_Data *o,
+ const char *font_name,
+ Evas_Font_Size font_size)
{
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
Eina_Bool is, was = EINA_FALSE;
Eina_Bool pass = EINA_FALSE, freeze = EINA_FALSE;
Eina_Bool source_invisible = EINA_FALSE;
- Evas_Font_Description *font_description;
-
+ Evas_Font_Description *fdesc;
+
if ((!font_name) || (!*font_name) || (font_size <= 0))
return;
evas_object_async_block(obj);
- font_description = evas_font_desc_new();
-
+ fdesc = evas_font_desc_new();
/* Set default language according to locale. */
- eina_stringshare_replace(&(font_description->lang),
+ eina_stringshare_replace(&(fdesc->lang),
evas_font_lang_normalize("auto"));
- evas_font_name_parse(font_description, font_name);
- if (o->cur.font_description &&
- !evas_font_desc_cmp(font_description, o->cur.font_description) &&
+ evas_font_name_parse(fdesc, font_name);
+ if (o->cur.font_description_normal &&
+ !evas_font_desc_cmp(fdesc, o->cur.font_description_normal) &&
(font_size == o->cur.font_size))
{
- evas_font_desc_unref(font_description);
+ evas_font_desc_unref(fdesc);
return;
}
- if (o->cur.font_description) evas_font_desc_unref(o->cur.font_description);
- o->cur.font_description = font_description;
+ if (o->cur.font_description_normal)
+ evas_font_desc_unref(o->cur.font_description_normal);
+ o->cur.font_description_normal = fdesc;
o->cur.font_size = font_size;
eina_stringshare_replace(&o->cur.font_name, font_name);
@@ -944,19 +1082,19 @@ _evas_textgrid_efl_text_properties_font_set(Eo *eo_obj, Evas_Textgrid_Data *o, c
obj->layer->evas->pointer.y,
1, 1);
}
-
- /* DO IT */
- if (o->font)
+
+ if (o->font_normal)
{
- evas_font_free(obj->layer->evas->evas, o->font);
- o->font = NULL;
+ evas_font_free(obj->layer->evas->evas, o->font_normal);
+ o->font_normal = NULL;
}
-
- o->font = evas_font_load(obj->layer->evas->evas, o->cur.font_description,
+
+ o->font_normal = evas_font_load(obj->layer->evas->evas,
+ o->cur.font_description_normal,
o->cur.font_source,
- (int)(((double) o->cur.font_size) *
+ (int)(((double) o->cur.font_size) *
obj->cur->scale));
- if (o->font)
+ if (o->font_normal)
{
Eina_Unicode W[2] = { 'O', 0 };
Evas_Font_Instance *script_fi = NULL;
@@ -964,21 +1102,21 @@ _evas_textgrid_efl_text_properties_font_set(Eo *eo_obj, Evas_Textgrid_Data *o, c
Evas_Text_Props text_props;
Evas_Script_Type script;
int advance, vadvance;
-
+
script = evas_common_language_script_type_get(W, 1);
- ENFN->font_run_end_get(ENDT, o->font, &script_fi, &cur_fi,
+ ENFN->font_run_end_get(ENDT, o->font_normal, &script_fi, &cur_fi,
script, W, 1);
memset(&text_props, 0, sizeof(Evas_Text_Props));
evas_common_text_props_script_set(&text_props, script);
ENFN->font_text_props_info_create(ENDT, script_fi, W, &text_props,
NULL, 0, 1,
EVAS_TEXT_PROPS_MODE_NONE,
- o->cur.font_description->lang);
- advance = ENFN->font_h_advance_get(ENDT, o->font, &text_props);
- vadvance = ENFN->font_v_advance_get(ENDT, o->font, &text_props);
+ fdesc->lang);
+ advance = ENFN->font_h_advance_get(ENDT, o->font_normal, &text_props);
+ vadvance = ENFN->font_v_advance_get(ENDT, o->font_normal, &text_props);
o->cur.char_width = advance;
o->cur.char_height = vadvance;
- o->ascent = ENFN->font_ascent_get(ENDT, o->font);;
+ o->ascent = ENFN->font_ascent_get(ENDT, o->font_normal);
evas_common_text_props_content_unref(&text_props);
}
else
@@ -993,6 +1131,68 @@ _evas_textgrid_efl_text_properties_font_set(Eo *eo_obj, Evas_Textgrid_Data *o, c
o->ascent = 0;
}
+ /* Bold */
+ if (o->font_bold)
+ {
+ evas_font_free(obj->layer->evas->evas, o->font_bold);
+ o->font_bold = NULL;
+ }
+ if (fdesc->weight == EVAS_FONT_WEIGHT_NORMAL)
+ {
+ Evas_Font_Description *bold_desc = evas_font_desc_dup(fdesc);
+ bold_desc->weight = EVAS_FONT_WEIGHT_BOLD;
+ _alternate_font_weight_slant(obj, o, &o->font_bold, bold_desc);
+ evas_font_desc_unref(bold_desc);
+ }
+
+ /* Italic */
+ if (o->font_italic)
+ {
+ evas_font_free(obj->layer->evas->evas, o->font_italic);
+ o->font_italic = NULL;
+ }
+ if (fdesc->slant == EVAS_FONT_SLANT_NORMAL)
+ {
+ Evas_Font_Description *italic_desc = evas_font_desc_dup(fdesc);
+ int ret;
+
+ italic_desc->slant = EVAS_FONT_SLANT_ITALIC;
+ ret = _alternate_font_weight_slant(obj, o, &o->font_italic,
+ italic_desc);
+ if (ret != 0)
+ {
+ italic_desc->slant = EVAS_FONT_SLANT_OBLIQUE;
+ _alternate_font_weight_slant(obj, o, &o->font_italic,
+ italic_desc);
+ }
+ evas_font_desc_unref(italic_desc);
+ }
+
+ /* BoldItalic */
+ if (o->font_bolditalic)
+ {
+ evas_font_free(obj->layer->evas->evas, o->font_bolditalic);
+ o->font_bolditalic = NULL;
+ }
+ if (fdesc->slant == EVAS_FONT_SLANT_NORMAL &&
+ fdesc->weight == EVAS_FONT_WEIGHT_NORMAL)
+ {
+ Evas_Font_Description *bolditalic_desc = evas_font_desc_dup(fdesc);
+ int ret;
+
+ bolditalic_desc->slant = EVAS_FONT_SLANT_ITALIC;
+ bolditalic_desc->weight = EVAS_FONT_WEIGHT_BOLD;
+ ret = _alternate_font_weight_slant(obj, o, &o->font_bolditalic,
+ bolditalic_desc);
+ if (ret != 0)
+ {
+ bolditalic_desc->slant = EVAS_FONT_SLANT_OBLIQUE;
+ _alternate_font_weight_slant(obj, o, &o->font_bolditalic,
+ bolditalic_desc);
+ }
+ evas_font_desc_unref(bolditalic_desc);
+ }
+
o->changed = 1;
evas_object_change(eo_obj, obj);
evas_object_clip_dirty(eo_obj, obj);