been working textblock...

SVN revision: 13129
This commit is contained in:
Carsten Haitzler 2005-01-29 16:28:18 +00:00
parent cdd37bfdfe
commit 0329745fd0
3 changed files with 699 additions and 89 deletions

View File

@ -53,24 +53,6 @@ typedef enum _Evas_Button_Flags
EVAS_BUTTON_TRIPLE_CLICK = (1 << 1) /**< This mouse button press was the 3rd press of a triple click */
} Evas_Button_Flags; /**< Flags for Mouse Button events */
typedef enum _Evas_Format_Type
{
EVAS_FORMAT_NONE = 0,
EVAS_FORMAT_FONT,
EVAS_FORMAT_SIZE,
EVAS_FORMAT_COLOR,
EVAS_FORMAT_COLOR2,
EVAS_FORMAT_COLOR3,
EVAS_FORMAT_ALIGN,
EVAS_FORMAT_STYLE,
EVAS_FORMAT_UNDERLINE,
EVAS_FORMAT_NEWLINE,
EVAS_FORMAT_TAB,
EVAS_FORMAT_L2R,
EVAS_FORMAT_R2L,
EVAS_FORMAT_ANCHOR
} Evas_Format_Type;
typedef enum _Evas_Format_Direction
{
EVAS_FORMAT_DIRECTION_VERTICAL = 0,
@ -454,8 +436,23 @@ extern "C" {
EAPI void evas_font_cache_set (Evas *e, int size);
EAPI int evas_font_cache_get (Evas *e);
EAPI Evas_Object *evas_object_textblock_add (Evas *e);
EAPI Evas_Object *evas_object_textblock_add (Evas *e);
EAPI void evas_object_textblock_clear (Evas_Object *obj);
EAPI void evas_object_textblock_cursor_pos_set (Evas_Object *obj, int pos);
EAPI int evas_object_textblock_cursor_pos_get (Evas_Object *obj);
EAPI int evas_object_textblock_length_get (Evas_Object *obj);
EAPI void evas_object_textblock_text_insert (Evas_Object *obj, const char *text);
EAPI char *evas_object_textblock_text_get (Evas_Object *obj, int len);
EAPI void evas_object_textblock_text_del (Evas_Object *obj, int len);
EAPI void evas_object_textblock_format_insert (Evas_Object *obj, const char *format);
EAPI int evas_object_textblock_format_next_pos_get (Evas_Object *obj);
EAPI int evas_object_textblock_format_prev_pos_get (Evas_Object *obj);
EAPI char *evas_object_textblock_format_get (Evas_Object *obj);
EAPI void evas_object_textblock_format_del (Evas_Object *obj);
EAPI void evas_object_textblock_format_direction_set (Evas_Object *obj, Evas_Format_Direction dir);
EAPI Evas_Format_Direction evas_object_textblock_format_direction_get (Evas_Object *obj);
EAPI void evas_object_textblock_native_size_get (Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);
EAPI void evas_object_del (Evas_Object *obj);
EAPI const char *evas_object_type_get (Evas_Object *obj);

View File

@ -2,26 +2,362 @@
#include "evas_private.h"
#include "Evas.h"
#define ENFN obj->layer->evas->engine.func
#define ENDT obj->layer->evas->engine.data.output
/* 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;
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;
};
struct _Evas_Object_Textblock
{
DATA32 magic;
DATA32 magic;
struct {
char *text;
char *font;
char *source;
Evas_Font_Size size;
int dummy;
} cur, prev;
char changed : 1;
char changed : 1;
void *engine_data;
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;
void *engine_data;
};
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;
}
/* private methods for textblock objects */
static void evas_object_textblock_init(Evas_Object *obj);
static void *evas_object_textblock_new(void);
@ -52,8 +388,7 @@ static Evas_Object_Func object_func =
NULL
};
/* the actual api call to add a rect */
/* it has no other api calls as all properties are standard */
/* the actual api call to add a textblock */
/**
* Adds a textblock to the given evas.
@ -75,7 +410,6 @@ evas_object_textblock_add(Evas *e)
return obj;
}
/* stubs of what we will need... */
void
evas_object_textblock_clear(Evas_Object *obj)
{
@ -88,6 +422,11 @@ evas_object_textblock_clear(Evas_Object *obj)
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
return;
MAGIC_CHECK_END();
evas_object_textblock_contents_clean(obj);
evas_object_textblock_layout_clean(obj);
o->len = 0;
o->pos = 0;
o->changed = 1;
}
void
@ -102,6 +441,9 @@ evas_object_textblock_cursor_pos_set(Evas_Object *obj, int pos)
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
return;
MAGIC_CHECK_END();
if (pos < 0) pos = 0;
else if (pos > o->len) pos = o->len;
o->pos = pos;
}
int
@ -116,11 +458,106 @@ evas_object_textblock_cursor_pos_get(Evas_Object *obj)
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
return 0;
MAGIC_CHECK_END();
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);
return 0;
MAGIC_CHECK_END();
return o->len;
}
void
evas_object_textblock_text_insert(Evas_Object *obj, char *text)
evas_object_textblock_text_insert(Evas_Object *obj, const char *text)
{
Evas_Object_Textblock *o;
Node *node;
int ps;
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 (!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;
}
}
char *
evas_object_textblock_text_get(Evas_Object *obj, int len)
{
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();
/* FIXME: get from pos up to len bytes of string - malloc it */
return NULL;
}
void
evas_object_textblock_text_del(Evas_Object *obj, int len)
{
Evas_Object_Textblock *o;
@ -131,64 +568,138 @@ evas_object_textblock_text_insert(Evas_Object *obj, char *text)
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 */
}
Evas_Format *
evas_format_new(Evas *e)
void
evas_object_textblock_format_insert(Evas_Object *obj, const char *format)
{
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
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);
}
}
}
int
evas_object_textblock_format_next_pos_get(Evas_Object *obj)
{
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;
}
int
evas_object_textblock_format_prev_pos_get(Evas_Object *obj)
{
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;
}
char *
evas_object_textblock_format_get(Evas_Object *obj)
{
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;
}
void
evas_format_del(Evas_Format *fmt)
{
}
void
evas_format_retain_set(Evas_Format *fmt, Evas_Bool retain)
{
}
void
evas_format_resize(Evas_Format *fmt, Evas_Coord w, Evas_Coord h)
{
}
void
evas_format_type_set(Evas_Format *fmt, Evas_Format_Type ft)
{
}
void
evas_format_size_set(Evas_Format *fmt, Evas_Coord size)
{
}
void
evas_format_enabled_set(Evas_Format *fmt, Evas_Bool enabled)
{
}
void
evas_format_color_set(Evas_Format *fmt, int r, int g, int b, int a)
{
}
void
evas_format_string_set(Evas_Format *fmt, const char *str)
{
}
void
evas_format_align_set(Evas_Format *fmt, double align)
{
}
void
evas_object_textblock_format_insert(Evas_Object *obj, Evas_Format *fmt)
evas_object_textblock_format_del(Evas_Object *obj)
{
Evas_Object_Textblock *o;
@ -199,14 +710,81 @@ evas_object_textblock_format_insert(Evas_Object *obj, Evas_Format *fmt)
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
return;
MAGIC_CHECK_END();
o->native.dirty = 1;
o->changed = 1;
}
void
evas_object_textblock_format_direction_set(Evas_Object *obj, Evas_Format_Direction dir)
{
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;
}
Evas_Format_Direction
evas_object_textblock_format_direction_get(Evas_Object *obj)
{
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;
}
void
evas_object_textblock_native_size_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h)
{
Evas_Object_Textblock *o;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
if (w) *w = 0;
if (h) *h = 0;
return;
MAGIC_CHECK_END();
o = (Evas_Object_Textblock *)(obj->object_data);
MAGIC_CHECK(o, Evas_Object_Textblock, MAGIC_OBJ_TEXT);
if (w) *w = 0;
if (h) *h = 0;
return;
MAGIC_CHECK_END();
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;
}
/* 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.)
*/
/* all nice and private */
@ -254,6 +832,8 @@ evas_object_textblock_free(Evas_Object *obj)
return;
MAGIC_CHECK_END();
/* free obj */
evas_object_textblock_layout_clean(obj);
evas_object_textblock_contents_clean(obj);
o->magic = 0;
free(o);
}
@ -262,21 +842,39 @@ static void
evas_object_textblock_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
{
Evas_Object_Textblock *o;
Evas_Object_List *l;
/* 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);
obj->layer->evas->engine.func->context_color_set(output,
context,
obj->cur.cache.clip.r,
obj->cur.cache.clip.g,
obj->cur.cache.clip.b,
obj->cur.cache.clip.a);
if (o->engine_data)
for (l = (Evas_Object_List *)o->layout_nodes; l; l = l->next)
{
Layout_Node *lnode;
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);
}
// if (o->engine_data)
// {
//
// }
}
static void
@ -332,6 +930,8 @@ evas_object_textblock_render_pre(Evas_Object *obj)
if (o->changed)
{
/* FIXME: calc sub-area changes */
evas_object_textblock_layout_clean(obj);
evas_object_textblock_layout(obj);
}
done:
evas_object_render_pre_effect_updates(updates, obj, is_v, was_v);
@ -382,3 +982,16 @@ evas_object_textblock_was_opaque(Evas_Object *obj)
o = (Evas_Object_Textblock *)(obj->object_data);
return 0;
}
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;
}
}

View File

@ -261,7 +261,7 @@ evas_common_copy_pixels_rgba_to_rgba_mmx2(DATA32 *src, DATA32 *dst, int len)
while (dst_ptr < dst_end_ptr_pre)
{
MOVE_16DWORDS_MMX2(src_ptr, dst_ptr);
MOVE_16DWORDS_MMX(src_ptr, dst_ptr);
src_ptr+=16;
dst_ptr+=16;
}