fix a corner-case textblock issue with end of line char pos
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 14 May 2009 12:52:44 +0000 (12:52 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 14 May 2009 12:52:44 +0000 (12:52 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@40640 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/bin/evas_cserve_main.c
src/lib/Evas.h
src/lib/canvas/evas_object_textblock.c

index d8b2465..d828037 100644 (file)
@@ -1064,12 +1064,15 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char *
              
              D("OP_GETINFO %i\n", c->pid);
              len = sizeof(Op_Getinfo_Reply);
+             D("... foreach\n");
              if (active_images)
                eina_hash_foreach(active_images, getinfo_hash_image_cb, &imgs);
+             D("... walk foreach list output\n");
              EINA_LIST_FOREACH(cache_images, l, img)
                {
                   imgs = eina_list_append(imgs, img);
                }
+             D("... walk image cache\n");
              EINA_LIST_FOREACH(imgs, l, img)
                {
                   len += sizeof(Op_Getinfo_Item);
@@ -1078,11 +1081,13 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char *
                   if (img->file.key) len += strlen(img->file.key);
                   len++;
                }
+             D("... malloc msg\n");
              msg = malloc(len);
              if (msg)
                {
                   unsigned char *p;
                   
+                  D("...   init msg\n");
                   memset(msg, 0, len);
                   p = (unsigned char *)msg;
                   msg->active.mem_total = 0;
@@ -1090,10 +1095,12 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char *
                   msg->cached.mem_total = 0;
                   msg->cached.count = 0;
                   p += sizeof(Op_Getinfo_Reply);
+                  D("...   walk all imgs\n");
                   EINA_LIST_FOREACH(imgs, l, img)
                     {
                        Op_Getinfo_Item *itt, it;
 
+                       D("...   img %p\n", img);
                        memset(&it, 0, sizeof(Op_Getinfo_Item));
                        itt = (Op_Getinfo_Item *)p;
                        it.file_key_size = 0;
@@ -1127,7 +1134,7 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char *
                        it.data_load_time = img->stats.load2;
                        it.alpha = img->image.alpha;
                        if (img->image.data)
-                        it.data_loaded = 1;
+                         it.data_loaded = 1;
                        else
                          it.data_loaded = 0;
                        it.active = img->active;
@@ -1143,9 +1150,13 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char *
                          }
                        it.dead = img->dead;
                        it.useless = img->useless;
+                       D("...   memcpy %p %p %i \n", 
+                         itt, &it, sizeof(Op_Getinfo_Item));
                        memcpy(itt, &it, sizeof(Op_Getinfo_Item));
+                       D("...   memcpy done n\n", img);
                        p += sizeof(Op_Getinfo_Item) + it.file_key_size;
                     }
+                  D("...   walk all imgs done\n");
                   msg->active.mem_total = 
                     (msg->active.mem_total + 1023) / 1024;
                   msg->cached.mem_total = 
@@ -1164,7 +1175,7 @@ message(void *fdata, Server *s, Client *c, int opcode, int size, unsigned char *
           } 
         break;
      default:
-        D("OP_... UNKNOWN??? %i opcoe: %i\n", c->pid, opcode);
+        D("OP_... UNKNOWN??? %i opcode: %i\n", c->pid, opcode);
         break;
      }
 }
index c72bee7..453acf8 100644 (file)
@@ -760,6 +760,9 @@ extern "C" {
    EAPI int                          evas_textblock_cursor_line_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord y) EINA_ARG_NONNULL(1);
    EAPI Eina_List                   *evas_textblock_cursor_range_geometry_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *cur2) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2) EINA_PURE;
    
+   EAPI Eina_Bool                    evas_textblock_cursor_eol_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE;
+   EAPI void                         evas_textblock_cursor_eol_set(Evas_Textblock_Cursor *cur, Eina_Bool eol) EINA_ARG_NONNULL(1);
+   
    EAPI Eina_Bool                    evas_object_textblock_line_number_geometry_get(const Evas_Object *obj, int line, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch) EINA_ARG_NONNULL(1);
    EAPI void                         evas_object_textblock_clear(Evas_Object *obj) EINA_ARG_NONNULL(1);
    EAPI void                         evas_object_textblock_size_formatted_get(const Evas_Object *obj, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
index 2e4a888..0427ab9 100644 (file)
@@ -27,20 +27,23 @@ typedef struct _Evas_Object_Textblock_Format      Evas_Object_Textblock_Format;
 #define  NODE_FORMAT 1
 
 struct _Evas_Object_Style_Tag
-{  EINA_INLIST;
+{
+   EINA_INLIST;
    char *tag;
    char *replace;
 };
 
 struct _Evas_Object_Textblock_Node
-{  EINA_INLIST;
+{
+   EINA_INLIST;
    char *text;
    int   type;
    int   len, alloc;
 };
 
 struct _Evas_Object_Textblock_Line
-{  EINA_INLIST;
+{
+   EINA_INLIST;
    Evas_Object_Textblock_Item        *items;
    Evas_Object_Textblock_Format_Item *format_items;
    int                                x, y, w, h;
@@ -49,7 +52,8 @@ struct _Evas_Object_Textblock_Line
 };
 
 struct _Evas_Object_Textblock_Item
-{  EINA_INLIST;
+{
+   EINA_INLIST;
    char                         *text;
    Evas_Object_Textblock_Format *format;
    Evas_Object_Textblock_Node   *source_node;
@@ -60,7 +64,8 @@ struct _Evas_Object_Textblock_Item
 };
 
 struct _Evas_Object_Textblock_Format_Item
-{  EINA_INLIST;
+{
+   EINA_INLIST;
    const char                   *item;
    Evas_Object_Textblock_Node   *source_node;
    int                           x, w;
@@ -111,6 +116,7 @@ struct _Evas_Textblock_Cursor
    Evas_Object                *obj;
    int                         pos;
    Evas_Object_Textblock_Node *node;
+   Eina_Bool                   eol : 1;
 };
 
 struct _Evas_Object_Textblock
@@ -2246,7 +2252,7 @@ _relayout(const Evas_Object *obj)
 }
 
 static void
-_find_layout_item_line_match(Evas_Object *obj, Evas_Object_Textblock_Node *n, int pos, Evas_Object_Textblock_Line **lnr, Evas_Object_Textblock_Item **itr)
+_find_layout_item_line_match(Evas_Object *obj, Evas_Object_Textblock_Node *n, int pos, int eol, Evas_Object_Textblock_Line **lnr, Evas_Object_Textblock_Item **itr)
 {
    Evas_Object_Textblock_Line *ln;
 /*    Evas_Object_Textblock_Node *nn; */
@@ -2255,6 +2261,13 @@ _find_layout_item_line_match(Evas_Object *obj, Evas_Object_Textblock_Node *n, in
    o = (Evas_Object_Textblock *)(obj->object_data);
 /*    EINA_INLIST_FOREACH(o->nodes, nn) */
 /*      ; */
+   if ((eol) && (n->type == NODE_TEXT))
+     {
+        int pos2 = pos;
+        
+        evas_common_font_utf8_get_prev(n->text, &pos2);
+        if (pos2 < pos) pos = pos2;
+     }
    EINA_INLIST_FOREACH(o->lines, ln)
      {
        Evas_Object_Textblock_Format_Item *fit;
@@ -3127,6 +3140,7 @@ evas_object_textblock_cursor_new(Evas_Object *obj)
    cur->obj = obj;
    cur->node = o->nodes;
    cur->pos = 0;
+   cur->eol = 0;
    o->cursors = eina_list_append(o->cursors, cur);
    return cur;
 }
@@ -3162,6 +3176,7 @@ evas_textblock_cursor_node_first(Evas_Textblock_Cursor *cur)
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
    cur->node = o->nodes;
    cur->pos = 0;
+   cur->eol = 0;
 }
 
 /**
@@ -3180,12 +3195,14 @@ evas_textblock_cursor_node_last(Evas_Textblock_Cursor *cur)
      {
        cur->node = (Evas_Object_Textblock_Node *)((EINA_INLIST_GET(o->nodes))->last);
        cur->pos = 0;
+        cur->eol = 0;  // 1
        evas_textblock_cursor_char_last(cur);
      }
    else
      {
        cur->node = NULL;
        cur->pos = 0;
+        cur->eol = 0; // 1
      }
 }
 
@@ -3206,6 +3223,7 @@ evas_textblock_cursor_node_next(Evas_Textblock_Cursor *cur)
      {
        cur->node = (Evas_Object_Textblock_Node *)((EINA_INLIST_GET(cur->node))->next);
        cur->pos = 0;
+        cur->eol = 0;
        return 1;
      }
    return 0;
@@ -3243,6 +3261,7 @@ evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur)
 {
    Evas_Object_Textblock *o;
    int index, tindex, ch;
+   int at_start_of_line = 0;
    
    if (!cur) return 0;
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
@@ -3250,11 +3269,24 @@ evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur)
    if (cur->node->type == NODE_FORMAT) return 0;
    if (!cur->node->text) return 0;
    index = cur->pos;
+
+   if (cur->node->type == NODE_TEXT)
+     {
+        Evas_Object_Textblock_Line *ln = NULL;
+        Evas_Object_Textblock_Item *it = NULL;
+        int pos;
+        
+       _find_layout_item_line_match(cur->obj, cur->node, cur->pos, cur->eol, &ln, &it);
+        pos = cur->pos - it->source_pos;
+        if (pos <= 0) index -= pos;
+     }
+   
    ch = evas_common_font_utf8_get_next((unsigned char *)(cur->node->text), &index);
    if ((ch == 0) || (index < 0)) return 0;
    if (cur->node->text[index] == 0) return 0;
    tindex = index;
    cur->pos = index;
+   cur->eol = 0; // 1
    return 1;
 }
 
@@ -3268,6 +3300,8 @@ evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur)
 {
    Evas_Object_Textblock *o;
    int index, ch;
+   int at_end_of_line = 0;
+   int at_start_of_line = 0;
    
    if (!cur) return 0;
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
@@ -3276,9 +3310,42 @@ evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur)
    if (!cur->node->text) return 0;
    index = cur->pos;
    if (index == 0) return 0;
+   
+   // XXX: FIXME: determine at_end_of_line and at_start_of_line
+  
+   if (cur->node->type == NODE_TEXT)
+     {
+        Evas_Object_Textblock_Line *ln = NULL;
+        Evas_Object_Textblock_Item *it = NULL;
+        int pos;
+        
+       _find_layout_item_line_match(cur->obj, cur->node, cur->pos, cur->eol, &ln, &it);
+        if (it)
+          {
+             pos = cur->pos - it->source_pos;
+             if (pos <= 0) at_start_of_line = 1;
+             if (it->text)
+               {
+                  int plast;
+                  
+                  plast = evas_common_font_utf8_get_last(it->text, strlen(it->text));
+                  if ((index - it->source_pos) == plast) at_end_of_line = 1;
+               }
+          }
+     }
+   
+   if ((cur->eol) && (at_end_of_line))
+     {
+        cur->eol = 0;
+        return 1;
+     }
    ch = evas_common_font_utf8_get_prev((unsigned char *)(cur->node->text), &index);
    if (/*(ch == 0) || */(index < 0)) return 0;
    cur->pos = index;
+   if (at_start_of_line)
+     cur->eol =1;
+   else
+     cur->eol = 0;
    return 1;
 }
 
@@ -3292,6 +3359,7 @@ evas_textblock_cursor_char_first(Evas_Textblock_Cursor *cur)
 {
    if (!cur) return;
    cur->pos = 0;
+   cur->eol = 0;
 }
 
 /**
@@ -3314,6 +3382,7 @@ evas_textblock_cursor_char_last(Evas_Textblock_Cursor *cur)
    index = evas_common_font_utf8_get_last((unsigned char *)cur->node->text, cur->node->len);
    if (index < 0) cur->pos = 0;
    cur->pos = index;
+   cur->eol = 0; // 1
 }
 
 /**
@@ -3333,10 +3402,11 @@ evas_textblock_cursor_line_first(Evas_Textblock_Cursor *cur)
    if (!cur->node) return;
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
    if (!o->formatted.valid) _relayout(cur->obj);
+   cur->eol = 0;
    if (cur->node->type == NODE_FORMAT)
      _find_layout_format_item_line_match(cur->obj, cur->node, &ln, &fi);
    else
-     _find_layout_item_line_match(cur->obj, cur->node, cur->pos, &ln, &it);
+     _find_layout_item_line_match(cur->obj, cur->node, cur->pos, cur->eol, &ln, &it);
    if (!ln) return;
    it = (Evas_Object_Textblock_Item *)ln->items;
    fi = (Evas_Object_Textblock_Format_Item *)ln->format_items;
@@ -3374,10 +3444,11 @@ evas_textblock_cursor_line_last(Evas_Textblock_Cursor *cur)
    if (!cur->node) return;
    o = (Evas_Object_Textblock *)(cur->obj->object_data);
    if (!o->formatted.valid) _relayout(cur->obj);
+   cur->eol = 1;
    if (cur->node->type == NODE_FORMAT)
      _find_layout_format_item_line_match(cur->obj, cur->node, &ln, &fi);
    else
-     _find_layout_item_line_match(cur->obj, cur->node, cur->pos, &ln, &it);
+     _find_layout_item_line_match(cur->obj, cur->node, cur->pos, cur->eol, &ln, &it);
    if (!ln) return;
    if (ln->items)
      it = (Evas_Object_Textblock_Item *)((EINA_INLIST_GET(ln->items))->last);
@@ -3404,6 +3475,7 @@ evas_textblock_cursor_line_last(Evas_Textblock_Cursor *cur)
    else if (fi)
      {
        cur->pos = 0;
+        cur->eol = 0;
        cur->node = fi->source_node;
      }
 }
@@ -3435,6 +3507,7 @@ evas_textblock_cursor_pos_set(Evas_Textblock_Cursor *cur, int pos)
    if (pos < 0) pos = 0;
    else if (pos > cur->node->len) pos = cur->node->len;
    cur->pos = pos;
+   cur->eol = 0;
 }
 
 /**
@@ -3467,13 +3540,16 @@ evas_textblock_cursor_line_set(Evas_Textblock_Cursor *cur, int line)
    if (it)
      {
        cur->pos = it->source_pos;
+        cur->eol = 0;
        cur->node = it->source_node;
      }
    else if (fi)
      {
        cur->pos = 0;
+        cur->eol = 0;
        cur->node = fi->source_node;
      }
+   cur->eol = 0;
    return 1;
 }
 
@@ -3496,10 +3572,12 @@ evas_textblock_cursor_compare(const Evas_Textblock_Cursor *cur1, const Evas_Text
      {
        if (cur1->pos < cur2->pos) return -1; /* cur1 < cur2 */
        else if (cur1->pos > cur2->pos) return 1; /* cur2 < cur1 */
-       return 0; /* cur1 == cur2 */
+        if ((cur1->eol) == (cur1->eol)) return 0; /* cur1 == cur2 */
+        if (cur1->eol) return 1; /* cur2 < cur1 */
+       return -1; /* cur1 < cur2 */
      }
    for (l1 = EINA_INLIST_GET(cur1->node),
-         l2 = EINA_INLIST_GET(cur1->node); (l1) || (l2);)
+        l2 = EINA_INLIST_GET(cur1->node); (l1) || (l2);)
      {
        if (l1 == EINA_INLIST_GET(cur2->node)) return 1; /* cur2 < cur 1 */
        else if (l2 == EINA_INLIST_GET(cur2->node)) return -1; /* cur1 < cur 2 */
@@ -3525,6 +3603,7 @@ evas_textblock_cursor_copy(const Evas_Textblock_Cursor *cur, Evas_Textblock_Curs
    if (cur->obj != cur_dest->obj) return;
    cur_dest->pos = cur->pos;
    cur_dest->node = cur->node;
+   cur_dest->eol = cur->eol;
 }
 
 
@@ -3593,6 +3672,7 @@ evas_textblock_cursor_text_append(Evas_Textblock_Cursor *cur, const char *text)
      n->text = _strbuf_append(n->text, (char *)text, &(n->len), &(n->alloc));
    else
      n->text = _strbuf_insert(n->text, (char *)text, cur->pos, &(n->len), &(n->alloc));
+// XXX: This makes no sense?   
    cur->pos += strlen(text);
    o->formatted.valid = 0;
    o->native.valid = 0;
@@ -3747,6 +3827,7 @@ evas_textblock_cursor_format_append(Evas_Textblock_Cursor *cur, const char *form
          }
      }
    cur->node = n;
+// XXX: This makes no sense   
    cur->pos = 0;
    o->formatted.valid = 0;
    o->native.valid = 0;
@@ -3883,6 +3964,7 @@ evas_textblock_cursor_node_delete(Evas_Textblock_Cursor *cur)
               {
                  o->cursor->node = cur->node;
                  o->cursor->pos = cur->pos;
+                  o->cursor->eol = cur->eol;
               }
          }
        EINA_LIST_FOREACH(o->cursors, l, data)
@@ -3893,6 +3975,7 @@ evas_textblock_cursor_node_delete(Evas_Textblock_Cursor *cur)
                    {
                       data->node = cur->node;
                       data->pos = cur->pos;
+                       data->eol = cur->eol;
                    }
               }
          }
@@ -4551,7 +4634,7 @@ evas_textblock_cursor_char_geometry_get(const Evas_Textblock_Cursor *cur, Evas_C
      }
    else
      {
-       _find_layout_item_line_match(cur->obj, cur->node, cur->pos, &ln, &it);
+       _find_layout_item_line_match(cur->obj, cur->node, cur->pos, cur->eol, &ln, &it);
      }
    if (!ln)
      {
@@ -4561,6 +4644,15 @@ evas_textblock_cursor_char_geometry_get(const Evas_Textblock_Cursor *cur, Evas_C
      {
        pos = cur->pos - it->source_pos;
        ret = -1;
+        if (cur->eol)
+          {
+             int pos2;
+             
+             pos2 = pos;
+             evas_common_font_utf8_get_next((unsigned char *)(it->text), &pos2);
+             if (pos2 > pos) pos = pos2;
+          }
+        if (pos < 0) pos = 0;
        if (it->format->font.font)
          ret = cur->ENFN->font_char_coords_get(cur->ENDT, it->format->font.font,
                                                it->text,
@@ -4627,7 +4719,7 @@ evas_textblock_cursor_line_geometry_get(const Evas_Textblock_Cursor *cur, Evas_C
    if (cur->node->type == NODE_FORMAT)
      _find_layout_format_item_line_match(cur->obj, cur->node, &ln, &fi);
    else
-     _find_layout_item_line_match(cur->obj, cur->node, cur->pos, &ln, &it);
+     _find_layout_item_line_match(cur->obj, cur->node, cur->pos, cur->eol, &ln, &it);
    if (!ln) return -1;
    x = ln->x;
    y = ln->y;
@@ -4697,6 +4789,7 @@ evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, E
                  if (((fi->x + ln->x) <= x) && (((fi->x + ln->x) + fi->w) > x))
                    {
                       cur->pos = 0;
+                       cur->eol = 0;
                       cur->node = fi->source_node;
                       return 1;
                    }
@@ -4705,6 +4798,7 @@ evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, E
               {
                  it = it_break;
                  cur->pos = it->source_pos;
+                  cur->eol = 0;
                  cur->node = it->source_node;
                  return 1;
               }
@@ -4841,6 +4935,21 @@ evas_textblock_cursor_range_geometry_get(const Evas_Textblock_Cursor *cur1, cons
    return rects;
 }
 
+EAPI Eina_Bool
+evas_textblock_cursor_eol_get(const Evas_Textblock_Cursor *cur)
+{
+   if (!cur) return 0;
+   return cur->eol;
+}
+
+EAPI void
+evas_textblock_cursor_eol_set(Evas_Textblock_Cursor *cur, Eina_Bool eol)
+{
+   if (!cur) return;
+   cur->eol = eol;
+}
+
+
 /* general controls */
 /**
  * to be documented.
@@ -4882,10 +4991,12 @@ evas_object_textblock_clear(Evas_Object *obj)
    _nodes_clear(obj);
    o->cursor->node = NULL;
    o->cursor->pos = 0;
+   o->cursor->eol = 0;
    EINA_LIST_FOREACH(o->cursors, l, cur)
      {
        cur->node = NULL;
        cur->pos = 0;
+        cur->eol = 0;
      }
    if (o->lines)
      {