Enlightenment CVS committal

Author  : raster
Project : e17
Module  : libs/evas

Dir     : e17/libs/evas/src/lib/canvas


Modified Files:
        evas_object_textblock.c 


Log Message:


ned textblock code finally formats and displays.. SOMETHING. this code now
needs cleaning up as it's got a bit of copy & paste work.

===================================================================
RCS file: 
/cvsroot/enlightenment/e17/libs/evas/src/lib/canvas/evas_object_textblock.c,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -3 -r1.61 -r1.62
--- evas_object_textblock.c     5 Aug 2005 10:08:05 -0000       1.61
+++ evas_object_textblock.c     8 Aug 2005 09:01:07 -0000       1.62
@@ -20,17 +20,17 @@
 static const char o_type[] = "textblock";
 
 /* private struct for textblock object internal data */
-typedef struct _Evas_Object_Textblock       Evas_Object_Textblock;
-typedef struct _Evas_Object_Style_Tag       Evas_Object_Style_Tag;
-typedef struct _Evas_Object_Textblock_Node  Evas_Object_Textblock_Node;
-typedef struct _Evas_Object_Textblock_Lnode Evas_Object_Textblock_Lnode;
+typedef struct _Evas_Object_Textblock        Evas_Object_Textblock;
+typedef struct _Evas_Object_Style_Tag        Evas_Object_Style_Tag;
+typedef struct _Evas_Object_Textblock_Node   Evas_Object_Textblock_Node;
+typedef struct _Evas_Object_Textblock_Line   Evas_Object_Textblock_Line;
+typedef struct _Evas_Object_Textblock_Item   Evas_Object_Textblock_Item;
+typedef struct _Evas_Object_Textblock_Format Evas_Object_Textblock_Format;
 
 /* the current state of the formatting */
 
 struct _Evas_Object_Style_Tag
-{
-   Evas_Object_List _list_data;
-   
+{  Evas_Object_List _list_data;
    char *tag;
    char *replace;
 };
@@ -39,19 +39,56 @@
 #define  NODE_FORMAT 1
 
 struct _Evas_Object_Textblock_Node
-{
-   Evas_Object_List _list_data;
+{  Evas_Object_List _list_data;
    int   type;
    char *text;
    int   len, alloc;
 };
 
-struct _Evas_Object_Textblock_Lnode
+struct _Evas_Object_Textblock_Line
+{  Evas_Object_List _list_data;
+   Evas_Object_Textblock_Item *items;
+   double                      align;
+   int                         x, y, w, h;
+   int                         baseline;
+   int                         line_no;
+};
+
+struct _Evas_Object_Textblock_Item
+{  Evas_Object_List _list_data;
+   char                         *text;
+   int                           x, w, h;
+   int                           inset, baseline;
+   Evas_Object_Textblock_Format *format;
+};
+
+struct _Evas_Object_Textblock_Format
 {
-   Evas_Object_List _list_data;
-   int   type;
-   char *text;
-   int   len, alloc;
+   int                  ref;
+   double               halign;
+   double               valign;
+   struct {
+      char             *name;
+      char             *source;
+      int               size;
+      void             *font;
+   } font;
+   struct {
+      struct {
+        unsigned char  r, g, b, a;
+      } normal, underline, underline2, outline, shadow, glow, backing,
+       strikethrough;
+   } color;
+   struct {
+      int               l, r;
+   } margin;
+   unsigned char        style;
+   unsigned char        wrap_word : 1;
+   unsigned char        wrap_char : 1;
+   unsigned char        underline : 1;
+   unsigned char        underline2 : 1;
+   unsigned char        strikethrough : 1;
+   unsigned char        backing : 1;
 };
 
 struct _Evas_Textblock_Style
@@ -80,7 +117,7 @@
    Evas_Textblock_Cursor       *cursor;
    Evas_List                   *cursors;
    Evas_Object_Textblock_Node  *nodes;
-   Evas_Object_Textblock_Lnode *lnodes;
+   Evas_Object_Textblock_Line *lines;
    char                        *markup_text;
    char                         changed : 1;
    void                        *engine_data;
@@ -177,12 +214,12 @@
       // popped
       // tags starting with / (ie </blah>) will ALWAYS pop UNLESS provided
       // with an override here in the style (like /p)
-      "DEFAULT='push font=Vera font_size=10 align=left color=#000000'"
-      "center='push align=middle'"
-      "h1='push font_size=20'"
-      "red='push color=#ff0000'"
-      "p='push font=Vera font_size=12 align=left'"
-      "/p='pop \n\n'" // you can define end tags - override default pop on /...
+      "DEFAULT='font=Vera font_size=10 align=left color=#000000'"
+      "center='+ align=middle'"
+      "h1='+ font_size=20'"
+      "red='+ color=#ff0000'"
+      "p='+ font=Vera font_size=12 align=left'"
+      "/p='- \n \n'" // you can define end tags - override default pop on /...
       "br='\n'"
       );
    evas_object_textblock2_style_set(obj, ts); // tell object to use this style
@@ -276,18 +313,20 @@
                  char *tags, *replaces;
                  Evas_Object_Style_Tag *tag;
                  
-                 tags = malloc(key_stop - key_start);
+                 tags = malloc(key_stop - key_start + 1);
                  if (tags)
                    {
                       tags[key_stop - key_start] = 0;
-                      strncpy(tags, key_start, key_stop - key_start - 1);
+                      strncpy(tags, key_start, key_stop - key_start);
+                      tags[key_stop - key_start] = 0;
                    }
                  
-                 replaces = malloc(val_stop - val_start);
+                 replaces = malloc(val_stop - val_start + 1);
                  if (replaces)
                    {
                       replaces[val_stop - val_start] = 0;
-                      strncpy(replaces, val_start, val_stop - val_start - 1);
+                      strncpy(replaces, val_start, val_stop - val_start);
+                      replaces[val_stop - val_start] = 0;
                    }
                  if ((tags) && (replaces))
                    {
@@ -500,18 +539,18 @@
 }
 
 static void
-_lnodes_clear(Evas_Object *obj)
+_lines_clear(Evas_Object *obj)
 {
    Evas_Object_Textblock *o;
 
    o = (Evas_Object_Textblock *)(obj->object_data);
-   while (o->lnodes)
+   while (o->lines)
      {
-       Evas_Object_Textblock_Lnode *ln;
+       Evas_Object_Textblock_Line *ln;
        
-       ln = (Evas_Object_Textblock_Lnode *)o->lnodes;
-       o->lnodes = evas_object_list_remove(o->lnodes, ln);
-       if (ln->text) free(ln->text);
+       ln = (Evas_Object_Textblock_Line *)o->lines;
+       o->lines = evas_object_list_remove(o->lines, ln);
+       /* FIXME: free line->items */
        free(ln);
      }
 }
@@ -685,7 +724,7 @@
      }
    if (text) o->markup_text = strdup(text);
    _nodes_clear(obj);
-   _lnodes_clear(obj);
+   _lines_clear(obj);
    o->changed = 1;
    evas_object_change(obj);
    if (o->markup_text)
@@ -704,18 +743,23 @@
               {
                  if (tag_end)
                    {
-                      char *ttag;
+                      char *ttag, *match;
                       
                       ttag = malloc(tag_end - tag_start);
                       if (ttag)
                         {
                            strncpy(ttag, tag_start + 1, tag_end - tag_start - 
1);
-                           ttag[tag_end - tag_start] = 0;
-                           s = _style_match_tag(o->style, ttag);
-                           if (s)
-                             evas_textblock2_cursor_format_append(o->cursor, 
s);
+                           ttag[tag_end - tag_start - 1] = 0;
+                           match = _style_match_tag(o->style, ttag);
+                           if (match)
+                             evas_textblock2_cursor_format_append(o->cursor, 
match);
                            else
-                             evas_textblock2_cursor_format_append(o->cursor, 
ttag);
+                             {
+                                if (ttag[0] == '/')
+                                  
evas_textblock2_cursor_format_append(o->cursor, "-");
+                                else
+                                  
evas_textblock2_cursor_format_append(o->cursor, ttag);
+                             }
                            free(ttag);
                         }
                       tag_start = tag_end = NULL;
@@ -735,20 +779,6 @@
                         }
                       esc_start = esc_end = NULL;
                    }
