Enlightenment CVS committal Author : moom Project : e17 Module : proto
Dir : e17/proto/etk/src/lib Modified Files: etk_textblock.c etk_textblock.h Log Message: * More TB work. It now supports more tags and all the format are correctly rendered. You can change the wrapping whenever you want, the textblock object will be automatically updated. Lines are also clipped, and only the visible lines are actually created. Now, let's edit!! :) =================================================================== RCS file: /cvs/e/e17/proto/etk/src/lib/etk_textblock.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -3 -r1.15 -r1.16 --- etk_textblock.c 4 Jul 2006 00:20:04 -0000 1.15 +++ etk_textblock.c 4 Jul 2006 21:37:26 -0000 1.16 @@ -12,19 +12,11 @@ * @{ */ -/* The smart data of a textblock object */ -typedef struct Etk_Textblock_Object_SD -{ - Etk_Textblock *tb; - - Etk_Textblock_Wrap wrap; - Evas_Textblock_Style *style; +#define ETK_TB_TAG_PARAM_IS(param, len) \ + (param_len == (len) && strncasecmp(param_start, (param), (len)) == 0) - Evas_List *lines; - Evas_Object *cursor_object; - - Ecore_Job *update_job; -} Etk_Textblock_Object_SD; +#define ETK_TB_TAG_VALUE_IS(value, len) \ + (value_len == (len) && strncasecmp(value_start, (value), (len)) == 0) /* A line for a textblock object is text terminated by '\n', <br> or </p>. * It can actually fill several "visual" lines because of wrapping */ @@ -39,6 +31,23 @@ Etk_Bool need_content_update; } Etk_Textblock_Object_Line; +/* The smart data of a textblock object */ +typedef struct Etk_Textblock_Object_SD +{ + Etk_Textblock *tb; + + Etk_Textblock_Wrap wrap; + Evas_Textblock_Style *style; + + Evas_List *lines; + Evas_List *first_visible_line; + + Evas_Object *cursor_object; + Evas_Object *clip; + + Ecore_Job *update_job; +} Etk_Textblock_Object_SD; + static void _etk_tb_constructor(Etk_Textblock *tb); static void _etk_tb_destructor(Etk_Textblock *tb); @@ -72,7 +81,7 @@ static void _etk_textblock_object_line_add(Evas_Object *tbo, Etk_Textblock_Node *line_node); static void _etk_textblock_object_line_update_queue(Evas_Object *tbo, Etk_Textblock_Object_Line *line, Etk_Bool content_update, Etk_Bool geometry_update); static void _etk_textblock_object_line_update(Evas_Object *tbo, Etk_Textblock_Object_Line *line, int y); -static void _etk_textblock_object_line_fill(Evas_Textblock_Cursor *cur, Etk_Textblock_Node *node); +static void _etk_textblock_object_line_fill(Evas_Object *tbo, Evas_Textblock_Cursor *cur, Etk_Textblock_Node *node); static void _etk_textblock_object_update(Evas_Object *tbo); static void _etk_textblock_object_update_job(void *data); @@ -686,24 +695,61 @@ } /** - * @brief Sets how the text of the textblock object should be wrapped + * @brief Sets how the text of the textblock object should be wrapped by default * @param tbo a textblock object - * @param wrap the wrap mode + * @param wrap the wrap mode. Here, ETK_TEXTBLOCK_WRAP_DEFAULT is equivalent to ETK_TEXTBLOCK_WRAP_WORD */ void etk_textblock_object_wrap_set(Evas_Object *tbo, Etk_Textblock_Wrap wrap) { Etk_Textblock_Object_SD *tbo_sd; + Etk_Textblock_Object_Line *line; + Evas_List *l; if (!tbo || !(tbo_sd = evas_object_smart_data_get(tbo))) return; + if (wrap == ETK_TEXTBLOCK_WRAP_DEFAULT) + wrap = ETK_TEXTBLOCK_WRAP_WORD; if (tbo_sd->wrap != wrap) tbo_sd->wrap = wrap; - /* TODO: update the object */ + + + /* Updates the object's lines */ + for (l = tbo_sd->lines; l; l = l->next) + { + line = l->data; + if (line->object && line->node && line->node->parent && + line->node->parent->type == ETK_TEXTBLOCK_NODE_PARAGRAPH && + line->node->parent->tag.params.p.wrap < 0) + { + Evas_Textblock_Cursor *cur; + const char *format; + + cur = evas_object_textblock_cursor_new(line->object); + for (evas_textblock_cursor_node_first(cur); evas_textblock_cursor_node_next(cur); ) + { + if ((format == evas_textblock_cursor_node_format_get(cur)) && strstr(format, "wrap")) + { + if (wrap == ETK_TEXTBLOCK_WRAP_WORD) + evas_textblock_cursor_format_append(cur, "+ wrap=word"); + else if (wrap == ETK_TEXTBLOCK_WRAP_CHAR) + evas_textblock_cursor_format_append(cur, "+ wrap=char"); + else + evas_textblock_cursor_format_append(cur, "+ wrap=none"); + evas_textblock_cursor_node_prev(cur); + evas_textblock_cursor_node_delete(cur); + evas_textblock_cursor_free(cur); + break; + } + } + + _etk_textblock_object_line_update_queue(tbo, line, ETK_FALSE, ETK_TRUE); + } + } } /** - * @brief Gets the wrap mode of the textblock object + * @brief Gets the default wrap mode of the textblock object * @param tbo a textblock object * @return Returns the wrap mode of the textblock object */ @@ -893,10 +939,14 @@ node->tag.params.u.color1.r = -1; node->tag.params.u.color2.r = -1; break; + case ETK_TEXTBLOCK_TAG_STRIKETHROUGH: + node->tag.params.s.color.r = -1; + break; case ETK_TEXTBLOCK_TAG_P: node->tag.params.p.align = -1.0; node->tag.params.p.left_margin = 0; node->tag.params.p.right_margin = 0; + node->tag.params.p.wrap = ETK_TEXTBLOCK_WRAP_DEFAULT; break; case ETK_TEXTBLOCK_TAG_STYLE: node->tag.params.style.type = ETK_TEXTBLOCK_STYLE_NONE; @@ -961,33 +1011,40 @@ static void _etk_textblock_node_format_get(Etk_Textblock_Node *node, Etk_Textblock_Format *format) { Etk_Textblock_Node *n; + Etk_Bool paragraph_met = ETK_FALSE; Etk_Bool style_met = ETK_FALSE; if (!format) return; /* Initializes the format: */ + format->align = -1.0; + format->left_margin = 0.0; + format->right_margin = 0.0; + format->wrap = ETK_TEXTBLOCK_WRAP_DEFAULT; format->style = ETK_TEXTBLOCK_STYLE_NONE; format->style_color1.r = -1; format->style_color2.r = -1; format->underline = ETK_TEXTBLOCK_UNDERLINE_NONE; format->underline_color1.r = -1; format->underline_color2.r = -1; + format->strikethrough = ETK_FALSE; + format->strikethrough = ETK_FALSE; format->font_face = NULL; format->font_size = -1; format->font_color.r = -1; - format->bold = 0; - format->italic = 0; + format->bold = ETK_FALSE; + format->italic = ETK_FALSE; for (n = node; n; n = n->parent) { switch (n->tag.type) { case ETK_TEXTBLOCK_TAG_BOLD: - format->bold = 1; + format->bold = ETK_TRUE; break; case ETK_TEXTBLOCK_TAG_ITALIC: - format->italic = 1; + format->italic = ETK_TRUE; break; case ETK_TEXTBLOCK_TAG_UNDERLINE: if (format->underline == ETK_TEXTBLOCK_UNDERLINE_NONE) @@ -997,6 +1054,13 @@ format->underline_color2 = n->tag.params.u.color2; } break; + case ETK_TEXTBLOCK_TAG_STRIKETHROUGH: + if (!format->strikethrough) + { + format->strikethrough = ETK_TRUE; + format->strikethrough_color = n->tag.params.s.color; + } + break; case ETK_TEXTBLOCK_TAG_STYLE: if (!style_met) { @@ -1006,6 +1070,16 @@ style_met = ETK_TRUE; } break; + case ETK_TEXTBLOCK_TAG_P: + if (!paragraph_met) + { + format->align = n->tag.params.p.align; + format->left_margin = n->tag.params.p.left_margin; + format->right_margin = n->tag.params.p.right_margin; + format->wrap = n->tag.params.p.wrap; + paragraph_met = ETK_TRUE; + } + break; case ETK_TEXTBLOCK_TAG_FONT: if (!format->font_face) format->font_face = n->tag.params.font.face; @@ -1129,6 +1203,8 @@ tag_type = ETK_TEXTBLOCK_TAG_ITALIC; else if (strcasecmp(tag_name, "u") == 0) tag_type = ETK_TEXTBLOCK_TAG_UNDERLINE; + else if (strcasecmp(tag_name, "s") == 0) + tag_type = ETK_TEXTBLOCK_TAG_STRIKETHROUGH; else if (strcasecmp(tag_name, "p") == 0) tag_type = ETK_TEXTBLOCK_TAG_P; else if (strcasecmp(tag_name, "style") == 0) @@ -1281,64 +1357,88 @@ { switch (tag_type) { + /* Underline */ case ETK_TEXTBLOCK_TAG_UNDERLINE: - if (param_len == 4 && strncasecmp(param_start, "type", 4) == 0) + if (ETK_TB_TAG_PARAM_IS("type", 4)) { - if (value_len == 6 && strncasecmp(value_start, "single", 6) == 0) + if (ETK_TB_TAG_VALUE_IS("single", 6)) new_node->tag.params.u.type = ETK_TEXTBLOCK_UNDERLINE_SINGLE; - else if (value_len == 6 && strncasecmp(value_start, "double", 6) == 0) + else if (ETK_TB_TAG_VALUE_IS("double", 6) == 0) new_node->tag.params.u.type = ETK_TEXTBLOCK_UNDERLINE_DOUBLE; } - else if (param_len == 6 && strncasecmp(param_start, "color1", 6) == 0) + else if (ETK_TB_TAG_PARAM_IS("color1", 6)) _etk_textblock_color_parse(value_start, value_len, &new_node->tag.params.u.color1); - - else if (param_len == 6 && strncasecmp(param_start, "color2", 6) == 0) + else if (ETK_TB_TAG_PARAM_IS("color2", 6)) _etk_textblock_color_parse(value_start, value_len, &new_node->tag.params.u.color2); break; + /* Striketrhough */ + case ETK_TEXTBLOCK_TAG_STRIKETHROUGH: + if (ETK_TB_TAG_PARAM_IS("color", 5)) + _etk_textblock_color_parse(value_start, value_len, &new_node->tag.params.s.color); + break; + /* Paragraph */ case ETK_TEXTBLOCK_TAG_P: - if (param_len == 5 && strncasecmp(param_start, "align", 5) == 0) + if (ETK_TB_TAG_PARAM_IS("align", 5)) { - if (value_len == 4 && strncasecmp(value_start, "left", 4) == 0) + if (ETK_TB_TAG_VALUE_IS("left", 4)) new_node->tag.params.p.align = 0.0; - else if (value_len == 6 && strncasecmp(value_start, "center", 6) == 0) + else if (ETK_TB_TAG_VALUE_IS("center", 6)) new_node->tag.params.p.align = 0.5; - else if (value_len == 5 && strncasecmp(value_start, "right", 5) == 0) + else if (ETK_TB_TAG_VALUE_IS("right", 5)) new_node->tag.params.p.align = 1.0; else new_node->tag.params.p.align = _etk_textblock_float_parse(value_start, value_len, -1.0); } - else if (param_len == 11 && strncasecmp(param_start, "left_margin", 11) == 0) + else if (ETK_TB_TAG_PARAM_IS("left_margin", 11)) new_node->tag.params.p.left_margin = _etk_textblock_int_parse(value_start, value_len, 0); - else if (param_len == 12 && strncasecmp(param_start, "right_margin", 12) == 0) + else if (ETK_TB_TAG_PARAM_IS("right_margin", 12)) new_node->tag.params.p.right_margin = _etk_textblock_int_parse(value_start, value_len, 0); break; + /* Style */ case ETK_TEXTBLOCK_TAG_STYLE: - if (param_len == 6 && strncasecmp(param_start, "effect", 6) == 0) + if (ETK_TB_TAG_PARAM_IS("effect", 6)) { - if (value_len == 4 && strncasecmp(value_start, "none", 4) == 0) + if (ETK_TB_TAG_VALUE_IS("none", 4)) new_node->tag.params.style.type = ETK_TEXTBLOCK_STYLE_NONE; - else if (value_len == 7 && strncasecmp(value_start, "outline", 7) == 0) + else if (ETK_TB_TAG_VALUE_IS("outline", 7)) new_node->tag.params.style.type = ETK_TEXTBLOCK_STYLE_OUTLINE; - else if (value_len == 6 && strncasecmp(value_start, "shadow", 6) == 0) + else if (ETK_TB_TAG_VALUE_IS("shadow", 6)) new_node->tag.params.style.type = ETK_TEXTBLOCK_STYLE_SHADOW; + else if (ETK_TB_TAG_VALUE_IS("soft_outline", 12)) + new_node->tag.params.style.type = ETK_TEXTBLOCK_STYLE_SOFT_OUTLINE; + else if (ETK_TB_TAG_VALUE_IS("glow", 4)) + new_node->tag.params.style.type = ETK_TEXTBLOCK_STYLE_GLOW; + else if (ETK_TB_TAG_VALUE_IS("outline_shadow", 14)) + new_node->tag.params.style.type = ETK_TEXTBLOCK_STYLE_OUTLINE_SHADOW; + else if (ETK_TB_TAG_VALUE_IS("far_shadow", 10)) + new_node->tag.params.style.type = ETK_TEXTBLOCK_STYLE_FAR_SHADOW; + else if (ETK_TB_TAG_VALUE_IS("outline_soft_shadow", 19)) + new_node->tag.params.style.type = ETK_TEXTBLOCK_STYLE_OUTLINE_SOFT_SHADOW; + else if (ETK_TB_TAG_VALUE_IS("soft_shadow", 11)) + new_node->tag.params.style.type = ETK_TEXTBLOCK_STYLE_SOFT_SHADOW; + else if (ETK_TB_TAG_VALUE_IS("far_soft_shadow", 15)) + new_node->tag.params.style.type = ETK_TEXTBLOCK_STYLE_FAR_SOFT_SHADOW; } - else if (param_len == 6 && strncasecmp(param_start, "color1", 6) == 0) + else if (ETK_TB_TAG_PARAM_IS("color1", 6)) _etk_textblock_color_parse(value_start, value_len, &new_node->tag.params.style.color1); - else if (param_len == 6 && strncasecmp(param_start, "color2", 6) == 0) + else if (ETK_TB_TAG_PARAM_IS("color2", 6)) _etk_textblock_color_parse(value_start, value_len, &new_node->tag.params.style.color2); break; + /* Font */ case ETK_TEXTBLOCK_TAG_FONT: - if (param_len == 4 && strncasecmp(param_start, "face", 4) == 0) + if (ETK_TB_TAG_PARAM_IS("face", 4)) { + free(new_node->tag.params.font.face); new_node->tag.params.font.face = malloc(value_len + 1); strncpy(new_node->tag.params.font.face, value_start, value_len); new_node->tag.params.font.face[value_len] = '\0'; } - else if (param_len == 4 && strncasecmp(param_start, "size", 4) == 0) + else if (ETK_TB_TAG_PARAM_IS("size", 4)) new_node->tag.params.font.size = _etk_textblock_int_parse(value_start, value_len, -1); - else if (param_len == 5 && strncasecmp(param_start, "color", 5) == 0) + else if (ETK_TB_TAG_PARAM_IS("color", 5)) _etk_textblock_color_parse(value_start, value_len, &new_node->tag.params.font.color); break; + default: break; } @@ -1425,17 +1525,27 @@ if (node->tag.params.u.color2.r >= 0) { - etk_string_insert_printf(start_tag, 6, " color2=#%.2X%.2X%.2X%.2X", node->tag.params.u.color2.r, + etk_string_insert_printf(start_tag, 2, " color2=#%.2X%.2X%.2X%.2X", node->tag.params.u.color2.r, node->tag.params.u.color2.g, node->tag.params.u.color2.b, node->tag.params.u.color2.a); } if (node->tag.params.u.color1.r >= 0) { - etk_string_insert_printf(start_tag, 6, " color1=#%.2X%.2X%.2X%.2X", node->tag.params.u.color1.r, + etk_string_insert_printf(start_tag, 2, " color1=#%.2X%.2X%.2X%.2X", node->tag.params.u.color1.r, node->tag.params.u.color1.g, node->tag.params.u.color1.b, node->tag.params.u.color1.a); } if (node->tag.params.u.type == ETK_TEXTBLOCK_UNDERLINE_DOUBLE) etk_string_insert(start_tag, 2, " type=\"double\""); break; + case ETK_TEXTBLOCK_TAG_STRIKETHROUGH: + start_tag = etk_string_new("<s>"); + end_tag = etk_string_new("</s>"); + + if (node->tag.params.s.color.r >= 0) + { + etk_string_insert_printf(start_tag, 2, " color=#%.2X%.2X%.2X%.2X", node->tag.params.s.color.r, + node->tag.params.s.color.g, node->tag.params.s.color.b, node->tag.params.s.color.a); + } + break; case ETK_TEXTBLOCK_TAG_P: if (_etk_textblock_node_is_default_paragraph(node)) break; @@ -1520,16 +1630,10 @@ for (n = node->children; n; n = n->next) _etk_textblock_node_text_get(n, markup, text); } - /* TODO: adds '\n' at the end of the lines */ - /*if (node->type == ETK_TEXTBLOCK_NODE_END_OF_LINE) - { - if (markup) - etk_string_append_char(text, '\n'); - else - etk_string_append_char(text, etk_string_get(node->text)); - }*/ etk_string_append(text, etk_string_get(end_tag)); + if (node->type == ETK_TEXTBLOCK_NODE_LINE && node->next) + etk_string_append_char(text, '\n'); etk_object_destroy(ETK_OBJECT(start_tag)); etk_object_destroy(ETK_OBJECT(end_tag)); @@ -1978,13 +2082,10 @@ tbo_sd->update_job = ecore_job_add(_etk_textblock_object_update_job, tbo); } -static Evas_Object *_tb_obj = NULL; - /* Updates the line of the textblock object */ static void _etk_textblock_object_line_update(Evas_Object *tbo, Etk_Textblock_Object_Line *line, int y) { Etk_Textblock_Object_SD *tbo_sd; - Etk_Textblock_Node *n; Evas *evas; int ox, oy, ow, oh; @@ -1992,7 +2093,7 @@ return; if (!(evas = evas_object_evas_get(tbo))) return; - if (!line->need_content_update && !line->need_geometry_update) + if (!line->need_content_update && !line->need_geometry_update && line->object) return; evas_object_geometry_get(tbo, &ox, &oy, &ow, &oh); @@ -2001,7 +2102,15 @@ { line->object = evas_object_textblock_add(evas); evas_object_textblock_style_set(line->object, tbo_sd->style); - evas_object_show(line->object); + evas_object_clip_set(line->object, tbo_sd->clip); + if (evas_object_visible_get(tbo)) + { + evas_object_show(line->object); + evas_object_show(tbo_sd->clip); + } + /* TODO: optimize!!! */ + line->need_content_update = ETK_TRUE; + line->need_geometry_update = ETK_TRUE; } if (line->need_content_update) @@ -2011,8 +2120,7 @@ evas_object_textblock_clear(line->object); cur = evas_object_textblock_cursor_new(line->object); evas_textblock_cursor_node_first(cur); - _tb_obj = line->object; - _etk_textblock_object_line_fill(cur, line->node); + _etk_textblock_object_line_fill(tbo, cur, line->node); evas_textblock_cursor_free(cur); line->need_content_update = ETK_FALSE; @@ -2022,18 +2130,9 @@ { line->geometry.x = 0; line->geometry.y = y; + line->geometry.w = ow; evas_object_resize(line->object, ow, 300); - evas_object_textblock_size_formatted_get(line->object, &line->geometry.w, &line->geometry.h); - - for (n = line->node; n; n = n->parent) - { - if (n->type == ETK_TEXTBLOCK_NODE_PARAGRAPH) - { - if (n->tag.params.p.align >= 0) - line->geometry.x = (ow - line->geometry.w) * n->tag.params.p.align; - break; - } - } + evas_object_textblock_size_formatted_get(line->object, NULL, &line->geometry.h); evas_object_move(line->object, ox + line->geometry.x, oy + line->geometry.y); evas_object_resize(line->object, line->geometry.w, line->geometry.h); @@ -2043,13 +2142,14 @@ } /* Fills recursively the line of the textblock object with the content of a node */ -static void _etk_textblock_object_line_fill(Evas_Textblock_Cursor *cur, Etk_Textblock_Node *node) +static void _etk_textblock_object_line_fill(Evas_Object *tbo, Evas_Textblock_Cursor *cur, Etk_Textblock_Node *node) { Etk_String *fmt_str = NULL; + Etk_Textblock_Object_SD *tbo_sd; Etk_Textblock_Node *n; int opened_nodes = 0, i; - if (!cur || !node) + if (!tbo || !cur || !node || !(tbo_sd = evas_object_smart_data_get(tbo))) return; /* A line node */ @@ -2059,6 +2159,19 @@ if ((paragraph = node->parent) && paragraph->type == ETK_TEXTBLOCK_NODE_PARAGRAPH) { + Etk_Textblock_Wrap wrap; + + /* Wrapping */ + if ((wrap = paragraph->tag.params.p.wrap) == ETK_TEXTBLOCK_WRAP_DEFAULT) + wrap = tbo_sd->wrap; + if (wrap == ETK_TEXTBLOCK_WRAP_WORD) + evas_textblock_cursor_format_append(cur, "+ wrap=word"); + else if (wrap == ETK_TEXTBLOCK_WRAP_CHAR) + evas_textblock_cursor_format_append(cur, "+ wrap=char"); + else + evas_textblock_cursor_format_append(cur, "+ wrap=none"); + opened_nodes++; + /* Alignment */ if (paragraph->tag.params.p.align == 0.5) { @@ -2091,11 +2204,15 @@ else if (node->type == ETK_TEXTBLOCK_NODE_NORMAL && etk_string_length_get(node->text) > 0) { Etk_Textblock_Format format; + Etk_Color color; + /* TODO: use default color here */ + Etk_Color black = { .r = 0, .g = 0, .b = 0, .a = 255 }; /* We add the format nodes */ /* TODO: we need to make the font changeable */ _etk_textblock_node_format_get(node, &format); + /* Font styles */ opened_nodes++; if (format.bold && !format.italic) evas_textblock_cursor_format_append(cur, "+ font=Vera-Bold"); @@ -2106,6 +2223,63 @@ else opened_nodes--; + /* Underline */ + if (format.underline != ETK_TEXTBLOCK_UNDERLINE_NONE) + { + if (format.underline == ETK_TEXTBLOCK_UNDERLINE_SINGLE) + { + evas_textblock_cursor_format_append(cur, "+ underline=single"); + opened_nodes++; + } + else if (format.underline == ETK_TEXTBLOCK_UNDERLINE_DOUBLE) + { + evas_textblock_cursor_format_append(cur, "+ underline=double"); + opened_nodes++; + } + + /* First color */ + if (format.underline_color1.r >= 0) + color = format.underline_color1; + else if (format.font_color.r >= 0) + color = format.font_color; + else + color = black; + fmt_str = etk_string_set_printf(fmt_str, "+ underline_color=#%.2X%.2X%.2X%.2X", + color.r, color.g, color.b, color.a); + evas_textblock_cursor_format_append(cur, etk_string_get(fmt_str)); + opened_nodes++; + + /* Second color */ + if (format.underline == ETK_TEXTBLOCK_UNDERLINE_DOUBLE) + { + if (format.underline_color2.r >= 0) + color = format.underline_color2; + fmt_str = etk_string_set_printf(fmt_str, "+ underline_color2=#%.2X%.2X%.2X%.2X", + color.r, color.g, color.b, color.a); + evas_textblock_cursor_format_append(cur, etk_string_get(fmt_str)); + opened_nodes++; + } + } + + /* Strikethrough */ + if (format.strikethrough) + { + evas_textblock_cursor_format_append(cur, "+ strikethrough=on"); + opened_nodes++; + + if (format.strikethrough_color.r >= 0) + color = format.underline_color1; + else if (format.font_color.r >= 0) + color = format.font_color; + else + color = black; + fmt_str = etk_string_set_printf(fmt_str, "+ strikethrough_color=#%.2X%.2X%.2X%.2X", + color.r, color.g, color.b, color.a); + evas_textblock_cursor_format_append(cur, etk_string_get(fmt_str)); + opened_nodes++; + } + + /* Font settings */ if (format.font_size >= 0) { fmt_str = etk_string_set_printf(fmt_str, "+ font_size=%d", format.font_size); @@ -2119,6 +2293,108 @@ evas_textblock_cursor_format_append(cur, etk_string_get(fmt_str)); opened_nodes++; } + + /* Effects */ + if (format.style != ETK_TEXTBLOCK_STYLE_NONE) + { + Etk_Bool append_color; + + switch (format.style) + { + case ETK_TEXTBLOCK_STYLE_OUTLINE: + evas_textblock_cursor_format_append(cur, "+ style=outline"); + break; + case ETK_TEXTBLOCK_STYLE_SHADOW: + evas_textblock_cursor_format_append(cur, "+ style=shadow"); + break; + case ETK_TEXTBLOCK_STYLE_SOFT_OUTLINE: + evas_textblock_cursor_format_append(cur, "+ style=soft_outline"); + break; + case ETK_TEXTBLOCK_STYLE_GLOW: + evas_textblock_cursor_format_append(cur, "+ style=glow"); + break; + case ETK_TEXTBLOCK_STYLE_OUTLINE_SHADOW: + evas_textblock_cursor_format_append(cur, "+ style=outline_shadow"); + break; + case ETK_TEXTBLOCK_STYLE_FAR_SHADOW: + evas_textblock_cursor_format_append(cur, "+ style=far_shadow"); + break; + case ETK_TEXTBLOCK_STYLE_OUTLINE_SOFT_SHADOW: + evas_textblock_cursor_format_append(cur, "+ style=outline_soft_shadow"); + break; + case ETK_TEXTBLOCK_STYLE_SOFT_SHADOW: + evas_textblock_cursor_format_append(cur, "+ style=soft_shadow"); + break; + case ETK_TEXTBLOCK_STYLE_FAR_SOFT_SHADOW: + evas_textblock_cursor_format_append(cur, "+ style=far_soft_shadow"); + break; + default: + opened_nodes--; + break; + } + opened_nodes++; + + /* First color */ + if (format.style_color1.r >= 0) + { + append_color = ETK_TRUE; + + switch (format.style) + { + case ETK_TEXTBLOCK_STYLE_OUTLINE: + case ETK_TEXTBLOCK_STYLE_SOFT_OUTLINE: + case ETK_TEXTBLOCK_STYLE_OUTLINE_SHADOW: + case ETK_TEXTBLOCK_STYLE_OUTLINE_SOFT_SHADOW: + fmt_str = etk_string_set(fmt_str, "+ outline_color="); + break; + case ETK_TEXTBLOCK_STYLE_SHADOW: + case ETK_TEXTBLOCK_STYLE_FAR_SHADOW: + case ETK_TEXTBLOCK_STYLE_SOFT_SHADOW: + case ETK_TEXTBLOCK_STYLE_FAR_SOFT_SHADOW: + fmt_str = etk_string_set(fmt_str, "+ shadow_color="); + case ETK_TEXTBLOCK_STYLE_GLOW: + fmt_str = etk_string_set(fmt_str, "+ glow_color1="); + default: + append_color = ETK_FALSE; + break; + } + + if (append_color) + { + fmt_str = etk_string_append_printf(fmt_str, "#%.2X%.2X%.2X%.2X", format.style_color1.r, + format.style_color1.g, format.style_color1.b, format.style_color1.a); + evas_textblock_cursor_format_append(cur, etk_string_get(fmt_str)); + opened_nodes++; + } + } + + /* Second color */ + if (format.style_color2.r >= 0) + { + append_color = ETK_TRUE; + + switch (format.style) + { + case ETK_TEXTBLOCK_STYLE_OUTLINE_SHADOW: + case ETK_TEXTBLOCK_STYLE_OUTLINE_SOFT_SHADOW: + fmt_str = etk_string_set(fmt_str, "+ shadow_color="); + break; + case ETK_TEXTBLOCK_STYLE_GLOW: + fmt_str = etk_string_set(fmt_str, "+ glow_color2="); + default: + append_color = ETK_FALSE; + break; + } + + if (append_color) + { + fmt_str = etk_string_append_printf(fmt_str, "#%.2X%.2X%.2X%.2X", format.style_color2.r, + format.style_color2.g, format.style_color2.b, format.style_color2.a); + evas_textblock_cursor_format_append(cur, etk_string_get(fmt_str)); + opened_nodes++; + } + } + } } etk_object_destroy(ETK_OBJECT(fmt_str)); @@ -2134,7 +2410,7 @@ } for (n = node->children; n; n = n->next) - _etk_textblock_object_line_fill(cur, n); + _etk_textblock_object_line_fill(tbo, cur, n); if (node->type == ETK_TEXTBLOCK_NODE_LINE) { @@ -2149,17 +2425,41 @@ Etk_Textblock_Object_SD *tbo_sd; Etk_Textblock_Object_Line *line; Evas_List *l; - int y; + int y_offset = 0; + int y, h; if (!tbo || !(tbo_sd = evas_object_smart_data_get(tbo))) return; y = 0; + evas_object_geometry_get(tbo, NULL, NULL, NULL, &h); + tbo_sd->first_visible_line = NULL; for (l = tbo_sd->lines; l; l = l->next) { line = l->data; + + if (y >= h) + { + if (line->object) + { + evas_object_del(line->object); + line->object = NULL; + continue; + } + else + break; + } + _etk_textblock_object_line_update(tbo, line, y); y = line->geometry.y + line->geometry.h; + + if (y <= y_offset) + { + evas_object_del(line->object); + line->object = NULL; + } + else if (!tbo_sd->first_visible_line) + tbo_sd->first_visible_line = l; } } @@ -2194,12 +2494,15 @@ tbo_sd = malloc(sizeof(Etk_Textblock_Object_SD)); tbo_sd->tb = NULL; tbo_sd->wrap = ETK_TEXTBLOCK_WRAP_WORD; + tbo_sd->update_job = NULL; + tbo_sd->cursor_object = NULL; + tbo_sd->clip = evas_object_rectangle_add(evas); tbo_sd->lines = NULL; - tbo_sd->update_job = NULL; + tbo_sd->first_visible_line = NULL; tbo_sd->style = evas_textblock_style_new(); - evas_textblock_style_set(tbo_sd->style, "DEFAULT='font=Vera font_size=10 align=left color=#000000 wrap=word'"); + evas_textblock_style_set(tbo_sd->style, "DEFAULT='font=Vera font_size=10 align=left color=#000000'"); evas_object_smart_data_set(obj, tbo_sd); } @@ -2251,6 +2554,8 @@ if (!obj || !(tbo_sd = evas_object_smart_data_get(obj))) return; + evas_object_move(tbo_sd->clip, x, y); + evas_object_geometry_get(obj, &prev_x, &prev_y, NULL, NULL); for (l = tbo_sd->lines; l; l = l->next) { @@ -2266,40 +2571,65 @@ static void _etk_tb_object_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) { Etk_Textblock_Object_SD *tbo_sd; + Evas_List *l; if (!obj || !(tbo_sd = evas_object_smart_data_get(obj))) return; - /* TODO: _etk_tb_object_smart_resize: optimize if the text is not wrapped? */ - /*if (tbo_sd->wrap == ETK_TEXTBLOCK_WRAP_NONE) - { - - } - else*/ - { - Evas_List *l; - - for (l = tbo_sd->lines; l; l = l->next) - _etk_textblock_object_line_update_queue(obj, l->data, ETK_FALSE, ETK_TRUE); - } + evas_object_resize(tbo_sd->clip, w, h); + + /* TODO: optimization for non-wrapped lines? */ + for (l = tbo_sd->lines; l; l = l->next) + _etk_textblock_object_line_update_queue(obj, l->data, ETK_FALSE, ETK_TRUE); } /* Shows the textblock object */ static void _etk_tb_object_smart_show(Evas_Object *obj) { Etk_Textblock_Object_SD *tbo_sd; + Etk_Textblock_Object_Line *line; + Evas_List *l; + Etk_Bool show_clip = ETK_FALSE; if (!obj || !(tbo_sd = evas_object_smart_data_get(obj))) return; + + for (l = tbo_sd->first_visible_line; l; l = l->next) + { + line = l->data; + if (line->object) + { + evas_object_show(line->object); + show_clip = ETK_TRUE; + } + else + break; + } + + if (show_clip) + evas_object_show(tbo_sd->clip); } /* Hides the textblock object */ static void _etk_tb_object_smart_hide(Evas_Object *obj) { Etk_Textblock_Object_SD *tbo_sd; + Etk_Textblock_Object_Line *line; + Evas_List *l; if (!obj || !(tbo_sd = evas_object_smart_data_get(obj))) return; + + for (l = tbo_sd->first_visible_line; l; l = l->next) + { + line = l->data; + if (line->object) + evas_object_hide(line->object); + else + break; + } + + evas_object_hide(tbo_sd->clip); } /* Set the color of the textblock object */ @@ -2309,6 +2639,7 @@ if (!obj || !(tbo_sd = evas_object_smart_data_get(obj))) return; + evas_object_color_set(tbo_sd->clip, r, g, b, a); } /* Clips the textblock object */ @@ -2318,6 +2649,7 @@ if (!obj || !(tbo_sd = evas_object_smart_data_get(obj))) return; + evas_object_clip_set(tbo_sd->clip, clip); } /* Unclips the textblock object */ @@ -2327,6 +2659,7 @@ if (!obj || !(tbo_sd = evas_object_smart_data_get(obj))) return; + evas_object_clip_unset(tbo_sd->clip); } /** @} */ =================================================================== RCS file: /cvs/e/e17/proto/etk/src/lib/etk_textblock.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -3 -r1.9 -r1.10 --- etk_textblock.h 3 Jul 2006 05:06:26 -0000 1.9 +++ etk_textblock.h 4 Jul 2006 21:37:26 -0000 1.10 @@ -23,6 +23,7 @@ typedef enum Etk_Textblock_Wrap { ETK_TEXTBLOCK_WRAP_NONE, /**< The text is not wrapped */ + ETK_TEXTBLOCK_WRAP_DEFAULT, /**< TODOC */ ETK_TEXTBLOCK_WRAP_WORD, /**< The text is wrapped between the words (or between the chars if it's not sufficient) */ ETK_TEXTBLOCK_WRAP_CHAR /**< The text is wrapped between the chars */ } Etk_Textblock_Wrap; @@ -43,19 +44,25 @@ ETK_TEXTBLOCK_TAG_BOLD, /**< The text is bold */ ETK_TEXTBLOCK_TAG_ITALIC, /**< The text is italic */ ETK_TEXTBLOCK_TAG_UNDERLINE, /**< The text is underlined */ + ETK_TEXTBLOCK_TAG_STRIKETHROUGH,/**< The text is strikethrough */ ETK_TEXTBLOCK_TAG_P, /**< The tag describes a paragraph */ ETK_TEXTBLOCK_TAG_STYLE, /**< The tag describes the style of the text (normal, glow, ...) */ ETK_TEXTBLOCK_TAG_FONT /**< The tag describes the font used by the text (face, size, ...) */ - /* ... */ } Etk_Textblock_Tag_Type; /** @brief The different types of style that can be applied on a text */ typedef enum Etk_Textblock_Style_Type { - ETK_TEXTBLOCK_STYLE_NONE, /**< No style is applied */ - ETK_TEXTBLOCK_STYLE_OUTLINE, /**< The text is oulined */ - ETK_TEXTBLOCK_STYLE_SHADOW /**< The text has a sharp shadow */ - /* ... */ + ETK_TEXTBLOCK_STYLE_NONE, /**< No style is applied */ + ETK_TEXTBLOCK_STYLE_OUTLINE, /**< The text is oulined */ + ETK_TEXTBLOCK_STYLE_SHADOW, /**< The text has a sharp shadow */ + ETK_TEXTBLOCK_STYLE_SOFT_OUTLINE, /**< The text has a soft outline */ + ETK_TEXTBLOCK_STYLE_GLOW, /**< The text has a glow */ + ETK_TEXTBLOCK_STYLE_OUTLINE_SHADOW, /**< The text is outlined and has a sharp shadow */ + ETK_TEXTBLOCK_STYLE_FAR_SHADOW, /**< The text has a sharp far shadow */ + ETK_TEXTBLOCK_STYLE_OUTLINE_SOFT_SHADOW, /**< The text is outlined and has a soft shadow */ + ETK_TEXTBLOCK_STYLE_SOFT_SHADOW, /**< The text has a soft shadow */ + ETK_TEXTBLOCK_STYLE_FAR_SOFT_SHADOW /**< The text has a far soft shadow */ } Etk_Textblock_Style_Type; /** @brief The different type of underlining for a text */ @@ -76,6 +83,11 @@ /** TODOC */ struct Etk_Textblock_Format { + Etk_Textblock_Wrap wrap; + float align; + int left_margin; + int right_margin; + Etk_Textblock_Style_Type style; Etk_Color style_color1; Etk_Color style_color2; @@ -84,13 +96,15 @@ Etk_Color underline_color1; Etk_Color underline_color2; + Etk_Bool strikethrough; + Etk_Color strikethrough_color; + const char *font_face; int font_size; Etk_Color font_color; - unsigned char bold : 1; - unsigned char italic : 1; - /* ... */ + Etk_Bool bold; + Etk_Bool italic; }; /** TODOC */ @@ -109,12 +123,19 @@ Etk_Color color2; } u; + /* Params for the <s> tag */ + struct + { + Etk_Color color; + } s; + /* Params for the <p> tag */ struct { float align; int left_margin; int right_margin; + Etk_Textblock_Wrap wrap; } p; /* Params for the <style> tag */ @@ -133,7 +154,6 @@ Etk_Color color; } font; - /* ... */ } params; Etk_Textblock_Tag_Type type; Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs