Hi,

Here is a patch that adds support for numerical escaping code in textblock. 
Until now textblock only handles escape characters of the form:
&
λ
...

But in html we can represent every unicode characters in the form:
λ --> lambda in hex
or
λ --> lambda in decimal

The patch adds also some functions to the api to convert these numeric 
notations 
to strings.

There is also a test program to test that patch.

Please review and apply!

-- 
------------------------
Raoul Hecky
Calaos
Index: src/lib/Evas.h
===================================================================
--- src/lib/Evas.h	(révision 59734)
+++ src/lib/Evas.h	(copie de travail)
@@ -5549,6 +5549,24 @@
  */
 EAPI const char                  *evas_textblock_escape_string_range_get(const char *escape_start, const char *escape_end) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2) EINA_PURE;
 
+/**
+ * Returns the unescaped version of escape.
+ * It decodes only numerical escaping (in decimal Ӓ or in hex: ሴ)
+ *
+ * @param escape the string to be escaped
+ * @return a Eina_stringshare of the unescaped version of the range, must be freed by eina_stringshare_del
+ */
+EAPI const char                  *evas_textblock_numeric_escape_string_get(const char *escape) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_PURE;
+
+/**
+ * Return the unescaped version of the string between start and end.
+ * It decodes only numerical escaping (in decimal Ӓ or in hex: ሴ)
+ *
+ * @param escape_start the start of the string.
+ * @param escape_end the end of the string.
+ * @return a Eina_stringshare of the unescaped version of the range, must be freed by eina_stringshare_del
+ */
+EAPI const char                  *evas_textblock_numeric_escape_string_range_get(const char *escape_start, const char *escape_end) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1, 2) EINA_PURE;
 
 /**
  * Creates a new textblock style.
Index: src/lib/canvas/evas_object_textblock.c
===================================================================
--- src/lib/canvas/evas_object_textblock.c	(révision 59734)
+++ src/lib/canvas/evas_object_textblock.c	(copie de travail)
@@ -398,6 +398,7 @@
    Eina_Rbtree                        *par_index;
    Eina_List                          *anchors_a;
    Eina_List                          *anchors_item;
+   Eina_List                          *escaped_chars;
    int                                 last_w, last_h;
    struct {
       int                              l, r, t, b;
@@ -4548,6 +4549,8 @@
 _escaped_char_get(const char *s, const char *s_end)
 {
    const char *map_itr, *map_end;
+   char ustr[10];
+   Eina_Unicode uchar[2] = { 0, 0 };
 
    map_itr = escape_strings;
    map_end = map_itr + sizeof(escape_strings);
@@ -4559,6 +4562,47 @@
         if (map_itr < map_end)
           _escaped_advance_after_end_of_string(&map_itr);
      }
+
+   return NULL;
+}
+
+/**
+ * @internal
+ * return a stringshare for the corresponding numeric value
+ */
+static inline const char *
+_numeric_escape_char_get(const char *s, const char *s_end)
+{
+   char ustr[10];
+   Eina_Unicode uchar[2] = { 0, 0 };
+   char *utf8_char;
+   const char *utf8_stringshare;
+
+   if (s[1] == '#')
+     {
+        memset(ustr, '\0', 10);
+
+        if (tolower(s[2]) == 'x')
+          {
+             memcpy(ustr, s + 3, s_end - s - 3);
+             uchar[0] = strtol(ustr, NULL, 16);
+          }
+        else
+          {
+             memcpy(ustr, s + 2, s_end - s - 2);
+             uchar[0] = strtol(ustr, NULL, 10);
+          }
+
+        if ((0xDC00 <= uchar[0] && uchar[0] <= 0xDFFF) || (uchar[0] == 0))
+          return NULL;
+
+        utf8_char = eina_unicode_unicode_to_utf8(uchar, NULL);
+        utf8_stringshare = eina_stringshare_add(utf8_char);
+        free(utf8_char);
+
+        return utf8_stringshare;
+     }
+
    return NULL;
 }
 
@@ -4582,6 +4626,19 @@
    return _escaped_char_match(string, len_ret);
 }
 
+EAPI const char *
+evas_textblock_numeric_escape_string_get(const char *escape)
+{
+   /* &#xxxx; -> char */
+   return _numeric_escape_char_get(escape, escape + strlen(escape));
+}
+
+EAPI const char *
+evas_textblock_numeric_escape_string_range_get(const char *escape_start, const char *escape_end)
+{
+   return _numeric_escape_char_get(escape_start, escape_end);
+}
+
 /**
  * @internal
  * Appends the escaped char beteewn s and s_end to the curosr
@@ -4599,6 +4656,21 @@
    escape = _escaped_char_get(s, s_end);
    if (escape)
      evas_textblock_cursor_text_append(cur, escape);
+
+   if (!escape)
+     {
+        escape = _numeric_escape_char_get(s, s_end);
+
+        if (escape)
+          {
+             Evas_Object *obj = cur->obj;
+             TB_HEAD();
+
+             /* add stringshare to the list so they can be freed later */
+             o->escaped_chars = eina_list_append(o->escaped_chars, escape);
+             evas_textblock_cursor_text_append(cur, escape);
+          }
+     }
 }
 
 /**
@@ -4618,6 +4690,21 @@
    escape = _escaped_char_get(s, s_end);
    if (escape)
      evas_textblock_cursor_text_prepend(cur, escape);
+
+   if (!escape)
+     {
+        escape = _numeric_escape_char_get(s, s_end);
+
+        if (escape)
+          {
+             Evas_Object *obj = cur->obj;
+             TB_HEAD();
+
+             /* add stringshare to the list so they can be freed later */
+             o->escaped_chars = eina_list_append(o->escaped_chars, escape);
+             evas_textblock_cursor_text_prepend(cur, escape);
+          }
+     }
 }
 
 
@@ -8121,6 +8208,7 @@
 evas_object_textblock_free(Evas_Object *obj)
 {
    Evas_Object_Textblock *o;
+   char *escaped_char;
 
    evas_object_textblock_clear(obj);
    evas_object_textblock_style_set(obj, NULL);
@@ -8136,6 +8224,8 @@
      }
    if (o->repch) eina_stringshare_del(o->repch);
    o->magic = 0;
+   EINA_LIST_FREE(o->escaped_chars, escaped_char)
+     eina_stringshare_del(escaped_char);
    EVAS_MEMPOOL_FREE(_mp_obj, o);
   _format_command_shutdown();
 }
/* Compile with:
gcc `pkg-config --libs --cflags evas ecore-evas` test.c -o test_textblock
*/
#include <Eina.h>
#include <Ecore_Evas.h>
#include <Evas.h>

static Evas_Object *text;

static void on_close_window(Ecore_Evas* ee) 
{
        ecore_main_loop_quit();
}

int main()
{
	ecore_evas_init();
        Ecore_Evas *ee = ecore_evas_new("software_x11", 0, 0, 800, 600, NULL);

        ecore_evas_show(ee);
        ecore_evas_callback_delete_request_set(ee, on_close_window);

        Evas *evas = ecore_evas_get(ee);

        Evas_Object *o = evas_object_rectangle_add(evas);
        evas_object_color_set(o, 5, 5, 5, 255);
        evas_object_move(o, 0, 0); 
        evas_object_resize(o, 800, 600);
        evas_object_show(o);

        text = evas_object_textblock_add(evas);
        evas_object_move(text, 10, 10);
        evas_object_resize(text, 790, 590);
        evas_object_color_set(text, 255, 255, 255, 255);
        evas_object_show(text);

	char buf[2000];
	Evas_Textblock_Style *st;

	snprintf(buf,
              2000,
              "DEFAULT='font=Sans font_size=14 color=#FFF wrap=word'"
              "br='\n'"
              "ps='ps'"
              "tab='\t'");

	st = evas_textblock_style_new();
	evas_textblock_style_set(st, buf);
	evas_object_textblock_style_set(text, st);

	evas_object_textblock_text_markup_set(text, "some tests: <br><br> * [&#36;] dollar sign<br> * [&#169;] copyright<br> * [&#955;] lambda<br> * [&#x03BB;] lambda<br> * [&#X03bb;] lambda<br> * [&#x2665;] heart<br><br>HTML characters manifest either directly as bytes according to document's encoding, if the encoding supports them, or users may write them as numeric character references based on the character's Unicode code point. For example, the references &#916;, &#1049;, &#1511;, &#1605;, &#3671;, &#12354;, &#21494;, &#33865;, and &#47568; <br><br>Exemple taken from http://en.wikipedia.org/wiki/Unicode#Web";);

	const char *t1 = evas_textblock_escape_string_get("&eacute;");
	const char *t2 = evas_textblock_numeric_escape_string_get("&#8220;");
	const char *t3 = evas_textblock_numeric_escape_string_get("&#x2019;");

	printf("char 1: %s\nchar 2: %s\nchar 3: %s\n", t1, t2, t3);

	eina_stringshare_del(t2);
	eina_stringshare_del(t3);

	ecore_main_loop_begin();

	ecore_evas_shutdown();

	return 0;
}

------------------------------------------------------------------------------
vRanger cuts backup time in half-while increasing security.
With the market-leading solution for virtual backup and recovery, 
you get blazing-fast, flexible, and affordable data protection.
Download your free trial now. 
http://p.sf.net/sfu/quest-d2dcopy1
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to