-                 else if (s)
-                   {
-                      char *ts;
-
-                      ts = malloc(p - s);
-                      if (ts)
-                        {
-                           strncpy(ts, s, p - s - 1);
-                           ts[p - s] = 0;
-                           evas_textblock2_cursor_text_append(o->cursor, ts);
-                           free(ts);
-                        }
-                      s = NULL;
-                   }
                  if (*p == 0)
                    break;
               }
@@ -758,6 +788,20 @@
                    {
                       tag_start = p;
                       tag_end = NULL;
+                      if ((s) && (p > s))
+                        {
+                           char *ts;
+                           
+                           ts = malloc(p - s + 1);
+                           if (ts)
+                             {
+                                strncpy(ts, s, p - s);
+                                ts[p - s] = 0;
+                                evas_textblock2_cursor_text_append(o->cursor, 
ts);
+                                free(ts);
+                             }
+                           s = NULL;
+                        }
                    }
               }
             else if (*p == '>')
@@ -774,6 +818,21 @@
                    {
                       esc_start = p;
                       esc_end = NULL;
+                      if ((s) && (p > s))
+                        {
+                           char *ts;
+                           
+                           ts = malloc(p - s + 1);
+                           if (ts)
+                             {
+                                strncpy(ts, s, p - s);
+                                ts[p - s] = 0;
+                                evas_textblock2_cursor_text_append(o->cursor, 
ts);
+                                free(ts);
+                             }
+                           s = NULL;
+                        }
+                      s = NULL;
                    }
               }
             else if (*p == ';')
@@ -850,6 +909,7 @@
                            ps = p + 1;
                         }
                       /* FIXME: learn how to do all the other escapes */
+                      /* FIXME: strip extra whitespace ala HTML */
                       p++;
                    }
               }
@@ -1005,7 +1065,7 @@
    n->text = _strbuf_append(n->text, (char *)text, &(n->len), &(n->alloc));
    cur->node = n;
    cur->pos = n->len - 1;
-   _lnodes_clear(cur->obj);
+   _lines_clear(cur->obj);
    o->changed = 1;
    evas_object_change(cur->obj);
 }
@@ -1037,7 +1097,7 @@
    n->text = _strbuf_append(n->text, (char *)format, &(n->len), &(n->alloc));
    cur->node = n;
    cur->pos = 0;
-   _lnodes_clear(cur->obj);
+   _lines_clear(cur->obj);
    o->changed = 1;
    evas_object_change(cur->obj);
 }
@@ -1077,7 +1137,7 @@
        free(o->markup_text);
        o->markup_text = NULL;
      }
-   _lnodes_clear(obj);
+   _lines_clear(obj);
    o->changed = 1;
    evas_object_change(obj);
 }
@@ -1089,30 +1149,584 @@
    /* FIXME */
 }
 
