9 #include "evas_suite.h"
12 #include "evas_tests_helpers.h"
14 /* Functions defined in evas_object_textblock.c */
16 _evas_textblock_check_item_node_link(Evas_Object *obj);
18 _evas_textblock_format_offset_get(const Evas_Object_Textblock_Node_Format *n);
19 /* end of functions defined in evas_object_textblock.c */
22 static const char *style_buf =
23 "DEFAULT='font=Sans font_size=10 color=#000 text_class=entry'"
25 "b='+ font=Sans:style=bold'";
27 #define START_TB_TEST() \
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); \
36 evas_object_textblock_legacy_newline_set(tb, EINA_FALSE); \
37 st = evas_textblock_style_new(); \
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); \
48 #define END_TB_TEST() \
51 evas_textblock_cursor_free(cur); \
52 evas_object_del(tb); \
53 evas_textblock_style_free(st); \
59 START_TEST(evas_textblock_simple)
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));
69 #define _CHECK_CURSOR_COORDS() \
72 Evas_Coord cx, cy, cw, ch; \
74 ret = evas_textblock_cursor_geometry_get(cur, &cx, &cy, &cw, &ch, \
75 NULL, EVAS_TEXTBLOCK_CURSOR_UNDER); \
77 ret = evas_textblock_cursor_geometry_get(cur, &cx, &cy, &cw, &ch, \
78 NULL, EVAS_TEXTBLOCK_CURSOR_BEFORE); \
80 ret = evas_textblock_cursor_char_geometry_get(cur, \
81 &cx, &cy, &cw, &ch); \
83 ret = evas_textblock_cursor_pen_geometry_get(cur, &cx, &cy, &cw, &ch); \
85 ret = evas_textblock_cursor_line_geometry_get(cur, \
86 &cx, &cy, &cw, &ch); \
90 START_TEST(evas_textblock_cursor)
93 Evas_Coord x, y, w, h;
96 const char *buf = "This is a<br/> test.<ps/>Lets see if this works.<ps/>עוד פסקה.";
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++)
104 _CHECK_CURSOR_COORDS();
106 fail_if(evas_textblock_cursor_pos_get(cur) != (int) i);
108 fail_if(!evas_textblock_cursor_char_next(cur) && (i < len - 1));
110 fail_if(evas_textblock_cursor_char_next(cur));
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);
116 evas_textblock_cursor_pos_set(cur, len + 5);
117 fail_if(evas_textblock_cursor_pos_get(cur) != (int) len);
119 for (i = 0 ; i < len ; i++)
121 evas_textblock_cursor_pos_set(cur, i);
123 _CHECK_CURSOR_COORDS();
125 fail_if(evas_textblock_cursor_pos_get(cur) != (int) i);
128 /* Create another cursor and insert text, making sure everything
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));
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));
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));
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));
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));
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);
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);
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);
178 /* Paragraph first */
179 evas_object_textblock_text_markup_set(tb, buf);
180 for (i = 0 ; i < len ; i++)
182 evas_textblock_cursor_pos_set(cur, i);
184 evas_textblock_cursor_paragraph_first(cur);
185 fail_if(evas_textblock_cursor_pos_get(cur) != 0);
189 for (i = 0 ; i < len ; i++)
191 evas_textblock_cursor_pos_set(cur, i);
193 evas_textblock_cursor_paragraph_last(cur);
194 fail_if(evas_textblock_cursor_pos_get(cur) != (int) len);
198 evas_textblock_cursor_paragraph_last(cur);
199 fail_if(evas_textblock_cursor_paragraph_next(cur));
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));
206 evas_textblock_cursor_paragraph_first(cur);
207 fail_if(evas_textblock_cursor_paragraph_prev(cur));
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));
214 evas_textblock_cursor_paragraph_last(cur);
215 fail_if(evas_textblock_cursor_char_next(cur));
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));
225 evas_textblock_cursor_paragraph_first(cur);
226 fail_if(evas_textblock_cursor_char_prev(cur));
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));
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));
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));
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));
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);
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));
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);
270 evas_textblock_cursor_paragraph_first(main_cur);
271 evas_textblock_cursor_paragraph_last(cur);
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));
279 fail_if(evas_textblock_cursor_line_set(cur, -1));
280 fail_if(evas_textblock_cursor_line_set(cur, 99));
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),
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("עוד פסקה."));
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), "ד"));
314 for (i = 0 ; i < len ; i++)
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);
320 if (!evas_textblock_cursor_compare(cur, main_cur))
322 fail_if(!evas_textblock_cursor_eol_get(cur));
326 fail_if(evas_textblock_cursor_eol_get(cur));
330 /* Format positions */
331 const Evas_Object_Textblock_Node_Format *fnode;
332 fnode = evas_textblock_node_format_first_get(tb);
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);
339 fnode = evas_textblock_node_format_next_get(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));
347 fnode = evas_textblock_node_format_prev_get(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));
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));
360 evas_object_textblock_text_markup_set(tb, buf);
362 /* Check that pen geometry and getting char at coord are in sync. */
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))
372 evas_textblock_cursor_char_prev(cur);
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));
379 while (evas_textblock_cursor_char_next(cur));
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,
388 evas_textblock_cursor_paragraph_first(main_cur);
389 fail_if(evas_textblock_cursor_compare(cur, main_cur));
391 evas_textblock_cursor_pos_set(cur, 5);
392 evas_textblock_cursor_char_coord_set(cur, nw / 2,
394 evas_textblock_cursor_paragraph_last(main_cur);
395 fail_if(evas_textblock_cursor_compare(cur, main_cur));
397 /* Try positions beyond the left/right limits of lines. */
398 for (i = 0 ; i < 2 ; i++)
400 evas_textblock_cursor_line_set(cur, i);
401 evas_textblock_cursor_line_geometry_get(cur, &x, &y, &w, &h);
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));
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));
414 evas_object_textblock_text_markup_set(tb,
415 "testנסיוןtestנסיון<ps/>"
416 "נסיוןtestנסיוןtest<ps/>"
418 "נסיוןtestנסיון<ps/>"
419 "testנסיון<br/>נסיון<ps/>"
423 for (i = 0 ; i < 8 ; i++)
425 evas_textblock_cursor_line_set(cur, i);
426 evas_textblock_cursor_line_geometry_get(cur, &x, &y, &w, &h);
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));
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));
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));
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));
462 evas_object_textblock_text_markup_set(tb, buf);
463 /* Testing line geometry.*/
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);
472 while (evas_textblock_cursor_compare(cur, main_cur) <= 0)
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));
485 evas_textblock_cursor_char_next(cur);
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);
493 while (evas_textblock_cursor_compare(cur, main_cur) <= 0)
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));
506 evas_textblock_cursor_char_next(cur);
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,
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)));
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,
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)));
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));
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);
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);
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));
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));
546 /* Fail if they are equal, i.e if it for some reason thinks it should
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));
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));
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));
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));
570 const char *buf_wb = "a This is_a t:e.s't a";
571 evas_object_textblock_text_markup_set(tb, buf_wb);
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));
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));
599 START_TEST(evas_textblock_format_removal)
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);
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);
613 fnode = evas_textblock_node_format_first_get(tb);
615 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
618 fnode = evas_textblock_node_format_next_get(fnode);
620 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
623 fnode = evas_textblock_node_format_next_get(fnode);
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);
633 /* Remove the "a" pair. */
634 evas_object_textblock_text_markup_set(tb, buf);
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);
641 fnode = evas_textblock_node_format_first_get(tb);
643 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
646 fnode = evas_textblock_node_format_next_get(fnode);
648 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
651 fnode = evas_textblock_node_format_next_get(fnode);
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);
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);
670 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
673 fnode = evas_textblock_node_format_next_get(fnode);
675 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
678 fnode = evas_textblock_node_format_next_get(fnode);
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);
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);
701 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
704 fnode = evas_textblock_node_format_next_get(fnode);
706 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
709 fnode = evas_textblock_node_format_next_get(fnode);
711 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
714 fnode = evas_textblock_node_format_next_get(fnode);
716 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
719 fnode = evas_textblock_node_format_next_get(fnode);
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);
729 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
732 fnode = evas_textblock_node_format_next_get(fnode);
734 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
737 fnode = evas_textblock_node_format_next_get(fnode);
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);
748 /* Range deletion across paragraphs */
749 evas_object_textblock_text_markup_set(tb,
750 "Th<b>is a<a>te<ps/>"
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);
757 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
760 fnode = evas_textblock_node_format_next_get(fnode);
762 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
765 fnode = evas_textblock_node_format_next_get(fnode);
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/>"
779 "Also you can stick in items with (relsize + ascent): "
780 "<item relsize=16x16 vsize=ascent href=emoticon/evil-laugh></item>"
782 "<item relsize=16x16 vsize=full href=emoticon/guilty-smile></item>"
783 " (to the left)<ps/>"
785 "Also (size + ascent): "
786 "<item size=16x16 vsize=ascent href=emoticon/haha></item>"
788 "<item size=16x16 vsize=full href=emoticon/happy-panting></item>"
789 " (before this)<ps/>"
791 "And as well (absize + ascent): "
792 "<item absize=64x64 vsize=ascent href=emoticon/knowing-grin></item>"
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>"
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);
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);
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);
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);
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);
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);
838 for (i = 0 ; i < 2 ; i++)
840 fnode = evas_textblock_node_format_first_get(tb);
842 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
844 fnode = evas_textblock_node_format_next_get(fnode);
846 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ i"));
848 fnode = evas_textblock_node_format_next_get(fnode);
850 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- b"));
852 fnode = evas_textblock_node_format_next_get(fnode);
854 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- i"));
856 fnode = evas_textblock_node_format_next_get(fnode);
859 evas_textblock_cursor_char_delete(cur);
861 fnode = evas_textblock_node_format_first_get(tb);
863 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
865 fnode = evas_textblock_node_format_next_get(fnode);
867 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- b"));
869 fnode = evas_textblock_node_format_next_get(fnode);
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);
876 for (i = 0 ; i < 2 ; i++)
878 fnode = evas_textblock_node_format_first_get(tb);
880 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
882 fnode = evas_textblock_node_format_next_get(fnode);
884 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ i"));
886 fnode = evas_textblock_node_format_next_get(fnode);
888 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- b"));
890 fnode = evas_textblock_node_format_next_get(fnode);
892 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- "));
894 fnode = evas_textblock_node_format_next_get(fnode);
897 evas_textblock_cursor_char_delete(cur);
899 fnode = evas_textblock_node_format_first_get(tb);
901 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
903 fnode = evas_textblock_node_format_next_get(fnode);
905 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- b"));
907 fnode = evas_textblock_node_format_next_get(fnode);
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);
917 fnode = evas_textblock_node_format_first_get(tb);
919 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ i"));
921 fnode = evas_textblock_node_format_next_get(fnode);
923 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- i"));
925 fnode = evas_textblock_node_format_next_get(fnode);
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);
936 fnode = evas_textblock_node_format_first_get(tb);
938 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
940 fnode = evas_textblock_node_format_next_get(fnode);
942 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- i"));
944 fnode = evas_textblock_node_format_next_get(fnode);
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);
952 fnode = evas_textblock_node_format_first_get(tb);
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);
962 fnode = evas_textblock_node_format_first_get(tb);
964 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ i"));
966 fnode = evas_textblock_node_format_next_get(fnode);
968 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- "));
970 fnode = evas_textblock_node_format_next_get(fnode);
972 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- i"));
974 fnode = evas_textblock_node_format_next_get(fnode);
982 START_TEST(evas_textblock_items)
984 Evas_Coord w, h, w2, h2, nw, nh, ih;
986 const char *buf = "This is an <item absize=93x152></>.";
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));
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));
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));
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));
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)));
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)));
1042 evas_object_scale_set(tb, 1.0);
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));
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));
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));
1077 /* FIXME: Also verify x,y positions of the item. */
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. */
1090 /* Wrapping tests */
1091 START_TEST(evas_textblock_wrapping)
1093 Evas_Coord bw, bh, w, h, nw, nh;
1096 evas_object_textblock_text_markup_set(tb, "a");
1097 evas_object_textblock_size_formatted_get(tb, &bw, &bh);
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 */
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 */
1117 /* Basic Word wrap */
1118 evas_object_textblock_text_markup_set(tb, "aaaa");
1119 evas_object_textblock_size_formatted_get(tb, &bw, &bh);
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 */
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 */
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));
1148 /* Reduce size until reaching the minimum, making sure we don't
1149 * get something wrong along the way */
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/>"
1159 evas_textblock_cursor_format_prepend(cur, "+ wrap=char");
1160 evas_object_textblock_size_native_get(tb, &nw, &nh);
1163 for (iw = nw ; iw >= bw ; iw--)
1165 evas_object_resize(tb, iw, 1000);
1166 evas_object_textblock_size_formatted_get(tb, &w, &h);
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/>"
1181 evas_textblock_cursor_format_prepend(cur, "+ wrap=word");
1182 evas_object_textblock_size_native_get(tb, &nw, &nh);
1184 for (iw = nw ; iw >= bw ; iw--)
1186 evas_object_resize(tb, iw, 1000);
1187 evas_object_textblock_size_formatted_get(tb, &w, &h);
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/>"
1202 evas_textblock_cursor_format_prepend(cur, "+ wrap=mixed");
1203 evas_object_textblock_size_native_get(tb, &nw, &nh);
1205 for (iw = nw ; iw >= bw ; iw--)
1207 evas_object_resize(tb, iw, 1000);
1208 evas_object_textblock_size_formatted_get(tb, &w, &h);
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);
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/>"
1228 "Also you can stick in items with (relsize + ascent): "
1229 "<item relsize=16x16 vsize=ascent href=emoticon/evil-laugh></item>"
1231 "<item relsize=16x16 vsize=full href=emoticon/guilty-smile></item>"
1232 " (to the left)<br/>"
1234 "Also (size + ascent): "
1235 "<item size=16x16 vsize=ascent href=emoticon/haha></item>"
1237 "<item size=16x16 vsize=full href=emoticon/happy-panting></item>"
1238 " (before this)<br/>"
1240 "And as well (absize + ascent): "
1241 "<item absize=64x64 vsize=ascent href=emoticon/knowing-grin></item>"
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>"
1249 /* Get minimum size */
1250 evas_object_textblock_size_native_get(tb, &nw, &nh);
1252 for (i = 0 ; i < wrap_items ; i++)
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);
1258 for (iw = nw ; iw >= bw ; iw--)
1260 evas_object_resize(tb, iw, 1000);
1261 evas_object_textblock_size_formatted_get(tb, &w, &h);
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));
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));
1288 /* Various textblock stuff */
1289 START_TEST(evas_textblock_various)
1291 Evas_Coord w, h, bw, bh;
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));
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));
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));
1322 /* These shouldn't crash (although the desired outcome is not yet defined) */
1323 evas_object_textblock_text_markup_set(tb, "");
1324 evas_textblock_cursor_pos_set(cur, 0);
1325 evas_textblock_cursor_char_delete(cur);
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);
1335 /* Various geometries. e.g. range geometry. */
1336 START_TEST(evas_textblock_geometries)
1339 const char *buf = "This is a <br/> test.";
1340 evas_object_textblock_text_markup_set(tb, buf);
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);
1347 Eina_List *rects, *rects2;
1348 Evas_Textblock_Rectangle *tr, *tr2;
1349 rects = evas_textblock_cursor_range_geometry_get(cur, main_cur);
1351 rects2 = evas_textblock_cursor_range_geometry_get(main_cur, cur);
1354 fail_if(eina_list_count(rects) != 1);
1355 fail_if(eina_list_count(rects2) != 1);
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));
1362 fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
1365 /* Multiline range */
1366 evas_textblock_cursor_pos_set(cur, 0);
1367 evas_textblock_cursor_pos_set(main_cur, 14);
1369 rects = evas_textblock_cursor_range_geometry_get(cur, main_cur);
1371 rects2 = evas_textblock_cursor_range_geometry_get(main_cur, cur);
1374 fail_if(eina_list_count(rects) != 2);
1375 fail_if(eina_list_count(rects2) != 2);
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));
1382 fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
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));
1390 fail_if((tr->x != tr2->x) || (tr->y != tr2->y) || (tr->w != tr2->w) ||
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);
1402 /* Should handle all the text editing. */
1403 START_TEST(evas_textblock_editing)
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);
1410 /* Check deletion works */
1411 /* Try deleting after the end of the textblock */
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)));
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."));
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."));
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),
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/>"));
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);
1463 evas_textblock_cursor_paragraph_first(cur);
1464 fail_if(evas_textblock_cursor_paragraph_next(cur));
1466 /* Split paragraphs */
1467 evas_textblock_cursor_format_prepend(cur, "ps");
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));
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);
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));
1485 /* Insert illegal characters inside the format. */
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);
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);
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);
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);
1506 /* FIXME: Also add text appending/prepending */
1513 START_TEST(evas_textblock_text_getters)
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);
1521 fail_if(strcmp(evas_textblock_cursor_paragraph_text_get(cur),
1522 "This is a <br/> test."));
1524 evas_textblock_cursor_paragraph_next(cur);
1525 fail_if(strcmp(evas_textblock_cursor_paragraph_text_get(cur),
1528 evas_textblock_cursor_paragraph_next(cur);
1529 fail_if(strcmp(evas_textblock_cursor_paragraph_text_get(cur),
1530 "and now in english."));
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));
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"));
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"));
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/>טק"));
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"));
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));
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"));
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"));
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/>טק"));
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"));
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"));
1592 /* Markup to plain and vice versa */
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/>"));
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"));
1611 tmp = evas_textblock_text_markup_to_utf8(tb, "a ");
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"));
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"));
1625 tmp = evas_textblock_text_markup_to_utf8(tb, "a&a");
1626 fail_if(strcmp(tmp, "a&a"));
1627 tmp2 = evas_textblock_text_utf8_to_markup(tb, tmp);
1628 fail_if(strcmp(tmp2, "a&a"));
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"));
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/>"));
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"));
1654 tmp = evas_textblock_text_markup_to_utf8(NULL, "a ");
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"));
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"));
1668 tmp = evas_textblock_text_markup_to_utf8(tb, "a&a");
1669 fail_if(strcmp(tmp, "a&a"));
1670 tmp2 = evas_textblock_text_utf8_to_markup(tb, tmp);
1671 fail_if(strcmp(tmp2, "a&a"));
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"));
1688 START_TEST(evas_textblock_formats)
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);
1695 /* Walk from the start */
1696 fnode = evas_textblock_node_format_first_get(tb);
1698 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
1700 fnode = evas_textblock_node_format_next_get(fnode);
1702 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
1703 "+ font_size=15 wrap=none"));
1705 fnode = evas_textblock_node_format_next_get(fnode);
1707 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
1710 fnode = evas_textblock_node_format_next_get(fnode);
1712 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- "));
1714 fnode = evas_textblock_node_format_next_get(fnode);
1716 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "br"));
1718 fnode = evas_textblock_node_format_next_get(fnode);
1720 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "ps"));
1722 fnode = evas_textblock_node_format_next_get(fnode);
1724 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ item"));
1726 fnode = evas_textblock_node_format_next_get(fnode);
1728 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- "));
1730 fnode = evas_textblock_node_format_next_get(fnode);
1733 /* Walk backwards */
1734 fnode = evas_textblock_node_format_last_get(tb);
1736 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- "));
1738 fnode = evas_textblock_node_format_prev_get(fnode);
1740 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ item"));
1742 fnode = evas_textblock_node_format_prev_get(fnode);
1744 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "ps"));
1746 fnode = evas_textblock_node_format_prev_get(fnode);
1748 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "br"));
1750 fnode = evas_textblock_node_format_prev_get(fnode);
1752 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- "));
1754 fnode = evas_textblock_node_format_prev_get(fnode);
1756 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
1759 fnode = evas_textblock_node_format_prev_get(fnode);
1761 fail_if(strcmp(evas_textblock_node_format_text_get(fnode),
1762 "+ font_size=15 wrap=none"));
1764 fnode = evas_textblock_node_format_prev_get(fnode);
1766 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
1768 fnode = evas_textblock_node_format_prev_get(fnode);
1771 /* Cursor and format detection */
1772 fnode = evas_textblock_node_format_first_get(tb);
1774 evas_textblock_cursor_at_format_set(cur, fnode);
1775 fail_if(evas_textblock_cursor_format_is_visible_get(cur));
1777 fnode = evas_textblock_node_format_next_get(fnode);
1779 evas_textblock_cursor_at_format_set(cur, fnode);
1780 fail_if(evas_textblock_cursor_format_is_visible_get(cur));
1782 fnode = evas_textblock_node_format_next_get(fnode);
1784 evas_textblock_cursor_at_format_set(cur, fnode);
1785 fail_if(evas_textblock_cursor_format_is_visible_get(cur));
1787 fnode = evas_textblock_node_format_next_get(fnode);
1789 evas_textblock_cursor_at_format_set(cur, fnode);
1790 fail_if(evas_textblock_cursor_format_is_visible_get(cur));
1792 fnode = evas_textblock_node_format_next_get(fnode);
1794 evas_textblock_cursor_at_format_set(cur, fnode);
1795 fail_if(!evas_textblock_cursor_format_is_visible_get(cur));
1797 fnode = evas_textblock_node_format_next_get(fnode);
1799 evas_textblock_cursor_at_format_set(cur, fnode);
1800 fail_if(!evas_textblock_cursor_format_is_visible_get(cur));
1803 evas_textblock_cursor_paragraph_first(cur);
1816 fail_if(!evas_textblock_cursor_is_format(cur));
1819 fail_if(evas_textblock_cursor_is_format(cur));
1820 fail_if(evas_textblock_cursor_format_is_visible_get(cur));
1825 while (evas_textblock_cursor_char_next(cur));
1827 /* Format text nodes invalidation */
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));
1837 /* FIXME: Should extend invalidation tests. */
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
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/>");
1863 /* Force a relayout */
1864 evas_object_textblock_size_formatted_get(tb, NULL, NULL);
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);
1872 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ b"));
1873 fnode = evas_textblock_node_format_next_get(fnode);
1875 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- b"));
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);
1883 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ a"));
1884 fnode = evas_textblock_node_format_next_get(fnode);
1886 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "- a"));
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)
1895 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ a"));
1898 flist = evas_textblock_node_format_list_get(tb, "item");
1899 EINA_LIST_FOREACH(flist, itr, fnode)
1901 fail_if(strcmp(evas_textblock_node_format_text_get(fnode), "+ item"));
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));
1933 /* Different text styles, for example, shadow. */
1934 START_TEST(evas_textblock_style)
1936 Evas_Coord w, h, nw, nh;
1937 Evas_Coord l, r, t, b;
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));
1944 evas_object_textblock_size_formatted_get(tb, &w, &h);
1945 newst = evas_textblock_style_new();
1947 evas_textblock_style_set(newst,
1948 "DEFAULT='font=Sans font_size=20 color=#000 text_class=entry'"
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
2007 /* Various setters and getters */
2008 START_TEST(evas_textblock_set_get)
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), "ש"));
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);
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), ",|"));
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);
2051 /* Aux evas stuff, such as scale. */
2052 START_TEST(evas_textblock_evas)
2054 Evas_Coord w, h, sw, sh;
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));
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));
2071 /* All the string escaping stuff */
2072 START_TEST(evas_textblock_escaping)
2076 fail_if(strcmp(evas_textblock_escape_string_get("&"), "&"));
2077 fail_if(strcmp(evas_textblock_string_escape_get("&", &len), "&"));
2080 fail_if(strcmp(evas_textblock_escape_string_get("·"), "\xc2\xb7"));
2081 fail_if(strcmp(evas_textblock_string_escape_get("\xc2\xb7", &len),
2085 fail_if(strcmp(evas_textblock_escape_string_get("👙"),
2086 "\xF0\x9F\x91\x99"));
2087 fail_if(strcmp(evas_textblock_escape_string_get("👙"),
2088 "\xF0\x9F\x91\x99"));
2090 fail_if(evas_textblock_escape_string_get("·aa"));
2091 const char *tmp = "·aa";
2092 fail_if(strcmp(evas_textblock_escape_string_range_get(tmp, tmp + 8),
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));
2098 const char *buf = "This · is";
2099 evas_object_textblock_text_markup_set(tb, buf);
2100 fail_if(strcmp(evas_object_textblock_text_markup_get(tb), buf));
2102 buf = "This is";
2103 evas_object_textblock_text_markup_set(tb, buf);
2104 fail_if(strcmp(evas_object_textblock_text_markup_get(tb), buf));
2110 START_TEST(evas_textblock_size)
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
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));
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));
2128 /* Two lines == double the height */
2129 fail_if(h * 2 != h2);
2131 evas_object_textblock_text_markup_set(tb, buf);
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));
2138 /* This time with margins. */
2140 Evas_Textblock_Style *newst;
2141 Evas_Coord oldw, oldh, oldnw, oldnh;
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);
2148 newst = evas_textblock_style_new();
2150 evas_textblock_style_set(newst,
2151 "DEFAULT='left_margin=4 right_margin=4'");
2152 evas_object_textblock_style_user_push(tb, newst);
2154 evas_object_textblock_size_formatted_get(tb, &w, &h);
2155 evas_object_textblock_size_native_get(tb, &nw, &nh);
2157 fail_if((w != oldw + 8) || (h != oldh) ||
2158 (nw != oldnw + 8) || (nh != oldnh));
2161 /* FIXME: There is a lot more to be done. */
2166 void evas_test_textblock(TCase *tc)
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);