more things taken off the list of things to do. styles seem to work.. :)

SVN revision: 13420
This commit is contained in:
Carsten Haitzler 2005-02-18 06:37:24 +00:00
parent cf1af057cc
commit 24799a4270
1 changed files with 164 additions and 36 deletions

View File

@ -10,13 +10,10 @@
*
* things to add:
*
* * if a word spans 2 layout nodes with no whitespace, it should not be splittable.
* * styles (outline, glow, etxra glow, shadow, soft shadow, etc.)
* * add spacing/padding for style effects (first scan all format nodes and find styles, add up/merge padding), then do real layout.
* * if a word (or char) doesnt fit at all do something sensible
* * anchors (for inline objects other than text - images etc.) - variable size ones too
* * tabs (indents)
* * left and right margins
* * anchors (for inline objects other than text - images etc.) - variable size ones too
* * if a word (or char) doesnt fit at all do something sensible
* * freeze thaw api
*
* tough ones:
@ -26,6 +23,7 @@
* * obstacle objects to wrap around
* * kerning control
* * fully justified text (space chars evenly to fit the line)
* * if a word spans 2 layout nodes with no whitespace, it should not be splittable.
*
* really tough ones:
* * fix core text code to properly handle unicode codeponts - handle ALL unicode domains properly.
@ -684,9 +682,79 @@ evas_object_textblock_layout_internal(Evas_Object *obj, int w, int h, int *forma
Layout_Node *line_start = NULL;
int text_pos = 0, fw = 0, fh = 0, last_mdescent = 0, line = 0, last_line = 0;
int last_line_underline = 0, last_line_double_underline = 0;
int pad_l = 0, pad_r = 0, pad_t = 0, pad_b = 0;
int ww, hh;
o = (Evas_Object_Textblock *)(obj->object_data);
ww = w;
hh = h;
evas_object_textblock_layout_init(&layout);
for (l = (Evas_Object_List *)o->nodes; l; l = l->next)
{
Node *node;
node = (Node *)l;
if (node->format)
{
evas_object_textblock_layout_format_modify(&layout, node->format);
if (layout.style == STYLE_SHADOW)
{
if (pad_r < 1) pad_r = 1;
if (pad_b < 1) pad_b = 1;
}
else if (layout.style == STYLE_OUTLINE)
{
if (pad_l < 1) pad_l = 1;
if (pad_r < 1) pad_r = 1;
if (pad_t < 1) pad_t = 1;
if (pad_b < 1) pad_b = 1;
}
else if (layout.style == STYLE_GLOW)
{
if (pad_l < 2) pad_l = 2;
if (pad_r < 2) pad_r = 2;
if (pad_t < 2) pad_t = 2;
if (pad_b < 2) pad_b = 2;
}
else if (layout.style == STYLE_OUTLINE_SHADOW)
{
if (pad_l < 1) pad_l = 1;
if (pad_r < 2) pad_r = 2;
if (pad_t < 1) pad_t = 1;
if (pad_b < 2) pad_b = 2;
}
else if (layout.style == STYLE_FAR_SHADOW)
{
if (pad_r < 2) pad_r = 2;
if (pad_b < 2) pad_b = 2;
}
else if (layout.style == STYLE_OUTLINE_SOFT_SHADOW)
{
if (pad_l < 1) pad_l = 1;
if (pad_r < 4) pad_r = 4;
if (pad_t < 1) pad_t = 1;
if (pad_b < 4) pad_b = 4;
}
else if (layout.style == STYLE_SOFT_SHADOW)
{
if (pad_l < 1) pad_l = 1;
if (pad_r < 3) pad_r = 3;
if (pad_t < 1) pad_t = 1;
if (pad_b < 3) pad_b = 3;
}
else if (layout.style == STYLE_FAR_SOFT_SHADOW)
{
if (pad_r < 4) pad_r = 4;
if (pad_b < 4) pad_b = 4;
}
}
}
ww -= pad_r;
hh -= pad_b;
evas_object_textblock_layout_clear(obj, &layout);
evas_object_textblock_layout_init(&layout);
layout.line.y = pad_t;
layout.line.x = pad_l;
/* format width is object width */
// printf("RE-LAYOUT %ix%i!\n", w, h);
for (l = (Evas_Object_List *)o->nodes; l; l = l->next)
@ -709,7 +777,7 @@ evas_object_textblock_layout_internal(Evas_Object *obj, int w, int h, int *forma
{
if (lnode)
lnode->line_end = 1;
layout.line.x = 0;
layout.line.x = pad_l;
if ((layout.line.y + layout.line.mascent + layout.line.mdescent) > h)
{
/* FIXME: this node would overflow to the next textblock */
@ -729,7 +797,7 @@ evas_object_textblock_layout_internal(Evas_Object *obj, int w, int h, int *forma
if (layout.second_underline) last_line_double_underline = 1;
}
}
if (node->text)
else if (node->text)
{
int inset = 0, hadvance = 0, vadvance = 0;
int ascent = 0, descent = 0, tw = 0, th = 0;
@ -744,7 +812,7 @@ evas_object_textblock_layout_internal(Evas_Object *obj, int w, int h, int *forma
/* FIXME: we cant do this - we need to be able to qury text
* overflow amounts */
/*
if (layout.line.y >= h)
if (layout.line.y >= hh)
{
free(text);
goto breakout;
@ -759,11 +827,11 @@ evas_object_textblock_layout_internal(Evas_Object *obj, int w, int h, int *forma
if (lnode->layout.font.name)
font = evas_font_load(obj->layer->evas, lnode->layout.font.name, lnode->layout.font.source, lnode->layout.font.size);
/* if this is at the start of the line... */
if (layout.line.x == 0)
if (layout.line.x == pad_l)
{
if (font) inset = ENFN->font_inset_get(ENDT, font, text);
layout.line.inset = inset;
layout.line.x = -inset;
layout.line.x = pad_l - inset;
layout.line.mascent = 0;
layout.line.mdescent = 0;
line_start = lnode;
@ -781,7 +849,7 @@ evas_object_textblock_layout_internal(Evas_Object *obj, int w, int h, int *forma
if (w > 0)
{
if (font) chrpos = ENFN->font_char_at_coords_get(ENDT, font, text,
w - layout.line.x, 0,
ww - layout.line.x, 0,
&cx, &cy, &cw, &ch);
}
else
@ -801,7 +869,7 @@ evas_object_textblock_layout_internal(Evas_Object *obj, int w, int h, int *forma
layout_nodes = evas_object_list_append(layout_nodes, lnode);
/* and advance */
/* fix up max ascent/descent for the line */
adj = (double)(w - (lnode->layout.line.x + tw + layout.line.inset)) * layout.align;
adj = (double)(w - (lnode->layout.line.x -pad_l + tw + layout.line.inset)) * layout.align;
adj -= line_start->layout.line.x;
if ((layout.line.x + hadvance) > fw)
fw = layout.line.x + hadvance;
@ -848,31 +916,48 @@ evas_object_textblock_layout_internal(Evas_Object *obj, int w, int h, int *forma
{
int ppos, pos, chr;
pos = chrpos;
chr = evas_common_font_utf8_get_prev(text, &pos);
ppos = pos = chrpos;
while ((!evas_object_textblock_char_is_white(chr))
&&
(pos >= 0) &&
(chr > 0))
if (chrpos == 0)
{
ppos = pos;
chr = evas_common_font_utf8_get_prev(text, &pos);
pos = chrpos;
nchrpos = pos;
}
chr = evas_common_font_utf8_get_next(text, &ppos);
if (ppos < 0) ppos = 0;
chrpos = ppos;
while ((evas_object_textblock_char_is_white(chr))
&&
(pos >= 0) &&
(chr > 0))
else
{
ppos = pos;
pos = chrpos;
chr = evas_common_font_utf8_get_prev(text, &pos);
ppos = pos = chrpos;
while ((!evas_object_textblock_char_is_white(chr))
&&
(pos >= 0) &&
(chr > 0))
{
ppos = pos;
chr = evas_common_font_utf8_get_prev(text, &pos);
}
if ((ppos == 0) &&
(!evas_object_textblock_char_is_white(chr)))
{
chrpos = 0;
nchrpos = 0;
}
else
{
chr = evas_common_font_utf8_get_next(text, &ppos);
if (ppos < 0) ppos = 0;
chrpos = ppos;
while ((evas_object_textblock_char_is_white(chr))
&&
(pos >= 0) &&
(chr > 0))
{
ppos = pos;
chr = evas_common_font_utf8_get_prev(text, &pos);
}
chr = evas_common_font_utf8_get_next(text, &ppos);
if (ppos < 0) ppos = 0;
nchrpos = ppos;
}
}
chr = evas_common_font_utf8_get_next(text, &ppos);
if (ppos < 0) ppos = 0;
nchrpos = ppos;
}
/* if the first char in the line can't fit!!! */
if ((chrpos == 0) && (lnode == line_start))
@ -884,6 +969,47 @@ evas_object_textblock_layout_internal(Evas_Object *obj, int w, int h, int *forma
evas_object_textblock_layout_clear(obj, &(lnode->layout));
free(lnode);
}
/* its not the first char on the line... but its the */
/* first char of a node, so defer this node until the next */
/* loop */
else if (chrpos == 0)
{
if (lnode->text) free(lnode->text);
evas_object_textblock_layout_clear(obj, &(lnode->layout));
free(lnode);
lnode = NULL;
if (layout_nodes)
lnode = (Layout_Node *)((Evas_Object_List *)layout_nodes)->last;
if (lnode)
{
adj = (double)(w - (layout.line.x - pad_l + tw + layout.line.inset)) * layout.align;
adj -= line_start->layout.line.x;
for (ll = (Evas_Object_List *)lnode; ll; ll = ll->prev)
{
Layout_Node *lnode2;
lnode2 = (Layout_Node *)ll;
lnode2->layout.line.x += adj;
lnode2->layout.line.mascent = layout.line.mascent;
lnode2->layout.line.mdescent = layout.line.mdescent;
if (ll == (Evas_Object_List *)line_start) break;
}
lnode->line_end = 1;
layout.line.inset = 0;
layout.line.x = pad_l;
if ((layout.line.y + layout.line.mascent + layout.line.mdescent) > hh)
{
/* FIXME: this node would overflow to the next textblock */
}
last_line_underline = 0;
last_line_double_underline = 0;
line++;
layout.line.y += layout.line.mascent + layout.line.mdescent;
fh = layout.line.y;
line_start = NULL;
goto new_node;
}
}
else
{
char *text1, *text2;
@ -906,7 +1032,7 @@ evas_object_textblock_layout_internal(Evas_Object *obj, int w, int h, int *forma
lnode->h = th;
lnode->layout.line.advance = hadvance;
layout_nodes = evas_object_list_append(layout_nodes, lnode);
adj = (double)(w - (lnode->layout.line.x + tw + layout.line.inset)) * layout.align;
adj = (double)(ww - (lnode->layout.line.x - pad_l + tw + layout.line.inset)) * layout.align;
adj -= line_start->layout.line.x;
for (ll = (Evas_Object_List *)lnode; ll; ll = ll->prev)
{
@ -920,8 +1046,8 @@ evas_object_textblock_layout_internal(Evas_Object *obj, int w, int h, int *forma
}
lnode->line_end = 1;
layout.line.inset = 0;
layout.line.x = 0;
if ((layout.line.y + layout.line.mascent + layout.line.mdescent) > h)
layout.line.x = pad_l;
if ((layout.line.y + layout.line.mascent + layout.line.mdescent) > hh)
{
/* FIXME: this node would overflow to the next textblock */
}
@ -944,6 +1070,7 @@ evas_object_textblock_layout_internal(Evas_Object *obj, int w, int h, int *forma
breakout:
evas_object_textblock_layout_clear(obj, &layout);
*line_count = last_line + 1;
fw += pad_r;
if (w > 0) *format_w = w;
else *format_w = fw;
if (last_line_double_underline)
@ -954,6 +1081,7 @@ evas_object_textblock_layout_internal(Evas_Object *obj, int w, int h, int *forma
{
if (last_mdescent < 1) fh += 1 - last_mdescent;
}
fh += pad_b;
*format_h = fh;
return (Layout_Node *)layout_nodes;
}