+static int
+_hex_string_get(char ch)
+{
+   if ((ch >= '0') && (ch <= '9')) return (ch - '0');
+   else if ((ch >= 'A') && (ch <= 'F')) return (ch - 'A' + 10);
+   else if ((ch >= 'a') && (ch <= 'f')) return (ch - 'a' + 10);
+   return 0;
+}
+
+static void
+_format_color_parse(char *str, unsigned char *r, unsigned char *g, unsigned 
char *b, unsigned char *a)
+{
+   int slen;
+   
+   slen = strlen(str);
+   *r = *g = *b = *a = 0;
+   
+   if (slen == 7) /* #RRGGBB */
+     {
+       *r = (_hex_string_get(str[1]) << 4) | (_hex_string_get(str[2]));
+       *g = (_hex_string_get(str[3]) << 4) | (_hex_string_get(str[4]));
+       *b = (_hex_string_get(str[5]) << 4) | (_hex_string_get(str[6]));
+       *a = 0xff;
+     }
+   else if (slen == 9) /* #RRGGBBAA */
+     {
+       *r = (_hex_string_get(str[1]) << 4) | (_hex_string_get(str[2]));
+       *g = (_hex_string_get(str[3]) << 4) | (_hex_string_get(str[4]));
+       *b = (_hex_string_get(str[5]) << 4) | (_hex_string_get(str[6]));
+       *a = (_hex_string_get(str[7]) << 4) | (_hex_string_get(str[8]));
+     }
+   else if (slen == 4) /* #RGB */
+     {
+       *r = _hex_string_get(str[1]);
+       *r = (*r << 4) | *r;
+       *g = _hex_string_get(str[2]);
+       *g = (*g << 4) | *g;
+       *b = _hex_string_get(str[3]);
+       *b = (*b << 4) | *b;
+       *a = 0xff;
+     }
+   else if (slen == 5) /* #RGBA */
+     {
+       *r = _hex_string_get(str[1]);
+       *r = (*r << 4) | *r;
+       *g = _hex_string_get(str[2]);
+       *g = (*g << 4) | *g;
+       *b = _hex_string_get(str[3]);
+       *b = (*b << 4) | *b;
+       *a = _hex_string_get(str[4]);
+       *a = (*a << 4) | *a;
+     }
+}
+
+static void
+_format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char 
*cmd, char *param)
+{
+   int new_font = 0;
+   
+   if (!strcmp(cmd, "font"))
+     {
+       if ((!fmt->font.name) ||
+           ((fmt->font.name) && (strcmp(fmt->font.name, param))))
+         {
+            if (fmt->font.name) free(fmt->font.name);
+            fmt->font.name = strdup(param);
+            new_font = 1;
+         }
+     }
+   else if (!strcmp(cmd, "font_size"))
+     {
+       int v;
+       
+       v = atoi(param);
+       if (v != fmt->font.size)
+         {
+            fmt->font.size = v;
+            new_font = 1;
+         }
+     }
+   else if (!strcmp(cmd, "font_source"))
+     {
+       if ((!fmt->font.source) ||
+           ((fmt->font.source) && (strcmp(fmt->font.source, param))))
+         {
+            if (fmt->font.source) free(fmt->font.source);
+            fmt->font.source = strdup(param);
+            new_font = 1;
+         }
+     }
+   else if (!strcmp(cmd, "color"))
+     {
+       _format_color_parse(param,
+                           &(fmt->color.normal.r), &(fmt->color.normal.g),
+                           &(fmt->color.normal.b), &(fmt->color.normal.a));
+     }
+   else if (!strcmp(cmd, "align"))
+     {
+       if (!strcmp(param, "middle")) fmt->halign = 0.5;
+       else if (!strcmp(param, "center")) fmt->halign = 0.5;
+       else if (!strcmp(param, "left")) fmt->halign = 0.0;
+       else if (!strcmp(param, "right")) fmt->halign = 1.0;
+       else if (strchr(param, '%'))
+         {
+            char *ts, *p;
+            
+            ts = strdup(param);
+            if (ts)
+              {
+                 p = strchr(ts, '%');
+                 *p = 0;
+                 fmt->halign = ((double)atoi(ts)) / 100.0;
+                 free(ts);
+              }
+         }
+       else
+         {
+            fmt->halign = atoi(param);
+         }
+       if (fmt->halign < 0.0) fmt->halign = 0.0;
+       else if (fmt->halign > 1.0) fmt->halign = 1.0;
+     }
+   else if (!strcmp(cmd, "wrap"))
+     {
+       if (!strcmp(param, "word"))
+         {
+            fmt->wrap_word = 1;
+            fmt->wrap_char = 0;
+         }
+       else if (!strcmp(param, "char"))
+         {
+            fmt->wrap_word = 0;
+            fmt->wrap_char = 1;
+         }
+       else
+         {
+            fmt->wrap_word = 0;
+            fmt->wrap_char = 0;
+         }
+     }
+   
+   if (new_font)
+     {
+       void *of;
+       
+       of = fmt->font.font;
+       fmt->font.font = evas_font_load(obj->layer->evas, 
+                                       fmt->font.name, fmt->font.source, 
+                                       fmt->font.size);
+       if (of) evas_font_free(obj->layer->evas, of);
+     }
+}
+
+static int
+_format_is_param(char *item)
+{
+   if (strchr(item, '=')) return 1;
+   return 0;
+}
+
+static void
+_format_param_parse(char *item, char **key, char **val)
+{
+   char *p, *pv;
+   char *k, *v;
+   int qoute = 0;
+   
+   p = strchr(item, '=');
+   k = malloc(p - item);
+   strncpy(k, item, p - item);
+   k[p - item] = 0;
+   *key = k;
+   p++;
+   v = strdup(p);
+   pv = v;
+   for (;;)
+     {
+       if (*p == 0)
+         {
+            *pv = 0;
+            break;
+         }
+       else if (*p != '"')
+         {
+            *pv = *p;
+         }
+       pv++;
+       p++;
+     }
+   *val = v;
+}
+
+static char *
+_format_parse(char **s)
+{
+   char *p, *item;
+   char *s1 = NULL, *s2 = NULL;
+   int quote = 0;
+   
+   p = *s;
+   if (*p == 0) return NULL;
+   for (;;)
+     {
+       if (!s1)
+         {
+            if (*p != ' ') s1 = p;
+         }
+       else if (!s2)
+         {
+            if (!quote)
+              {
+                 if (*p == '"') quote = 1;
+                 else if (*p == ' ') s2 = p;
+                 else if (*p == 0) s2 = p;
+              }
+            else
+              {
+                 if (*p == '"') quote = 0;
+              }
+         }
+       p++;
+       if (s1 && s2)
+         {
+            item = malloc(s2 - s1 + 1);
+            if (item)
+              {
+                 strncpy(item, s1, s2 - s1);
+                 item[s2 - s1] = 0;
+              }
+            *s = s2;
+            return item;
+         }
+     }
+   *s = p;
+   return NULL;
+}
+
+static void
+_format_fill(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, char *str)
+{
+   char *s;
+   char *item;
+   
+   s = str;
+   while ((item = _format_parse(&s)))
+     {
+       if (_format_is_param(item))
+         {
+            char *key = NULL, *val = NULL;
+            
+            _format_param_parse(item, &key, &val);
+            _format_command(obj, fmt, key, val);
+            free(key);
+            free(val);
+         }
+       else
+         {
+            /* immediate - not handled here */
+         }
+       free(item);
+     }
+}
+
+static Evas_Object_Textblock_Format *
+_format_dup(Evas_Object *obj, Evas_Object_Textblock_Format *fmt)
+{
+   Evas_Object_Textblock_Format *fmt2;
+   
+   fmt2 = calloc(1, sizeof(Evas_Object_Textblock_Format));
+   memcpy(fmt2, fmt, sizeof(Evas_Object_Textblock_Format));
+   fmt2->ref = 1;
+   if (fmt->font.name) fmt2->font.name = strdup(fmt->font.name);
+   if (fmt->font.source) fmt2->font.source = strdup(fmt->font.source);
+   fmt2->font.font = evas_font_load(obj->layer->evas, 
+                                  fmt2->font.name, fmt2->font.source, 
+                                  fmt2->font.size);
+   return fmt2;
+}
+
+static void
+_format_free(Evas_Object *obj, Evas_Object_Textblock_Format *fmt)
+{
+   fmt->ref--;
+   if (fmt->ref > 0) return;
+   if (fmt->font.name) free(fmt->font.name);
+   if (fmt->font.source) free(fmt->font.source);
+   evas_font_free(obj->layer->evas, fmt->font.font);
+   free(fmt);
+}
+
+static int
+_is_white(int c)
+{
+   /*
+    * unicode list of whitespace chars
+    *
+    * 0009..000D <control-0009>..<control-000D>
+    * 0020 SPACE
+    * 0085 <control-0085>
+    * 00A0 NO-BREAK SPACE
+    * 1680 OGHAM SPACE MARK
+    * 180E MONGOLIAN VOWEL SEPARATOR
+    * 2000..200A EN QUAD..HAIR SPACE
+    * 2028 LINE SEPARATOR
+    * 2029 PARAGRAPH SEPARATOR
+    * 202F NARROW NO-BREAK SPACE
+    * 205F MEDIUM MATHEMATICAL SPACE
+    * 3000 IDEOGRAPHIC SPACE
+    */
+   if (
+       (c == 0x20) ||
+       ((c >= 0x9) && (c <= 0xd)) ||
+       (c == 0x85) ||
+       (c == 0xa0) ||
+       (c == 0x1680) ||
+       (c == 0x180e) ||
+       ((c >= 0x2000) && (c <= 0x200a)) ||
+       (c == 0x2028) ||
+       (c == 0x2029) ||
+       (c == 0x202f) ||
+       (c == 0x205f) ||
+       (c == 0x3000)
+       )
+     return 1;
+   return 0;
+}
+
 static void
 _layout(Evas_Object *obj, int calc_only, int w, int h, int *w_ret, int *h_ret)
 {
    Evas_Object_Textblock *o;
    Evas_Object_List *l;
-   Evas_Object_Textblock_Lnode *lnodes = NULL;
-   int x, y, wmax, hmax;
+   Evas_Object_Textblock_Line *lines = NULL, *ln = NULL;
+   int x, y, wmax, hmax, ascent, descent, maxascent, maxdescent, advance, 
+     maxadvance, maxh, line_no;
+   Evas_List *format_stack = NULL;
+   Evas_Object_Textblock_Item *it = NULL;   
+   Evas_Object_Textblock_Format *fmt = NULL;
    
+   /* this is formatting context */
    x = 0;
    y = 0;
    wmax = 0;
    hmax = 0;
+   
+   ascent = 0;
+   descent = 0;
+   maxascent = 0;
+   maxdescent = 0;
+   maxh = 0;
+   line_no = 0;
+   
    o = (Evas_Object_Textblock *)(obj->object_data);
-   /* FIXME: generate format stack using default format from the style */
+   if ((o->style) && (o->style->default_tag))
+     {
+       fmt = calloc(1, sizeof(Evas_Object_Textblock_Format));
+       fmt->ref = 1;
+       format_stack  = evas_list_prepend(format_stack, fmt);
+       _format_fill(obj, fmt, o->style->default_tag);
+     }
    for (l = (Evas_Object_List *)o->nodes; l; l = l->next)
      {
        Evas_Object_Textblock_Node *n;
        
        n = (Evas_Object_Textblock_Node *)l;
-       /* FIXME: go thru o->nodes and generate o->lnodes */
+       if (!ln)
+         {
+            ln = calloc(1, sizeof(Evas_Object_Textblock_Line));
+            ln->align = fmt->halign;
+            lines = evas_object_list_append(lines, ln);
+            x = 0;
+            maxascent = 0;
+            maxdescent = 0;
+            ascent = ENFN->font_max_ascent_get(ENDT, fmt->font.font);
+            descent = ENFN->font_max_descent_get(ENDT, fmt->font.font);
+            if (maxascent < ascent) maxascent = ascent;
+            if (maxdescent < descent) maxdescent = descent;
+         }
+       if ((n->type == NODE_FORMAT) && (n->text))
+         {
+            char *s;
+            char *item;
+            
+//          printf("F: %s\n", n->text);
+            s = n->text;
+            if (s[0] == '+')
+              {
+                 if (fmt)
+                   {
+                      fmt = _format_dup(obj, fmt);
+                      format_stack  = evas_list_prepend(format_stack, fmt);
+                   }
+                 else
+                   {
+                      fmt = calloc(1, sizeof(Evas_Object_Textblock_Format));
+                      format_stack  = evas_list_prepend(format_stack, fmt);
+                   }
+                 s++;
+              }
+            else if (s[0] == '-')
+              {
+                 if ((format_stack) && (format_stack->next))
+                   {
+                      _format_free(obj, fmt);
+                      format_stack = evas_list_remove_list(format_stack, 
format_stack);
+                      fmt = format_stack->data;
+                   }
+                 s++;
+              }
+            while ((item = _format_parse(&s)))
+              {
+//               printf("ITEM %s\n", item);
+                 if (_format_is_param(item))
+                   {
+                      char *key = NULL, *val = NULL;
+                      
+                      _format_param_parse(item, &key, &val);
+                      _format_command(obj, fmt, key, val);
+                      free(key);
+                      free(val);
+                      ascent = ENFN->font_max_ascent_get(ENDT, fmt->font.font);
+                      descent = ENFN->font_max_descent_get(ENDT, 
fmt->font.font);
+                      if (maxascent < ascent) maxascent = ascent;
+                      if (maxdescent < descent) maxdescent = descent;
+                      ln->align = fmt->halign;
+                   }
+                 else
+                   {
+//                    printf("IMM: ->%s<-\n", item);
+                      /* immediate */
+                      if (!strcmp(item, "\n"))
+                        {
+                           /* finish line */
+                           if (ln->w > wmax) wmax = ln->w;
+                           ln->y = y;
+                           ln->h = maxascent + maxdescent;
+                           ln->baseline = maxascent;
+                           ln->line_no = line_no;
+                           line_no++;
+                           x = 0;
+                           y += maxascent + maxdescent;
+                           ln->x = (w - ln->w) * ln->align;
+                           
+                           ln = calloc(1, sizeof(Evas_Object_Textblock_Line));
+                           ln->align = fmt->halign;
+                           lines = evas_object_list_append(lines, ln);
+                           maxascent = 0;
+                           maxdescent = 0;
+                           ascent = ENFN->font_max_ascent_get(ENDT, 
fmt->font.font);
+                           descent = ENFN->font_max_descent_get(ENDT, 
fmt->font.font);
+                           if (maxascent < ascent) maxascent = ascent;
+                           if (maxdescent < descent) maxdescent = descent;
+                        }
+                      else if (!strcmp(item, "\t"))
+                        {
+                           /* jump to next tabstop */
+                        }
+                   }
+                 free(item);
+              }
+         }
+       else if ((n->type == NODE_TEXT) && (n->text))
+         {
+            int adv, inset, tw, th, x2;
+            char *str, new_line;
+            
+            str = n->text;
+            new_line = 0;
+            while (str)
+              {
+                 it = calloc(1, sizeof(Evas_Object_Textblock_Item));
+                 fmt->ref++;
+                 it->format = fmt;
+                 it->text = strdup(str);
+                 inset = ENFN->font_inset_get(ENDT, fmt->font.font, it->text);
+                 //         if (ln->items == NULL) x += inset;
+                 ENFN->font_string_size_get(ENDT, fmt->font.font,
+                                            it->text, &tw, &th);
+                 if (((fmt->wrap_word) || (fmt->wrap_char)) &&
+                     ((x + tw) > w))
+                   {
+                      int wrap, twrap, cx, cy, cw, ch;
+                      
+                      wrap = ENFN->font_char_at_coords_get(ENDT,
+                                                           fmt->font.font,
+                                                           it->text, w - x, 0,
+                                                           &cx, &cy,
+                                                           &cw, &ch);
+                      if (wrap >= 0)
+                        {
+                           char *ts;
+                           
+                           /* FIXME: handle wrap */
+                           if (fmt->wrap_word)
+                             {
+                                /* walk pack to start of word */
+                                while ((wrap >= 0) &&
+                                       (!_is_white(str[wrap])))
+                                  {
+                                     wrap--;
+                                  }
+                                wrap++;
+                                /* cut of pointless whitespace at end of
+                                 * previous line
+                                 */
+                                twrap = wrap - 1;
+                                while ((twrap > 0) &&
+                                       _is_white(it->text[twrap]))
+                                  {
+                                     twrap--;
+                                  }
+                                ts = it->text;
+                                ts[twrap] = 0;
+                                it->text = strdup(ts);
+                                free(ts);
+                                /* back to start of word */
+                                str = str + wrap - 1;
+                             }
+                           else if (fmt->wrap_char)
+                             {
+                                ts = it->text;
+                                ts[wrap] = 0;
+                                it->text = strdup(ts);
+                                free(ts);
+                                str = str + wrap;
+                             }
+                           new_line = 1;
+                        }
+                      ENFN->font_string_size_get(ENDT, fmt->font.font,
+                                                 it->text, &tw, &th);
+                   }
+                 else
+                   str = NULL;
+                 it->w = tw;
+                 it->h = th;
+                 it->inset = inset;
+                 it->x = x;
+                 adv = ENFN->font_h_advance_get(ENDT, fmt->font.font,
+                                                it->text);
+                 x2 = x + tw - inset;
+                 x += adv;
+                 if (x2 > ln->w) ln->w = x2;
+                 ln->items = evas_object_list_append(ln->items, it);
+                 if (new_line)
+                   {
+                      new_line = 0;
+                      /* finish line */
+                      if (ln->w > wmax) wmax = ln->w;
+                      ln->y = y;
+                      ln->h = maxascent + maxdescent;
+                      ln->baseline = maxascent;
+                      ln->line_no = line_no;
+                      line_no++;
+                      x = 0;
+                      y += maxascent + maxdescent;
+                      ln->x = (w - ln->w) * ln->align;
+                      
+                      ln = calloc(1, sizeof(Evas_Object_Textblock_Line));
+                      ln->align = fmt->halign;
+                      lines = evas_object_list_append(lines, ln);
+                      maxascent = 0;
+                      maxdescent = 0;
+                      ascent = ENFN->font_max_ascent_get(ENDT, fmt->font.font);
+                      descent = ENFN->font_max_descent_get(ENDT, 
fmt->font.font);
+                      if (maxascent < ascent) maxascent = ascent;
+                      if (maxdescent < descent) maxdescent = descent;
+                   }
+              }
+         }
      }
+   hmax = y;
    if (!calc_only)
      {
-       o->lnodes = lnodes;
+       o->lines = lines;
+     }
+   else
+     {
+       /* free lines */
      }
 }
 
@@ -1183,7 +1797,8 @@
 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, *ll;
+   
    /* 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,
@@ -1200,6 +1815,28 @@
                                                   obj->cur.cache.geometry.w,
                                                   obj->cur.cache.geometry.h);
 #endif
+   for (l = (Evas_Object_List *)o->lines; l; l = l->next)
+     {
+       Evas_Object_Textblock_Line *ln;
+       
+       ln = (Evas_Object_Textblock_Line *)l;
+       for (ll = (Evas_Object_List *)ln->items; ll; ll = ll->next)
+         {
+            Evas_Object_Textblock_Item *it;
+            
+            it = (Evas_Object_Textblock_Item *)ll;
+            ENFN->context_color_set(output, context,
+                                    it->format->color.normal.r,
+                                    it->format->color.normal.g,
+                                    it->format->color.normal.b,
+                                    it->format->color.normal.a);
+            ENFN->font_draw(output, context, surface, it->format->font.font,
+                            obj->cur.cache.geometry.x + ln->x + it->x + x,
+                            obj->cur.cache.geometry.y + ln->y + ln->baseline + 
y,
+                            it->w, it->h, it->w, it->h, it->text);
+         }
+     }
+     
 /*
    if (o->engine_data)
      {




-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to