efl/src/lib/evas/canvas/evas_object_textgrid.c

1537 lines
51 KiB
C
Raw Normal View History

#include "evas_common_private.h" /* Includes evas_bidi_utils stuff. */
#include "evas_private.h"
#define MY_CLASS EVAS_TEXTGRID_CLASS
#define MY_CLASS_NAME "Evas_Textgrid"
/* private magic number for text objects */
static const char o_type[] = "textgrid";
/* private struct for line object internal data */
2014-03-09 05:21:41 -07:00
typedef struct _Evas_Textgrid_Data Evas_Textgrid_Data;
typedef struct _Evas_Object_Textgrid_Cell Evas_Object_Textgrid_Cell;
typedef struct _Evas_Object_Textgrid_Color Evas_Object_Textgrid_Color;
typedef struct _Evas_Object_Textgrid_Row Evas_Object_Textgrid_Row;
typedef struct _Evas_Object_Textgrid_Rect Evas_Object_Textgrid_Rect;
typedef struct _Evas_Object_Textgrid_Text Evas_Object_Textgrid_Text;
typedef struct _Evas_Object_Textgrid_Line Evas_Object_Textgrid_Line;
2014-03-09 05:21:41 -07:00
struct _Evas_Textgrid_Data
{
DATA32 magic;
struct {
int w, h;
int char_width;
int char_height;
Evas_Object_Textgrid_Row *rows;
Evas_Textgrid_Cell *cells;
const char *font_source;
const char *font_name;
Evas_Font_Size font_size;
Evas_Font_Description *font_description_normal;
Eina_Array palette_standard;
Eina_Array palette_extended;
Efl_Text_Font_Bitmap_Scalable bitmap_scalable;
} cur, prev;
int ascent;
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;
unsigned int row_change : 1;
unsigned int pal_change : 1;
};
struct _Evas_Object_Textgrid_Color
{
unsigned char r, g, b, a;
};
struct _Evas_Object_Textgrid_Row
{
int ch1, ch2; // change region, -1 == none
int rects_num, texts_num, lines_num;
int rects_alloc, texts_alloc, lines_alloc;
Evas_Object_Textgrid_Rect *rects; // rects + colors
Evas_Object_Textgrid_Text *texts; // text
Evas_Object_Textgrid_Line *lines; // underlines, strikethroughs
};
struct _Evas_Object_Textgrid_Rect
{
unsigned char r, g, b, a;
int x, w;
};
struct _Evas_Object_Textgrid_Text
{
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
{
unsigned char r, g, b, a;
int x, w, y;
};
/* private methods for textgrid objects */
static void evas_object_textgrid_init(Evas_Object *eo_obj);
static void evas_object_textgrid_render(Evas_Object *eo_obj,
Evas_Object_Protected_Data *obj,
void *type_private_data,
void *engine, void *output, void *context, void *surface,
int x, int y, Eina_Bool do_async);
static void evas_object_textgrid_render_pre(Evas_Object *eo_obj,
Evas_Object_Protected_Data *obj,
void *type_private_data);
static void evas_object_textgrid_render_post(Evas_Object *eo_obj,
Evas_Object_Protected_Data *obj,
void *type_private_data);
static unsigned int evas_object_textgrid_id_get(Evas_Object *eo_obj);
static unsigned int evas_object_textgrid_visual_id_get(Evas_Object *eo_obj);
static void *evas_object_textgrid_engine_data_get(Evas_Object *eo_obj);
static int evas_object_textgrid_is_opaque(Evas_Object *eo_obj,
Evas_Object_Protected_Data *obj,
void *type_private_data);
static int evas_object_textgrid_was_opaque(Evas_Object *eo_obj,
Evas_Object_Protected_Data *obj,
void *type_private_data);
static void evas_object_textgrid_scale_update(Evas_Object *eo_obj,
Evas_Object_Protected_Data *pd,
void *type_private_data);
static const Evas_Object_Func object_func =
{
/* methods (compulsory) */
NULL,
evas_object_textgrid_render,
evas_object_textgrid_render_pre,
evas_object_textgrid_render_post,
evas_object_textgrid_id_get,
evas_object_textgrid_visual_id_get,
evas_object_textgrid_engine_data_get,
/* these are optional. NULL = nothing */
NULL,
NULL,
NULL,
NULL,
evas_object_textgrid_is_opaque,
evas_object_textgrid_was_opaque,
NULL,
NULL,
NULL,
evas_object_textgrid_scale_update,
NULL,
NULL,
NULL,
NULL, // render_prepare
NULL
};
/* all nice and private */
static void
evas_object_textgrid_init(Evas_Object *eo_obj)
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
/* set up methods (compulsory) */
obj->func = &object_func;
obj->private_data = efl_data_ref(eo_obj, MY_CLASS);
obj->type = o_type;
2014-03-09 05:21:41 -07:00
Evas_Textgrid_Data *o = obj->private_data;
o->magic = MAGIC_OBJ_TEXTGRID;
o->prev.bitmap_scalable = o->cur.bitmap_scalable = EFL_TEXT_FONT_BITMAP_SCALABLE_COLOR;
o->prev = o->cur;
eina_array_step_set(&o->cur.palette_standard, sizeof (Eina_Array), 16);
eina_array_step_set(&o->cur.palette_extended, sizeof (Eina_Array), 16);
}
static void
evas_object_textgrid_row_clear(Evas_Textgrid_Data *o EINA_UNUSED,
Evas_Object_Textgrid_Row *r)
{
int i;
if (r->rects)
{
free(r->rects);
r->rects = NULL;
r->rects_num = 0;
r->rects_alloc = 0;
}
if (r->texts)
{
for (i = 0; i < r->texts_num; i++)
evas_common_text_props_content_unref(&(r->texts[i].text_props));
free(r->texts);
r->texts = NULL;
r->texts_num = 0;
r->texts_alloc = 0;
}
if (r->lines)
{
free(r->lines);
r->lines = NULL;
r->lines_num = 0;
r->lines_alloc = 0;
}
}
static void
evas_object_textgrid_rows_clear(Evas_Object *eo_obj)
{
int i;
Evas_Textgrid_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
if (!o->cur.rows) return;
for (i = 0; i < o->cur.h; i++)
{
evas_object_textgrid_row_clear(o, &(o->cur.rows[i]));
o->cur.rows[i].ch1 = 0;
o->cur.rows[i].ch2 = o->cur.w - 1;
}
}
static void
evas_object_textgrid_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
{
Evas_Object_Textgrid_Color *c;
Evas_Textgrid_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
/* free obj */
evas_object_textgrid_rows_clear(eo_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_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);
eina_array_flush(&o->cur.palette_standard);
while ((c = eina_array_pop(&o->cur.palette_extended)))
free(c);
eina_array_flush(&o->cur.palette_extended);
o->magic = 0;
}
2014-03-09 05:21:41 -07:00
EOLIAN static void
_evas_textgrid_efl_object_destructor(Eo *eo_obj, Evas_Textgrid_Data *o EINA_UNUSED)
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
evas_object_textgrid_free(eo_obj, obj);
efl_data_unref(eo_obj, obj->private_data);
efl_destructor(efl_super(eo_obj, MY_CLASS));
}
static void
evas_object_textgrid_row_rect_append(Evas_Object_Textgrid_Row *row,
int x, int w,
int r, int g, int b, int a)
{
row->rects_num++;
if (row->rects_num > row->rects_alloc)
{
Evas_Object_Textgrid_Rect *t;
row->rects_alloc += 8; // dont expect many rects per line
t = realloc(row->rects, sizeof(Evas_Object_Textgrid_Rect) * row->rects_alloc);
if (!t)
{
row->rects_num--;
return;
}
row->rects = t;
}
row->rects[row->rects_num - 1].x = x;
row->rects[row->rects_num - 1].w = w;
row->rects[row->rects_num - 1].r = r;
row->rects[row->rects_num - 1].g = g;
row->rects[row->rects_num - 1].b = b;
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,
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)
{
Evas_Object_Textgrid_Text *t;
row->texts_alloc += 32; // expect more text per line
t = realloc(row->texts, sizeof(Evas_Object_Textgrid_Text) * row->texts_alloc);
if (!t)
{
row->texts_num--;
return;
}
row->texts = t;
}
script = evas_common_language_script_type_get(&codepoint, 1);
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(ENC, font, &script_fi, &cur_fi,
script, &codepoint, 1);
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(ENC, 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
evas_object_textgrid_row_line_append(Evas_Object_Textgrid_Row *row, int x, int w, int y, int r, int g, int b, int a)
{
row->lines_num++;
if (row->lines_num > row->lines_alloc)
{
Evas_Object_Textgrid_Line *t;
row->lines_alloc += 8; // dont expect many lines per line
t = realloc(row->lines, sizeof(Evas_Object_Textgrid_Line) * row->lines_alloc);
if (!t)
{
row->lines_num--;
return;
}
row->lines = t;
}
row->lines[row->lines_num - 1].x = x;
row->lines[row->lines_num - 1].w = w;
row->lines[row->lines_num - 1].y = y;
row->lines[row->lines_num - 1].r = r;
row->lines[row->lines_num - 1].g = g;
row->lines[row->lines_num - 1].b = b;
row->lines[row->lines_num - 1].a = a;
}
static Eina_Bool
_drop_glyphs_ref(const void *container EINA_UNUSED, void *data, void *fdata)
{
Evas_Font_Array_Data *fad = data;
Evas_Public_Data *pd = fdata;
evas_common_font_glyphs_unref(fad->glyphs);
eina_array_pop(&pd->glyph_unref_queue);
return EINA_TRUE;
}
static void
evas_object_textgrid_render(Evas_Object *eo_obj EINA_UNUSED,
Evas_Object_Protected_Data *obj,
void *type_private_data,
void *engine, void *output, void *context, void *surface,
int x, int y, Eina_Bool do_async)
{
Evas_Textgrid_Cell *cells;
Evas_Object_Textgrid_Color *c;
Eina_Array *palette;
int xx, yy, xp, yp, w, h, ww, hh;
int rr = 0, rg = 0, rb = 0, ra = 0, rx = 0, rw = 0, run;
/* render object to surface with context, and offset by x,y */
2014-03-09 05:21:41 -07:00
Evas_Textgrid_Data *o = type_private_data;
ENFN->context_multiplier_unset(engine, context);
ENFN->context_render_op_set(engine, context, obj->cur->render_op);
if (!(o->font_normal) || (!o->cur.cells)) return;
w = o->cur.char_width;
h = o->cur.char_height;
ww = obj->cur->geometry.w;
hh = obj->cur->geometry.h;
// generate row data from cells (and only deal with rows that updated)
for (yy = 0, cells = o->cur.cells; yy < o->cur.h; yy++)
{
Evas_Object_Textgrid_Row *row = &(o->cur.rows[yy]);
if (row->ch1 < 0)
{
cells += o->cur.w;
continue;
}
row->ch1 = -1;
row->ch2 = 0;
run = 0;
xp = 0;
for (xx = 0; xx < o->cur.w; xx++, cells++)
{
if (cells->bg_extended) palette = &(o->cur.palette_extended);
else palette = &(o->cur.palette_standard);
if (cells->bg >= eina_array_count(palette)) c = NULL;
else c = eina_array_data_get(palette, cells->bg);
if ((c) && (c->a > 0))
{
if (!run)
{
run = 1;
rr = c->r;
rg = c->g;
rb = c->b;
ra = c->a;
rx = xp;
rw = w;
}
else if ((c->r != rr) || (c->g != rg) ||
(c->b != rb) || (c->a != ra))
{
evas_object_textgrid_row_rect_append(row, rx, rw,
rr, rg, rb, ra);
rr = c->r;
rg = c->g;
rb = c->b;
ra = c->a;
rx = xp;
rw = w;
}
else rw += w;
}
else if (run)
{
run = 0;
evas_object_textgrid_row_rect_append(row, rx, rw,
rr, rg, rb, ra);
}
if ((cells->codepoint > 0) || (cells->underline) ||
(cells->strikethrough))
{
if (cells->fg_extended) palette = &(o->cur.palette_extended);
else palette = &(o->cur.palette_standard);
if (cells->fg >= eina_array_count(palette)) c = NULL;
else c = eina_array_data_get(palette, cells->fg);
if ((c) && (c->a > 0))
{
if (cells->codepoint > 0)
evas_object_textgrid_row_text_append(row, obj,
o, xp,
cells->codepoint,
c->r, c->g, c->b, c->a,
cells->bold,
cells->italic);
// XXX: underlines and strikethroughs don't get
// merged into horizontal runs like bg rects above
if (cells->underline)
evas_object_textgrid_row_line_append(row, xp, w,
o->ascent + 1,
c->r, c->g, c->b, c->a);
if (cells->strikethrough)
evas_object_textgrid_row_line_append(row, xp, w,
((3 * o->ascent) / 4),
c->r, c->g, c->b, c->a);
}
}
xp += w;
}
if (run)
{
run = 0;
evas_object_textgrid_row_rect_append(row, rx, rw,
rr, rg, rb, ra);
}
}
yp = obj->cur->geometry.y + y;
// draw the row data that is generated from the cell array
for (yy = 0, cells = o->cur.cells; yy < o->cur.h; yy++)
{
Evas_Object_Textgrid_Row *row = &(o->cur.rows[yy]);
Evas_Font_Array *texts;
xp = obj->cur->geometry.x + x;
for (xx = 0; xx < row->rects_num; xx++)
{
ENFN->context_color_set(engine, context,
row->rects[xx].r, row->rects[xx].g,
row->rects[xx].b, row->rects[xx].a);
ENFN->context_cutout_target(engine, context,
xp + row->rects[xx].x, yp,
row->rects[xx].w, h);
ENFN->rectangle_draw(engine, output, context, surface,
xp + row->rects[xx].x, yp,
row->rects[xx].w, h,
do_async);
}
if (row->texts_num)
{
if ((do_async) && (ENFN->multi_font_draw))
{
Evas_Font_Set *font, *current_font;
Eina_Bool async_unref;
Evas_Object_Textgrid_Text *text;
xx = 0;
do
{
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);
ENFN->context_cutout_target(engine, context,
xp - w, yp + o->ascent - h,
w * 3, h * 3);
async_unref =
ENFN->multi_font_draw(engine, 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
{
for (xx = 0; xx < row->texts_num; xx++)
{
Evas_Text_Props *props;
unsigned int r, g, b, a;
Evas_Object_Textgrid_Text *text = &row->texts[xx];
int tx = xp + text->x;
int ty = yp + o->ascent;
Evas_Font_Set *font;
props = &text->text_props;
r = text->r;
g = text->g;
b = text->b;
a = text->a;
ENFN->context_color_set(engine, context,
r, g, b, a);
font = _textgrid_font_get(o, text->bold, text->italic);
ENFN->context_cutout_target(engine, context,
tx - w, ty - h,
w * 3, h * 3);
evas_font_draw_async_check(obj, engine, output, context, surface,
font, tx, ty, ww, hh,
ww, hh, props, do_async);
}
}
}
for (xx = 0; xx < row->lines_num; xx++)
{
ENFN->context_color_set(engine, context,
row->lines[xx].r, row->lines[xx].g,
row->lines[xx].b, row->lines[xx].a);
ENFN->context_cutout_target(engine, context,
xp + row->lines[xx].x, yp + row->lines[xx].y,
row->lines[xx].w, 1);
ENFN->rectangle_draw(engine, output, context, surface,
xp + row->lines[xx].x, yp + row->lines[xx].y,
row->lines[xx].w, 1,
do_async);
}
yp += h;
}
}
static void
evas_object_textgrid_render_pre(Evas_Object *eo_obj,
Evas_Object_Protected_Data *obj,
void *type_private_data)
{
int is_v, was_v;
2014-03-09 05:21:41 -07:00
Evas_Textgrid_Data *o = type_private_data;
/* don't pre-render the obj twice! */
if (obj->pre_render_done) return;
obj->pre_render_done = EINA_TRUE;
/* pre-render phase. This does anything an object needs to do just before */
/* rendering. That could mean loading the image data, retrieving it from */
/* elsewhere, decoding video, etc. */
/* When this is done the object needs to figure if it changed and */
/* if so what and where and add the appropriate redraw rectangles */
/* if someone is clipping this obj - go calculate the clipper */
if (obj->cur->clipper)
{
if (obj->cur->cache.clip.dirty)
evas_object_clip_recalc(obj->cur->clipper);
obj->cur->clipper->func->render_pre(obj->cur->clipper->object,
obj->cur->clipper,
obj->cur->clipper->private_data);
}
/* now figure what changed and add draw rects */
/* if it just became visible or invisible */
is_v = evas_object_is_visible(eo_obj, obj);
was_v = evas_object_was_visible(eo_obj, obj);
if (is_v != was_v)
{
evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes, eo_obj, is_v, was_v);
goto done;
}
if (obj->changed_map || obj->changed_src_visible)
{
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
eo_obj, obj);
goto done;
}
/* its not visible - we accounted for it appearing or not so just abort */
if (!is_v) goto done;
/* clipper changed this is in addition to anything else for obj */
evas_object_render_pre_clipper_change(&obj->layer->evas->clip_changes, eo_obj);
/* if we restacked (layer or just within a layer) and don't clip anyone */
if (obj->restack)
{
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
goto done;
}
/* if it changed color */
if ((obj->cur->color.r != obj->prev->color.r) ||
(obj->cur->color.g != obj->prev->color.g) ||
(obj->cur->color.b != obj->prev->color.b) ||
(obj->cur->color.a != obj->prev->color.a))
{
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
goto done;
}
/* if it changed geometry - and obviously not visibility or color */
/* calculate differences since we have a constant color fill */
/* we really only need to update the differences */
if ((obj->cur->geometry.x != obj->prev->geometry.x) ||
(obj->cur->geometry.y != obj->prev->geometry.y) ||
(obj->cur->geometry.w != obj->prev->geometry.w) ||
(obj->cur->geometry.h != obj->prev->geometry.h))
{
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
goto done;
}
if (obj->cur->render_op != obj->prev->render_op)
{
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
goto done;
}
if (!EINA_DBL_EQ(obj->cur->scale, obj->prev->scale))
{
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
goto done;
}
if (o->changed)
{
if (o->core_change)
{
if ((o->cur.h != o->prev.h) ||
(o->cur.w != o->prev.w) ||
(o->cur.font_size != o->prev.font_size) ||
((o->cur.font_name) && (o->prev.font_name) &&
(strcmp(o->cur.font_name, o->prev.font_name))) ||
((o->cur.font_name) && (!o->prev.font_name)) ||
((!o->cur.font_name) && (o->prev.font_name)))
{
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
eo_obj, obj);
goto done;
}
}
if (o->pal_change)
{
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
goto done;
}
if (o->row_change)
{
int i;
2014-03-09 05:21:41 -07:00
for (i = 0; i < o->cur.h; i++)
{
Evas_Object_Textgrid_Row *r = &(o->cur.rows[i]);
if (r->ch1 >= 0)
{
Evas_Coord chx, chy, chw, chh;
chx = r->ch1 * o->cur.char_width;
chy = i * o->cur.char_height;
chw = (r->ch2 - r->ch1 + 1) * o->cur.char_width;
chh = o->cur.char_height;
chx -= o->cur.char_width;
chy -= o->cur.char_height;
chw += o->cur.char_width * 2;
chh += o->cur.char_height * 2;
chx += obj->cur->geometry.x;
chy += obj->cur->geometry.y;
RECTS_CLIP_TO_RECT(chx, chy, chw, chh,
obj->cur->cache.clip.x,
obj->cur->cache.clip.y,
obj->cur->cache.clip.w,
obj->cur->cache.clip.h);
evas_add_rect(&obj->layer->evas->clip_changes,
chx, chy, chw, chh);
}
}
}
}
done:
o->core_change = 0;
o->row_change = 0;
o->pal_change = 0;
evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, eo_obj, is_v, was_v);
}
static void
evas render - drop eo overhead by using ptrs we already have several calls, specifically evas_object_change_reset, evas_object_cur_prev, and evas_object_clip_changes_clean that are called directly or indirectly as part of evas render on at least every active object if not more, were doing full eo obj lookups when their calling functions already all had the eo protected data looked up. tha's silly and just adds overhead we don't need. my test dropped _eo_obj_pointer_get overhead in perf profiles from 4.48% to 2.65%. see: 4.48% libeo.so.1.18.99 [.] _eo_obj_pointer_get 4.23% libevas.so.1.18.99 [.] evas_render_updates_internal 2.61% libevas.so.1.18.99 [.] evas_render_updates_internal_loop 1.68% libeo.so.1.18.99 [.] efl_data_scope_get 1.57% libc-2.24.so [.] _int_malloc 1.42% libevas.so.1.18.99 [.] evas_object_smart_changed_get 1.09% libevas.so.1.18.99 [.] evas_object_clip_recalc.part.37 1.08% libpthread-2.24.so [.] pthread_getspecific 1.05% libevas.so.1.18.99 [.] efl_canvas_object_class_get 1.01% libevas.so.1.18.99 [.] evas_object_cur_prev 0.99% libeo.so.1.18.99 [.] _efl_object_event_callback_legacy_call 0.87% libevas.so.1.18.99 [.] _evas_render_phase1_object_ctx_render_cache_append 0.82% libpthread-2.24.so [.] pthread_mutex_lock 0.81% libevas.so.1.18.99 [.] _evas_render_phase1_object_process 0.79% libc-2.24.so [.] _int_free vs now the improved: 4.82% libevas.so.1.18.99 [.] evas_render_updates_internal 3.44% libevas.so.1.18.99 [.] evas_render_updates_internal_loop 2.65% libeo.so.1.18.99 [.] _eo_obj_pointer_get 2.22% libc-2.24.so [.] _int_malloc 1.46% libevas.so.1.18.99 [.] evas_object_smart_changed_get 1.04% libeo.so.1.18.99 [.] _efl_object_event_callback_legacy_call 1.03% libevas.so.1.18.99 [.] _evas_render_phase1_object_ctx_render_cache_append 0.97% libeina.so.1.18.99 [.] eina_chained_mempool_malloc 0.93% libevas.so.1.18.99 [.] evas_object_clip_recalc.part.37 0.92% libpthread-2.24.so [.] pthread_mutex_lock 0.91% libevas.so.1.18.99 [.] _evas_render_phase1_object_process 0.84% libc-2.24.so [.] _int_free 0.84% libevas.so.1.18.99 [.] evas_object_cur_prev 0.83% libeina.so.1.18.99 [.] eina_chained_mempool_free 0.80% libeo.so.1.18.99 [.] efl_data_scope_get of course other things "increase their percentage" as oe overhead now dropped, and things seem to move around a bit, but it does make sense to do this with no downsides i can see as we already are accessing the protected data ptr in the parent func.
2017-02-03 18:31:55 -08:00
evas_object_textgrid_render_post(Evas_Object *eo_obj EINA_UNUSED,
Evas_Object_Protected_Data *obj,
void *type_private_data)
{
/* this moves the current data to the previous state parts of the object */
/* in whatever way is safest for the object. also if we don't need object */
/* data anymore we can free it if the object deems this is a good idea */
2014-03-09 05:21:41 -07:00
Evas_Textgrid_Data *o = type_private_data;
/* remove those pesky changes */
evas render - drop eo overhead by using ptrs we already have several calls, specifically evas_object_change_reset, evas_object_cur_prev, and evas_object_clip_changes_clean that are called directly or indirectly as part of evas render on at least every active object if not more, were doing full eo obj lookups when their calling functions already all had the eo protected data looked up. tha's silly and just adds overhead we don't need. my test dropped _eo_obj_pointer_get overhead in perf profiles from 4.48% to 2.65%. see: 4.48% libeo.so.1.18.99 [.] _eo_obj_pointer_get 4.23% libevas.so.1.18.99 [.] evas_render_updates_internal 2.61% libevas.so.1.18.99 [.] evas_render_updates_internal_loop 1.68% libeo.so.1.18.99 [.] efl_data_scope_get 1.57% libc-2.24.so [.] _int_malloc 1.42% libevas.so.1.18.99 [.] evas_object_smart_changed_get 1.09% libevas.so.1.18.99 [.] evas_object_clip_recalc.part.37 1.08% libpthread-2.24.so [.] pthread_getspecific 1.05% libevas.so.1.18.99 [.] efl_canvas_object_class_get 1.01% libevas.so.1.18.99 [.] evas_object_cur_prev 0.99% libeo.so.1.18.99 [.] _efl_object_event_callback_legacy_call 0.87% libevas.so.1.18.99 [.] _evas_render_phase1_object_ctx_render_cache_append 0.82% libpthread-2.24.so [.] pthread_mutex_lock 0.81% libevas.so.1.18.99 [.] _evas_render_phase1_object_process 0.79% libc-2.24.so [.] _int_free vs now the improved: 4.82% libevas.so.1.18.99 [.] evas_render_updates_internal 3.44% libevas.so.1.18.99 [.] evas_render_updates_internal_loop 2.65% libeo.so.1.18.99 [.] _eo_obj_pointer_get 2.22% libc-2.24.so [.] _int_malloc 1.46% libevas.so.1.18.99 [.] evas_object_smart_changed_get 1.04% libeo.so.1.18.99 [.] _efl_object_event_callback_legacy_call 1.03% libevas.so.1.18.99 [.] _evas_render_phase1_object_ctx_render_cache_append 0.97% libeina.so.1.18.99 [.] eina_chained_mempool_malloc 0.93% libevas.so.1.18.99 [.] evas_object_clip_recalc.part.37 0.92% libpthread-2.24.so [.] pthread_mutex_lock 0.91% libevas.so.1.18.99 [.] _evas_render_phase1_object_process 0.84% libc-2.24.so [.] _int_free 0.84% libevas.so.1.18.99 [.] evas_object_cur_prev 0.83% libeina.so.1.18.99 [.] eina_chained_mempool_free 0.80% libeo.so.1.18.99 [.] efl_data_scope_get of course other things "increase their percentage" as oe overhead now dropped, and things seem to move around a bit, but it does make sense to do this with no downsides i can see as we already are accessing the protected data ptr in the parent func.
2017-02-03 18:31:55 -08:00
evas_object_clip_changes_clean(obj);
/* move cur to prev safely for object data */
evas render - drop eo overhead by using ptrs we already have several calls, specifically evas_object_change_reset, evas_object_cur_prev, and evas_object_clip_changes_clean that are called directly or indirectly as part of evas render on at least every active object if not more, were doing full eo obj lookups when their calling functions already all had the eo protected data looked up. tha's silly and just adds overhead we don't need. my test dropped _eo_obj_pointer_get overhead in perf profiles from 4.48% to 2.65%. see: 4.48% libeo.so.1.18.99 [.] _eo_obj_pointer_get 4.23% libevas.so.1.18.99 [.] evas_render_updates_internal 2.61% libevas.so.1.18.99 [.] evas_render_updates_internal_loop 1.68% libeo.so.1.18.99 [.] efl_data_scope_get 1.57% libc-2.24.so [.] _int_malloc 1.42% libevas.so.1.18.99 [.] evas_object_smart_changed_get 1.09% libevas.so.1.18.99 [.] evas_object_clip_recalc.part.37 1.08% libpthread-2.24.so [.] pthread_getspecific 1.05% libevas.so.1.18.99 [.] efl_canvas_object_class_get 1.01% libevas.so.1.18.99 [.] evas_object_cur_prev 0.99% libeo.so.1.18.99 [.] _efl_object_event_callback_legacy_call 0.87% libevas.so.1.18.99 [.] _evas_render_phase1_object_ctx_render_cache_append 0.82% libpthread-2.24.so [.] pthread_mutex_lock 0.81% libevas.so.1.18.99 [.] _evas_render_phase1_object_process 0.79% libc-2.24.so [.] _int_free vs now the improved: 4.82% libevas.so.1.18.99 [.] evas_render_updates_internal 3.44% libevas.so.1.18.99 [.] evas_render_updates_internal_loop 2.65% libeo.so.1.18.99 [.] _eo_obj_pointer_get 2.22% libc-2.24.so [.] _int_malloc 1.46% libevas.so.1.18.99 [.] evas_object_smart_changed_get 1.04% libeo.so.1.18.99 [.] _efl_object_event_callback_legacy_call 1.03% libevas.so.1.18.99 [.] _evas_render_phase1_object_ctx_render_cache_append 0.97% libeina.so.1.18.99 [.] eina_chained_mempool_malloc 0.93% libevas.so.1.18.99 [.] evas_object_clip_recalc.part.37 0.92% libpthread-2.24.so [.] pthread_mutex_lock 0.91% libevas.so.1.18.99 [.] _evas_render_phase1_object_process 0.84% libc-2.24.so [.] _int_free 0.84% libevas.so.1.18.99 [.] evas_object_cur_prev 0.83% libeina.so.1.18.99 [.] eina_chained_mempool_free 0.80% libeo.so.1.18.99 [.] efl_data_scope_get of course other things "increase their percentage" as oe overhead now dropped, and things seem to move around a bit, but it does make sense to do this with no downsides i can see as we already are accessing the protected data ptr in the parent func.
2017-02-03 18:31:55 -08:00
evas_object_cur_prev(obj);
o->prev = o->cur;
}
static unsigned int
evas_object_textgrid_id_get(Evas_Object *eo_obj)
{
Evas_Textgrid_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
if (!o) return 0;
return MAGIC_OBJ_TEXTGRID;
}
static unsigned int
evas_object_textgrid_visual_id_get(Evas_Object *eo_obj)
{
Evas_Textgrid_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
if (!o) return 0;
return MAGIC_OBJ_SHAPE;
}
static void *
evas_object_textgrid_engine_data_get(Evas_Object *eo_obj)
{
Evas_Textgrid_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
if (!o) return NULL;
return o->font_normal; /* TODO: why ? */
}
static int
evas_object_textgrid_is_opaque(Evas_Object *eo_obj EINA_UNUSED,
Evas_Object_Protected_Data *obj EINA_UNUSED,
void *type_private_data EINA_UNUSED)
{
/* this returns 1 if the internal object data implies that the object is
currently fully opaque over the entire gradient it occupies */
return 0;
}
static int
evas_object_textgrid_was_opaque(Evas_Object *eo_obj EINA_UNUSED,
Evas_Object_Protected_Data *obj EINA_UNUSED,
void *type_private_data EINA_UNUSED)
{
/* this returns 1 if the internal object data implies that the object was
currently fully opaque over the entire gradient it occupies */
return 0;
}
static void
evas_object_textgrid_scale_update(Evas_Object *eo_obj,
Evas_Object_Protected_Data *pd EINA_UNUSED,
void *type_private_data)
{
int font_size;
const char *font_name;
2014-03-09 05:21:41 -07:00
Evas_Textgrid_Data *o = type_private_data;
font_name = eina_stringshare_add(o->cur.font_name);
font_size = o->cur.font_size;
if (o->cur.font_name) eina_stringshare_del(o->cur.font_name);
o->cur.font_name = NULL;
o->prev.font_name = NULL;
o->cur.font_size = 0;
o->prev.font_size = 0;
evas_object_textgrid_font_set(eo_obj, font_name, font_size);
eina_stringshare_del(font_name);
}
/********************* LOCAL *********************/
/********************* API *********************/
EAPI Evas_Object *
evas_object_textgrid_add(Evas *e)
{
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return NULL;
MAGIC_CHECK_END();
return efl_add(EVAS_TEXTGRID_CLASS, e, efl_canvas_object_legacy_ctor(efl_added));
}
EOLIAN static Eo *
_evas_textgrid_efl_object_constructor(Eo *eo_obj, Evas_Textgrid_Data *class_data EINA_UNUSED)
{
eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS));
evas_object_textgrid_init(eo_obj);
return eo_obj;
}
2014-03-09 05:21:41 -07:00
EOLIAN static void
_evas_textgrid_size_set(Eo *eo_obj, Evas_Textgrid_Data *o, int w, int h)
{
int i;
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
if ((h <= 0) || (w <= 0)) return;
if ((o->cur.w == w) && (o->cur.h == h)) return;
evas_object_async_block(obj);
evas_object_textgrid_rows_clear(eo_obj);
if (o->cur.rows)
{
free(o->cur.rows);
o->cur.rows = NULL;
}
if (o->cur.cells)
{
free(o->cur.cells);
o->cur.cells = NULL;
}
o->cur.cells = calloc(w * h, sizeof(Evas_Textgrid_Cell));
if (!o->cur.cells) return;
o->cur.rows = calloc(h, sizeof(Evas_Object_Textgrid_Row));
if (!o->cur.rows)
{
free(o->cur.cells);
o->cur.cells = NULL;
return;
}
for (i = 0; i < h; i++)
{
o->cur.rows[i].ch1 = 0;
o->cur.rows[i].ch2 = w - 1;
}
o->cur.w = w;
o->cur.h = h;
o->changed = 1;
o->core_change = 1;
evas_object_change(eo_obj, obj);
}
2014-03-09 05:21:41 -07:00
EOLIAN static void
_evas_textgrid_size_get(Eo *eo_obj EINA_UNUSED, Evas_Textgrid_Data *o, int *w, int *h)
{
if (w) *w = o->cur.w;
if (h) *h = o->cur.h;
}
2014-03-09 05:21:41 -07:00
EOLIAN static void
_evas_textgrid_efl_text_properties_font_source_set(Eo *eo_obj, Evas_Textgrid_Data *o, const char *font_source)
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
if ((!font_source) || (!*font_source))
return;
if ((o->cur.font_source) && (font_source) &&
(!strcmp(o->cur.font_source, font_source))) return;
evas_object_async_block(obj);
eina_stringshare_replace(&o->cur.font_source, font_source);
o->changed = 1;
o->core_change = 1;
evas_object_change(eo_obj, obj);
}
2014-03-09 05:21:41 -07:00
EOLIAN static const char*
_evas_textgrid_efl_text_properties_font_source_get(Eo *eo_obj EINA_UNUSED, Evas_Textgrid_Data *o)
{
2014-03-09 05:21:41 -07:00
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,
const char *kind)
{
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),
o->cur.bitmap_scalable);
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(ENC, 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(ENC, script_fi, W, &text_props,
NULL, 0, 1,
EVAS_TEXT_PROPS_MODE_NONE,
fdesc->lang);
advance = ENFN->font_h_advance_get(ENC, font, &text_props);
vadvance = ENFN->font_v_advance_get(ENC, font, &text_props);
ascent = ENFN->font_ascent_get(ENC, font);
DBG("on font '%s', with alternate weight/slant %s, "
"width: %d vs %d, height: %d vs %d, ascent: %d vs %d",
fdesc->name, kind,
o->cur.char_width, advance,
o->cur.char_height, vadvance,
o->ascent, ascent);
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);
}
else
{
DBG("cannot load font '%s' with alternate weight/slant %s",
fdesc->name, kind);
}
return ret;
}
static void
_evas_textgrid_font_reload(Eo *eo_obj, Evas_Textgrid_Data *o)
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
Eina_Bool pass = EINA_FALSE, freeze = EINA_FALSE;
Eina_Bool source_invisible = EINA_FALSE;
Evas_Font_Description *fdesc;
Eina_List *was = NULL;
fdesc = o->cur.font_description_normal;
if (!(obj->layer->evas->is_frozen))
{
pass = evas_event_passes_through(eo_obj, obj);
freeze = evas_event_freezes_through(eo_obj, obj);
source_invisible = evas_object_is_source_invisible(eo_obj, obj);
if ((!pass) && (!freeze) && (!source_invisible))
was = _evas_pointer_list_in_rect_get(obj->layer->evas, eo_obj, obj,
1, 1);
}
if (o->font_normal)
{
evas_font_free(obj->layer->evas->evas, o->font_normal);
o->font_normal = NULL;
}
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) *
obj->cur->scale),
o->cur.bitmap_scalable);
if (o->font_normal)
{
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;
script = evas_common_language_script_type_get(W, 1);
ENFN->font_run_end_get(ENC, 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(ENC, script_fi, W, &text_props,
NULL, 0, 1,
EVAS_TEXT_PROPS_MODE_NONE,
fdesc->lang);
advance = ENFN->font_h_advance_get(ENC, o->font_normal, &text_props);
vadvance = ENFN->font_v_advance_get(ENC, o->font_normal, &text_props);
o->cur.char_width = advance;
o->cur.char_height = vadvance;
o->ascent = ENFN->font_ascent_get(ENC, o->font_normal);
evas_common_text_props_content_unref(&text_props);
}
else
{
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
{
state_write->geometry.w = 0;
state_write->geometry.h = 0;
}
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
o->ascent = 0;
}
DBG("font: '%s' weight: %d, slant: %d",
fdesc->name, fdesc->weight, fdesc->slant);
/* 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) ||
(fdesc->weight == EVAS_FONT_WEIGHT_BOOK))
{
Evas_Font_Description *bold_desc = evas_font_desc_dup(fdesc);
eina_stringshare_del(bold_desc->style);
bold_desc->style = NULL;
bold_desc->weight = EVAS_FONT_WEIGHT_BOLD;
_alternate_font_weight_slant(obj, o, &o->font_bold, bold_desc,
"bold");
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;
eina_stringshare_del(italic_desc->style);
italic_desc->style = NULL;
italic_desc->slant = EVAS_FONT_SLANT_ITALIC;
ret = _alternate_font_weight_slant(obj, o, &o->font_italic,
italic_desc, "italic");
if (ret != 0)
{
italic_desc->slant = EVAS_FONT_SLANT_OBLIQUE;
_alternate_font_weight_slant(obj, o, &o->font_italic,
italic_desc,
"oblique");
}
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) ||
(fdesc->weight == EVAS_FONT_WEIGHT_BOOK)))
{
Evas_Font_Description *bolditalic_desc = evas_font_desc_dup(fdesc);
int ret;
eina_stringshare_del(bolditalic_desc->style);
bolditalic_desc->style = NULL;
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,
"bolditalic");
if (ret != 0)
{
bolditalic_desc->slant = EVAS_FONT_SLANT_OBLIQUE;
_alternate_font_weight_slant(obj, o, &o->font_bolditalic,
bolditalic_desc,
"boldoblique");
}
evas_font_desc_unref(bolditalic_desc);
}
o->changed = 1;
evas_object_change(eo_obj, obj);
evas_object_clip_dirty(eo_obj, obj);
evas_object_coords_recalc(eo_obj, obj);
if (!obj->layer->evas->is_frozen && !pass && !freeze && obj->cur->visible)
_evas_canvas_event_pointer_in_list_mouse_move_feed(obj->layer->evas, was, eo_obj, obj, 1, 1, EINA_TRUE, NULL);
eina_list_free(was);
evas_object_inform_call_resize(eo_obj);
o->changed = 1;
o->core_change = 1;
evas_object_textgrid_rows_clear(eo_obj);
evas_object_change(eo_obj, obj);
}
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_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
Evas_Font_Description *fdesc;
if ((!font_name) || (!*font_name) || (font_size <= 0))
return;
evas_object_async_block(obj);
fdesc = evas_font_desc_new();
/* Set default language according to locale. */
eina_stringshare_replace(&(fdesc->lang),
evas_font_lang_normalize("auto"));
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(fdesc);
return;
}
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);
o->prev.font_name = NULL;
_evas_textgrid_font_reload(eo_obj, o);
}
2014-03-09 05:21:41 -07:00
EOLIAN static void
_evas_textgrid_efl_text_properties_font_get(Eo *eo_obj EINA_UNUSED, Evas_Textgrid_Data *o, const char **font_name, Evas_Font_Size *font_size)
{
if (font_name) *font_name = o->cur.font_name;
if (font_size) *font_size = o->cur.font_size;
}
2014-03-09 05:21:41 -07:00
EOLIAN static void
_evas_textgrid_cell_size_get(Eo *eo_obj EINA_UNUSED, Evas_Textgrid_Data *o, int *w, int *h)
{
if (w) *w = o->cur.char_width;
if (h) *h = o->cur.char_height;
}
2014-03-09 05:21:41 -07:00
EOLIAN static void
_evas_textgrid_palette_set(Eo *eo_obj, Evas_Textgrid_Data *o, Evas_Textgrid_Palette pal, int idx, int r, int g, int b, int a)
{
Eina_Array *palette;
Evas_Object_Textgrid_Color *color, *c;
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
int count, i;
if ((idx < 0) || (idx > 255)) return;
if (a > 255) a = 255;
if (a < 0) a = 0;
if (r > 255) r = 255;
if (r < 0) r = 0;
if (g > 255) g = 255;
if (g < 0) g = 0;
if (b > 255) b = 255;
if (b < 0) b = 0;
if (r > a)
{
r = a;
ERR("Evas only handles pre multiplied colors!");
}
if (g > a)
{
g = a;
ERR("Evas only handles pre multiplied colors!");
}
if (b > a)
{
b = a;
ERR("Evas only handles pre multiplied colors!");
}
evas_object_async_block(obj);
switch (pal)
{
case EVAS_TEXTGRID_PALETTE_STANDARD:
palette = &(o->cur.palette_standard);
break;
case EVAS_TEXTGRID_PALETTE_EXTENDED:
palette = &(o->cur.palette_extended);
break;
default:
return;
}
count = eina_array_count(palette);
if (idx < count)
{
color = eina_array_data_get(palette, idx);
if (color->a == a &&
color->r == r &&
color->g == g &&
color->b == b)
2013-06-20 04:28:18 -07:00
return;
}
else
{
color = malloc(sizeof(Evas_Object_Textgrid_Color));
if (!color) return;
}
color->a = a;
color->r = r;
color->g = g;
color->b = b;
if (idx < count) eina_array_data_set(palette, idx, color);
else if (idx == count) eina_array_push(palette, color);
else
{
for (i = count; i < idx; i++)
{
c = calloc(1, sizeof(Evas_Object_Textgrid_Color));
if (!c)
{
ERR("Evas cannot allocate memory");
free(color);
return;
}
eina_array_push(palette, c);
}
eina_array_push(palette, color);
}
o->changed = 1;
o->pal_change = 1;
evas_object_textgrid_rows_clear(eo_obj);
evas_object_change(eo_obj, obj);
}
2014-03-09 05:21:41 -07:00
EOLIAN static void
_evas_textgrid_palette_get(const Eo *eo_obj EINA_UNUSED, Evas_Textgrid_Data *o, Evas_Textgrid_Palette pal, int idx, int *r, int *g, int *b, int *a)
{
Eina_Array *palette;
Evas_Object_Textgrid_Color *color;
if (idx < 0) return;
switch (pal)
{
case EVAS_TEXTGRID_PALETTE_STANDARD:
2014-03-09 05:21:41 -07:00
palette = &(((Evas_Textgrid_Data *)o)->cur.palette_standard);
break;
case EVAS_TEXTGRID_PALETTE_EXTENDED:
2014-03-09 05:21:41 -07:00
palette = &(((Evas_Textgrid_Data *)o)->cur.palette_extended);
break;
default:
return;
}
if (idx >= (int)eina_array_count(palette)) return;
color = eina_array_data_get(palette, idx);
if (!color) return;
if (a) *a = color->a;
if (r) *r = color->r;
if (g) *g = color->g;
if (b) *b = color->b;
}
2014-03-09 05:21:41 -07:00
EOLIAN static void
_evas_textgrid_supported_font_styles_set(Eo *eo_obj, Evas_Textgrid_Data *o, Evas_Textgrid_Font_Style styles)
{
/* FIXME: to do */
if (styles)
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
o->changed = 1;
evas_object_change(eo_obj, obj);
}
}
2014-03-09 05:21:41 -07:00
EOLIAN static Evas_Textgrid_Font_Style
_evas_textgrid_supported_font_styles_get(Eo *eo_obj EINA_UNUSED, Evas_Textgrid_Data *o EINA_UNUSED)
{
/* FIXME: to do */
return EVAS_TEXTGRID_FONT_STYLE_NORMAL;
}
2014-03-09 05:21:41 -07:00
EOLIAN static void
_evas_textgrid_cellrow_set(Eo *eo_obj EINA_UNUSED, Evas_Textgrid_Data *o, int y, const Evas_Textgrid_Cell *row)
{
if (!row) return;
if ((y < 0) || (y >= o->cur.h)) return;
}
2014-03-09 05:21:41 -07:00
EOLIAN static Evas_Textgrid_Cell*
_evas_textgrid_cellrow_get(const Eo *eo_obj EINA_UNUSED, Evas_Textgrid_Data *o, int y)
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
evas_object_async_block(obj);
if ((y < 0) || (y >= o->cur.h)) return NULL;
return o->cur.cells + (y * o->cur.w);
}
2014-03-09 05:21:41 -07:00
EOLIAN static void
_evas_textgrid_update_add(Eo *eo_obj, Evas_Textgrid_Data *o, int x, int y, int w, int h)
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
int i, x2;
RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, o->cur.w, o->cur.h);
if ((w <= 0) || (h <= 0)) return;
evas_object_async_block(obj);
x2 = x + w - 1;
for (i = 0; i < h; i++)
{
Evas_Object_Textgrid_Row *r = &(o->cur.rows[y + i]);
if (r->ch1 < 0)
{
evas_object_textgrid_row_clear(o, r);
r->ch1 = x;
r->ch2 = x2;
}
else
{
if (x < r->ch1) r->ch1 = x;
if (x2 > r->ch2) r->ch2 = x2;
}
}
o->row_change = 1;
o->changed = 1;
evas_object_change(eo_obj, obj);
}
2014-03-09 05:21:41 -07:00
EOLIAN static void
_evas_textgrid_efl_object_dbg_info_get(Eo *eo_obj, Evas_Textgrid_Data *o EINA_UNUSED, Efl_Dbg_Info *root)
{
efl_dbg_info_get(efl_super(eo_obj, MY_CLASS), root);
Efl_Dbg_Info *group = EFL_DBG_INFO_LIST_APPEND(root, MY_CLASS_NAME);
Efl_Dbg_Info *node;
const char *text;
int size;
efl_text_properties_font_get(eo_obj, &text, &size);
EFL_DBG_INFO_APPEND(group, "Font", EINA_VALUE_TYPE_STRING, text);
EFL_DBG_INFO_APPEND(group, "Text size", EINA_VALUE_TYPE_INT, size);
text = efl_text_properties_font_source_get(eo_obj);
EFL_DBG_INFO_APPEND(group, "Font source", EINA_VALUE_TYPE_STRING, text);
{
int w, h;
evas_obj_textgrid_size_get(eo_obj, &w, &h);
node = EFL_DBG_INFO_LIST_APPEND(group, "Grid size");
EFL_DBG_INFO_APPEND(node, "w", EINA_VALUE_TYPE_INT, w);
EFL_DBG_INFO_APPEND(node, "h", EINA_VALUE_TYPE_INT, h);
}
}
EAPI void
evas_object_textgrid_font_source_set(Eo *obj, const char *font_source)
{
efl_text_properties_font_source_set((Eo *) obj, font_source);
}
EAPI const char *
evas_object_textgrid_font_source_get(const Eo *obj)
{
const char *font_source = NULL;
font_source = efl_text_properties_font_source_get((Eo *) obj);
return font_source;
}
EAPI void
evas_object_textgrid_font_set(Eo *obj, const char *font_name, Evas_Font_Size font_size)
{
efl_text_properties_font_set((Eo *) obj, font_name, font_size);
}
EAPI void
evas_object_textgrid_font_get(const Eo *obj, const char **font_name, Evas_Font_Size *font_size)
{
efl_text_properties_font_get((Eo *) obj, font_name, font_size);
}
EOLIAN static void
_evas_textgrid_efl_text_font_font_bitmap_scalable_set(Eo *eo_obj, Evas_Textgrid_Data *o, Efl_Text_Font_Bitmap_Scalable bitmap_scalable)
{
if (o->cur.bitmap_scalable == bitmap_scalable) return;
o->prev.bitmap_scalable = o->cur.bitmap_scalable;
o->cur.bitmap_scalable = bitmap_scalable;
_evas_textgrid_font_reload(eo_obj, o);
}
EOLIAN static Efl_Text_Font_Bitmap_Scalable
_evas_textgrid_efl_text_font_font_bitmap_scalable_get(Eo *eo_obj EINA_UNUSED, Evas_Textgrid_Data *o)
{
return o->cur.bitmap_scalable;
}
#define EVAS_TEXTGRID_EXTRA_OPS \
EFL_OBJECT_OP_FUNC(efl_dbg_info_get, _evas_textgrid_efl_object_dbg_info_get)
2014-03-09 05:21:41 -07:00
#include "canvas/evas_textgrid.eo.c"