tb2 work! :)

SVN revision: 16671
This commit is contained in:
Carsten Haitzler 2005-09-09 14:19:06 +00:00
parent d9eb3e3958
commit b672283702
3 changed files with 335 additions and 18 deletions

View File

@ -463,8 +463,14 @@ extern "C" {
/* NEW texblock api - intended to replace the old - not complete yet */
typedef struct _Evas_Textblock_Style Evas_Textblock_Style;
typedef struct _Evas_Textblock_Cursor Evas_Textblock_Cursor;
typedef struct _Evas_Textblock_Style Evas_Textblock_Style;
typedef struct _Evas_Textblock_Cursor Evas_Textblock_Cursor;
typedef struct _Evas_Textblock_Rectangle Evas_Textblock_Rectangle;
struct _Evas_Textblock_Rectangle
{
Evas_Coord x, y, w, h;
};
EAPI Evas_Object *evas_object_textblock2_add(Evas *e);
@ -505,16 +511,20 @@ extern "C" {
EAPI void evas_textblock2_cursor_format_append(Evas_Textblock_Cursor *cur, const char *format);
EAPI void evas_textblock2_cursor_format_prepend(Evas_Textblock_Cursor *cur, const char *format);
/* FIXME: add node delete, cursor delete, range delete */
EAPI void evas_textblock2_cursor_node_delete(Evas_Textblock_Cursor *cur);
EAPI void evas_textblock2_cursor_char_delete(Evas_Textblock_Cursor *cur);
EAPI void evas_textblock2_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_Cursor *cur2);
EAPI const char *evas_textblock2_cursor_node_text_get(Evas_Textblock_Cursor *cur);
EAPI const char *evas_textblock2_cursor_node_format_get(Evas_Textblock_Cursor *cur);
/* FIXME: add text range get */
EAPI char *evas_textblock2_cursor_range_text_get(Evas_Textblock_Cursor *cur1, Evas_Textblock_Cursor *cur2);
EAPI int evas_textblock2_cursor_char_geometry_get(Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch);
EAPI int evas_textblock2_cursor_line_geometry_get(Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch);
EAPI Evas_Bool evas_textblock2_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, Evas_Coord y);
EAPI int evas_textblock2_cursor_line_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord y);
EAPI Evas_List *evas_textblock2_cursor_range_geometry_get(Evas_Textblock_Cursor *cur1, Evas_Textblock_Cursor *cur2);
EAPI Evas_Bool evas_object_textblock2_line_number_geometry_get(Evas_Object *obj, int line, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch);
EAPI void evas_object_textblock2_clear(Evas_Object *obj);
EAPI void evas_object_textblock2_size_formatted_get(Evas_Object *obj, Evas_Coord *w, Evas_Coord *h);

View File

