Evas textblock: Fixed two textblock issues (range_delete).
[profile/ivi/evas.git] / src / tests / evas_test_textblock.c
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 #include <stdio.h>
6
7 #include <Eina.h>
8
9 #include "evas_suite.h"
10 #include "Evas.h"
11
12 #include "evas_tests_helpers.h"
13
14 /* Functions defined in evas_object_textblock.c */
15 EAPI Eina_Bool
16 _evas_textblock_check_item_node_link(Evas_Object *obj);
17 EAPI int
18 _evas_textblock_format_offset_get(const Evas_Object_Textblock_Node_Format *n);
19 /* end of functions defined in evas_object_textblock.c */
20
21
22 static const char *style_buf =
23    "DEFAULT='font=Sans font_size=10 color=#000 text_class=entry'"
24    "newline='br'"
25    "b='+ font=Sans:style=bold'";
26
27 #define START_TB_TEST() \
28    Evas *evas; \
29    Evas_Object *tb; \
30    Evas_Textblock_Style *st; \
31    Evas_Textblock_Cursor *cur; \
32    evas = EVAS_TEST_INIT_EVAS(); \
33    evas_font_hinting_set(evas, EVAS_FONT_HINTING_AUTO); \
34    tb = evas_object_textblock_add(evas); \
35    fail_if(!tb); \
36    evas_object_textblock_legacy_newline_set(tb, EINA_FALSE); \
37    st = evas_textblock_style_new(); \
38    fail_if(!st); \
39    evas_textblock_style_set(st, style_buf); \
40    fail_if(strcmp(style_buf, evas_textblock_style_get(st))); \
41    evas_object_textblock_style_set(tb, st); \
42    cur = evas_object_textblock_cursor_new(tb); \
43 do \
44 { \
45 } \
46 while (0)
47
48 #define END_TB_TEST() \
49 do \
50 { \
51    evas_textblock_cursor_free(cur); \
52    evas_object_del(tb); \
53    evas_textblock_style_free(st); \
54    evas_free(evas); \
55    evas_shutdown(); \
56 } \
57 while (0)
58
59 START_TEST(evas_textblock_simple)
60 {
61    START_TB_TEST();
62    const char *buf = "Th<i>i</i>s is a <br/> te<b>s</b>t.";
63    evas_object_textblock_text_markup_set(tb, buf);
64    fail_if(strcmp(evas_object_textblock_text_markup_get(tb), buf));
65    END_TB_TEST();
66 }
67 END_TEST
68
69 #define _CHECK_CURSOR_COORDS() \
70 do \
71 { \
72         Evas_Coord cx, cy, cw, ch; \
73         int ret; \
74         ret = evas_textblock_cursor_geometry_get(cur, &cx, &cy, &cw, &ch, \
75               NULL, EVAS_TEXTBLOCK_CURSOR_UNDER); \
76         fail_if(ret == -1); \
77         ret = evas_textblock_cursor_geometry_get(cur, &cx, &cy, &cw, &ch, \
78               NULL, EVAS_TEXTBLOCK_CURSOR_BEFORE); \
79         fail_if(ret == -1); \
80         ret = evas_textblock_cursor_char_geometry_get(cur, \
81               &cx, &cy, &cw, &ch); \
82         fail_if(ret == -1); \
83         ret = evas_textblock_cursor_pen_geometry_get(cur, &cx, &cy, &cw, &ch); \
84         fail_if(ret == -1); \
85         ret = evas_textblock_cursor_line_geometry_get(cur, \
86               &cx, &cy, &cw, &ch); \
87         fail_if(ret == -1); \
88 } \
89 while (0)
90 START_TEST(evas_textblock_cursor)
91 {
92    START_TB_TEST();
93    Evas_Coord x, y, w, h;
94    size_t i, len;
95    Evas_Coord nw, nh;
96    const char *buf = "This is a<br/> test.<ps/>Lets see if this works.<ps/>עוד פסקה.";
97
98    /* Walk the textblock using cursor_char_next */
99    evas_object_textblock_text_markup_set(tb, buf);
100    fail_if(strcmp(evas_object_textblock_text_markup_get(tb), buf));
101    len = eina_unicode_utf8_get_len(buf) - 12; /* 12 because len(<br/>) == 1 and len(<ps/>) == 1 */
102    for (i = 0 ; i < len ; i++)
103      {
104         _CHECK_CURSOR_COORDS();
105
106         fail_if(evas_textblock_cursor_pos_get(cur) != (int) i);
107
108         fail_if(!evas_textblock_cursor_char_next(cur) && (i < len - 1));
109      }
110    fail_if(evas_textblock_cursor_char_next(cur));
111
112    /* Jump to positions all aronud the textblock */
113    evas_textblock_cursor_pos_set(cur, -1);
114    fail_if(evas_textblock_cursor_pos_get(cur) != 0);
115
116    evas_textblock_cursor_pos_set(cur, len + 5);
117    fail_if(evas_textblock_cursor_pos_get(cur) != (int) len);
118
119    for (i = 0 ; i < len ; i++)
120      {
121         evas_textblock_cursor_pos_set(cur, i);
122
123         _CHECK_CURSOR_COORDS();
124
125         fail_if(evas_textblock_cursor_pos_get(cur) != (int) i);
126      }
127
128    /* Create another cursor and insert text, making sure everything
129     * is in sync. */
130    evas_object_textblock_clear(tb);
131    Evas_Textblock_Cursor *main_cur = evas_object_textblock_cursor_get(tb);
132    evas_textblock_cursor_copy(main_cur, cur);
133    fail_if(evas_textblock_cursor_pos_get(cur) !=
134          evas_textblock_cursor_pos_get(main_cur));
135
136    evas_textblock_cursor_text_prepend(main_cur, "a");
137    fail_if(evas_textblock_cursor_pos_get(cur) ==
138          evas_textblock_cursor_pos_get(main_cur));
139    evas_textblock_cursor_text_prepend(main_cur, "a");
140    fail_if(evas_textblock_cursor_pos_get(cur) ==
141          evas_textblock_cursor_pos_get(main_cur));
142
143    /* Insert text to a non-empty textblock */
144    evas_object_textblock_clear(tb);
145    evas_object_textblock_text_markup_set(tb, buf);
146    evas_textblock_cursor_copy(main_cur, cur);
147    fail_if(evas_textblock_cursor_pos_get(cur) !=
148          evas_textblock_cursor_pos_get(main_cur));
149
150    evas_textblock_cursor_text_prepend(main_cur, "a");
151    fail_if(evas_textblock_cursor_pos_get(cur) ==
152          evas_textblock_cursor_pos_get(main_cur));
153    evas_textblock_cursor_text_prepend(main_cur, "a");
154    fail_if(evas_textblock_cursor_pos_get(cur) ==
155          evas_textblock_cursor_pos_get(main_cur));
156
157    /* Make sure append works */
158    evas_textblock_cursor_copy(main_cur, cur);
159    fail_if(evas_textblock_cursor_pos_get(cur) !=
160          evas_textblock_cursor_pos_get(main_cur));
161    evas_textblock_cursor_text_append(main_cur, "a");
162    fail_if(evas_textblock_cursor_pos_get(cur) !=
163          evas_textblock_cursor_pos_get(main_cur));
164
165    /* Cursor comparison */
166    evas_textblock_cursor_pos_set(cur, 1);
167    evas_textblock_cursor_pos_set(main_cur, 2);
168    fail_if(evas_textblock_cursor_compare(cur, main_cur) != -1);
169
170    evas_textblock_cursor_pos_set(cur, 2);
171    evas_textblock_cursor_pos_set(main_cur, 2);
172    fail_if(evas_textblock_cursor_compare(cur, main_cur) != 0);
173
174    evas_textblock_cursor_pos_set(cur, 3);
175    evas_textblock_cursor_pos_set(main_cur, 2);
176    fail_if(evas_textblock_cursor_compare(cur, main_cur) != 1);
177
178    /* Paragraph first */
179    evas_object_textblock_text_markup_set(tb, buf);
180    for (i = 0 ; i < len ; i++)
181      {
182         evas_textblock_cursor_pos_set(cur, i);
183
184         evas_textblock_cursor_paragraph_first(cur);
185         fail_if(evas_textblock_cursor_pos_get(cur) != 0);
186      }
187
188    /* Paragraph last */
189    for (i = 0 ; i < len ; i++)
190      {
191         evas_textblock_cursor_pos_set(cur, i);
192
193         evas_textblock_cursor_paragraph_last(cur);
194         fail_if(evas_textblock_cursor_pos_get(cur) != (int) len);
195      }
196
197    /* Paragraph next */
198    evas_textblock_cursor_paragraph_last(cur);
199    fail_if(evas_textblock_cursor_paragraph_next(cur));
200
201    evas_textblock_cursor_paragraph_first(cur);
202    fail_if(!evas_textblock_cursor_paragraph_next(cur));
203    fail_if(!evas_textblock_cursor_paragraph_next(cur));
204
205    /* Paragraph prev */
206    evas_textblock_cursor_paragraph_first(cur);
207    fail_if(evas_textblock_cursor_paragraph_prev(cur));
208
209    evas_textblock_cursor_paragraph_last(cur);
210    fail_if(!evas_textblock_cursor_paragraph_prev(cur));
211    fail_if(!evas_textblock_cursor_paragraph_prev(cur));
212
213    /* Cher next */
214    evas_textblock_cursor_paragraph_last(cur);
215    fail_if(evas_textblock_cursor_char_next(cur));
216
217    evas_textblock_cursor_paragraph_first(cur);
218    fail_if(!evas_textblock_cursor_char_next(cur));
219    fail_if(!evas_textblock_cursor_paragraph_next(cur));
220    fail_if(!evas_textblock_cursor_char_next(cur));
221    fail_if(!evas_textblock_cursor_paragraph_next(cur));
222    fail_if(!evas_textblock_cursor_char_next(cur));
223
224    /* Cher prev */
225    evas_textblock_cursor_paragraph_first(cur);
226    fail_if(evas_textblock_cursor_char_prev(cur));
227
228    evas_textblock_cursor_paragraph_last(cur);
229    fail_if(!evas_textblock_cursor_char_prev(cur));
230    fail_if(!evas_textblock_cursor_paragraph_prev(cur));
231    fail_if(!evas_textblock_cursor_char_prev(cur));
232
233    /* Paragraph char first */
234    evas_textblock_cursor_paragraph_first(main_cur);
235    evas_textblock_cursor_paragraph_first(cur);
236    fail_if(!evas_textblock_cursor_char_next(cur));
237    evas_textblock_cursor_paragraph_char_first(cur);
238    fail_if(evas_textblock_cursor_compare(cur, main_cur));
239
240    /* Paragraph char last */
241    evas_textblock_cursor_paragraph_last(main_cur);
242    evas_textblock_cursor_paragraph_last(cur);
243    fail_if(!evas_textblock_cursor_char_prev(cur));
244    evas_textblock_cursor_paragraph_char_last(cur);
245    fail_if(evas_textblock_cursor_compare(cur, main_cur));
246
247    /* Line char first */
248    evas_textblock_cursor_paragraph_first(main_cur);
249    evas_textblock_cursor_paragraph_first(cur);
250    fail_if(!evas_textblock_cursor_char_next(cur));
251    evas_textblock_cursor_line_char_first(cur);
252    fail_if(evas_textblock_cursor_compare(cur, main_cur));
253
254    evas_textblock_cursor_pos_set(cur, 12);
255    evas_textblock_cursor_line_char_first(cur);
256    fail_if(evas_textblock_cursor_pos_get(cur) != 10);
257
258    /* Line char first */
259    evas_textblock_cursor_paragraph_last(main_cur);
260    evas_textblock_cursor_paragraph_last(cur);
261    fail_if(!evas_textblock_cursor_char_prev(cur));
262    evas_textblock_cursor_line_char_last(cur);
263    fail_if(evas_textblock_cursor_compare(cur, main_cur));
264
265    evas_textblock_cursor_pos_set(cur, 12);
266    evas_textblock_cursor_line_char_last(cur);
267    fail_if(evas_textblock_cursor_pos_get(cur) != 16);
268
269    /* Line set */
270    evas_textblock_cursor_paragraph_first(main_cur);
271    evas_textblock_cursor_paragraph_last(cur);
272
273    fail_if(!evas_textblock_cursor_line_set(cur, 0));
274    fail_if(evas_textblock_cursor_compare(cur, main_cur));
275    fail_if(!evas_textblock_cursor_line_set(cur, 1));
276    fail_if(!evas_textblock_cursor_line_set(cur, 2));
277    fail_if(!evas_textblock_cursor_line_set(cur, 3));
278
279    fail_if(evas_textblock_cursor_line_set(cur, -1));
280    fail_if(evas_textblock_cursor_line_set(cur, 99));
281
282    /* Paragraph text get */
283    evas_textblock_cursor_paragraph_first(cur);
284    fail_if(strcmp(evas_textblock_cursor_paragraph_text_get(cur),
285             "This is a<br/> test."));
286    evas_textblock_cursor_paragraph_next(cur);
287    fail_if(strcmp(evas_textblock_cursor_paragraph_text_get(cur),
288             "Lets see if this works."));
289    evas_textblock_cursor_paragraph_next(cur);
290    fail_if(strcmp(evas_textblock_cursor_paragraph_text_get(cur),
291             "עוד פסקה."));
292
293    /* Paragraph length get */
294    evas_textblock_cursor_paragraph_first(cur);
295    /* -4 because len(<br/>) == 1 */
296    fail_if(evas_textblock_cursor_paragraph_text_length_get(cur) !=
297             eina_unicode_utf8_get_len("This is a<br/> test.") - 4);
298    evas_textblock_cursor_paragraph_next(cur);
299    fail_if(evas_textblock_cursor_paragraph_text_length_get(cur) !=
300             eina_unicode_utf8_get_len("Lets see if this works."));
301    evas_textblock_cursor_paragraph_next(cur);
302    fail_if(evas_textblock_cursor_paragraph_text_length_get(cur) !=
303             eina_unicode_utf8_get_len("עוד פסקה."));
304
305    /* Cursor content get */
306    evas_textblock_cursor_pos_set(cur, 0);
307    fail_if(strcmp(evas_textblock_cursor_content_get(cur), "T"));
308    evas_textblock_cursor_pos_set(cur, 9);
309    fail_if(strcmp(evas_textblock_cursor_content_get(cur), "<br/>"));
310    evas_textblock_cursor_pos_set(cur, 43);
311    fail_if(strcmp(evas_textblock_cursor_content_get(cur), "ד"));
312
313    /* Eol get */
314    for (i = 0 ; i < len ; i++)
315      {
316         evas_textblock_cursor_pos_set(cur, i);
317         evas_textblock_cursor_copy(cur, main_cur);
318         evas_textblock_cursor_line_char_last(main_cur);
319
320         if (!evas_textblock_cursor_compare(cur, main_cur))
321           {
322              fail_if(!evas_textblock_cursor_eol_get(cur));
323           }
324         else
325           {
326              fail_if(evas_textblock_cursor_eol_get(cur));
327           }
328      }
329
330    /* Format positions */
331    const Evas_Object_Textblock_Node_Format *fnode;
332    fnode = evas_textblock_node_format_first_get(tb);
333    fail_if(!fnode);
334    evas_textblock_cursor_at_format_set(cur, fnode);
335    evas_textblock_cursor_copy(cur, main_cur);
336    fail_if(evas_textblock_cursor_pos_get(cur) != 9);
337    fail_if(evas_textblock_cursor_format_get(cur) != fnode);
338
339    fnode = evas_textblock_node_format_next_get(fnode);
340    fail_if(!fnode);
341    evas_textblock_cursor_at_format_set(cur, fnode);
342    fail_if(evas_textblock_cursor_pos_get(cur) != 16);
343    fail_if(evas_textblock_cursor_format_get(cur) != fnode);
344    evas_textblock_cursor_format_next(main_cur);
345    fail_if(evas_textblock_cursor_compare(main_cur, cur));
346
347    fnode = evas_textblock_node_format_prev_get(fnode);
348    fail_if(!fnode);
349    evas_textblock_cursor_at_format_set(cur, fnode);
350    fail_if(evas_textblock_cursor_pos_get(cur) != 9);
351    fail_if(evas_textblock_cursor_format_get(cur) != fnode);
352    evas_textblock_cursor_format_prev(main_cur);
353    fail_if(evas_textblock_cursor_compare(main_cur, cur));
354
355    evas_textblock_cursor_char_next(main_cur);
356    evas_textblock_cursor_format_prev(main_cur);
357    fail_if(evas_textblock_cursor_compare(main_cur, cur));
358
359
360    evas_object_textblock_text_markup_set(tb, buf);
361
362    /* Check that pen geometry and getting char at coord are in sync. */
363    do
364      {
365         int cur_pos;
366
367         /* Check if it's the last char, if it is, break, otherwise, go back
368          * to the current char because our test advanced the cursor. */
369         if (!evas_textblock_cursor_char_next(cur))
370            break;
371         else
372            evas_textblock_cursor_char_prev(cur);
373
374         cur_pos = evas_textblock_cursor_pos_get(cur);
375         evas_textblock_cursor_pen_geometry_get(cur, &x, &y, &w, &h);
376         evas_textblock_cursor_char_coord_set(cur, x + (w / 2), y + (h / 2));
377         fail_if(cur_pos != evas_textblock_cursor_pos_get(cur));
378      }
379    while (evas_textblock_cursor_char_next(cur));
380
381    /* Try positions before the first paragraph, and after the last paragraph */
382    evas_object_textblock_text_markup_set(tb, buf);
383    evas_object_textblock_size_native_get(tb, &nw, &nh);
384    evas_object_resize(tb, nw, nh);
385    evas_textblock_cursor_pos_set(cur, 5);
386    evas_textblock_cursor_char_coord_set(cur, nw / 2,
387          -50);
388    evas_textblock_cursor_paragraph_first(main_cur);
389    fail_if(evas_textblock_cursor_compare(cur, main_cur));
390
391    evas_textblock_cursor_pos_set(cur, 5);
392    evas_textblock_cursor_char_coord_set(cur, nw / 2,
393          nh + 50);
394    evas_textblock_cursor_paragraph_last(main_cur);
395    fail_if(evas_textblock_cursor_compare(cur, main_cur));
396
397    /* Try positions beyond the left/right limits of lines. */
398    for (i = 0 ; i < 2 ; i++)
399      {
400         evas_textblock_cursor_line_set(cur, i);
401         evas_textblock_cursor_line_geometry_get(cur, &x, &y, &w, &h);
402
403         evas_textblock_cursor_pos_set(main_cur, 5);
404         evas_textblock_cursor_char_coord_set(main_cur, x - 50, y);
405         fail_if(evas_textblock_cursor_compare(main_cur, cur));
406
407         evas_textblock_cursor_line_char_last(cur);
408         evas_textblock_cursor_pos_set(main_cur, 5);
409         evas_textblock_cursor_char_coord_set(main_cur, x + w + 50, y);
410         fail_if(evas_textblock_cursor_compare(main_cur, cur));
411      }
412
413 #ifdef HAVE_FRIBIDI
414    evas_object_textblock_text_markup_set(tb,
415          "testנסיוןtestנסיון<ps/>"
416          "נסיוןtestנסיוןtest<ps/>"
417          "testנסיוןtest<ps/>"
418          "נסיוןtestנסיון<ps/>"
419          "testנסיון<br/>נסיון<ps/>"
420          "נסיוןtest<br/>test"
421          );
422
423    for (i = 0 ; i < 8 ; i++)
424      {
425         evas_textblock_cursor_line_set(cur, i);
426         evas_textblock_cursor_line_geometry_get(cur, &x, &y, &w, &h);
427         switch (i)
428           {
429            case 0:
430            case 2:
431            case 4:
432            case 5:
433               /* Ltr paragraph */
434               evas_textblock_cursor_pos_set(main_cur, 7);
435               evas_textblock_cursor_char_coord_set(main_cur, x - 50, y);
436               fail_if(evas_textblock_cursor_compare(main_cur, cur));
437
438               evas_textblock_cursor_line_char_last(cur);
439               evas_textblock_cursor_pos_set(main_cur, 7);
440               evas_textblock_cursor_char_coord_set(main_cur, x + w + 50, y);
441               fail_if(evas_textblock_cursor_compare(main_cur, cur));
442               break;
443            case 1:
444            case 3:
445            case 6:
446            case 7:
447               /* Rtl paragraph */
448               evas_textblock_cursor_line_char_last(cur);
449               evas_textblock_cursor_pos_set(main_cur, 7);
450               evas_textblock_cursor_char_coord_set(main_cur, x - 50, y);
451               fail_if(evas_textblock_cursor_compare(main_cur, cur));
452
453               evas_textblock_cursor_line_char_first(cur);
454               evas_textblock_cursor_pos_set(main_cur, 7);
455               evas_textblock_cursor_char_coord_set(main_cur, x + w + 50, y);
456               fail_if(evas_textblock_cursor_compare(main_cur, cur));
457               break;
458           }
459      }
460 #endif
461
462    evas_object_textblock_text_markup_set(tb, buf);
463    /* Testing line geometry.*/
464      {
465         Evas_Coord lx, ly, lw, lh;
466         Evas_Coord plx, ply, plw, plh;
467         evas_textblock_cursor_line_set(cur, 0);
468         evas_textblock_cursor_copy(cur, main_cur);
469         evas_textblock_cursor_line_char_last(main_cur);
470         evas_textblock_cursor_line_geometry_get(cur, &plx, &ply, &plw, &plh);
471
472         while (evas_textblock_cursor_compare(cur, main_cur) <= 0)
473           {
474              evas_textblock_cursor_pen_geometry_get(cur, &x, &y, &w, &h);
475              fail_if(0 != evas_textblock_cursor_line_geometry_get(
476                       cur, &lx, &ly, &lw, &lh));
477              fail_if((x < lx) || (x + w > lx + lw) ||
478                    (y < ly) || (y + h > ly + lh));
479              fail_if((lx != plx) || (ly != ply) || (lw != plw) || (lh != plh));
480
481              plx = lx;
482              ply = ly;
483              plw = lw;
484              plh = lh;
485              evas_textblock_cursor_char_next(cur);
486           }
487
488         evas_textblock_cursor_line_set(cur, 1);
489         evas_textblock_cursor_copy(cur, main_cur);
490         evas_textblock_cursor_line_char_last(main_cur);
491         evas_textblock_cursor_line_geometry_get(cur, &plx, &ply, &plw, &plh);
492
493         while (evas_textblock_cursor_compare(cur, main_cur) <= 0)
494           {
495              evas_textblock_cursor_pen_geometry_get(cur, &x, &y, &w, &h);
496              fail_if(1 != evas_textblock_cursor_line_geometry_get(
497                       cur, &lx, &ly, &lw, &lh));
498              fail_if((x < lx) || (x + w > lx + lw) ||
499                    (y < ly) || (y + h > ly + lh));
500              fail_if((lx != plx) || (ly != ply) || (lw != plw) || (lh != plh));
501
502              plx = lx;
503              ply = ly;
504              plw = lw;
505              plh = lh;
506              evas_textblock_cursor_char_next(cur);
507           }
508
509         evas_textblock_cursor_paragraph_last(cur);
510         evas_textblock_cursor_line_set(cur, 0);
511         evas_textblock_cursor_line_geometry_get(cur, &plx, &ply, &plw, &plh);
512         evas_object_textblock_line_number_geometry_get(tb, 0,
513               &lx, &ly, &lw, &lh);
514         fail_if((lx != plx) || (ly != ply) || (lw != plw) || (lh != plh));
515         fail_if(0 != evas_textblock_cursor_line_coord_set(cur, ly + (lh / 2)));
516
517         evas_textblock_cursor_line_set(cur, 1);
518         evas_textblock_cursor_line_geometry_get(cur, &plx, &ply, &plw, &plh);
519         evas_object_textblock_line_number_geometry_get(tb, 1,
520               &lx, &ly, &lw, &lh);
521         fail_if((lx != plx) || (ly != ply) || (lw != plw) || (lh != plh));
522         fail_if(1 != evas_textblock_cursor_line_coord_set(cur, ly + (lh / 2)));
523
524         /* Before the start of the textblock */
525         fail_if(0 != evas_textblock_cursor_line_coord_set(cur, -50));
526         fail_if(3 != evas_textblock_cursor_line_coord_set(cur, 100000));
527
528         /* And now with a valigned textblock. */
529         evas_object_textblock_text_markup_set(tb, buf);
530         evas_object_textblock_size_native_get(tb, &nw, &nh);
531         evas_object_resize(tb, 2 * nw, 2 * nh);
532
533         evas_object_textblock_valign_set(tb, 0.5);
534         evas_textblock_cursor_paragraph_first(cur);
535         evas_textblock_cursor_pen_geometry_get(cur, &x, &y, &w, &h);
536         fail_if(y <= 0);
537
538         evas_textblock_cursor_paragraph_last(main_cur);
539         evas_textblock_cursor_char_coord_set(main_cur, x + w, y / 2);
540         fail_if(evas_textblock_cursor_compare(main_cur, cur));
541
542         evas_textblock_cursor_paragraph_last(main_cur);
543         evas_textblock_cursor_line_coord_set(main_cur, y / 2);
544         fail_if(evas_textblock_cursor_compare(main_cur, cur));
545
546         /* Fail if they are equal, i.e if it for some reason thinks it should
547          * go to the end. */
548         evas_textblock_cursor_paragraph_first(main_cur);
549         evas_textblock_cursor_paragraph_last(cur);
550         evas_textblock_cursor_char_coord_set(main_cur, x + w, nh + 1);
551         fail_if(!evas_textblock_cursor_compare(main_cur, cur));
552
553         evas_textblock_cursor_paragraph_first(main_cur);
554         evas_textblock_cursor_paragraph_last(cur);
555         evas_textblock_cursor_line_coord_set(main_cur, nh + 1);
556         fail_if(!evas_textblock_cursor_compare(main_cur, cur));
557
558         /* Fail if it doesn't go to the end. */
559         evas_textblock_cursor_paragraph_last(cur);
560         evas_textblock_cursor_paragraph_first(main_cur);
561         evas_textblock_cursor_char_coord_set(main_cur, x + w, (2 * nh) - 1);
562         fail_if(evas_textblock_cursor_compare(main_cur, cur));
563
564         evas_textblock_cursor_paragraph_first(main_cur);
565         evas_textblock_cursor_line_coord_set(main_cur, (2 * nh) - 1);
566         fail_if(evas_textblock_cursor_compare(main_cur, cur));
567      }
568
569      {
570         const char *buf_wb = "a This is_a t:e.s't a";
571         evas_object_textblock_text_markup_set(tb, buf_wb);
572
573         /* Word start/end */
574         evas_textblock_cursor_pos_set(cur, 3);
575         evas_textblock_cursor_word_start(cur);
576         fail_if(2 != evas_textblock_cursor_pos_get(cur));
577         evas_textblock_cursor_word_end(cur);
578         fail_if(5 != evas_textblock_cursor_pos_get(cur));
579
580         evas_textblock_cursor_pos_set(cur, 13);
581         evas_textblock_cursor_word_end(cur);
582         fail_if(18 != evas_textblock_cursor_pos_get(cur));
583         evas_textblock_cursor_word_start(cur);
584         fail_if(12 != evas_textblock_cursor_pos_get(cur));
585         evas_textblock_cursor_word_start(cur);
586         fail_if(12 != evas_textblock_cursor_pos_get(cur));
587         evas_textblock_cursor_word_start(cur);
588         fail_if(12 != evas_textblock_cursor_pos_get(cur));
589         evas_textblock_cursor_word_end(cur);
590         fail_if(18 != evas_textblock_cursor_pos_get(cur));
591         evas_textblock_cursor_word_end(cur);
592         fail_if(18 != evas_textblock_cursor_pos_get(cur));
593      }
594
595    END_TB_TEST();
596 }
597 END_TEST
598
599 START_TEST(evas_textblock_format_removal)
600 {
601    START_TB_TEST();
602    int i;
603    const char *buf = "Th<b>is a<a>tes</a>st</b>.";
604    const Evas_Object_Textblock_Node_Format *fnode;
605    Evas_Textblock_Cursor *main_cur = evas_object_textblock_cursor_get(tb);
606    evas_object_textblock_text_markup_set(tb, buf);
607
608    /* Remove the "b" pair. */
609    fnode = evas_textblock_node_format_first_get(tb);
610    evas_textblock_node_format_remove_pair(tb,
611          (Evas_Object_Textblock_Node_Format *) fnode);
612
613    fnode = evas_textblock_node_format_first_get(tb);
614    fail_if (!fnode);
615    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
616             "+ a"));
617
618    fnode = evas_textblock_node_format_next_get(fnode);
619    fail_if (!fnode);
620    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
621             "- a"));
622
623    fnode = evas_textblock_node_format_next_get(fnode);
624    fail_if (fnode);
625
626    /* Now also remove the a pair */
627    fnode = evas_textblock_node_format_first_get(tb);
628    evas_textblock_node_format_remove_pair(tb,
629          (Evas_Object_Textblock_Node_Format *) fnode);
630    fnode = evas_textblock_node_format_first_get(tb);
631    fail_if (fnode);
632
633    /* Remove the "a" pair. */
634    evas_object_textblock_text_markup_set(tb, buf);
635
636    fnode = evas_textblock_node_format_first_get(tb);
637    fnode = evas_textblock_node_format_next_get(fnode);
638    evas_textblock_node_format_remove_pair(tb,
639          (Evas_Object_Textblock_Node_Format *) fnode);
640
641    fnode = evas_textblock_node_format_first_get(tb);
642    fail_if (!fnode);
643    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
644             "+ b"));
645
646    fnode = evas_textblock_node_format_next_get(fnode);
647    fail_if (!fnode);
648    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
649             "- b"));
650
651    fnode = evas_textblock_node_format_next_get(fnode);
652    fail_if (fnode);
653
654    /* Now also remove the b pair */
655    fnode = evas_textblock_node_format_first_get(tb);
656    evas_textblock_node_format_remove_pair(tb,
657          (Evas_Object_Textblock_Node_Format *) fnode);
658    fnode = evas_textblock_node_format_first_get(tb);
659    fail_if (fnode);
660
661    /* Now remove formats by removing text */
662    evas_object_textblock_text_markup_set(tb, buf);
663    evas_textblock_cursor_pos_set(cur, 6);
664    evas_textblock_cursor_char_delete(cur);
665    evas_textblock_cursor_char_delete(cur);
666    evas_textblock_cursor_char_delete(cur);
667    /* Only b formats should remain */
668    fnode = evas_textblock_node_format_first_get(tb);
669    fail_if (!fnode);
670    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
671             "+ b"));
672
673    fnode = evas_textblock_node_format_next_get(fnode);
674    fail_if (!fnode);
675    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
676             "- b"));
677
678    fnode = evas_textblock_node_format_next_get(fnode);
679    fail_if (fnode);
680
681    /* No formats should remain. */
682    evas_textblock_cursor_pos_set(cur, 2);
683    evas_textblock_cursor_char_delete(cur);
684    evas_textblock_cursor_char_delete(cur);
685    evas_textblock_cursor_char_delete(cur);
686    evas_textblock_cursor_char_delete(cur);
687    evas_textblock_cursor_char_delete(cur);
688    evas_textblock_cursor_char_delete(cur);
689    fnode = evas_textblock_node_format_first_get(tb);
690    fail_if (fnode);
691
692    /* Try to remove the formats in a way that shouldn't remove them */
693    evas_object_textblock_text_markup_set(tb, buf);
694    evas_textblock_cursor_pos_set(cur, 7);
695    evas_textblock_cursor_char_delete(cur);
696    evas_textblock_cursor_char_delete(cur);
697    evas_textblock_cursor_char_delete(cur);
698    evas_textblock_cursor_char_delete(cur);
699    fnode = evas_textblock_node_format_first_get(tb);
700    fail_if (!fnode);
701    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
702             "+ b"));
703
704    fnode = evas_textblock_node_format_next_get(fnode);
705    fail_if (!fnode);
706    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
707             "+ a"));
708
709    fnode = evas_textblock_node_format_next_get(fnode);
710    fail_if (!fnode);
711    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
712             "- a"));
713
714    fnode = evas_textblock_node_format_next_get(fnode);
715    fail_if (!fnode);
716    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
717             "- b"));
718
719    fnode = evas_textblock_node_format_next_get(fnode);
720    fail_if (fnode);
721
722    /* Try range deletion to delete a */
723    evas_object_textblock_text_markup_set(tb, buf);
724    evas_textblock_cursor_pos_set(cur, 6);
725    evas_textblock_cursor_pos_set(main_cur, 9);
726    evas_textblock_cursor_range_delete(cur, main_cur);
727    fnode = evas_textblock_node_format_first_get(tb);
728    fail_if (!fnode);
729    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
730             "+ b"));
731
732    fnode = evas_textblock_node_format_next_get(fnode);
733    fail_if (!fnode);
734    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
735             "- b"));
736
737    fnode = evas_textblock_node_format_next_get(fnode);
738    fail_if (fnode);
739
740    /* Range deletion to delete both */
741    evas_object_textblock_text_markup_set(tb, buf);
742    evas_textblock_cursor_pos_set(cur, 2);
743    evas_textblock_cursor_pos_set(main_cur, 11);
744    evas_textblock_cursor_range_delete(cur, main_cur);
745    fnode = evas_textblock_node_format_first_get(tb);
746    fail_if (fnode);
747
748    /* Range deletion across paragraphs */
749    evas_object_textblock_text_markup_set(tb,
750          "Th<b>is a<a>te<ps/>"
751          "s</a>st</b>.");
752    evas_textblock_cursor_pos_set(cur, 6);
753    evas_textblock_cursor_pos_set(main_cur, 10);
754    evas_textblock_cursor_range_delete(cur, main_cur);
755    fnode = evas_textblock_node_format_first_get(tb);
756    fail_if (!fnode);
757    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
758             "+ b"));
759
760    fnode = evas_textblock_node_format_next_get(fnode);
761    fail_if (!fnode);
762    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
763             "- b"));
764
765    fnode = evas_textblock_node_format_next_get(fnode);
766    fail_if (fnode);
767
768    /* Range deletion across paragraph - a bug found in elm. */
769    evas_object_textblock_text_markup_set(tb,
770          "This is an entry widget in this window that<ps/>"
771          "uses markup <b>like this</> for styling and<ps/>"
772          "formatting <em>like this</>, as well as<ps/>"
773          "<a href=X><link>links in the text</></a>, so enter text<ps/>"
774          "in here to edit it. By the way, links are<ps/>"
775          "called <a href=anc-02>Anchors</a> so you will need<ps/>"
776          "to refer to them this way.<ps/>"
777          "<ps/>"
778
779          "Also you can stick in items with (relsize + ascent): "
780          "<item relsize=16x16 vsize=ascent href=emoticon/evil-laugh></item>"
781          " (full) "
782          "<item relsize=16x16 vsize=full href=emoticon/guilty-smile></item>"
783          " (to the left)<ps/>"
784
785          "Also (size + ascent): "
786          "<item size=16x16 vsize=ascent href=emoticon/haha></item>"
787          " (full) "
788          "<item size=16x16 vsize=full href=emoticon/happy-panting></item>"
789          " (before this)<ps/>"
790
791          "And as well (absize + ascent): "
792          "<item absize=64x64 vsize=ascent href=emoticon/knowing-grin></item>"
793          " (full) "
794          "<item absize=64x64 vsize=full href=emoticon/not-impressed></item>"
795          " or even paths to image files on disk too like: "
796          "<item absize=96x128 vsize=full href=file://bla/images/sky_01.jpg></item>"
797          " ... end.");
798    evas_textblock_cursor_paragraph_first(cur);
799    evas_textblock_cursor_paragraph_last(main_cur);
800    evas_textblock_cursor_range_delete(cur, main_cur);
801    fnode = evas_textblock_node_format_first_get(tb);
802    fail_if(fnode);
803
804    /* Two formats in the same place. */
805    evas_object_textblock_text_markup_set(tb, "a<b><a>b</a></b>b");
806    evas_textblock_cursor_pos_set(cur, 1);
807    evas_textblock_cursor_char_delete(cur);
808    fnode = evas_textblock_node_format_first_get(tb);
809    fail_if (fnode);
810
811    /* Two formats across different paragraphs with notihng in between. */
812    evas_object_textblock_text_markup_set(tb, "<b><ps/></b>");
813    evas_textblock_cursor_pos_set(cur, 0);
814    evas_textblock_cursor_char_delete(cur);
815    fnode = evas_textblock_node_format_first_get(tb);
816    fail_if (fnode);
817
818    /* Try with range */
819    evas_object_textblock_text_markup_set(tb, "<b><ps/></b>");
820    evas_textblock_cursor_pos_set(cur, 0);
821    evas_textblock_cursor_pos_set(main_cur, 1);
822    evas_textblock_cursor_range_delete(cur, main_cur);
823    fnode = evas_textblock_node_format_first_get(tb);
824    fail_if (fnode);
825
826    /* Verify fmt position and REP_CHAR positions are the same */
827    evas_object_textblock_text_markup_set(tb,
828          "This is<ps/>an <item absize=93x152 vsize=ascent></>a.");
829    evas_textblock_cursor_pos_set(cur, 7);
830    evas_textblock_cursor_char_delete(cur);
831    fnode = evas_textblock_node_format_first_get(tb);
832    fail_if(_evas_textblock_format_offset_get(fnode) != 10);
833
834    /* Out of order <b><i></b></i> mixes. */
835    evas_object_textblock_text_markup_set(tb, "a<b>b<i>c</b>d</i>e");
836    evas_textblock_cursor_pos_set(cur, 2);
837
838    for (i = 0 ; i < 2 ; i++)
839      {
840         fnode = evas_textblock_node_format_first_get(tb);
841         fail_if (!fnode);
842         fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
843
844         fnode = evas_textblock_node_format_next_get(fnode);
845         fail_if (!fnode);
846         fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ i"));
847
848         fnode = evas_textblock_node_format_next_get(fnode);
849         fail_if (!fnode);
850         fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- b"));
851
852         fnode = evas_textblock_node_format_next_get(fnode);
853         fail_if (!fnode);
854         fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- i"));
855
856         fnode = evas_textblock_node_format_next_get(fnode);
857         fail_if (fnode);
858
859         evas_textblock_cursor_char_delete(cur);
860      }
861    fnode = evas_textblock_node_format_first_get(tb);
862    fail_if (!fnode);
863    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
864
865    fnode = evas_textblock_node_format_next_get(fnode);
866    fail_if (!fnode);
867    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- b"));
868
869    fnode = evas_textblock_node_format_next_get(fnode);
870    fail_if (fnode);
871
872    /* This time with a generic closer */
873    evas_object_textblock_text_markup_set(tb, "a<b>b<i>c</b>d</>e");
874    evas_textblock_cursor_pos_set(cur, 2);
875
876    for (i = 0 ; i < 2 ; i++)
877      {
878         fnode = evas_textblock_node_format_first_get(tb);
879         fail_if (!fnode);
880         fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
881
882         fnode = evas_textblock_node_format_next_get(fnode);
883         fail_if (!fnode);
884         fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ i"));
885
886         fnode = evas_textblock_node_format_next_get(fnode);
887         fail_if (!fnode);
888         fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- b"));
889
890         fnode = evas_textblock_node_format_next_get(fnode);
891         fail_if (!fnode);
892         fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- "));
893
894         fnode = evas_textblock_node_format_next_get(fnode);
895         fail_if (fnode);
896
897         evas_textblock_cursor_char_delete(cur);
898      }
899    fnode = evas_textblock_node_format_first_get(tb);
900    fail_if (!fnode);
901    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
902
903    fnode = evas_textblock_node_format_next_get(fnode);
904    fail_if (!fnode);
905    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- b"));
906
907    fnode = evas_textblock_node_format_next_get(fnode);
908    fail_if (fnode);
909
910    /* And now with remove pair. */
911    evas_object_textblock_text_markup_set(tb, "a<b>b<i>c</b>d</i>e");
912    evas_textblock_cursor_pos_set(cur, 2);
913    fnode = evas_textblock_node_format_first_get(tb);
914    evas_textblock_node_format_remove_pair(tb,
915          (Evas_Object_Textblock_Node_Format *) fnode);
916
917    fnode = evas_textblock_node_format_first_get(tb);
918    fail_if (!fnode);
919    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ i"));
920
921    fnode = evas_textblock_node_format_next_get(fnode);
922    fail_if (!fnode);
923    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- i"));
924
925    fnode = evas_textblock_node_format_next_get(fnode);
926    fail_if (fnode);
927
928    /* Remove the other pair */
929    evas_object_textblock_text_markup_set(tb, "a<b>b<i>c</>d</i>e");
930    evas_textblock_cursor_pos_set(cur, 2);
931    fnode = evas_textblock_node_format_first_get(tb);
932    fnode = evas_textblock_node_format_next_get(fnode);
933    evas_textblock_node_format_remove_pair(tb,
934          (Evas_Object_Textblock_Node_Format *) fnode);
935
936    fnode = evas_textblock_node_format_first_get(tb);
937    fail_if (!fnode);
938    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
939
940    fnode = evas_textblock_node_format_next_get(fnode);
941    fail_if (!fnode);
942    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- i"));
943
944    fnode = evas_textblock_node_format_next_get(fnode);
945    fail_if (fnode);
946
947    /* Remove two pairs with the same name and same positions. */
948    evas_object_textblock_text_markup_set(tb, "<a><a>A</a></a>");
949    evas_textblock_cursor_pos_set(cur, 0);
950    evas_textblock_cursor_char_delete(cur);
951
952    fnode = evas_textblock_node_format_first_get(tb);
953    fail_if (fnode);
954
955    /* Try to remove a format that doesn't have a pair (with a bad mkup) */
956    evas_object_textblock_text_markup_set(tb, "a<b>b<i>c</>d</i>e");
957    evas_textblock_cursor_pos_set(cur, 2);
958    fnode = evas_textblock_node_format_first_get(tb);
959    evas_textblock_node_format_remove_pair(tb,
960          (Evas_Object_Textblock_Node_Format *) fnode);
961
962    fnode = evas_textblock_node_format_first_get(tb);
963    fail_if (!fnode);
964    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ i"));
965
966    fnode = evas_textblock_node_format_next_get(fnode);
967    fail_if (!fnode);
968    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- "));
969
970    fnode = evas_textblock_node_format_next_get(fnode);
971    fail_if (!fnode);
972    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- i"));
973
974    fnode = evas_textblock_node_format_next_get(fnode);
975    fail_if (fnode);
976
977    END_TB_TEST();
978 }
979 END_TEST
980
981 /* Testing items */
982 START_TEST(evas_textblock_items)
983 {
984    Evas_Coord w, h, w2, h2, nw, nh, ih;
985    START_TB_TEST();
986    const char *buf = "This is an <item absize=93x152></>.";
987
988    /* Absolute item size */
989    buf = "This is an <item absize=93x152 vsize=full></>.";
990    evas_object_textblock_text_markup_set(tb, buf);
991    evas_object_textblock_size_formatted_get(tb, &w, &h);
992    fail_if((w < 93) || (h != 152));
993    evas_textblock_cursor_pos_set(cur, 11);
994    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
995    fail_if((w != 93) || (h != 152));
996
997    buf = "This is an <item absize=93x152 vsize=ascent></>.";
998    evas_object_textblock_text_markup_set(tb, buf);
999    evas_object_textblock_size_formatted_get(tb, &w, &h);
1000    fail_if((w < 93) || (h <= 152));
1001    evas_textblock_cursor_pos_set(cur, 11);
1002    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
1003    fail_if((w != 93) || (h != 152));
1004
1005    /* Size is the same as abssize, unless there's scaling applied. */
1006    buf = "This is an <item size=93x152 vsize=full></>.";
1007    evas_object_textblock_text_markup_set(tb, buf);
1008    evas_object_textblock_size_formatted_get(tb, &w, &h);
1009    fail_if((w < 93) || (h != 152));
1010    evas_textblock_cursor_pos_set(cur, 11);
1011    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
1012    fail_if((w != 93) || (h != 152));
1013
1014    buf = "This is an <item size=93x152 vsize=ascent></>.";
1015    evas_object_textblock_text_markup_set(tb, buf);
1016    evas_object_textblock_size_formatted_get(tb, &w, &h);
1017    fail_if((w < 93) || (h <= 152));
1018    evas_textblock_cursor_pos_set(cur, 11);
1019    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
1020    fail_if((w != 93) || (h != 152));
1021
1022    evas_object_scale_set(tb, 2.0);
1023    buf = "This is an <item size=93x152 vsize=full></>.";
1024    evas_object_textblock_text_markup_set(tb, buf);
1025    evas_object_textblock_size_formatted_get(tb, &w, &h);
1026    fail_if((w < (2 * 93)) || (h != (2 * 152)));
1027    evas_textblock_cursor_pos_set(cur, 11);
1028    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
1029    fail_if((w != (2 * 93)) || (h != (2 * 152)));
1030    evas_textblock_cursor_pos_set(cur, 11);
1031    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
1032    fail_if((w != (2 * 93)) || (h != (2 * 152)));
1033
1034    buf = "This is an <item size=93x152 vsize=ascent></>.";
1035    evas_object_textblock_text_markup_set(tb, buf);
1036    evas_object_textblock_size_formatted_get(tb, &w, &h);
1037    fail_if((w < (2 * 93)) || (h <= (2 * 152)));
1038    evas_textblock_cursor_pos_set(cur, 11);
1039    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
1040    fail_if((w != (2 * 93)) || (h != (2 * 152)));
1041
1042    evas_object_scale_set(tb, 1.0);
1043
1044    /* Relsize */
1045    /* relsize means it should adjust itself to the size of the line */
1046    buf = "This is an <item relsize=93x152 vsize=full></>.";
1047    evas_object_textblock_text_markup_set(tb, buf);
1048    evas_object_textblock_size_formatted_get(tb, &w, &h);
1049    fail_if((w >= 93) || (h >= 152));
1050    evas_textblock_cursor_pos_set(cur, 11);
1051    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &ih);
1052    fail_if((w > 90) || (h != ih));
1053
1054    buf = "This is an <item relize=93x152 vsize=ascent></>.";
1055    evas_object_textblock_text_markup_set(tb, buf);
1056    evas_object_textblock_size_formatted_get(tb, &w, &h);
1057    fail_if((w >= 93) || (h >= 152));
1058    evas_textblock_cursor_pos_set(cur, 11);
1059    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &ih);
1060    fail_if((w > 90) || (h <= ih));
1061
1062    /* Relsize and abs size in the same line, all should be the same size */
1063    buf = "<item relsize=64x64 vsize=ascent href=emoticon/knowing-grin></item><item absize=64x64 vsize=ascent href=emoticon/knowing-grin></item><item relsize=64x64 vsize=ascent href=emoticon/knowing-grin></item>";
1064    evas_object_textblock_text_markup_set(tb, buf);
1065    evas_object_textblock_size_formatted_get(tb, &w, &h);
1066    evas_object_textblock_size_native_get(tb, &nw, &nh);
1067    fail_if((nw != w) || (nh != h));
1068    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
1069    evas_textblock_cursor_char_next(cur);
1070    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w2, &h2);
1071    fail_if((w != w2) || (h != h2));
1072    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w, &h);
1073    evas_textblock_cursor_char_next(cur);
1074    evas_textblock_cursor_format_item_geometry_get(cur, NULL, NULL, &w2, &h2);
1075    fail_if((w != w2) || (h != h2));
1076
1077    /* FIXME: Also verify x,y positions of the item. */
1078
1079    /* FIXME We need some item tests that involve line wrapping that make the
1080     * items move between lines that are in different sizes.
1081     * Also, tests that involve wrapping positions with relsized items. We
1082     * want to make sure the item gets a relsize on the correct time (before
1083     * the wrapping, and then is updated after the wrapping) and that
1084     * all the lines have the correct sizes afterwards. */
1085
1086    END_TB_TEST();
1087 }
1088 END_TEST
1089
1090 /* Wrapping tests */
1091 START_TEST(evas_textblock_wrapping)
1092 {
1093    Evas_Coord bw, bh, w, h, nw, nh;
1094    int i;
1095    START_TB_TEST();
1096    evas_object_textblock_text_markup_set(tb, "a");
1097    evas_object_textblock_size_formatted_get(tb, &bw, &bh);
1098
1099    /* Char wrap */
1100    evas_object_textblock_text_markup_set(tb, "aaaaaaa");
1101    evas_textblock_cursor_format_prepend(cur, "+ wrap=char");
1102    evas_object_resize(tb, bw, bh);
1103    evas_object_textblock_size_formatted_get(tb, &w, &h);
1104    /* Wrap to minimum */
1105    fail_if(w != bw);
1106    fail_if(h <= bh);
1107
1108    /* Mixed - fallback to char wrap */
1109    evas_object_textblock_text_markup_set(tb, "aaaaaaa");
1110    evas_textblock_cursor_format_prepend(cur, "+ wrap=mixed");
1111    evas_object_resize(tb, bw, bh);
1112    evas_object_textblock_size_formatted_get(tb, &w, &h);
1113    /* Wrap to minimum */
1114    fail_if(w != bw);
1115    fail_if(h <= bh);
1116
1117    /* Basic Word wrap */
1118    evas_object_textblock_text_markup_set(tb, "aaaa");
1119    evas_object_textblock_size_formatted_get(tb, &bw, &bh);
1120
1121    evas_object_textblock_text_markup_set(tb, "aaaa aa");
1122    evas_textblock_cursor_format_prepend(cur, "+ wrap=word");
1123    evas_object_resize(tb, bw, bh);
1124    evas_object_textblock_size_formatted_get(tb, &w, &h);
1125    /* Wrap to minimum */
1126    fail_if(w != bw);
1127    fail_if(h <= bh);
1128
1129    /* Mixed - fallback to word wrap */
1130    evas_object_textblock_text_markup_set(tb, "aaaa aa");
1131    evas_textblock_cursor_format_prepend(cur, "+ wrap=mixed");
1132    evas_object_resize(tb, bw + 1, bh);
1133    evas_object_textblock_size_formatted_get(tb, &w, &h);
1134    /* Wrap to minimum */
1135    fail_if(w != bw);
1136    fail_if(h <= bh);
1137
1138    /* Wrap and then expand again. */
1139    evas_object_textblock_text_markup_set(tb, "aaaa aa");
1140    evas_textblock_cursor_format_prepend(cur, "+ wrap=word");
1141    evas_object_resize(tb, bw, bh);
1142    evas_object_textblock_size_formatted_get(tb, &w, &h);
1143    evas_object_textblock_size_native_get(tb, &nw, &nh);
1144    evas_object_resize(tb, nw, nh);
1145    evas_object_textblock_size_formatted_get(tb, &w, &h);
1146    fail_if((w != nw) || (h != nh));
1147
1148    /* Reduce size until reaching the minimum, making sure we don't
1149     * get something wrong along the way */
1150    /* Char wrap */
1151    evas_object_textblock_text_markup_set(tb, "a");
1152    evas_object_textblock_size_formatted_get(tb, &bw, &bh);
1153    evas_object_textblock_text_markup_set(tb,
1154          "aaaa aaaa aaa aa aaa<ps/>"
1155          "aaaa aaa aaa aaa aaa<ps/>"
1156          "a aaaaa aaaaaaaaaaaaaa<br/>aaaaa<ps/>"
1157          "aaaaaa"
1158          );
1159    evas_textblock_cursor_format_prepend(cur, "+ wrap=char");
1160    evas_object_textblock_size_native_get(tb, &nw, &nh);
1161
1162    Evas_Coord iw;
1163    for (iw = nw ; iw >= bw ; iw--)
1164      {
1165         evas_object_resize(tb, iw, 1000);
1166         evas_object_textblock_size_formatted_get(tb, &w, &h);
1167         fail_if(w < bw);
1168         fail_if(w > iw);
1169      }
1170    fail_if(w != bw);
1171
1172    /* Word wrap */
1173    evas_object_textblock_text_markup_set(tb, "aaaaaa");
1174    evas_object_textblock_size_formatted_get(tb, &bw, &bh);
1175    evas_object_textblock_text_markup_set(tb,
1176          "aaaa aaaa aaa aa aaa<ps/>"
1177          "aaaa aaa aaa aaa aaa<ps/>"
1178          "a aaaaa aaaaaa<br/>aaaaa<ps/>"
1179          "aaaaa"
1180          );
1181    evas_textblock_cursor_format_prepend(cur, "+ wrap=word");
1182    evas_object_textblock_size_native_get(tb, &nw, &nh);
1183
1184    for (iw = nw ; iw >= bw ; iw--)
1185      {
1186         evas_object_resize(tb, iw, 1000);
1187         evas_object_textblock_size_formatted_get(tb, &w, &h);
1188         fail_if(w < bw);
1189         fail_if(w > iw);
1190      }
1191    fail_if(w != bw);
1192
1193    /* Mixed wrap */
1194    evas_object_textblock_text_markup_set(tb, "a");
1195    evas_object_textblock_size_formatted_get(tb, &bw, &bh);
1196    evas_object_textblock_text_markup_set(tb,
1197          "aaaa aaaa aaa aa aaa<ps/>"
1198          "aaaa aaa aaa aaa aaa<ps/>"
1199          "a aaaaa aaaaaa<br/>aaaaa<ps/>"
1200          "aaaaa"
1201          );
1202    evas_textblock_cursor_format_prepend(cur, "+ wrap=mixed");
1203    evas_object_textblock_size_native_get(tb, &nw, &nh);
1204
1205    for (iw = nw ; iw >= bw ; iw--)
1206      {
1207         evas_object_resize(tb, iw, 1000);
1208         evas_object_textblock_size_formatted_get(tb, &w, &h);
1209         fail_if(w < bw);
1210         fail_if(w > iw);
1211      }
1212    fail_if(w != bw);
1213
1214    /* Resize, making sure we keep going down in the minimum size. */
1215    char *wrap_style[] = { "+ wrap=word", "+ wrap=char", "+ wrap=mixed" };
1216    int wrap_items = sizeof(wrap_style) / sizeof(*wrap_style);
1217
1218    evas_object_textblock_text_markup_set(tb,
1219          "This is an entry widget in this window that<br/>"
1220          "uses markup <b>like this</> for styling and<br/>"
1221          "formatting <em>like this</>, as well as<br/>"
1222          "<a href=X><link>links in the text</></a>, so enter text<br/>"
1223          "in here to edit it. By the way, links are<br/>"
1224          "called <a href=anc-02>Anchors</a> so you will need<br/>"
1225          "to refer to them this way.<br/>"
1226          "<br/>"
1227
1228          "Also you can stick in items with (relsize + ascent): "
1229          "<item relsize=16x16 vsize=ascent href=emoticon/evil-laugh></item>"
1230          " (full) "
1231          "<item relsize=16x16 vsize=full href=emoticon/guilty-smile></item>"
1232          " (to the left)<br/>"
1233
1234          "Also (size + ascent): "
1235          "<item size=16x16 vsize=ascent href=emoticon/haha></item>"
1236          " (full) "
1237          "<item size=16x16 vsize=full href=emoticon/happy-panting></item>"
1238          " (before this)<br/>"
1239
1240          "And as well (absize + ascent): "
1241          "<item absize=64x64 vsize=ascent href=emoticon/knowing-grin></item>"
1242          " (full) "
1243          "<item absize=64x64 vsize=full href=emoticon/not-impressed></item>"
1244          " or even paths to image files on disk too like: "
1245          "<item absize=96x128 vsize=full href=file://%s/images/sky_01.jpg></item>"
1246          " ... end."
1247          );
1248
1249    /* Get minimum size */
1250    evas_object_textblock_size_native_get(tb, &nw, &nh);
1251
1252    for (i = 0 ; i < wrap_items ; i++)
1253      {
1254         evas_textblock_cursor_format_prepend(cur, wrap_style[i]);
1255         evas_object_resize(tb, 0, 0);
1256         evas_object_textblock_size_formatted_get(tb, &bw, &bh);
1257
1258         for (iw = nw ; iw >= bw ; iw--)
1259           {
1260              evas_object_resize(tb, iw, 1000);
1261              evas_object_textblock_size_formatted_get(tb, &w, &h);
1262              fail_if(w < bw);
1263              fail_if(w > iw);
1264           }
1265         fail_if(w != bw);
1266      }
1267
1268
1269    /* Ellipsis */
1270    evas_object_textblock_text_markup_set(tb, "aaaaaaaaaa");
1271    evas_textblock_cursor_format_prepend(cur, "+ ellipsis=1.0");
1272    evas_object_textblock_size_native_get(tb, &nw, &nh);
1273    evas_object_resize(tb, nw / 2, nh);
1274    evas_object_textblock_size_formatted_get(tb, &w, &h);
1275    fail_if((w > (nw / 2)) || (h != nh));
1276
1277    evas_object_textblock_text_markup_set(tb, "aaaaaaaaaaaaaaaaaa<br/>b");
1278    evas_textblock_cursor_format_prepend(cur, "+ ellipsis=1.0 wrap=word");
1279    evas_object_textblock_size_native_get(tb, &nw, &nh);
1280    evas_object_resize(tb, nw / 2, nh * 2);
1281    evas_object_textblock_size_formatted_get(tb, &w, &h);
1282    fail_if(w > (nw / 2));
1283
1284    END_TB_TEST();
1285 }
1286 END_TEST
1287
1288 /* Various textblock stuff */
1289 START_TEST(evas_textblock_various)
1290 {
1291    Evas_Coord w, h, bw, bh;
1292    START_TB_TEST();
1293    const char *buf = "This<ps/>textblock<ps/>has<ps/>a<ps/>lot<ps/>of<ps/>lines<ps/>.";
1294    evas_object_textblock_text_markup_set(tb, buf);
1295    evas_object_textblock_size_formatted_get(tb, &w, &h);
1296    /* Move outside of the screen so it'll have to search for the correct
1297     * paragraph and etc. */
1298    evas_object_move(tb, -(w / 2), -(h / 2));
1299
1300    /* Replacement char */
1301    evas_object_textblock_text_markup_set(tb, "*");
1302    evas_object_textblock_size_formatted_get(tb, &bw, &bh);
1303    evas_object_textblock_replace_char_set(tb, "*");
1304    evas_object_textblock_text_markup_set(tb, "|");
1305    evas_object_textblock_size_formatted_get(tb, &w, &h);
1306    fail_if((w != bw) || (h != bh));
1307
1308    /* Items have correct text node information */
1309    evas_object_textblock_text_markup_set(tb, "");
1310    fail_if(!_evas_textblock_check_item_node_link(tb));
1311    evas_object_textblock_text_markup_set(tb, "<ps/>");
1312    fail_if(!_evas_textblock_check_item_node_link(tb));
1313    evas_object_textblock_text_markup_set(tb, "a<ps/>");
1314    fail_if(!_evas_textblock_check_item_node_link(tb));
1315    evas_object_textblock_text_markup_set(tb, "a<ps/>a");
1316    fail_if(!_evas_textblock_check_item_node_link(tb));
1317    evas_object_textblock_text_markup_set(tb, "a<ps/>a<ps/>");
1318    fail_if(!_evas_textblock_check_item_node_link(tb));
1319    evas_object_textblock_text_markup_set(tb, "a<ps/>a<ps/>a");
1320    fail_if(!_evas_textblock_check_item_node_link(tb));
1321
1322    /* These shouldn't crash (although the desired outcome is not yet defined) */
1323    evas_object_textblock_text_markup_set(tb, "&#xfffc;");
1324    evas_textblock_cursor_pos_set(cur, 0);
1325    evas_textblock_cursor_char_delete(cur);
1326
1327    evas_object_textblock_text_markup_set(tb, "\xEF\xBF\xBC");
1328    evas_textblock_cursor_pos_set(cur, 0);
1329    evas_textblock_cursor_char_delete(cur);
1330
1331    END_TB_TEST();
1332 }
1333 END_TEST
1334
1335 /* Various geometries. e.g. range geometry. */
1336 START_TEST(evas_textblock_geometries)
1337 {
1338    START_TB_TEST();
1339    const char *buf = "This is a <br/> test.";
1340    evas_object_textblock_text_markup_set(tb, buf);
1341
1342    /* Single line range */
1343    Evas_Textblock_Cursor *main_cur = evas_object_textblock_cursor_get(tb);
1344    evas_textblock_cursor_pos_set(cur, 0);
1345    evas_textblock_cursor_pos_set(main_cur, 6);
1346
1347    Eina_List *rects, *rects2;
1348    Evas_Textblock_Rectangle *tr, *tr2;
1349    rects = evas_textblock_cursor_range_geometry_get(cur, main_cur);
1350    fail_if(!rects);
1351    rects2 = evas_textblock_cursor_range_geometry_get(main_cur, cur);
1352    fail_if(!rects2);
1353
1354    fail_if(eina_list_count(rects) != 1);
1355    fail_if(eina_list_count(rects2) != 1);
1356
1357    tr = eina_list_data_get(rects);
1358    fail_if((tr->h <= 0) || (tr->w <= 0));
1359    tr2 = eina_list_data_get(rects2);
1360    fail_if((tr2->h <= 0) || (tr2->w <= 0));
1361
1362    fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
1363          (tr->h != tr2->h));
1364
1365    /* Multiline range */
1366    evas_textblock_cursor_pos_set(cur, 0);
1367    evas_textblock_cursor_pos_set(main_cur, 14);
1368
1369    rects = evas_textblock_cursor_range_geometry_get(cur, main_cur);
1370    fail_if(!rects);
1371    rects2 = evas_textblock_cursor_range_geometry_get(main_cur, cur);
1372    fail_if(!rects2);
1373
1374    fail_if(eina_list_count(rects) != 2);
1375    fail_if(eina_list_count(rects2) != 2);
1376
1377    tr = eina_list_data_get(rects);
1378    fail_if((tr->h <= 0) || (tr->w <= 0));
1379    tr2 = eina_list_data_get(rects2);
1380    fail_if((tr2->h <= 0) || (tr2->w <= 0));
1381
1382    fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
1383          (tr->h != tr2->h));
1384
1385    tr = eina_list_data_get(eina_list_next(rects));
1386    fail_if((tr->h <= 0) || (tr->w <= 0));
1387    tr2 = eina_list_data_get(eina_list_next(rects2));
1388    fail_if((tr2->h <= 0) || (tr2->w <= 0));
1389
1390    fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
1391          (tr->h != tr2->h));
1392
1393    /* Check that the second line is positioned below the first */
1394    tr = eina_list_data_get(rects);
1395    tr2 = eina_list_data_get(eina_list_next(rects));
1396    fail_if(tr->y >= tr2->y);
1397
1398    END_TB_TEST();
1399 }
1400 END_TEST
1401
1402 /* Should handle all the text editing. */
1403 START_TEST(evas_textblock_editing)
1404 {
1405    START_TB_TEST();
1406    const char *buf = "First par.<ps/>Second par.";
1407    evas_object_textblock_text_markup_set(tb, buf);
1408    Evas_Textblock_Cursor *main_cur = evas_object_textblock_cursor_get(tb);
1409
1410    /* Check deletion works */
1411    /* Try deleting after the end of the textblock */
1412      {
1413         char *content;
1414         evas_textblock_cursor_paragraph_last(cur);
1415         content = strdup(evas_object_textblock_text_markup_get(tb));
1416         evas_textblock_cursor_char_delete(cur);
1417         fail_if(strcmp(content, evas_object_textblock_text_markup_get(tb)));
1418         free(content);
1419      }
1420
1421    /* Delete the first char */
1422    evas_textblock_cursor_paragraph_first(cur);
1423    evas_textblock_cursor_char_delete(cur);
1424    fail_if(strcmp(evas_object_textblock_text_markup_get(tb),
1425             "irst par.<ps/>Second par."));
1426
1427    /* Delete some arbitrary char */
1428    evas_textblock_cursor_char_next(cur);
1429    evas_textblock_cursor_char_next(cur);
1430    evas_textblock_cursor_char_next(cur);
1431    evas_textblock_cursor_char_delete(cur);
1432    fail_if(strcmp(evas_object_textblock_text_markup_get(tb),
1433             "irs par.<ps/>Second par."));
1434
1435    /* Delete a range */
1436    evas_textblock_cursor_pos_set(main_cur, 1);
1437    evas_textblock_cursor_pos_set(cur, 6);
1438    evas_textblock_cursor_range_delete(cur, main_cur);
1439    fail_if(strcmp(evas_object_textblock_text_markup_get(tb),
1440             "ir.<ps/>Second par."));
1441    evas_textblock_cursor_paragraph_char_first(main_cur);
1442    evas_textblock_cursor_paragraph_char_last(cur);
1443    evas_textblock_cursor_char_next(cur);
1444    evas_textblock_cursor_range_delete(cur, main_cur);
1445    fail_if(strcmp(evas_object_textblock_text_markup_get(tb),
1446             "Second par."));
1447
1448    evas_object_textblock_text_markup_set(tb, buf);
1449    evas_textblock_cursor_paragraph_last(main_cur);
1450    evas_object_textblock_text_markup_prepend(main_cur, "Test<b>bla</b>bla.");
1451    evas_textblock_cursor_paragraph_last(cur);
1452    evas_textblock_cursor_paragraph_char_first(main_cur);
1453    evas_textblock_cursor_range_delete(cur, main_cur);
1454    fail_if(strcmp(evas_object_textblock_text_markup_get(tb),
1455             "First par.<ps/>"));
1456
1457    /* Merging paragraphs */
1458    evas_object_textblock_text_markup_set(tb, buf);
1459    evas_textblock_cursor_paragraph_char_last(cur);
1460    evas_textblock_cursor_copy(cur, main_cur);
1461    evas_textblock_cursor_char_delete(cur);
1462
1463    evas_textblock_cursor_paragraph_first(cur);
1464    fail_if(evas_textblock_cursor_paragraph_next(cur));
1465
1466    /* Split paragraphs */
1467    evas_textblock_cursor_format_prepend(cur, "ps");
1468
1469    evas_textblock_cursor_paragraph_first(cur);
1470    fail_if(!evas_textblock_cursor_paragraph_next(cur));
1471    fail_if(evas_textblock_cursor_paragraph_next(cur));
1472
1473    /* Merge paragraphs using range deletion */
1474    evas_object_textblock_text_markup_set(tb, buf);
1475    evas_textblock_cursor_paragraph_first(cur);
1476    evas_textblock_cursor_paragraph_char_last(cur);
1477    evas_textblock_cursor_copy(cur, main_cur);
1478    evas_textblock_cursor_char_prev(cur);
1479    evas_textblock_cursor_char_next(main_cur);
1480
1481    evas_textblock_cursor_range_delete(cur, main_cur);
1482    evas_textblock_cursor_paragraph_first(cur);
1483    fail_if(evas_textblock_cursor_paragraph_next(cur));
1484
1485    /* Insert illegal characters inside the format. */
1486      {
1487         const char *content;
1488         evas_object_textblock_text_markup_set(tb, "a\n");
1489         evas_textblock_cursor_pos_set(cur, 1);
1490         content = evas_textblock_cursor_content_get(cur);
1491
1492         evas_object_textblock_text_markup_set(tb, "a\t");
1493         evas_textblock_cursor_pos_set(cur, 1);
1494         content = evas_textblock_cursor_content_get(cur);
1495
1496         evas_object_textblock_text_markup_set(tb, "a\xEF\xBF\xBC");
1497         evas_textblock_cursor_pos_set(cur, 1);
1498         content = evas_textblock_cursor_content_get(cur);
1499
1500         evas_object_textblock_text_markup_set(tb, "a\xE2\x80\xA9");
1501         evas_textblock_cursor_pos_set(cur, 1);
1502         content = evas_textblock_cursor_content_get(cur);
1503         (void) content;
1504      }
1505
1506    /* FIXME: Also add text appending/prepending */
1507
1508    END_TB_TEST();
1509 }
1510 END_TEST
1511
1512 /* Text getters */
1513 START_TEST(evas_textblock_text_getters)
1514 {
1515    START_TB_TEST();
1516    const char *buf = "This is a <br/> test.<ps/>"
1517       "טקסט בעברית<ps/>and now in english.";
1518    evas_object_textblock_text_markup_set(tb, buf);
1519    evas_textblock_cursor_paragraph_first(cur);
1520
1521    fail_if(strcmp(evas_textblock_cursor_paragraph_text_get(cur),
1522             "This is a <br/> test."));
1523
1524    evas_textblock_cursor_paragraph_next(cur);
1525    fail_if(strcmp(evas_textblock_cursor_paragraph_text_get(cur),
1526             "טקסט בעברית"));
1527
1528    evas_textblock_cursor_paragraph_next(cur);
1529    fail_if(strcmp(evas_textblock_cursor_paragraph_text_get(cur),
1530             "and now in english."));
1531
1532    /* Range get */
1533    Evas_Textblock_Cursor *main_cur = evas_object_textblock_cursor_get(tb);
1534    evas_textblock_cursor_pos_set(main_cur, 2);
1535    evas_textblock_cursor_pos_set(cur, 2);
1536    fail_if(*evas_textblock_cursor_range_text_get(main_cur, cur,
1537             EVAS_TEXTBLOCK_TEXT_MARKUP));
1538
1539    evas_textblock_cursor_pos_set(main_cur, 2);
1540    evas_textblock_cursor_pos_set(cur, 6);
1541    fail_if(strcmp(evas_textblock_cursor_range_text_get(main_cur, cur,
1542             EVAS_TEXTBLOCK_TEXT_MARKUP), "is i"));
1543
1544    evas_textblock_cursor_pos_set(main_cur, 5);
1545    evas_textblock_cursor_pos_set(cur, 14);
1546    fail_if(strcmp(evas_textblock_cursor_range_text_get(main_cur, cur,
1547             EVAS_TEXTBLOCK_TEXT_MARKUP), "is a <br/> te"));
1548
1549    evas_textblock_cursor_pos_set(main_cur, 14);
1550    evas_textblock_cursor_pos_set(cur, 20);
1551    fail_if(strcmp(evas_textblock_cursor_range_text_get(main_cur, cur,
1552             EVAS_TEXTBLOCK_TEXT_MARKUP), "st.<ps/>טק"));
1553
1554    evas_textblock_cursor_pos_set(main_cur, 14);
1555    evas_textblock_cursor_pos_set(cur, 32);
1556    fail_if(strcmp(evas_textblock_cursor_range_text_get(main_cur, cur,
1557             EVAS_TEXTBLOCK_TEXT_MARKUP), "st.<ps/>טקסט בעברית<ps/>an"));
1558
1559    /* Backward range get */
1560    evas_textblock_cursor_pos_set(main_cur, 2);
1561    evas_textblock_cursor_pos_set(cur, 2);
1562    fail_if(*evas_textblock_cursor_range_text_get(cur, main_cur,
1563             EVAS_TEXTBLOCK_TEXT_MARKUP));
1564
1565    evas_textblock_cursor_pos_set(main_cur, 2);
1566    evas_textblock_cursor_pos_set(cur, 6);
1567    fail_if(strcmp(evas_textblock_cursor_range_text_get(cur, main_cur,
1568             EVAS_TEXTBLOCK_TEXT_MARKUP), "is i"));
1569
1570    evas_textblock_cursor_pos_set(main_cur, 5);
1571    evas_textblock_cursor_pos_set(cur, 14);
1572    fail_if(strcmp(evas_textblock_cursor_range_text_get(cur, main_cur,
1573             EVAS_TEXTBLOCK_TEXT_MARKUP), "is a <br/> te"));
1574
1575    evas_textblock_cursor_pos_set(main_cur, 14);
1576    evas_textblock_cursor_pos_set(cur, 20);
1577    fail_if(strcmp(evas_textblock_cursor_range_text_get(cur, main_cur,
1578             EVAS_TEXTBLOCK_TEXT_MARKUP), "st.<ps/>טק"));
1579
1580    evas_textblock_cursor_pos_set(main_cur, 14);
1581    evas_textblock_cursor_pos_set(cur, 32);
1582    fail_if(strcmp(evas_textblock_cursor_range_text_get(cur, main_cur,
1583             EVAS_TEXTBLOCK_TEXT_MARKUP), "st.<ps/>טקסט בעברית<ps/>an"));
1584
1585    /* Uninit cursors and other weird cases */
1586    evas_object_textblock_clear(tb);
1587    evas_textblock_cursor_copy(main_cur, cur);
1588    evas_textblock_cursor_text_prepend(main_cur, "aaa");
1589    fail_if(strcmp(evas_textblock_cursor_range_text_get(cur, main_cur,
1590             EVAS_TEXTBLOCK_TEXT_MARKUP), "aaa"));
1591
1592    /* Markup to plain and vice versa */
1593      {
1594         char *tmp, *tmp2;
1595
1596         /* Real textblock object */
1597         tmp = evas_textblock_text_markup_to_utf8(tb, "<br/>aa<\n/>bb<\t/>");
1598         fail_if(strcmp(tmp, "\naa\nbb\t"));
1599         tmp2 = evas_textblock_text_utf8_to_markup(tb, tmp);
1600         fail_if(strcmp(tmp2, "<br/>aa<br/>bb<tab/>"));
1601         free(tmp2);
1602         free(tmp);
1603
1604         tmp = evas_textblock_text_markup_to_utf8(tb, "a<item></item>");
1605         fail_if(strcmp(tmp, "a\xEF\xBF\xBC"));
1606         tmp2 = evas_textblock_text_utf8_to_markup(tb, tmp);
1607         fail_if(strcmp(tmp2, "a&#xfffc;"));
1608         free(tmp2);
1609         free(tmp);
1610
1611         tmp = evas_textblock_text_markup_to_utf8(tb, "a&nbsp;");
1612         fail_if(strcmp(tmp, "a\xC2\xA0"));
1613         tmp2 = evas_textblock_text_utf8_to_markup(tb, tmp);
1614         fail_if(strcmp(tmp2, "a\xC2\xA0"));
1615         free(tmp2);
1616         free(tmp);
1617
1618         tmp = evas_textblock_text_markup_to_utf8(tb, "a<b>b</b><more></>a");
1619         fail_if(strcmp(tmp, "aba"));
1620         tmp2 = evas_textblock_text_utf8_to_markup(tb, tmp);
1621         fail_if(strcmp(tmp2, "aba"));
1622         free(tmp2);
1623         free(tmp);
1624
1625         tmp = evas_textblock_text_markup_to_utf8(tb, "a&amp;a");
1626         fail_if(strcmp(tmp, "a&a"));
1627         tmp2 = evas_textblock_text_utf8_to_markup(tb, tmp);
1628         fail_if(strcmp(tmp2, "a&amp;a"));
1629         free(tmp2);
1630         free(tmp);
1631
1632         tmp = evas_textblock_text_markup_to_utf8(tb, "a<newline/>a");
1633         fail_if(strcmp(tmp, "a\na"));
1634         tmp2 = evas_textblock_text_utf8_to_markup(tb, tmp);
1635         fail_if(strcmp(tmp2, "a<br/>a"));
1636         free(tmp2);
1637         free(tmp);
1638
1639         /* NULL textblock object */
1640         tmp = evas_textblock_text_markup_to_utf8(NULL, "<br/>aa<\n/>bb<\t/>");
1641         fail_if(strcmp(tmp, "\naa\nbb\t"));
1642         tmp2 = evas_textblock_text_utf8_to_markup(NULL, tmp);
1643         fail_if(strcmp(tmp2, "<br/>aa<br/>bb<tab/>"));
1644         free(tmp2);
1645         free(tmp);
1646
1647         tmp = evas_textblock_text_markup_to_utf8(NULL, "a<item></item>");
1648         fail_if(strcmp(tmp, "a\xEF\xBF\xBC"));
1649         tmp2 = evas_textblock_text_utf8_to_markup(NULL, tmp);
1650         fail_if(strcmp(tmp2, "a&#xfffc;"));
1651         free(tmp2);
1652         free(tmp);
1653
1654         tmp = evas_textblock_text_markup_to_utf8(NULL, "a&nbsp;");
1655         fail_if(strcmp(tmp, "a\xC2\xA0"));
1656         tmp2 = evas_textblock_text_utf8_to_markup(NULL, tmp);
1657         fail_if(strcmp(tmp2, "a\xC2\xA0"));
1658         free(tmp2);
1659         free(tmp);
1660
1661         tmp = evas_textblock_text_markup_to_utf8(NULL, "a<b>b</b><more></>a");
1662         fail_if(strcmp(tmp, "aba"));
1663         tmp2 = evas_textblock_text_utf8_to_markup(NULL, tmp);
1664         fail_if(strcmp(tmp2, "aba"));
1665         free(tmp2);
1666         free(tmp);
1667
1668         tmp = evas_textblock_text_markup_to_utf8(tb, "a&amp;a");
1669         fail_if(strcmp(tmp, "a&a"));
1670         tmp2 = evas_textblock_text_utf8_to_markup(tb, tmp);
1671         fail_if(strcmp(tmp2, "a&amp;a"));
1672         free(tmp2);
1673         free(tmp);
1674
1675         tmp = evas_textblock_text_markup_to_utf8(NULL, "a<newline/>a");
1676         fail_if(strcmp(tmp, "aa"));
1677         tmp2 = evas_textblock_text_utf8_to_markup(NULL, tmp);
1678         fail_if(strcmp(tmp2, "aa"));
1679         free(tmp2);
1680         free(tmp);
1681      }
1682
1683    END_TB_TEST();
1684 }
1685 END_TEST
1686
1687 /* Formats */
1688 START_TEST(evas_textblock_formats)
1689 {
1690    START_TB_TEST();
1691    const char *buf = "Th<b>i<font_size=15 wrap=none>s i</font_size=13>s</> a <br/> te<ps/>st<item></>.";
1692    const Evas_Object_Textblock_Node_Format *fnode;
1693    evas_object_textblock_text_markup_set(tb, buf);
1694
1695    /* Walk from the start */
1696    fnode = evas_textblock_node_format_first_get(tb);
1697    fail_if(!fnode);
1698    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
1699
1700    fnode = evas_textblock_node_format_next_get(fnode);
1701    fail_if(!fnode);
1702    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
1703             "+ font_size=15 wrap=none"));
1704
1705    fnode = evas_textblock_node_format_next_get(fnode);
1706    fail_if(!fnode);
1707    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
1708             "- font_size=13"));
1709
1710    fnode = evas_textblock_node_format_next_get(fnode);
1711    fail_if(!fnode);
1712    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- "));
1713
1714    fnode = evas_textblock_node_format_next_get(fnode);
1715    fail_if(!fnode);
1716    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "br"));
1717
1718    fnode = evas_textblock_node_format_next_get(fnode);
1719    fail_if(!fnode);
1720    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "ps"));
1721
1722    fnode = evas_textblock_node_format_next_get(fnode);
1723    fail_if(!fnode);
1724    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ item"));
1725
1726    fnode = evas_textblock_node_format_next_get(fnode);
1727    fail_if(!fnode);
1728    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- "));
1729
1730    fnode = evas_textblock_node_format_next_get(fnode);
1731    fail_if(fnode);
1732
1733    /* Walk backwards */
1734    fnode = evas_textblock_node_format_last_get(tb);
1735    fail_if(!fnode);
1736    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- "));
1737
1738    fnode = evas_textblock_node_format_prev_get(fnode);
1739    fail_if(!fnode);
1740    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ item"));
1741
1742    fnode = evas_textblock_node_format_prev_get(fnode);
1743    fail_if(!fnode);
1744    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "ps"));
1745
1746    fnode = evas_textblock_node_format_prev_get(fnode);
1747    fail_if(!fnode);
1748    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "br"));
1749
1750    fnode = evas_textblock_node_format_prev_get(fnode);
1751    fail_if(!fnode);
1752    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- "));
1753
1754    fnode = evas_textblock_node_format_prev_get(fnode);
1755    fail_if(!fnode);
1756    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
1757             "- font_size=13"));
1758
1759    fnode = evas_textblock_node_format_prev_get(fnode);
1760    fail_if(!fnode);
1761    fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
1762             "+ font_size=15 wrap=none"));
1763
1764    fnode = evas_textblock_node_format_prev_get(fnode);
1765    fail_if(!fnode);
1766    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
1767
1768    fnode = evas_textblock_node_format_prev_get(fnode);
1769    fail_if(fnode);
1770
1771    /* Cursor and format detection */
1772    fnode = evas_textblock_node_format_first_get(tb);
1773    fail_if(!fnode);
1774    evas_textblock_cursor_at_format_set(cur, fnode);
1775    fail_if(evas_textblock_cursor_format_is_visible_get(cur));
1776
1777    fnode = evas_textblock_node_format_next_get(fnode);
1778    fail_if(!fnode);
1779    evas_textblock_cursor_at_format_set(cur, fnode);
1780    fail_if(evas_textblock_cursor_format_is_visible_get(cur));
1781
1782    fnode = evas_textblock_node_format_next_get(fnode);
1783    fail_if(!fnode);
1784    evas_textblock_cursor_at_format_set(cur, fnode);
1785    fail_if(evas_textblock_cursor_format_is_visible_get(cur));
1786
1787    fnode = evas_textblock_node_format_next_get(fnode);
1788    fail_if(!fnode);
1789    evas_textblock_cursor_at_format_set(cur, fnode);
1790    fail_if(evas_textblock_cursor_format_is_visible_get(cur));
1791
1792    fnode = evas_textblock_node_format_next_get(fnode);
1793    fail_if(!fnode);
1794    evas_textblock_cursor_at_format_set(cur, fnode);
1795    fail_if(!evas_textblock_cursor_format_is_visible_get(cur));
1796
1797    fnode = evas_textblock_node_format_next_get(fnode);
1798    fail_if(!fnode);
1799    evas_textblock_cursor_at_format_set(cur, fnode);
1800    fail_if(!evas_textblock_cursor_format_is_visible_get(cur));
1801
1802    size_t i = 0;
1803    evas_textblock_cursor_paragraph_first(cur);
1804    do
1805      {
1806         switch (i)
1807           {
1808            case 2:
1809            case 3:
1810            case 6:
1811            case 7:
1812            case 10:
1813            case 14:
1814            case 17:
1815            case 18:
1816               fail_if(!evas_textblock_cursor_is_format(cur));
1817               break;
1818            default:
1819               fail_if(evas_textblock_cursor_is_format(cur));
1820               fail_if(evas_textblock_cursor_format_is_visible_get(cur));
1821               break;
1822           }
1823         i++;
1824      }
1825    while (evas_textblock_cursor_char_next(cur));
1826
1827    /* Format text nodes invalidation */
1828      {
1829         Evas_Coord w, h, nw, nh;
1830         evas_object_textblock_text_markup_set(tb, "Test");
1831         evas_object_textblock_size_formatted_get(tb, &w, &h);
1832         evas_textblock_cursor_paragraph_first(cur);
1833         evas_textblock_cursor_format_prepend(cur, "+ font_size=40");
1834         evas_object_textblock_size_formatted_get(tb, &nw, &nh);
1835         fail_if((w >= nw) || (h >= nh));
1836      }
1837    /* FIXME: Should extend invalidation tests. */
1838
1839    /* Various formats, just verify there's no seg, we can't really
1840     * verify them visually, well, we can some of them. Possibly in the
1841     * future we will */
1842    evas_object_textblock_text_markup_set(tb,
1843          "<font_size=40>font_size=40</><ps/>"
1844          "<color=#F210B3FF>color=#F210B3FF</><ps/>"
1845          "<underline=single underline_color=#A2B3C4>underline=single underline_color=#A2B3C4</><ps/>"
1846          "<underline=double underline_color=#F00 underline2_color=#00F>underline=double underline_color=#F00 underline2_color=#00F</><ps/>"
1847          "<underline=dashed underline_dash_color=#0F0 underline_dash_width=2 underline_dash_gap=1>underline=dashed underline_dash_color=#0F0 underline_dash_width=2 underline_dash_gap=1</><ps/>"
1848          "<style=outline outline_color=#F0FA>style=outline outline_color=#F0FA</><ps/>"
1849          "<style=shadow shadow_color=#F0F>style=shadow shadow_color=#F0F</><ps/>"
1850          "<style=glow glow_color=#BBB>style=glow glow_color=#BBB</><ps/>"
1851          "<style=glow glow2_color=#0F0>style=glow glow2_color=#0F0</><ps/>"
1852          "<style=glow color=#fff glow2_color=#fe87 glow_color=#f214>style=glow color=#fff glow2_color=#fe87 glow_color=#f214</><ps/>"
1853          "<backing=on backing_color=#00F>backing=on backing_color=#00F</><ps/>"
1854          "<strikethrough=on strikethrough_color=#FF0>strikethrough=on strikethrough_color=#FF0</><ps/>"
1855          "<align=right>align=right</><ps/>"
1856          "<backing=on backing_color=#F008 valign=0.0>valign=0.0</><ps/>"
1857          "<backing=on backing_color=#0F08 tabstops=50>tabstops=<\\t></>50</><ps/>"
1858          "<backing=on backing_color=#00F8 linesize=40>linesize=40</><ps/>"
1859          "<backing=on backing_color=#F0F8 linerelsize=200%>linerelsize=200%</><ps/>"
1860          "<backing=on backing_color=#0FF8 linegap=20>linegap=20</><ps/>"
1861          "<backing=on backing_color=#FF08 linerelgap=100%>linerelgap=100%</><ps/>");
1862
1863    /* Force a relayout */
1864    evas_object_textblock_size_formatted_get(tb, NULL, NULL);
1865
1866    /* Removing paired formats. */
1867    evas_object_textblock_text_markup_set(tb, "<a>aa<b>bb</b>cc</a>");
1868    fnode = evas_textblock_node_format_first_get(tb);
1869    evas_textblock_node_format_remove_pair(tb, (Evas_Object_Textblock_Node_Format *) fnode);
1870    fnode = evas_textblock_node_format_first_get(tb);
1871    fail_if(!fnode);
1872    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
1873    fnode = evas_textblock_node_format_next_get(fnode);
1874    fail_if(!fnode);
1875    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- b"));
1876
1877    evas_object_textblock_text_markup_set(tb, "<a>aa<b>bb</b>cc</a>");
1878    fnode = evas_textblock_node_format_first_get(tb);
1879    fnode = evas_textblock_node_format_next_get(fnode);
1880    evas_textblock_node_format_remove_pair(tb, (Evas_Object_Textblock_Node_Format *) fnode);
1881    fnode = evas_textblock_node_format_first_get(tb);
1882    fail_if(!fnode);
1883    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ a"));
1884    fnode = evas_textblock_node_format_next_get(fnode);
1885    fail_if(!fnode);
1886    fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- a"));
1887
1888    /* Format list get */
1889    evas_object_textblock_text_markup_set(tb, "<a>a</>a<item>b</>"
1890          "b<item>b</>c<a>c</>");
1891    const Eina_List *flist = evas_textblock_node_format_list_get(tb, "a");
1892    const Eina_List *itr;
1893    EINA_LIST_FOREACH(flist, itr, fnode)
1894      {
1895         fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ a"));
1896      }
1897
1898    flist = evas_textblock_node_format_list_get(tb, "item");
1899    EINA_LIST_FOREACH(flist, itr, fnode)
1900      {
1901         fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ item"));
1902      }
1903
1904    /* Make sure we get all the types of visible formats correctly. */
1905    evas_object_textblock_text_markup_set(tb, "<ps/>a<br/>a<tab/>a<item></>");
1906    fail_if(strcmp(evas_textblock_node_format_text_get(
1907                evas_textblock_cursor_format_get(cur)), "ps"));
1908    fail_if(strcmp(evas_textblock_cursor_content_get(cur), "<ps/>"));
1909    fail_if(!evas_textblock_cursor_format_is_visible_get(cur));
1910    fail_if(!evas_textblock_cursor_char_next(cur));
1911    fail_if(!evas_textblock_cursor_char_next(cur));
1912    fail_if(strcmp(evas_textblock_node_format_text_get(
1913                evas_textblock_cursor_format_get(cur)), "br"));
1914    fail_if(strcmp(evas_textblock_cursor_content_get(cur), "<br/>"));
1915    fail_if(!evas_textblock_cursor_format_is_visible_get(cur));
1916    fail_if(!evas_textblock_cursor_char_next(cur));
1917    fail_if(!evas_textblock_cursor_char_next(cur));
1918    fail_if(strcmp(evas_textblock_node_format_text_get(
1919                evas_textblock_cursor_format_get(cur)), "tab"));
1920    fail_if(strcmp(evas_textblock_cursor_content_get(cur), "<tab/>"));
1921    fail_if(!evas_textblock_cursor_format_is_visible_get(cur));
1922    fail_if(!evas_textblock_cursor_char_next(cur));
1923    fail_if(!evas_textblock_cursor_char_next(cur));
1924    fail_if(strcmp(evas_textblock_node_format_text_get(
1925                evas_textblock_cursor_format_get(cur)), "+ item"));
1926    fail_if(strcmp(evas_textblock_cursor_content_get(cur), "<item>"));
1927    fail_if(!evas_textblock_cursor_format_is_visible_get(cur));
1928
1929    END_TB_TEST();
1930 }
1931 END_TEST
1932
1933 /* Different text styles, for example, shadow. */
1934 START_TEST(evas_textblock_style)
1935 {
1936    Evas_Coord w, h, nw, nh;
1937    Evas_Coord l, r, t, b;
1938    START_TB_TEST();
1939    Evas_Textblock_Style *newst;
1940    const char *buf = "Test<ps/>Test2<ps/>נסיון";
1941    evas_object_textblock_text_markup_set(tb, buf);
1942    fail_if(strcmp(evas_object_textblock_text_markup_get(tb), buf));
1943
1944    evas_object_textblock_size_formatted_get(tb, &w, &h);
1945    newst = evas_textblock_style_new();
1946    fail_if(!newst);
1947    evas_textblock_style_set(newst,
1948          "DEFAULT='font=Sans font_size=20 color=#000 text_class=entry'"
1949          "br='\n'"
1950          "ps='ps'"
1951          "tab='\t'");
1952    evas_object_textblock_style_set(tb, newst);
1953    evas_object_textblock_size_formatted_get(tb, &nw, &nh);
1954    fail_if((w >= nw) || (h >= nh));
1955
1956    /* Style padding. */
1957    evas_object_textblock_text_markup_set(tb, "Test");
1958    evas_object_textblock_style_insets_get(tb, &l, &r, &t, &b);
1959    fail_if((l != 0) || (r != 0) || (t != 0) || (b != 0));
1960
1961    evas_object_textblock_text_markup_set(tb, "<style=shadow>Test</>");
1962    evas_object_textblock_style_insets_get(tb, &l, &r, &t, &b);
1963    fail_if((l != 0) || (r != 1) || (t != 0) || (b != 1));
1964
1965    evas_object_textblock_text_markup_set(tb, "<style=outline>Test</>");
1966    evas_object_textblock_style_insets_get(tb, &l, &r, &t, &b);
1967    fail_if((l != 1) || (r != 1) || (t != 1) || (b != 1));
1968
1969    evas_object_textblock_text_markup_set(tb, "<style=soft_outline>Test</>");
1970    evas_object_textblock_style_insets_get(tb, &l, &r, &t, &b);
1971    fail_if((l != 2) || (r != 2) || (t != 2) || (b != 2));
1972
1973    evas_object_textblock_text_markup_set(tb, "<style=glow>Test</>");
1974    evas_object_textblock_style_insets_get(tb, &l, &r, &t, &b);
1975    fail_if((l != 2) || (r != 2) || (t != 2) || (b != 2));
1976
1977    evas_object_textblock_text_markup_set(tb, "<style=outline_shadow>Test</>");
1978    evas_object_textblock_style_insets_get(tb, &l, &r, &t, &b);
1979    fail_if((l != 1) || (r != 2) || (t != 1) || (b != 2));
1980
1981    evas_object_textblock_text_markup_set(tb, "<style=far_shadow>Test</>");
1982    evas_object_textblock_style_insets_get(tb, &l, &r, &t, &b);
1983    fail_if((l != 1) || (r != 2) || (t != 1) || (b != 2));
1984
1985    evas_object_textblock_text_markup_set(tb, "<style=outline_soft_shadow>Test</>");
1986    evas_object_textblock_style_insets_get(tb, &l, &r, &t, &b);
1987    fail_if((l != 1) || (r != 3) || (t != 1) || (b != 3));
1988
1989    evas_object_textblock_text_markup_set(tb, "<style=soft_shadow>Test</>");
1990    evas_object_textblock_style_insets_get(tb, &l, &r, &t, &b);
1991    fail_if((l != 1) || (r != 3) || (t != 1) || (b != 3));
1992
1993    evas_object_textblock_text_markup_set(tb, "<style=far_soft_shadow>Test</>");
1994    evas_object_textblock_style_insets_get(tb, &l, &r, &t, &b);
1995    fail_if((l != 0) || (r != 4) || (t != 0) || (b != 4));
1996
1997    /* Mixed style padding */
1998    evas_object_textblock_text_markup_set(tb,
1999          "<style=far_shadow>Test</><style=far_soft_shadow>Test</>");
2000    evas_object_textblock_style_insets_get(tb, &l, &r, &t, &b);
2001    fail_if((l != 1) || (r != 4) || (t != 1) || (b != 4));
2002
2003    END_TB_TEST();
2004 }
2005 END_TEST
2006
2007 /* Various setters and getters */
2008 START_TEST(evas_textblock_set_get)
2009 {
2010    START_TB_TEST();
2011    const char *buf = "";
2012    evas_object_textblock_text_markup_set(tb, buf);
2013    fail_if(strcmp(evas_textblock_style_get(st), style_buf));
2014    fail_if(evas_object_textblock_style_get(tb) != st);
2015    evas_object_textblock_replace_char_set(tb, "|");
2016    fail_if(strcmp(evas_object_textblock_replace_char_get(tb), "|"));
2017    evas_object_textblock_replace_char_set(tb, "ש");
2018    fail_if(strcmp(evas_object_textblock_replace_char_get(tb), "ש"));
2019
2020    evas_object_textblock_valign_set(tb, -1.0);
2021    fail_if(evas_object_textblock_valign_get(tb) != 0.0);
2022    evas_object_textblock_valign_set(tb, 0.0);
2023    fail_if(evas_object_textblock_valign_get(tb) != 0.0);
2024    evas_object_textblock_valign_set(tb, 0.432);
2025    fail_if(evas_object_textblock_valign_get(tb) != 0.432);
2026    evas_object_textblock_valign_set(tb, 1.0);
2027    fail_if(evas_object_textblock_valign_get(tb) != 1.0);
2028    evas_object_textblock_valign_set(tb, 1.5);
2029    fail_if(evas_object_textblock_valign_get(tb) != 1.0);
2030
2031    evas_object_textblock_bidi_delimiters_set(tb, ",.|");
2032    fail_if(strcmp(evas_object_textblock_bidi_delimiters_get(tb), ",.|"));
2033    evas_object_textblock_bidi_delimiters_set(tb, ",|");
2034    fail_if(strcmp(evas_object_textblock_bidi_delimiters_get(tb), ",|"));
2035    evas_object_textblock_bidi_delimiters_set(tb, NULL);
2036    fail_if(evas_object_textblock_bidi_delimiters_get(tb));
2037    evas_object_textblock_bidi_delimiters_set(tb, ",|");
2038    fail_if(strcmp(evas_object_textblock_bidi_delimiters_get(tb), ",|"));
2039
2040    /* Hinting */
2041    evas_object_textblock_text_markup_set(tb, "This is<ps/>a test<br/>bla");
2042    /* Force relayout */
2043    evas_object_textblock_size_formatted_get(tb, NULL, NULL);
2044    evas_font_hinting_set(evas, EVAS_FONT_HINTING_NONE);
2045    evas_font_hinting_set(evas, EVAS_FONT_HINTING_AUTO);
2046    evas_font_hinting_set(evas, EVAS_FONT_HINTING_BYTECODE);
2047    END_TB_TEST();
2048 }
2049 END_TEST
2050
2051 /* Aux evas stuff, such as scale. */
2052 START_TEST(evas_textblock_evas)
2053 {
2054    Evas_Coord w, h, sw, sh;
2055    START_TB_TEST();
2056    const char *buf = "Test";
2057    evas_object_textblock_text_markup_set(tb, buf);
2058    evas_object_textblock_size_formatted_get(tb, &w, &h);
2059    evas_object_scale_set(tb, 3.0);
2060    evas_object_textblock_size_formatted_get(tb, &sw, &sh);
2061    fail_if((sw <= w) || (sh <= h));
2062
2063    evas_object_scale_set(tb, 0.5);
2064    evas_object_textblock_size_formatted_get(tb, &sw, &sh);
2065    fail_if((sw >= w) || (sh >= h));
2066
2067    END_TB_TEST();
2068 }
2069 END_TEST
2070
2071 /* All the string escaping stuff */
2072 START_TEST(evas_textblock_escaping)
2073 {
2074    int len;
2075    START_TB_TEST();
2076    fail_if(strcmp(evas_textblock_escape_string_get("&amp;"), "&"));
2077    fail_if(strcmp(evas_textblock_string_escape_get("&", &len), "&amp;"));
2078    fail_if(len != 1);
2079
2080    fail_if(strcmp(evas_textblock_escape_string_get("&middot;"), "\xc2\xb7"));
2081    fail_if(strcmp(evas_textblock_string_escape_get("\xc2\xb7", &len),
2082             "&middot;"));
2083    fail_if(len != 2);
2084
2085    fail_if(strcmp(evas_textblock_escape_string_get("&#x1f459;"),
2086             "\xF0\x9F\x91\x99"));
2087    fail_if(strcmp(evas_textblock_escape_string_get("&#128089;"),
2088             "\xF0\x9F\x91\x99"));
2089
2090    fail_if(evas_textblock_escape_string_get("&middot;aa"));
2091    const char *tmp = "&middot;aa";
2092    fail_if(strcmp(evas_textblock_escape_string_range_get(tmp, tmp + 8),
2093             "\xc2\xb7"));
2094    fail_if(evas_textblock_escape_string_range_get(tmp, tmp + 9));
2095    fail_if(evas_textblock_escape_string_range_get(tmp, tmp + 7));
2096    fail_if(evas_textblock_escape_string_range_get(tmp, tmp + 5));
2097
2098    const char *buf = "This &middot; is";
2099    evas_object_textblock_text_markup_set(tb, buf);
2100    fail_if(strcmp(evas_object_textblock_text_markup_get(tb), buf));
2101
2102    buf = "This &nbsp; is";
2103    evas_object_textblock_text_markup_set(tb, buf);
2104    fail_if(strcmp(evas_object_textblock_text_markup_get(tb), buf));
2105
2106    END_TB_TEST();
2107 }
2108 END_TEST
2109
2110 START_TEST(evas_textblock_size)
2111 {
2112    START_TB_TEST();
2113    Evas_Coord w, h, h2, nw, nh;
2114    const char *buf = "This is a <br/> test.<br/>גם בעברית";
2115    /* When wrapping is off, native size should be the same as formatted
2116     * size */
2117
2118    evas_object_textblock_size_formatted_get(tb, &w, &h);
2119    evas_object_textblock_size_native_get(tb, &nw, &nh);
2120    fail_if((w != nw) || (h != nh));
2121    fail_if(w != 0);
2122
2123    evas_object_textblock_text_markup_set(tb, "a<br/>a");
2124    evas_object_textblock_size_formatted_get(tb, &w, &h2);
2125    evas_object_textblock_size_native_get(tb, &nw, &nh);
2126    fail_if((w != nw) || (h2 != nh));
2127
2128    /* Two lines == double the height */
2129    fail_if(h * 2 != h2);
2130
2131    evas_object_textblock_text_markup_set(tb, buf);
2132
2133    evas_object_textblock_size_formatted_get(tb, &w, &h);
2134    evas_object_textblock_size_native_get(tb, &nw, &nh);
2135    fail_if((w != nw) || (h != nh));
2136    fail_if(w <= 0);
2137
2138    /* This time with margins. */
2139      {
2140         Evas_Textblock_Style *newst;
2141         Evas_Coord oldw, oldh, oldnw, oldnh;
2142
2143         evas_object_textblock_text_markup_set(tb, buf);
2144         evas_object_textblock_size_formatted_get(tb, &oldw, &oldh);
2145         evas_object_textblock_size_native_get(tb, &oldnw, &oldnh);
2146
2147
2148         newst = evas_textblock_style_new();
2149         fail_if(!newst);
2150         evas_textblock_style_set(newst,
2151               "DEFAULT='left_margin=4 right_margin=4'");
2152         evas_object_textblock_style_user_push(tb, newst);
2153
2154         evas_object_textblock_size_formatted_get(tb, &w, &h);
2155         evas_object_textblock_size_native_get(tb, &nw, &nh);
2156
2157         fail_if((w != oldw + 8) || (h != oldh) ||
2158               (nw != oldnw + 8) || (nh != oldnh));
2159      }
2160
2161    /* FIXME: There is a lot more to be done. */
2162    END_TB_TEST();
2163 }
2164 END_TEST
2165
2166 void evas_test_textblock(TCase *tc)
2167 {
2168    tcase_add_test(tc, evas_textblock_simple);
2169    tcase_add_test(tc, evas_textblock_cursor);
2170    tcase_add_test(tc, evas_textblock_size);
2171    tcase_add_test(tc, evas_textblock_editing);
2172    tcase_add_test(tc, evas_textblock_style);
2173    tcase_add_test(tc, evas_textblock_evas);
2174    tcase_add_test(tc, evas_textblock_text_getters);
2175    tcase_add_test(tc, evas_textblock_formats);
2176    tcase_add_test(tc, evas_textblock_format_removal);
2177    tcase_add_test(tc, evas_textblock_escaping);
2178    tcase_add_test(tc, evas_textblock_set_get);
2179    tcase_add_test(tc, evas_textblock_geometries);
2180    tcase_add_test(tc, evas_textblock_various);
2181    tcase_add_test(tc, evas_textblock_wrapping);
2182    tcase_add_test(tc, evas_textblock_items);
2183 }
2184