2005-01-08 02:02:18 -08:00
|
|
|
#include "evas_common.h"
|
|
|
|
#include "evas_private.h"
|
|
|
|
#include "Evas.h"
|
|
|
|
|
2005-01-29 08:28:18 -08:00
|
|
|
#define ENFN obj->layer->evas->engine.func
|
|
|
|
#define ENDT obj->layer->evas->engine.data.output
|
|
|
|
|
2005-01-08 02:02:18 -08:00
|
|
|
/* private magic number for textblock objects */
|
|
|
|
static const char o_type[] = "textblock";
|
|
|
|
|
|
|
|
/* private struct for textblock object internal data */
|
|
|
|
typedef struct _Evas_Object_Textblock Evas_Object_Textblock;
|
2005-01-29 08:28:18 -08:00
|
|
|
typedef struct _Layout Layout;
|
|
|
|
typedef struct _Node Node;
|
|
|
|
typedef struct _Layout_Node Layout_Node;
|
|
|
|
|
|
|
|
/* the current state of the formatting */
|
|
|
|
struct _Layout
|
|
|
|
{
|
|
|
|
struct {
|
|
|
|
char *name;
|
|
|
|
char *source;
|
|
|
|
Evas_Font_Size size;
|
|
|
|
void *font;
|
|
|
|
} font;
|
|
|
|
struct {
|
|
|
|
unsigned char r, g, b, a;
|
|
|
|
} color, underline_color, outline_color, shadow_color;
|
|
|
|
struct {
|
|
|
|
Evas_Coord x, y, ascent, descent, mascent, mdescent;
|
|
|
|
} line;
|
|
|
|
double align;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* a node of formatting data */
|
|
|
|
struct _Node
|
|
|
|
{
|
|
|
|
Evas_Object_List _list_data;
|
|
|
|
|
|
|
|
char *format; /* format data */
|
|
|
|
char *text; /* text data until the next node */
|
|
|
|
int text_len; /* length of the text */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* a node of formatting data */
|
|
|
|
struct _Layout_Node
|
|
|
|
{
|
|
|
|
Evas_Object_List _list_data;
|
|
|
|
|
|
|
|
/* the current state */
|
|
|
|
Layout layout;
|
|
|
|
char *text; /* text data until the next node */
|
|
|
|
int w, h;
|
|
|
|
};
|
2005-01-08 02:02:18 -08:00
|
|
|
|
|
|
|
struct _Evas_Object_Textblock
|
|
|
|
{
|
2005-01-29 08:28:18 -08:00
|
|
|
DATA32 magic;
|
2005-01-08 02:02:18 -08:00
|
|
|
struct {
|
2005-01-29 08:28:18 -08:00
|
|
|
int dummy;
|
2005-01-08 02:02:18 -08:00
|
|
|
} cur, prev;
|
2005-01-29 08:28:18 -08:00
|
|
|
char changed : 1;
|
|
|
|
|
|
|
|
int pos, len;
|
|
|
|
Evas_Format_Direction format_dir;
|
|
|
|
Node *nodes;
|
|
|
|
Layout_Node *layout_nodes;
|
|
|
|
Evas_Coord last_w, last_h;
|
|
|
|
struct {
|
|
|
|
unsigned char dirty : 1;
|
|
|
|
Evas_Coord w, h;
|
|
|
|
} native;
|
2005-01-08 02:02:18 -08:00
|
|
|
|
2005-01-29 08:28:18 -08:00
|
|
|
void *engine_data;
|
2005-01-08 02:02:18 -08:00
|
|
|
};
|
|
|
|
|
2005-01-29 08:28:18 -08:00
|
|
|
static void
|
|
|
|
evas_object_textblock_layout_init(Layout *layout)
|
|
|
|
{
|
|
|
|
layout->font.name = NULL;
|
|
|
|
layout->font.source = NULL;
|
|
|
|
layout->font.size = 0;
|
|
|
|
layout->font.font = NULL;
|
|
|
|
layout->color.r = 255;
|
|
|
|
layout->color.g = 255;
|
|
|
|
layout->color.b = 255;
|
|
|
|
layout->color.a = 255;
|
|
|
|
layout->underline_color.r = 255;
|
|
|
|
layout->underline_color.g = 255;
|
|
|
|
layout->underline_color.b = 255;
|
|
|
|
layout->underline_color.a = 255;
|
|
|
|
layout->outline_color.r = 255;
|
|
|
|
layout->outline_color.g = 255;
|
|
|
|
layout->outline_color.b = 255;
|
|
|
|
layout->outline_color.a = 255;
|
|
|
|
layout->shadow_color.r = 255;
|
|
|
|
layout->shadow_color.g = 255;
|
|
|
|
layout->shadow_color.b = 255;
|
|
|
|
layout->shadow_color.a = 255;
|
|
|
|
layout->line.x = 0;
|
|
|
|
layout->line.y = 0;
|
|
|
|
layout->line.ascent = 0;
|
|
|
|
layout->line.descent = 0;
|
|
|
|
layout->line.mascent = 0;
|
|
|
|
layout->line.mdescent = 0;
|
|
|
|
layout->align = 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
evas_object_textblock_format_merge(char *ofmt, char *fmt)
|
|
|
|
{
|
|
|
|
int l1 = 0, l2 = 0;
|
|
|
|
char *buf;
|
|
|
|
|
|
|
|
return strdup(fmt);
|
|
|
|
/* this is more correct */
|
|
|
|
if (ofmt) l1 = strlen(ofmt);
|
|
|
|
if (fmt) l2 = strlen(fmt);
|
|
|
|
buf = malloc(l1 + 1 + l2 + 1);
|
|
|
|
if (ofmt) strcpy(buf, ofmt);
|
|
|
|
strcpy(ofmt + l1, " ");
|
|
|
|
if (fmt) strcpy(buf + l1 + 1, fmt);
|
|
|
|
/* FIXME: sanitise buf */
|
|
|
|
return strdup(buf);
|
|
|
|
/* FIXME: actually merge */
|
|
|
|
/* snprintf to a buffer, return strdup buffer */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_textblock_layout_format_modify(Layout *layout, const char *format)
|
|
|
|
{
|
|
|
|
/* FIXME: parse format string and make mods to layout struct */
|
|
|
|
/* prop=value ... ...
|
|
|
|
* prop='value' (escape ' with \\' (\ needs escpae for c)
|
|
|
|
* prop="value" (escape " with \\\" (\ and " need escape in c)
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_textblock_layout_copy(Layout *layout, Layout *layout_dst)
|
|
|
|
{
|
|
|
|
*layout_dst = *layout;
|
|
|
|
if (layout->font.name) layout_dst->font.name = strdup(layout->font.name);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_textblock_layout_clear(Evas_Object *obj, Layout *layout)
|
|
|
|
{
|
|
|
|
if (layout->font.name) free(layout->font.name);
|
|
|
|
if (layout->font.source) free(layout->font.source);
|
|
|
|
if (layout->font.font) ENFN->font_free(ENDT, layout->font.font);
|
|
|
|
memset(layout, 0, sizeof(Layout));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_textblock_layout_clean(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
while (o->layout_nodes)
|
|
|
|
{
|
|
|
|
Layout_Node *lnode;
|
|
|
|
|
|
|
|
lnode = (Layout_Node *)o->layout_nodes;
|
|
|
|
o->layout_nodes = evas_object_list_remove(o->layout_nodes, lnode);
|
|
|
|
evas_object_textblock_layout_clear(obj, &lnode->layout);
|
|
|
|
if (lnode->text) free(lnode->text);
|
|
|
|
free(lnode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_textblock_contents_clean(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
while (o->nodes)
|
|
|
|
{
|
|
|
|
Node *node;
|
|
|
|
|
|
|
|
node = (Node *)o->nodes;
|
|
|
|
o->nodes = evas_object_list_remove(o->nodes, node);
|
|
|
|
if (node->format) free(node->format);
|
|
|
|
if (node->text) free(node->text);
|
|
|
|
free(node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_textblock_layout(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
Layout layout;
|
|
|
|
Evas_Object_List *l, *ll;
|
|
|
|
Evas_Coord w, h;
|
|
|
|
Layout_Node *line_start = NULL;
|
|
|
|
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
/* FIXME: takes nodes and produce layotu nodes */
|
|
|
|
evas_object_textblock_layout_init(&layout);
|
|
|
|
w = obj->cur.geometry.w;
|
|
|
|
h = obj->cur.geometry.h;
|
|
|
|
for (l = (Evas_Object_List *)o->nodes; l; l = l->next)
|
|
|
|
{
|
|
|
|
Layout_Node *lnode;
|
|
|
|
Node *node;
|
|
|
|
|
|
|
|
node = (Node *)l;
|
|
|
|
if (node->format)
|
|
|
|
evas_object_textblock_layout_format_modify(&layout, node->format);
|
|
|
|
if (node->text)
|
|
|
|
{
|
|
|
|
int inset, hadvance, vadvance, ascent, descent, tw, th;
|
|
|
|
int chrpos, x, y, cx, cy, cw, ch;
|
|
|
|
void *font;
|
|
|
|
char *text;
|
|
|
|
|
|
|
|
text = strdup(node->text);
|
|
|
|
new_node:
|
|
|
|
lnode = calloc(1, sizeof(Layout_Node));
|
|
|
|
evas_object_textblock_layout_copy(&layout, &(lnode->layout));
|
|
|
|
font = ENFN->font_load(ENDT, lnode->layout.font.name, lnode->layout.font.size);
|
|
|
|
lnode->layout.font.font = font;
|
|
|
|
ascent = ENFN->font_ascent_get(ENDT, font);
|
|
|
|
descent = ENFN->font_descent_get(ENDT, font);
|
|
|
|
layout.line.ascent = ascent;
|
|
|
|
layout.line.descent = descent;
|
|
|
|
if (layout.line.mascent < ascent) layout.line.mascent = descent;
|
|
|
|
if (layout.line.mdescent < descent) layout.line.mdescent = descent;
|
|
|
|
#if 0
|
|
|
|
/* if this is at the start of the line... */
|
|
|
|
if (layout.line.x == 0)
|
|
|
|
{
|
|
|
|
inset = ENFN->font_inset_get(ENDT, font, node->text);
|
|
|
|
layout.line.x = -inset;
|
|
|
|
line_start = lnode;
|
|
|
|
}
|
|
|
|
chrpos = ENFN->font_char_at_coords_get(ENDT, font, text,
|
|
|
|
w - layout.line.x, 0,
|
|
|
|
&cx, &cy, &cw, &ch);
|
|
|
|
/* if the text fits... just add */
|
|
|
|
if (chrpos < 0)
|
|
|
|
{
|
|
|
|
ENFN->font_string_size_get(ENDT, font, text, &tw, &th);
|
|
|
|
lnode->w = tw;
|
|
|
|
lnode->h = th;
|
|
|
|
lnode->text = text;
|
|
|
|
hadvance = ENFN->font_h_advance_get(ENDT, font, text);
|
|
|
|
o->layout_nodes = evas_object_list_append(o->layout_nodes, lnode);
|
|
|
|
/* and advance */
|
|
|
|
layout.line.x += hadvance;
|
|
|
|
/* fix up max ascent/descent for the line */
|
|
|
|
/* FIXME: fixup align */
|
|
|
|
for (ll = (Evas_Object_List *)lnode; ll; ll = ll->prev)
|
|
|
|
{
|
|
|
|
Layout_Node *lnode2;
|
|
|
|
|
|
|
|
lnode2 = (Layout_Node *)ll;
|
|
|
|
lnode2->layout.line.mascent = lnode->layout.line.mascent;
|
|
|
|
lnode2->layout.line.mdescent = lnode->layout.line.mdescent;
|
|
|
|
if (ll == line_start) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* text doesnt fit */
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* if the first char in the line can't fit!!! */
|
|
|
|
if ((chrpos == 0) && (lnode == line_start))
|
|
|
|
{
|
|
|
|
/* the first char can't fit. put it in there anyway */
|
|
|
|
/* FIXME */
|
|
|
|
free(text);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char *text1, *text2;
|
|
|
|
|
|
|
|
/* byte chrpos is over... so cut there */
|
|
|
|
text1 = malloc(chrpos + 1);
|
|
|
|
strncpy(text1, text, chrpos);
|
|
|
|
text1[chrpos] = 0;
|
|
|
|
text2 = strdup(text + chrpos);
|
|
|
|
lnode->text = text1;
|
|
|
|
free(text);
|
|
|
|
text = text1;
|
|
|
|
ENFN->font_string_size_get(ENDT, font, text, &tw, &th);
|
|
|
|
lnode->w = tw;
|
|
|
|
lnode->h = th;
|
|
|
|
o->layout_nodes = evas_object_list_append(o->layout_nodes, lnode);
|
|
|
|
/* fix up max ascent/descent for the line */
|
|
|
|
/* FIXME: fixup align */
|
|
|
|
for (ll = (Evas_Object_List *)lnode; ll; ll = ll->prev)
|
|
|
|
{
|
|
|
|
Layout_Node *lnode2;
|
|
|
|
|
|
|
|
lnode2 = (Layout_Node *)ll;
|
|
|
|
lnode2->layout.line.mascent = lnode->layout.line.mascent;
|
|
|
|
lnode2->layout.line.mdescent = lnode->layout.line.mdescent;
|
|
|
|
if (ll == line_start) break;
|
|
|
|
}
|
|
|
|
layout.line.x = 0;
|
|
|
|
layout.line.y += lnode->layout.line.mascent + lnode->layout.line.mdescent;
|
|
|
|
text = text2;
|
|
|
|
/* still more text to go */
|
|
|
|
goto new_node;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
inset = ENFN->font_inset_get(ENDT, font, node->text);
|
|
|
|
hadvance = ENFN->font_h_advance_get(ENDT, font, node->text);
|
|
|
|
vadvance = ENFN->font_v_advance_get(ENDT, font, node->text);
|
|
|
|
ascent = ENFN->font_ascent_get(ENDT, font);
|
|
|
|
descent = ENFN->font_descent_get(ENDT, font);
|
|
|
|
ENFN->font_string_size_get(ENDT, font, text, &tw, &th);
|
|
|
|
*/
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_textblock_native_calc(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
Layout layout;
|
|
|
|
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
/* FIXME: takes nodes and produce layotu nodes ignoring object size */
|
|
|
|
}
|
|
|
|
|
|
|
|
static Node *
|
|
|
|
evas_object_textblock_node_pos_get(Evas_Object *obj, int pos, int *pstart)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
Evas_Object_List *l;
|
|
|
|
int p, ps;
|
|
|
|
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
ps = p = 0;
|
|
|
|
for (l = (Evas_Object_List *)o->nodes; l; l = l->next)
|
|
|
|
{
|
|
|
|
Node *node;
|
|
|
|
|
|
|
|
node = (Node *)l;
|
|
|
|
if (node->text)
|
|
|
|
{
|
|
|
|
ps = p;
|
|
|
|
p += node->text_len;
|
|
|
|
if (p > pos)
|
|
|
|
{
|
|
|
|
*pstart = ps;
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2005-01-08 02:02:18 -08:00
|
|
|
/* private methods for textblock objects */
|
|
|
|
static void evas_object_textblock_init(Evas_Object *obj);
|
|
|
|
static void *evas_object_textblock_new(void);
|
|
|
|
static void evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y);
|
|
|
|
static void evas_object_textblock_free(Evas_Object *obj);
|
|
|
|
static void evas_object_textblock_render_pre(Evas_Object *obj);
|
|
|
|
static void evas_object_textblock_render_post(Evas_Object *obj);
|
|
|
|
|
|
|
|
static int evas_object_textblock_is_opaque(Evas_Object *obj);
|
|
|
|
static int evas_object_textblock_was_opaque(Evas_Object *obj);
|
|
|
|
|
|
|
|
static Evas_Object_Func object_func =
|
|
|
|
{
|
|
|
|
/* methods (compulsory) */
|
|
|
|
evas_object_textblock_free,
|
|
|
|
evas_object_textblock_render,
|
|
|
|
evas_object_textblock_render_pre,
|
|
|
|
evas_object_textblock_render_post,
|
|
|
|
/* these are optional. NULL = nothing */
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
evas_object_textblock_is_opaque,
|
|
|
|
evas_object_textblock_was_opaque,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2005-01-29 08:28:18 -08:00
|
|
|
/* the actual api call to add a textblock */
|
2005-01-08 02:02:18 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds a textblock to the given evas.
|
|
|
|
* @param e The given evas.
|
|
|
|
* @return The new textblock object.
|
|
|
|
* @todo Find a documentation group to put this under.
|
|
|
|
*/
|
|
|
|
Evas_Object *
|
|
|
|
evas_object_textblock_add(Evas *e)
|
|
|
|
{
|
|
|
|
Evas_Object *obj;
|
|
|
|
|
|
|
|
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
|
|
|
|
return NULL;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
obj = evas_object_new();
|
|
|
|
evas_object_textblock_init(obj);
|
|
|
|
evas_object_inject(obj, e);
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2005-01-08 04:47:36 -08:00
|
|
|
void
|
2005-01-19 22:54:45 -08:00
|
|
|
evas_object_textblock_clear(Evas_Object *obj)
|
2005-01-08 04:47:36 -08:00
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
2005-01-08 07:25:50 -08:00
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
2005-01-08 04:47:36 -08:00
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
2005-01-29 08:28:18 -08:00
|
|
|
evas_object_textblock_contents_clean(obj);
|
|
|
|
evas_object_textblock_layout_clean(obj);
|
|
|
|
o->len = 0;
|
|
|
|
o->pos = 0;
|
|
|
|
o->changed = 1;
|
2005-01-08 04:47:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_object_textblock_cursor_pos_set(Evas_Object *obj, int pos)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
2005-01-08 07:25:50 -08:00
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
2005-01-08 04:47:36 -08:00
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
2005-01-29 08:28:18 -08:00
|
|
|
if (pos < 0) pos = 0;
|
|
|
|
else if (pos > o->len) pos = o->len;
|
|
|
|
o->pos = pos;
|
2005-01-08 04:47:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
evas_object_textblock_cursor_pos_get(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
|
|
return 0;
|
|
|
|
MAGIC_CHECK_END();
|
2005-01-08 07:25:50 -08:00
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
2005-01-08 04:47:36 -08:00
|
|
|
return 0;
|
|
|
|
MAGIC_CHECK_END();
|
2005-01-29 08:28:18 -08:00
|
|
|
return o->pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
evas_object_textblock_length_get(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
|
|
return 0;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
2005-01-08 04:47:36 -08:00
|
|
|
return 0;
|
2005-01-29 08:28:18 -08:00
|
|
|
MAGIC_CHECK_END();
|
|
|
|
return o->len;
|
2005-01-08 04:47:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2005-01-29 08:28:18 -08:00
|
|
|
evas_object_textblock_text_insert(Evas_Object *obj, const char *text)
|
2005-01-08 04:47:36 -08:00
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
2005-01-29 08:28:18 -08:00
|
|
|
Node *node;
|
|
|
|
int ps;
|
2005-01-08 04:47:36 -08:00
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
2005-01-08 07:25:50 -08:00
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
2005-01-08 04:47:36 -08:00
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
2005-01-29 08:28:18 -08:00
|
|
|
if (!text) return;
|
|
|
|
o->native.dirty = 1;
|
|
|
|
o->changed = 1;
|
|
|
|
node = evas_object_textblock_node_pos_get(obj, o->pos, &ps);
|
|
|
|
/* at the end - just append */
|
|
|
|
if (!node)
|
|
|
|
{
|
|
|
|
if (!o->nodes)
|
|
|
|
{
|
|
|
|
node = calloc(1, sizeof(Node));
|
|
|
|
node->text = strdup(text);
|
|
|
|
node->text_len = strlen(node->text);
|
|
|
|
o->pos = node->text_len;
|
|
|
|
o->len = node->text_len;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char *ntext;
|
|
|
|
|
|
|
|
node = (Node *)(((Evas_Object_List *)(o->nodes))->last);
|
|
|
|
len = strlen(text);
|
|
|
|
ntext = malloc(node->text_len + len + 1);
|
|
|
|
if (node->text) strcpy(ntext, node->text);
|
|
|
|
strcpy(ntext + node->text_len, text);
|
|
|
|
if (node->text) free(node->text);
|
|
|
|
node->text = ntext;
|
|
|
|
node->text_len += len;
|
|
|
|
o->pos += len;
|
|
|
|
o->len += len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char *ntext;
|
|
|
|
|
|
|
|
len = strlen(text);
|
|
|
|
ntext = malloc(node->text_len + len + 1);
|
|
|
|
if (node->text) strncpy(ntext, node->text, o->pos - ps);
|
|
|
|
strcpy(ntext + o->pos - ps, text);
|
|
|
|
if (node->text) strcpy(ntext + o->pos - ps + len, node->text + o->pos - ps);
|
|
|
|
if (node->text) free(node->text);
|
|
|
|
node->text = ntext;
|
|
|
|
node->text_len += len;
|
|
|
|
o->pos += len;
|
|
|
|
o->len += len;
|
|
|
|
}
|
2005-01-08 04:47:36 -08:00
|
|
|
}
|
|
|
|
|
2005-01-29 08:28:18 -08:00
|
|
|
char *
|
|
|
|
evas_object_textblock_text_get(Evas_Object *obj, int len)
|
2005-01-19 22:54:45 -08:00
|
|
|
{
|
2005-01-29 08:28:18 -08:00
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
2005-01-19 22:54:45 -08:00
|
|
|
return NULL;
|
|
|
|
MAGIC_CHECK_END();
|
2005-01-29 08:28:18 -08:00
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
|
|
|
return NULL;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
/* FIXME: get from pos up to len bytes of string - malloc it */
|
2005-01-19 22:54:45 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2005-01-29 08:28:18 -08:00
|
|
|
evas_object_textblock_text_del(Evas_Object *obj, int len)
|
2005-01-19 22:54:45 -08:00
|
|
|
{
|
2005-01-29 08:28:18 -08:00
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
o->native.dirty = 1;
|
|
|
|
o->changed = 1;
|
|
|
|
/* FIXME: delete len bytes of string starting at pos */
|
2005-01-19 22:54:45 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2005-01-29 08:28:18 -08:00
|
|
|
evas_object_textblock_format_insert(Evas_Object *obj, const char *format)
|
2005-01-19 22:54:45 -08:00
|
|
|
{
|
2005-01-29 08:28:18 -08:00
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
Node *node;
|
|
|
|
int ps;
|
|
|
|
char *nformat;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
o->native.dirty = 1;
|
|
|
|
o->changed = 1;
|
|
|
|
node = evas_object_textblock_node_pos_get(obj, o->pos, &ps);
|
|
|
|
/* at the end - just append */
|
|
|
|
if (!node)
|
|
|
|
{
|
|
|
|
if (!o->nodes)
|
|
|
|
{
|
|
|
|
nformat = evas_object_textblock_format_merge(NULL, (char *)format);
|
|
|
|
if (nformat)
|
|
|
|
{
|
|
|
|
node = calloc(1, sizeof(Node));
|
|
|
|
node->format = nformat;
|
|
|
|
o->nodes = node;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char *ntext;
|
|
|
|
|
|
|
|
node = (Node *)(((Evas_Object_List *)(o->nodes))->last);
|
|
|
|
if (node->text)
|
|
|
|
{
|
|
|
|
node = calloc(1, sizeof(Node));
|
|
|
|
nformat = evas_object_textblock_format_merge(NULL, (char *)format);
|
|
|
|
node->format = nformat;
|
|
|
|
o->nodes = evas_object_list_append(o->nodes, node);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nformat = evas_object_textblock_format_merge(node->format, (char *)format);
|
|
|
|
if (node->format) free(node->format);
|
|
|
|
node->format = nformat;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!node->text)
|
|
|
|
{
|
|
|
|
nformat = evas_object_textblock_format_merge(node->format, (char *)format);
|
|
|
|
if (node->format) free(node->format);
|
|
|
|
node->format = nformat;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char *ntext1, *ntext2;
|
|
|
|
|
|
|
|
ntext1 = malloc(o->pos - ps + 1);
|
|
|
|
ntext2 = malloc(node->text_len - (o->pos - ps) + 1);
|
|
|
|
strncpy(ntext1, node->text, o->pos - ps);
|
|
|
|
ntext1[o->pos - ps] = 0;
|
|
|
|
strcpy(ntext2, node->text + o->pos - ps);
|
|
|
|
free(node->text);
|
|
|
|
node->text = ntext1;
|
|
|
|
node->text_len = o->pos - ps;
|
|
|
|
node = calloc(1, sizeof(Node));
|
|
|
|
nformat = evas_object_textblock_format_merge(NULL, (char *)format);
|
|
|
|
node->format = nformat;
|
|
|
|
o->nodes = evas_object_list_append(o->nodes, node);
|
|
|
|
}
|
|
|
|
}
|
2005-01-19 22:54:45 -08:00
|
|
|
}
|
|
|
|
|
2005-01-29 08:28:18 -08:00
|
|
|
int
|
|
|
|
evas_object_textblock_format_next_pos_get(Evas_Object *obj)
|
2005-01-19 22:54:45 -08:00
|
|
|
{
|
2005-01-29 08:28:18 -08:00
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
|
|
return -1;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
|
|
|
return -1;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
return -1;
|
2005-01-19 22:54:45 -08:00
|
|
|
}
|
|
|
|
|
2005-01-29 08:28:18 -08:00
|
|
|
int
|
|
|
|
evas_object_textblock_format_prev_pos_get(Evas_Object *obj)
|
2005-01-19 22:54:45 -08:00
|
|
|
{
|
2005-01-29 08:28:18 -08:00
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
|
|
return -1;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
|
|
|
return -1;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
return -1;
|
2005-01-19 22:54:45 -08:00
|
|
|
}
|
|
|
|
|
2005-01-29 08:28:18 -08:00
|
|
|
char *
|
|
|
|
evas_object_textblock_format_get(Evas_Object *obj)
|
2005-01-19 22:54:45 -08:00
|
|
|
{
|
2005-01-29 08:28:18 -08:00
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
|
|
return NULL;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
|
|
|
return NULL;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
return NULL;
|
2005-01-19 22:54:45 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2005-01-29 08:28:18 -08:00
|
|
|
evas_object_textblock_format_del(Evas_Object *obj)
|
2005-01-19 22:54:45 -08:00
|
|
|
{
|
2005-01-29 08:28:18 -08:00
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
o->native.dirty = 1;
|
|
|
|
o->changed = 1;
|
2005-01-19 22:54:45 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2005-01-29 08:28:18 -08:00
|
|
|
evas_object_textblock_format_direction_set(Evas_Object *obj, Evas_Format_Direction dir)
|
2005-01-19 22:54:45 -08:00
|
|
|
{
|
2005-01-29 08:28:18 -08:00
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
if (o->format_dir == dir) return;
|
|
|
|
o->native.dirty = 1;
|
|
|
|
o->changed = 1;
|
2005-01-19 22:54:45 -08:00
|
|
|
}
|
|
|
|
|
2005-01-29 08:28:18 -08:00
|
|
|
Evas_Format_Direction
|
|
|
|
evas_object_textblock_format_direction_get(Evas_Object *obj)
|
2005-01-19 22:54:45 -08:00
|
|
|
{
|
2005-01-29 08:28:18 -08:00
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
|
|
|
return EVAS_FORMAT_DIRECTION_VERTICAL;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
|
|
|
return EVAS_FORMAT_DIRECTION_VERTICAL;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
return o->format_dir;
|
2005-01-19 22:54:45 -08:00
|
|
|
}
|
|
|
|
|
2005-01-08 04:47:36 -08:00
|
|
|
void
|
2005-01-29 08:28:18 -08:00
|
|
|
evas_object_textblock_native_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
|
2005-01-08 04:47:36 -08:00
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
|
2005-01-29 08:28:18 -08:00
|
|
|
if (w) *w = 0;
|
|
|
|
if (h) *h = 0;
|
2005-01-08 04:47:36 -08:00
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
2005-01-08 07:25:50 -08:00
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
|
2005-01-29 08:28:18 -08:00
|
|
|
if (w) *w = 0;
|
|
|
|
if (h) *h = 0;
|
2005-01-08 04:47:36 -08:00
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
2005-01-29 08:28:18 -08:00
|
|
|
if (o->native.dirty)
|
|
|
|
{
|
|
|
|
evas_object_textblock_native_calc(obj);
|
|
|
|
o->last_w = obj->cur.geometry.w;
|
|
|
|
o->last_h = obj->cur.geometry.h;
|
|
|
|
o->native.dirty = 0;
|
|
|
|
}
|
|
|
|
if (w) *w = o->native.w;
|
|
|
|
if (h) *h = o->native.h;
|
2005-01-08 04:47:36 -08:00
|
|
|
}
|
|
|
|
|
2005-01-29 08:28:18 -08:00
|
|
|
/* FIXME:
|
|
|
|
*
|
|
|
|
* things to add:
|
|
|
|
*
|
|
|
|
* overflow objects (overflow from this textblock can go into another)
|
|
|
|
* obstacle objects to wrap around
|
|
|
|
* on change figure out what node the change is in and figure out what line
|
|
|
|
* (nodes) it affects and only modify those nodes on that line or maybe\
|
|
|
|
* others until changes dont happen further down
|
|
|
|
*
|
|
|
|
* lots more format handling (styles, right to left etc.)
|
|
|
|
*/
|
2005-01-08 02:02:18 -08:00
|
|
|
|
|
|
|
|
|
|
|
/* all nice and private */
|
|
|
|
static void
|
|
|
|
evas_object_textblock_init(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
/* alloc image ob, setup methods and default values */
|
|
|
|
obj->object_data = evas_object_textblock_new();
|
|
|
|
/* set up default settings for this kind of object */
|
|
|
|
obj->cur.color.r = 255;
|
|
|
|
obj->cur.color.g = 255;
|
|
|
|
obj->cur.color.b = 255;
|
|
|
|
obj->cur.color.a = 255;
|
|
|
|
obj->cur.geometry.x = 0.0;
|
|
|
|
obj->cur.geometry.y = 0.0;
|
|
|
|
obj->cur.geometry.w = 0.0;
|
|
|
|
obj->cur.geometry.h = 0.0;
|
|
|
|
obj->cur.layer = 0;
|
|
|
|
/* set up object-specific settings */
|
|
|
|
obj->prev = obj->cur;
|
|
|
|
/* set up methods (compulsory) */
|
|
|
|
obj->func = &object_func;
|
|
|
|
obj->type = o_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
evas_object_textblock_new(void)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
/* alloc obj private data */
|
|
|
|
o = calloc(1, sizeof(Evas_Object_Textblock));
|
|
|
|
o->magic = MAGIC_OBJ_TEXTBLOCK;
|
|
|
|
return o;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_textblock_free(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
/* frees private object data. very simple here */
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXTBLOCK);
|
|
|
|
return;
|
|
|
|
MAGIC_CHECK_END();
|
|
|
|
/* free obj */
|
2005-01-29 08:28:18 -08:00
|
|
|
evas_object_textblock_layout_clean(obj);
|
|
|
|
evas_object_textblock_contents_clean(obj);
|
2005-01-08 02:02:18 -08:00
|
|
|
o->magic = 0;
|
|
|
|
free(o);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
2005-01-29 08:28:18 -08:00
|
|
|
Evas_Object_List *l;
|
|
|
|
|
2005-01-08 02:02:18 -08:00
|
|
|
/* render object to surface with context, and offxet by x,y */
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
obj->layer->evas->engine.func->context_multiplier_unset(output,
|
|
|
|
context);
|
2005-01-29 08:28:18 -08:00
|
|
|
for (l = (Evas_Object_List *)o->layout_nodes; l; l = l->next)
|
2005-01-08 02:02:18 -08:00
|
|
|
{
|
2005-01-29 08:28:18 -08:00
|
|
|
Layout_Node *lnode;
|
2005-01-08 02:02:18 -08:00
|
|
|
|
2005-01-29 08:28:18 -08:00
|
|
|
lnode = (Layout_Node *)l;
|
|
|
|
ENFN->context_color_set(output,
|
|
|
|
context,
|
|
|
|
(obj->cur.cache.clip.r * lnode->layout.color.r) / 255,
|
|
|
|
(obj->cur.cache.clip.g * lnode->layout.color.g) / 255,
|
|
|
|
(obj->cur.cache.clip.b * lnode->layout.color.b) / 255,
|
|
|
|
(obj->cur.cache.clip.a * lnode->layout.color.a) / 255);
|
|
|
|
ENFN->font_draw(output,
|
|
|
|
context,
|
|
|
|
surface,
|
|
|
|
lnode->layout.font.font,
|
|
|
|
obj->cur.cache.geometry.x + lnode->layout.line.x,
|
|
|
|
obj->cur.cache.geometry.y + lnode->layout.line.y + lnode->layout.line.mascent,
|
|
|
|
lnode->w,
|
|
|
|
lnode->h,
|
|
|
|
lnode->w,
|
|
|
|
lnode->h,
|
|
|
|
lnode->text);
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
2005-01-29 08:28:18 -08:00
|
|
|
// if (o->engine_data)
|
|
|
|
// {
|
|
|
|
//
|
|
|
|
// }
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_textblock_render_pre(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_List *updates = NULL;
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
int is_v, was_v;
|
|
|
|
|
|
|
|
/* dont pre-render the obj twice! */
|
|
|
|
if (obj->pre_render_done) return;
|
|
|
|
obj->pre_render_done = 1;
|
|
|
|
/* pre-render phase. this does anything an object needs to do just before */
|
|
|
|
/* rendering. this could mean loading the image data, retrieving it from */
|
|
|
|
/* elsewhere, decoding video etc. */
|
|
|
|
/* then when this is done the object needs to figure if it changed and */
|
|
|
|
/* if so what and where and add the appropriate redraw textblocks */
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
/* if someone is clipping this obj - go calculate the clipper */
|
|
|
|
if (obj->cur.clipper)
|
|
|
|
{
|
|
|
|
evas_object_clip_recalc(obj->cur.clipper);
|
|
|
|
obj->cur.clipper->func->render_pre(obj->cur.clipper);
|
|
|
|
}
|
|
|
|
/* now figure what changed and add draw rects */
|
|
|
|
/* if it just became visible or invisible */
|
|
|
|
is_v = evas_object_is_visible(obj);
|
|
|
|
was_v = evas_object_was_visible(obj);
|
|
|
|
if (is_v != was_v)
|
|
|
|
{
|
|
|
|
updates = evas_object_render_pre_visible_change(updates, obj, is_v, was_v);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
/* it's 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 */
|
|
|
|
updates = evas_object_render_pre_clipper_change(updates, obj);
|
|
|
|
/* if we restacked (layer or just within a layer) and don't clip anyone */
|
|
|
|
if (obj->restack)
|
|
|
|
{
|
|
|
|
updates = evas_object_render_pre_prev_cur_add(updates, 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))
|
|
|
|
{
|
|
|
|
updates = evas_object_render_pre_prev_cur_add(updates, obj);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
if (o->changed)
|
|
|
|
{
|
|
|
|
/* FIXME: calc sub-area changes */
|
2005-01-29 08:28:18 -08:00
|
|
|
evas_object_textblock_layout_clean(obj);
|
|
|
|
evas_object_textblock_layout(obj);
|
2005-01-08 02:02:18 -08:00
|
|
|
}
|
|
|
|
done:
|
|
|
|
evas_object_render_pre_effect_updates(updates, obj, is_v, was_v);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_textblock_render_post(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
/* 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 */
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
/* remove those pesky changes */
|
|
|
|
while (obj->clip.changes)
|
|
|
|
{
|
|
|
|
Evas_Rectangle *r;
|
|
|
|
|
|
|
|
r = (Evas_Rectangle *)obj->clip.changes->data;
|
|
|
|
obj->clip.changes = evas_list_remove(obj->clip.changes, r);
|
|
|
|
free(r);
|
|
|
|
}
|
|
|
|
/* move cur to prev safely for object data */
|
|
|
|
obj->prev = obj->cur;
|
|
|
|
o->prev = o->cur;
|
|
|
|
o->changed = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
evas_object_textblock_is_opaque(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
/* this returns 1 if the internal object data implies that the object is */
|
|
|
|
/* currently fulyl opque over the entire gradient it occupies */
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
evas_object_textblock_was_opaque(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
/* this returns 1 if the internal object data implies that the object was */
|
|
|
|
/* currently fulyl opque over the entire gradient it occupies */
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
return 0;
|
|
|
|
}
|
2005-01-29 08:28:18 -08:00
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_textblock_coords_recalc(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Evas_Object_Textblock *o;
|
|
|
|
|
|
|
|
o = (Evas_Object_Textblock *)(obj->object_data);
|
|
|
|
if ((obj->cur.geometry.w != o->last_w) ||
|
|
|
|
(obj->cur.geometry.h != o->last_h))
|
|
|
|
{
|
|
|
|
o->changed = 1;
|
|
|
|
}
|
|
|
|
}
|