@ -138,10 +138,10 @@ struct _Evas_Object_Textblock
Evas_Textblock_Cursor *cursor;
Evas_List *cursors;
Evas_Object_Textblock_Node *nodes;
Evas_Object_Textblock_Line *lines;
int last_w;
Evas_Object_Textblock_Line *lines;
int last_w;
struct {
int l, r, t, b;
int l, r, t, b;
} style_pad;
char *markup_text;
char changed : 1;
@ -357,12 +357,23 @@ _strbuf_insert(char *s, char *s2, int pos, int *len, int *alloc)
static char *
_strbuf_remove(char *s, int p, int p2, int *len, int *alloc)
{
/*
int l2;
int tlen;
char *tbuf;
tlen = *len + l2;
if (tlen > *alloc)
if ((p == 0) && (p2 == *len))
{
free(s);
*len = 0;
*alloc = 0;
return NULL;
}
tbuf = malloc(*len - p2 + 1);
strcpy(tbuf, s + p2);
strcpy(s + p, tbuf);
free(tbuf);
tlen = *len - (p2 - p);
if (tlen < ((*alloc >> 5) << 15))
{
char *ts;
int talloc;
@ -373,11 +384,7 @@ _strbuf_remove(char *s, int p, int p2, int *len, int *alloc)
s = ts;
*alloc = talloc;
}
strncpy(s + pos + l2, s + pos, *len - pos);
strncpy(s + pos, s2, l2);
*len = tlen;
s[tlen] = 0;
*/
return s;
}
@ -2482,6 +2489,7 @@ evas_object_textblock2_text_markup_set(Evas_Object *obj, const char *text)
}
o->markup_text = strdup(text);
}
/* FIXME: adjust cursors that are affected by the change */
}
const char *
@ -2880,6 +2888,7 @@ evas_textblock2_cursor_compare(Evas_Textblock_Cursor *cur1, Evas_Textblock_Curso
Evas_Object_List *l1, *l2;
if (!cur1) return 0;
if (!cur2) return 0;
if (cur1->obj != cur2->obj) return 0;
if ((!cur1->node) || (!cur2->node)) return 0;
if (cur1->node == cur2->node)
@ -2946,6 +2955,7 @@ evas_textblock2_cursor_text_append(Evas_Textblock_Cursor *cur, const char *text)
o->native.valid = 0;
o->changed = 1;
evas_object_change(cur->obj);
/* FIXME: adjust cursors that are affected by the change */
}
void
@ -2975,6 +2985,7 @@ evas_textblock2_cursor_text_prepend(Evas_Textblock_Cursor *cur, const char *text
o->native.valid = 0;
o->changed = 1;
evas_object_change(cur->obj);
/* FIXME: adjust cursors that are affected by the change */
}
void
@ -3035,6 +3046,7 @@ evas_textblock2_cursor_format_append(Evas_Textblock_Cursor *cur, const char *for
o->native.valid = 0;
o->changed = 1;
evas_object_change(cur->obj);
/* FIXME: adjust cursors that are affected by the change */
}
void
@ -3090,6 +3102,168 @@ evas_textblock2_cursor_format_prepend(Evas_Textblock_Cursor *cur, const char *fo
o->native.valid = 0;
o->changed = 1;
evas_object_change(cur->obj);
/* FIXME: adjust cursors that are affected by the change */
}
void
evas_textblock2_cursor_node_delete(Evas_Textblock_Cursor *cur)
{
Evas_Object_Textblock *o;
Evas_Object_Textblock_Node *n, *n2;
if (!cur) return;
o = (Evas_Object_Textblock *)(cur->obj->object_data);
n = cur->node;
n2 = (Evas_Object_Textblock_Node *)(((Evas_Object_List *)n)->next);
if (n2)
{
cur->node = n2;
cur->pos = 0;
}
else
{
n2 = (Evas_Object_Textblock_Node *)(((Evas_Object_List *)n)->prev);
cur->node = n2;
cur->pos = 0;
evas_textblock2_cursor_char_last(cur);
}
o->nodes = evas_object_list_remove(o->nodes, n);
if (n->text) free(n->text);
free(n);
o->formatted.valid = 0;
o->native.valid = 0;
o->changed = 1;
evas_object_change(cur->obj);
/* FIXME: adjust cursors that are affected by the change */
}
void
evas_textblock2_cursor_char_delete(Evas_Textblock_Cursor *cur)
{
Evas_Object_Textblock *o;
Evas_Object_Textblock_Node *n, *n2;
int chr, index;
if (!cur) return;
o = (Evas_Object_Textblock *)(cur->obj->object_data);
n = cur->node;
if (n->type == NODE_FORMAT)
{
evas_textblock2_cursor_node_delete(cur);
return;
}
index = cur->pos;
chr = evas_common_font_utf8_get_next((unsigned char *)n->text, &index);
if (chr == 0) return;
n->text = _strbuf_remove(n->text, cur->pos, index, &(n->len), &(n->alloc));
if (!n->text)
{
evas_textblock2_cursor_node_delete(cur);
return;
}
if (cur->pos == n->len)
{
n2 = (Evas_Object_Textblock_Node *)(((Evas_Object_List *)n)->next);
if (n2)
{
cur->node = n2;
cur->pos = 0;
}
else
{
cur->pos = 0;
evas_textblock2_cursor_char_last(cur);
}
}
o->formatted.valid = 0;
o->native.valid = 0;
o->changed = 1;
evas_object_change(cur->obj);
/* FIXME: adjust cursors that are affected by the change */
}
void
evas_textblock2_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_Cursor *cur2)
{
Evas_Object_Textblock *o;
Evas_Object_Textblock_Node *n1, *n2, *n;
Evas_Object_List *l;
int chr, index;
if (!cur1) return;
if (!cur2) return;
if (cur1->obj != cur2->obj) return;
o = (Evas_Object_Textblock *)(cur1->obj->object_data);
if (evas_textblock2_cursor_compare(cur1, cur2) > 0)
{
Evas_Textblock_Cursor *tc;
tc = cur1;
cur1 = cur2;
cur2 = tc;
}
n1 = cur1->node;
n2 = cur2->node;
index = cur2->pos;
chr = evas_common_font_utf8_get_next((unsigned char *)n2->text, &index);
if (chr == 0) return;
if (n1 == n2)
{
if (cur1->pos == cur2->pos)
{
evas_textblock2_cursor_char_delete(cur1);
return;
}
n1->text = _strbuf_remove(n1->text, cur1->pos, index, &(n->len), &(n->alloc));
if (!n1->text)
{
evas_textblock2_cursor_node_delete(cur1);
return;
}
if (cur1->pos == n1->len)
{
n2 = (Evas_Object_Textblock_Node *)(((Evas_Object_List *)n1)->next);
if (n2)
{
cur1->node = n2;
cur1->pos = 0;
}
else
{
cur1->pos = 0;
evas_textblock2_cursor_char_last(cur1);
}
}
}
else
{
Evas_List *removes = NULL;
n1->text = _strbuf_remove(n1->text, cur1->pos, index, &(n->len), &(n->alloc));
for (l = ((Evas_Object_List *)n1)->next; l != (Evas_Object_List *)n2; l = l->next)
removes = evas_list_append(removes, l);
while (removes)
{
n = removes->data;
o->nodes = evas_object_list_remove(o->nodes, n);
if (n->text) free(n->text);
free(n);
removes = evas_list_remove_list(removes, removes);
}
if (!n1->text)
evas_textblock2_cursor_node_delete(cur1);
if (!n2->text)
evas_textblock2_cursor_node_delete(cur2);
}
o->formatted.valid = 0;
o->native.valid = 0;
o->changed = 1;
evas_object_change(cur1->obj);
/* FIXME: adjust cursors that are affected by the change */
}
const char *
@ -3116,6 +3290,30 @@ evas_textblock2_cursor_node_format_get(Evas_Textblock_Cursor *cur)
return NULL;
}
char *
evas_textblock2_cursor_range_text_get(Evas_Textblock_Cursor *cur1, Evas_Textblock_Cursor *cur2)
{
Evas_Object_Textblock *o;
Evas_Object_Textblock_Node *n1, *n2;
if (!cur1) return NULL;
if (!cur2) return NULL;
if (cur1->obj != cur2->obj) return NULL;
o = (Evas_Object_Textblock *)(cur1->obj->object_data);
if (evas_textblock2_cursor_compare(cur1, cur2) > 0)
{
Evas_Textblock_Cursor *tc;
tc = cur1;
cur1 = cur2;
cur2 = tc;
}
n1 = cur1->node;
n2 = cur2->node;
/* FIXME: */
return NULL;
}
int
evas_textblock2_cursor_char_geometry_get(Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
{
@ -3144,6 +3342,11 @@ evas_textblock2_cursor_char_geometry_get(Evas_Textblock_Cursor *cur, Evas_Coord
&x, &y, &w, &h);
if (ret <= 0) return -1;
x = ln->x + it->x - it->inset + x;
if (x < ln->x)
{
x = ln->x;
w -= (ln->x - x);
}
y = ln->y;
h = ln->h;
}
@ -3205,6 +3408,8 @@ evas_textblock2_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x,
if (!cur) return 0;
o = (Evas_Object_Textblock *)(cur->obj->object_data);
if (!o->formatted.valid) _relayout(cur->obj);
x += o->style_pad.l;
y += o->style_pad.t;
for (l = (Evas_Object_List *)o->lines; l; l = l->next)
{
Evas_Object_Textblock_Line *ln;
@ -3261,6 +3466,96 @@ evas_textblock2_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x,
return 0;
}
int
evas_textblock2_cursor_line_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord y)
{
Evas_Object_Textblock *o;
Evas_Object_List *l;
Evas_Object_Textblock_Line *ln = NULL;
if (!cur) return -1;
o = (Evas_Object_Textblock *)(cur->obj->object_data);
if (!o->formatted.valid) _relayout(cur->obj);
y += o->style_pad.t;
for (l = (Evas_Object_List *)o->lines; l; l = l->next)
{
Evas_Object_Textblock_Line *ln;
ln = (Evas_Object_Textblock_Line *)l;
if (ln->y > y) break;
if ((ln->y <= y) && ((ln->y + ln->h) > y))
{
evas_textblock2_cursor_line_set(cur, ln->line_no);
return ln->line_no;
}
}
return -1;
}
Evas_List *
evas_textblock2_cursor_range_geometry_get(Evas_Textblock_Cursor *cur1, Evas_Textblock_Cursor *cur2)
{
Evas_Object_Textblock *o;
Evas_List *rects = NULL;
Evas_Coord cx, cy, cw, ch, lx, ly, lw, lh;
Evas_Textblock_Rectangle *tr;
int i, line, line2;
if (!cur1) return NULL;
if (!cur2) return NULL;
if (cur1->obj != cur2->obj) return NULL;
o = (Evas_Object_Textblock *)(cur1->obj->object_data);
if (evas_textblock2_cursor_compare(cur1, cur2) > 0)
{
Evas_Textblock_Cursor *tc;
tc = cur1;
cur1 = cur2;
cur2 = tc;
}
line = evas_textblock2_cursor_char_geometry_get(cur1, &cx, &cy, &cw, &ch);
line = evas_textblock2_cursor_line_geometry_get(cur1, &lx, &ly, &lw, &lh);
line2 = evas_textblock2_cursor_line_geometry_get(cur2, NULL, NULL, NULL, NULL);
if (line == line2)
{
tr = calloc(1, sizeof(Evas_Textblock_Rectangle));
rects = evas_list_append(rects, tr);
tr->x = cx;
tr->y = ly;
tr->h = lh;
line = evas_textblock2_cursor_char_geometry_get(cur2, &cx, &cy, &cw, &ch);
tr->w = cx + cw - tr->x;
}
else
{
tr = calloc(1, sizeof(Evas_Textblock_Rectangle));
rects = evas_list_append(rects, tr);
tr->x = cx;
tr->y = ly;
tr->h = lh;
tr->w = lx + lw - cx;
for (i = line +1; i < line2; i++)
{
evas_object_textblock2_line_number_geometry_get(cur1->obj, i, &lx, &ly, &lw, &lh);
tr = calloc(1, sizeof(Evas_Textblock_Rectangle));
rects = evas_list_append(rects, tr);
tr->x = lx;
tr->y = ly;
tr->h = lh;
tr->w = lw;
}
line = evas_textblock2_cursor_char_geometry_get(cur2, &cx, &cy, &cw, &ch);
line = evas_textblock2_cursor_line_geometry_get(cur2, &lx, &ly, &lw, &lh);
tr = calloc(1, sizeof(Evas_Textblock_Rectangle));
rects = evas_list_append(rects, tr);
tr->x = lx;
tr->y = ly;
tr->h = lh;
tr->w = cx + cw - lx;
}
return rects;
}
/* general controls */
Evas_Bool
evas_object_textblock2_line_number_geometry_get(Evas_Object *obj, int line, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
@ -3308,6 +3603,7 @@ evas_object_textblock2_clear(Evas_Object *obj)
o->native.valid = 0;
o->changed = 1;
evas_object_change(obj);
/* FIXME: adjust cursors that are affected by the change */
}
void

View File

@ -27,7 +27,7 @@ evas_common_font_query_size(RGBA_Font *fn, const char *text, int *w, int *h)
FT_UInt index;
RGBA_Font_Glyph *fg;
int chr_x, chr_y, chr_w;
int gl;
int gl, kern;
gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
if (gl == 0) break;
@ -35,6 +35,7 @@ evas_common_font_query_size(RGBA_Font *fn, const char *text, int *w, int *h)
/* hmmm kerning means i can't sanely do my own cached metric tables! */
/* grrr - this means font face sharing is kinda... not an option if */
/* you want performance */
kern = 0;
if ((use_kerning) && (prev_index) && (index) &&
(pface == fi->src->ft.face))
{
@ -42,7 +43,10 @@ evas_common_font_query_size(RGBA_Font *fn, const char *text, int *w, int *h)
if (FT_Get_Kerning(fi->src->ft.face, prev_index, index,
ft_kerning_default, &delta) == 0)
pen_x += delta.x << 2;
{
kern = delta.x << 2;
pen_x += kern;
}
}
pface = fi->src->ft.face;
fg = evas_common_font_int_cache_glyph_get(fi, index);
@ -50,7 +54,14 @@ evas_common_font_query_size(RGBA_Font *fn, const char *text, int *w, int *h)
chr_x = (pen_x + (fg->glyph_out->left << 8)) >> 8;
chr_y = (pen_y + (fg->glyph_out->top << 8)) >> 8;
chr_w = fg->glyph_out->bitmap.width;
// chr_w = fg->glyph_out->bitmap.width;
chr_w = fg->glyph_out->bitmap.width + (kern >> 8);
{
int advw;
advw = ((fg->glyph->advance.x + (kern << 8)) >> 16);
if (chr_w < advw) chr_w = advw;
}
if ((!prev_index) && (chr_x < 0))
start_x = chr_x;