1/* Pango
2 * testattributes.c: Test pango attributes
3 *
4 * Copyright (C) 2015 Red Hat, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22#include <pango/pango.h>
23
24static void
25test_copy (PangoAttribute *attr)
26{
27 PangoAttribute *a;
28
29 a = pango_attribute_copy (attr);
30 g_assert_true (pango_attribute_equal (attr, a));
31 pango_attribute_destroy (attr: a);
32 pango_attribute_destroy (attr);
33}
34
35static void
36test_attributes_basic (void)
37{
38 PangoFontDescription *desc;
39 PangoRectangle rect = { 0, 0, 10, 10 };
40
41 test_copy (attr: pango_attr_language_new (language: pango_language_from_string (language: "ja-JP")));
42 test_copy (attr: pango_attr_family_new (family: "Times"));
43 test_copy (attr: pango_attr_foreground_new (red: 100, green: 200, blue: 300));
44 test_copy (attr: pango_attr_background_new (red: 100, green: 200, blue: 300));
45 test_copy (attr: pango_attr_size_new (size: 1024));
46 test_copy (attr: pango_attr_size_new_absolute (size: 1024));
47 test_copy (attr: pango_attr_style_new (style: PANGO_STYLE_ITALIC));
48 test_copy (attr: pango_attr_weight_new (weight: PANGO_WEIGHT_ULTRALIGHT));
49 test_copy (attr: pango_attr_variant_new (variant: PANGO_VARIANT_SMALL_CAPS));
50 test_copy (attr: pango_attr_stretch_new (stretch: PANGO_STRETCH_SEMI_EXPANDED));
51 desc = pango_font_description_from_string (str: "Computer Modern 12");
52 test_copy (attr: pango_attr_font_desc_new (desc));
53 pango_font_description_free (desc);
54 test_copy (attr: pango_attr_underline_new (underline: PANGO_UNDERLINE_LOW));
55 test_copy (attr: pango_attr_underline_new (underline: PANGO_UNDERLINE_ERROR_LINE));
56 test_copy (attr: pango_attr_underline_color_new (red: 100, green: 200, blue: 300));
57 test_copy (attr: pango_attr_overline_new (overline: PANGO_OVERLINE_SINGLE));
58 test_copy (attr: pango_attr_overline_color_new (red: 100, green: 200, blue: 300));
59 test_copy (attr: pango_attr_strikethrough_new (TRUE));
60 test_copy (attr: pango_attr_strikethrough_color_new (red: 100, green: 200, blue: 300));
61 test_copy (attr: pango_attr_rise_new (rise: 256));
62 test_copy (attr: pango_attr_scale_new (scale_factor: 2.56));
63 test_copy (attr: pango_attr_fallback_new (FALSE));
64 test_copy (attr: pango_attr_letter_spacing_new (letter_spacing: 1024));
65 test_copy (attr: pango_attr_shape_new (ink_rect: &rect, logical_rect: &rect));
66 test_copy (attr: pango_attr_gravity_new (gravity: PANGO_GRAVITY_SOUTH));
67 test_copy (attr: pango_attr_gravity_hint_new (hint: PANGO_GRAVITY_HINT_STRONG));
68 test_copy (attr: pango_attr_font_features_new (features: "csc=1"));
69 test_copy (attr: pango_attr_foreground_alpha_new (alpha: 8000));
70 test_copy (attr: pango_attr_background_alpha_new (alpha: 8000));
71 test_copy (attr: pango_attr_allow_breaks_new (FALSE));
72 test_copy (attr: pango_attr_show_new (flags: PANGO_SHOW_SPACES));
73 test_copy (attr: pango_attr_insert_hyphens_new (FALSE));
74 test_copy (attr: pango_attr_text_transform_new (transform: PANGO_TEXT_TRANSFORM_UPPERCASE));
75 test_copy (attr: pango_attr_line_height_new (factor: 1.5));
76 test_copy (attr: pango_attr_line_height_new_absolute (height: 3000));
77 test_copy (attr: pango_attr_word_new ());
78 test_copy (attr: pango_attr_sentence_new ());
79}
80
81static void
82test_attributes_equal (void)
83{
84 PangoAttribute *attr1, *attr2, *attr3;
85
86 /* check that pango_attribute_equal compares values, but not ranges */
87 attr1 = pango_attr_size_new (size: 10);
88 attr2 = pango_attr_size_new (size: 20);
89 attr3 = pango_attr_size_new (size: 20);
90 attr3->start_index = 1;
91 attr3->end_index = 2;
92
93 g_assert_true (!pango_attribute_equal (attr1, attr2));
94 g_assert_true (pango_attribute_equal (attr2, attr3));
95
96 pango_attribute_destroy (attr: attr1);
97 pango_attribute_destroy (attr: attr2);
98 pango_attribute_destroy (attr: attr3);
99}
100
101static void
102test_attributes_register (void)
103{
104 PangoAttrType type;
105 GEnumClass *class;
106
107 type = pango_attr_type_register (name: "my-attribute");
108 g_assert_cmpstr (pango_attr_type_get_name (type), ==, "my-attribute");
109
110 class = g_type_class_ref (type: PANGO_TYPE_ATTR_TYPE);
111 for (int i = 0; i < class->n_values; i++)
112 {
113 g_assert_cmpint (type, !=, class->values[i].value);
114 g_assert_null (pango_attr_type_get_name (class->values[i].value));
115 }
116
117 g_type_class_unref (g_class: class);
118}
119
120static void
121test_binding (PangoAttribute *attr)
122{
123 enum {
124 INVALID, INT, LANGUAGE, STRING, SIZE, FONT_DESC, COLOR, SHAPE, FLOAT, FONT_FEATURES,
125 } attr_base[] = {
126 INVALID, LANGUAGE, STRING, INT, INT, INT, INT, SIZE, FONT_DESC, COLOR,
127 COLOR, INT, INT, INT, SHAPE, FLOAT, INT, INT, COLOR, COLOR, SIZE,
128 INT, INT, FONT_FEATURES, INT, INT, INT, INT, INT, INT, COLOR, FLOAT,
129 INT, INT, INT, INT, INT, INT
130 };
131
132 switch (attr_base[attr->klass->type])
133 {
134 case INT:
135 g_assert_nonnull (pango_attribute_as_int (attr));
136 break;
137 case LANGUAGE:
138 g_assert_nonnull (pango_attribute_as_language (attr));
139 break;
140 case STRING:
141 g_assert_nonnull (pango_attribute_as_string (attr));
142 break;
143 case SIZE:
144 g_assert_nonnull (pango_attribute_as_size (attr));
145 break;
146 case FONT_DESC:
147 g_assert_nonnull (pango_attribute_as_font_desc (attr));
148 break;
149 case COLOR:
150 g_assert_nonnull (pango_attribute_as_color (attr));
151 break;
152 case SHAPE:
153 g_assert_nonnull (pango_attribute_as_shape (attr));
154 break;
155 case FLOAT:
156 g_assert_nonnull (pango_attribute_as_float (attr));
157 break;
158 case FONT_FEATURES:
159 g_assert_nonnull (pango_attribute_as_font_features (attr));
160 break;
161 case INVALID:
162 default:
163 g_assert_not_reached ();
164 }
165
166 pango_attribute_destroy (attr);
167}
168
169static void
170test_binding_helpers (void)
171{
172 PangoFontDescription *desc;
173 PangoRectangle rect = { 0, 0, 10, 10 };
174
175 test_binding (attr: pango_attr_language_new (language: pango_language_from_string (language: "ja-JP")));
176 test_binding (attr: pango_attr_family_new (family: "Times"));
177 test_binding (attr: pango_attr_foreground_new (red: 100, green: 200, blue: 300));
178 test_binding (attr: pango_attr_background_new (red: 100, green: 200, blue: 300));
179 test_binding (attr: pango_attr_size_new (size: 1024));
180 test_binding (attr: pango_attr_size_new_absolute (size: 1024));
181 test_binding (attr: pango_attr_style_new (style: PANGO_STYLE_ITALIC));
182 test_binding (attr: pango_attr_weight_new (weight: PANGO_WEIGHT_ULTRALIGHT));
183 test_binding (attr: pango_attr_variant_new (variant: PANGO_VARIANT_SMALL_CAPS));
184 test_binding (attr: pango_attr_stretch_new (stretch: PANGO_STRETCH_SEMI_EXPANDED));
185 desc = pango_font_description_from_string (str: "Computer Modern 12");
186 test_binding (attr: pango_attr_font_desc_new (desc));
187 pango_font_description_free (desc);
188 test_binding (attr: pango_attr_underline_new (underline: PANGO_UNDERLINE_LOW));
189 test_binding (attr: pango_attr_underline_new (underline: PANGO_UNDERLINE_ERROR_LINE));
190 test_binding (attr: pango_attr_underline_color_new (red: 100, green: 200, blue: 300));
191 test_binding (attr: pango_attr_overline_new (overline: PANGO_OVERLINE_SINGLE));
192 test_binding (attr: pango_attr_overline_color_new (red: 100, green: 200, blue: 300));
193 test_binding (attr: pango_attr_strikethrough_new (TRUE));
194 test_binding (attr: pango_attr_strikethrough_color_new (red: 100, green: 200, blue: 300));
195 test_binding (attr: pango_attr_rise_new (rise: 256));
196 test_binding (attr: pango_attr_scale_new (scale_factor: 2.56));
197 test_binding (attr: pango_attr_fallback_new (FALSE));
198 test_binding (attr: pango_attr_letter_spacing_new (letter_spacing: 1024));
199 test_binding (attr: pango_attr_shape_new (ink_rect: &rect, logical_rect: &rect));
200 test_binding (attr: pango_attr_gravity_new (gravity: PANGO_GRAVITY_SOUTH));
201 test_binding (attr: pango_attr_gravity_hint_new (hint: PANGO_GRAVITY_HINT_STRONG));
202 test_binding (attr: pango_attr_font_features_new (features: "csc=1"));
203 test_binding (attr: pango_attr_foreground_alpha_new (alpha: 8000));
204 test_binding (attr: pango_attr_background_alpha_new (alpha: 8000));
205 test_binding (attr: pango_attr_allow_breaks_new (FALSE));
206 test_binding (attr: pango_attr_show_new (flags: PANGO_SHOW_SPACES));
207 test_binding (attr: pango_attr_insert_hyphens_new (FALSE));
208 test_binding (attr: pango_attr_text_transform_new (transform: PANGO_TEXT_TRANSFORM_UPPERCASE));
209 test_binding (attr: pango_attr_line_height_new (factor: 1.5));
210 test_binding (attr: pango_attr_line_height_new_absolute (height: 3000));
211 test_binding (attr: pango_attr_word_new ());
212 test_binding (attr: pango_attr_sentence_new ());
213}
214
215static void
216assert_attributes (GSList *attrs,
217 const char *expected)
218{
219 PangoAttrList *list2;
220 GSList *attrs2, *l, *l2;
221
222 list2 = pango_attr_list_from_string (text: expected);
223 attrs2 = pango_attr_list_get_attributes (list: list2);
224
225 if (g_slist_length (list: attrs) != g_slist_length (list: attrs2))
226 g_assert_not_reached ();
227
228 for (l = attrs, l2 = attrs2; l; l = l->next, l2 = l2->next)
229 {
230 PangoAttribute *a = l->data;
231 PangoAttribute *a2 = l2->data;
232 if (!pango_attribute_equal (attr1: a, attr2: a2))
233 g_assert_not_reached ();
234 }
235
236 g_slist_free_full (list: attrs2, free_func: (GDestroyNotify)pango_attribute_destroy);
237 pango_attr_list_unref (list: list2);
238}
239
240static void
241assert_attr_list_order (PangoAttrList *list)
242{
243 GSList *attrs, *l;
244 guint start = 0;
245
246 attrs = pango_attr_list_get_attributes (list);
247
248 for (l = attrs; l; l = l->next)
249 {
250 PangoAttribute *attr = l->data;
251 g_assert (start <= attr->start_index);
252 start = attr->start_index;
253 }
254
255 g_slist_free_full (list: attrs, free_func: (GDestroyNotify) pango_attribute_destroy);
256}
257
258static void
259assert_attr_list (PangoAttrList *list,
260 const char *expected)
261{
262 PangoAttrList *list2;
263
264 assert_attr_list_order (list);
265
266 list2 = pango_attr_list_from_string (text: expected);
267 if (!pango_attr_list_equal (list, other_list: list2))
268 {
269 char *s = pango_attr_list_to_string (list);
270 g_print (format: "-----\nattribute list mismatch\nexpected:\n%s\n-----\nreceived:\n%s\n-----\n",
271 expected, s);
272 g_free (mem: s);
273 g_assert_not_reached ();
274 }
275
276 pango_attr_list_unref (list: list2);
277}
278
279static void
280assert_attr_iterator (PangoAttrIterator *iter,
281 const char *expected)
282{
283 GSList *attrs;
284
285 attrs = pango_attr_iterator_get_attrs (iterator: iter);
286 assert_attributes (attrs, expected);
287 g_slist_free_full (list: attrs, free_func: (GDestroyNotify)pango_attribute_destroy);
288}
289
290static PangoAttribute *
291attribute_from_string (const char *str)
292{
293 PangoAttrList *list;
294 GSList *attrs;
295 PangoAttribute *attr;
296
297 list = pango_attr_list_from_string (text: str);
298 attrs = pango_attr_list_get_attributes (list);
299 g_assert_true (attrs->next == NULL);
300
301 attr = attrs->data;
302
303 g_slist_free (list: attrs);
304 pango_attr_list_unref (list);
305
306 return attr;
307}
308
309static void
310test_list (void)
311{
312 PangoAttrList *list, *list2;
313 PangoAttribute *attr;
314
315 list = pango_attr_list_new ();
316
317 attr = pango_attr_size_new (size: 10);
318 pango_attr_list_insert (list, attr);
319 attr = pango_attr_size_new (size: 20);
320 pango_attr_list_insert (list, attr);
321 attr = pango_attr_size_new (size: 30);
322 pango_attr_list_insert (list, attr);
323
324 list2 = pango_attr_list_from_string (text: "0 -1 size 10\n"
325 "0 -1 size 20\n"
326 "0 -1 size 30\n");
327 g_assert_true (pango_attr_list_equal (list, list2));
328 pango_attr_list_unref (list: list2);
329
330 assert_attr_list (list, expected: "0 -1 size 10\n"
331 "0 -1 size 20\n"
332 "0 -1 size 30");
333 pango_attr_list_unref (list);
334
335 list = pango_attr_list_new ();
336
337 /* test that insertion respects start_index */
338 attr = attribute_from_string (str: "0 -1 size 10");
339 pango_attr_list_insert (list, attr);
340 attr = attribute_from_string (str: "10 20 size 20");
341 pango_attr_list_insert (list, attr);
342 attr = attribute_from_string (str: "0 -1 size 30");
343 pango_attr_list_insert (list, attr);
344 attr = attribute_from_string (str: " 10 40 size 40");
345 pango_attr_list_insert_before (list, attr);
346
347 assert_attr_list (list, expected: "0 -1 size 10\n"
348 "0 -1 size 30\n"
349 "10 40 size 40\n"
350 "10 20 size 20");
351 pango_attr_list_unref (list);
352}
353
354static void
355test_list_change (void)
356{
357 PangoAttrList *list;
358 PangoAttribute *attr;
359
360 list = pango_attr_list_from_string (text: " 0 10 size 10\n"
361 " 0 30 weight 700\n"
362 " 20 30 size 20\n");
363
364 /* no-op */
365 attr = attribute_from_string (str: "10 10 variant small-caps");
366 pango_attr_list_change (list, attr);
367
368 assert_attr_list (list, expected: "0 10 size 10\n"
369 "0 30 weight bold\n"
370 "20 30 size 20");
371
372 /* simple insertion with pango_attr_list_change */
373 attr = attribute_from_string (str: "10 20 variant small-caps");
374 pango_attr_list_change (list, attr);
375
376 assert_attr_list (list, expected: "0 10 size 10\n"
377 "0 30 weight bold\n"
378 "10 20 variant small-caps\n"
379 "20 30 size 20");
380
381 /* insertion with splitting */
382 attr = attribute_from_string (str: "15 20 weight light");
383 pango_attr_list_change (list, attr);
384
385 assert_attr_list (list, expected: "0 10 size 10\n"
386 "0 15 weight bold\n"
387 "10 20 variant small-caps\n"
388 "15 20 weight light\n"
389 "20 30 size 20\n"
390 "20 30 weight bold");
391
392 /* insertion with joining */
393 attr = attribute_from_string (str: "5 20 size 20");
394 pango_attr_list_change (list, attr);
395
396 assert_attr_list (list, expected: "0 5 size 10\n"
397 "0 15 weight bold\n"
398 "5 30 size 20\n"
399 "10 20 variant small-caps\n"
400 "15 20 weight light\n"
401 "20 30 weight bold");
402
403 pango_attr_list_unref (list);
404}
405
406/* See https://gitlab.gnome.org/GNOME/pango/-/issues/564 */
407static void
408test_list_change2 (void)
409{
410 PangoAttrList *list;
411 PangoAttribute *attr;
412
413 list = pango_attr_list_from_string (text: "0 3 style italic\n"
414 "3 4 style normal\n"
415 "4 18 style italic\n");
416
417 /* insertion with joining */
418 attr = attribute_from_string (str: "0 18 style normal");
419 pango_attr_list_change (list, attr);
420
421 assert_attr_list (list, expected: "0 18 style normal");
422
423 pango_attr_list_unref (list);
424}
425
426static void
427test_list_change3 (void)
428{
429 PangoAttrList *list;
430 PangoAttribute *attr;
431
432 list = pango_attr_list_from_string (text: "0 3 style italic\n"
433 "3 4 style normal\n"
434 "4 18 style italic\n");
435
436 /* insertion with joining */
437 attr = attribute_from_string (str: "1 1 style normal");
438 pango_attr_list_change (list, attr);
439
440 assert_attr_list (list, expected: "0 3 style italic\n"
441 "3 4 style normal\n"
442 "4 18 style italic");
443
444 pango_attr_list_unref (list);
445}
446
447static void
448test_list_change4 (void)
449{
450 PangoAttrList *list;
451 PangoAttribute *attr;
452
453 list = pango_attr_list_new ();
454
455 /* insertion with joining */
456 attr = attribute_from_string (str: "0 10 style normal");
457 pango_attr_list_change (list, attr);
458
459 assert_attr_list (list, expected: "0 10 style normal");
460
461 pango_attr_list_unref (list);
462}
463
464static void
465test_list_change5 (void)
466{
467 PangoAttrList *list;
468 PangoAttribute *attr;
469
470 list = pango_attr_list_from_string (text: "0 3 weight 800\n"
471 "2 4 style normal\n"
472 "10 20 style normal\n"
473 "15 18 fallback false\n");
474
475 /* insertion with joining */
476 attr = attribute_from_string (str: "5 15 style italic");
477 g_assert (attr->start_index == 5);
478 g_assert (attr->end_index == 15);
479 g_assert (((PangoAttrInt *)attr)->value == PANGO_STYLE_ITALIC);
480 pango_attr_list_change (list, attr);
481
482 assert_attr_list (list, expected: "0 3 weight ultrabold\n"
483 "2 4 style normal\n"
484 "5 15 style italic\n"
485 "15 20 style normal\n"
486 "15 18 fallback false");
487
488 pango_attr_list_unref (list);
489}
490
491static void
492test_list_change6 (void)
493{
494 PangoAttrList *list;
495 PangoAttribute *attr;
496
497 list = pango_attr_list_from_string (text: "0 3 weight 800\n"
498 "2 4 style normal\n"
499 "10 20 style normal\n"
500 "15 18 fallback false\n");
501
502 /* insertion with joining */
503 attr = attribute_from_string (str: "3 10 style normal");
504 pango_attr_list_change (list, attr);
505
506 assert_attr_list (list, expected: "0 3 weight ultrabold\n"
507 "2 20 style normal\n"
508 "15 18 fallback false");
509
510 pango_attr_list_unref (list);
511}
512
513static void
514test_list_change7 (void)
515{
516 PangoAttrList *list;
517 PangoAttribute *attr;
518
519 list = pango_attr_list_from_string (text: "0 3 weight 800\n"
520 "2 4 style normal\n"
521 "10 20 style normal\n"
522 "15 18 fallback false\n");
523
524 /* insertion with joining */
525 attr = attribute_from_string (str: "3 4 style normal");
526 pango_attr_list_change (list, attr);
527
528 assert_attr_list (list, expected: "0 3 weight ultrabold\n"
529 "2 4 style normal\n"
530 "10 20 style normal\n"
531 "15 18 fallback false");
532
533 pango_attr_list_unref (list);
534}
535
536static void
537test_list_change8 (void)
538{
539 PangoAttrList *list;
540 PangoAttribute *attr;
541
542 list = pango_attr_list_from_string (text: "0 3 weight 800\n"
543 "2 4 style normal\n"
544 "10 20 style normal\n"
545 "15 18 fallback false\n");
546
547 /* insertion with joining */
548 attr = attribute_from_string (str: "3 11 style italic");
549 pango_attr_list_change (list, attr);
550
551 assert_attr_list (list, expected: "0 3 weight ultrabold\n"
552 "2 3 style normal\n"
553 "3 11 style italic\n"
554 "11 20 style normal\n"
555 "15 18 fallback false");
556
557 pango_attr_list_unref (list);
558}
559
560static void
561test_list_change9 (void)
562{
563 PangoAttrList *list;
564 PangoAttribute *attr;
565
566 list = pango_attr_list_from_string (text: "0 3 weight 800\n"
567 "2 4 style normal\n"
568 "10 20 style normal\n"
569 "15 18 fallback false\n");
570
571 /* insertion with joining */
572 attr = attribute_from_string (str: "2 3 style italic");
573 pango_attr_list_change (list, attr);
574
575 assert_attr_list (list, expected: "0 3 weight ultrabold\n"
576 "2 3 style italic\n"
577 "3 4 style normal\n"
578 "10 20 style normal\n"
579 "15 18 fallback false");
580
581 pango_attr_list_unref (list);
582}
583
584static void
585test_list_change10 (void)
586{
587 PangoAttrList *list;
588 PangoAttribute *attr;
589
590 list = pango_attr_list_from_string (text: "0 3 weight 800\n"
591 "2 4 style normal\n"
592 "10 20 style normal\n"
593 "15 18 fallback false\n");
594
595 /* insertion with joining */
596 attr = attribute_from_string (str: "3 4 style italic");
597 pango_attr_list_change (list, attr);
598
599 assert_attr_list (list, expected: "0 3 weight ultrabold\n"
600 "2 3 style normal\n"
601 "3 4 style italic\n"
602 "10 20 style normal\n"
603 "15 18 fallback false");
604
605 pango_attr_list_unref (list);
606}
607
608static void
609test_list_change11 (void)
610{
611 PangoAttrList *list;
612 PangoAttribute *attr;
613
614 list = pango_attr_list_from_string (text: "0 3 weight 800\n"
615 "2 4 style normal\n"
616 "3 5 fallback false\n"
617 "10 20 style italic\n"
618 "15 18 fallback false\n"
619 "22 30 style italic\n");
620
621 /* insertion with joining */
622 attr = attribute_from_string (str: "3 22 style italic");
623 pango_attr_list_change (list, attr);
624
625 assert_attr_list (list, expected: "0 3 weight ultrabold\n"
626 "2 3 style normal\n"
627 "3 30 style italic\n"
628 "3 5 fallback false\n"
629 "15 18 fallback false\n");
630
631 pango_attr_list_unref (list);
632}
633
634static void
635test_list_change12 (void)
636{
637 PangoAttrList *list;
638 PangoAttribute *attr;
639
640 list = pango_attr_list_from_string (text: "0 3 weight 800\n"
641 "2 4 style normal\n"
642 "3 5 fallback false\n"
643 "10 20 style normal\n"
644 "15 18 fallback false\n"
645 "20 30 style oblique\n"
646 "21 22 fallback false");
647
648 /* insertion with joining */
649 attr = attribute_from_string (str: "3 22 style italic");
650 pango_attr_list_change (list, attr);
651
652 assert_attr_list (list, expected: "0 3 weight ultrabold\n"
653 "2 3 style normal\n"
654 "3 22 style italic\n"
655 "3 5 fallback false\n"
656 "15 18 fallback false\n"
657 "21 22 fallback false\n"
658 "22 30 style oblique");
659
660 pango_attr_list_unref (list);
661}
662
663static void
664test_list_splice (void)
665{
666 PangoAttrList *base;
667 PangoAttrList *list;
668 PangoAttrList *other;
669
670 base = pango_attr_list_from_string (text: "0 -1 size 10\n"
671 "10 15 weight 700\n"
672 "20 30 variant 1\n");
673
674 /* splice in an empty list */
675 list = pango_attr_list_copy (list: base);
676 other = pango_attr_list_new ();
677 pango_attr_list_splice (list, other, pos: 11, len: 5);
678
679 assert_attr_list (list, expected: "0 -1 size 10\n"
680 "10 20 weight bold\n"
681 "25 35 variant small-caps\n");
682
683 pango_attr_list_unref (list);
684 pango_attr_list_unref (list: other);
685
686 /* splice in some attributes */
687 list = pango_attr_list_copy (list: base);
688
689 other = pango_attr_list_from_string (text: "0 3 size 20\n"
690 "2 4 stretch 2\n");
691
692 pango_attr_list_splice (list, other, pos: 11, len: 5);
693
694 assert_attr_list (list, expected: "0 11 size 10\n"
695 "10 20 weight bold\n"
696 "11 14 size 20\n"
697 "13 15 stretch condensed\n"
698 "14 -1 size 10\n"
699 "25 35 variant small-caps\n");
700
701 pango_attr_list_unref (list);
702 pango_attr_list_unref (list: other);
703
704 pango_attr_list_unref (list: base);
705}
706
707/* Test that empty lists work in pango_attr_list_splice */
708static void
709test_list_splice2 (void)
710{
711 PangoAttrList *list;
712 PangoAttrList *other;
713 PangoAttribute *attr;
714
715 list = pango_attr_list_new ();
716 other = pango_attr_list_new ();
717
718 pango_attr_list_splice (list, other, pos: 11, len: 5);
719
720 g_assert_null (pango_attr_list_get_attributes (list));
721
722 attr = attribute_from_string (str: "0 -1 size 10");
723 pango_attr_list_insert (list: other, attr);
724
725 pango_attr_list_splice (list, other, pos: 11, len: 5);
726
727 assert_attr_list (list, expected: "11 16 size 10\n");
728
729 pango_attr_list_unref (list: other);
730 other = pango_attr_list_new ();
731
732 pango_attr_list_splice (list, other, pos: 11, len: 5);
733
734 assert_attr_list (list, expected: "11 21 size 10\n");
735
736 pango_attr_list_unref (list: other);
737 pango_attr_list_unref (list);
738}
739
740/* Test that attributes in other aren't leaking out in pango_attr_list_splice */
741static void
742test_list_splice3 (void)
743{
744 PangoAttrList *list;
745 PangoAttrList *other;
746
747 list = pango_attr_list_from_string (text: "10 30 variant 1\n");
748 other = pango_attr_list_from_string (text: "0 -1 weight 700\n");
749
750 pango_attr_list_splice (list, other, pos: 20, len: 5);
751
752 assert_attr_list (list, expected: "10 35 variant small-caps\n"
753 "20 25 weight bold\n");
754
755 pango_attr_list_unref (list: other);
756 pango_attr_list_unref (list);
757}
758
759static gboolean
760never_true (PangoAttribute *attribute, gpointer user_data)
761{
762 return FALSE;
763}
764
765static gboolean
766just_weight (PangoAttribute *attribute, gpointer user_data)
767{
768 if (attribute->klass->type == PANGO_ATTR_WEIGHT)
769 return TRUE;
770 else
771 return FALSE;
772}
773
774static void
775test_list_filter (void)
776{
777 PangoAttrList *list;
778 PangoAttrList *out;
779
780 list = pango_attr_list_from_string (text: "0 -1 size 10\n"
781 "10 20 stretch 2\n"
782 "20 -1 weight 700\n");
783
784 out = pango_attr_list_filter (list, func: never_true, NULL);
785 g_assert_null (out);
786
787 out = pango_attr_list_filter (list, func: just_weight, NULL);
788 g_assert_nonnull (out);
789
790 assert_attr_list (list, expected: "0 -1 size 10\n"
791 "10 20 stretch condensed\n");
792 assert_attr_list (list: out, expected: "20 -1 weight bold\n");
793
794 pango_attr_list_unref (list);
795 pango_attr_list_unref (list: out);
796}
797
798static void
799test_iter (void)
800{
801 PangoAttrList *list;
802 PangoAttribute *attr;
803 PangoAttrIterator *iter;
804 PangoAttrIterator *copy;
805 gint start, end;
806
807 /* Empty list */
808 list = pango_attr_list_new ();
809 iter = pango_attr_list_get_iterator (list);
810
811 g_assert_false (pango_attr_iterator_next (iter));
812 g_assert_null (pango_attr_iterator_get_attrs (iter));
813 pango_attr_iterator_destroy (iterator: iter);
814 pango_attr_list_unref (list);
815
816 list = pango_attr_list_new ();
817 attr = attribute_from_string (str: "0 -1 size 10");
818 pango_attr_list_insert (list, attr);
819 attr = attribute_from_string (str: "10 30 stretch condensed");
820 pango_attr_list_insert (list, attr);
821 attr = attribute_from_string (str: "20 -1 weight bold");
822 pango_attr_list_insert (list, attr);
823
824 iter = pango_attr_list_get_iterator (list);
825 copy = pango_attr_iterator_copy (iterator: iter);
826 pango_attr_iterator_range (iterator: iter, start: &start, end: &end);
827 g_assert_cmpint (start, ==, 0);
828 g_assert_cmpint (end, ==, 10);
829 g_assert_true (pango_attr_iterator_next (iter));
830 pango_attr_iterator_range (iterator: iter, start: &start, end: &end);
831 g_assert_cmpint (start, ==, 10);
832 g_assert_cmpint (end, ==, 20);
833 g_assert_true (pango_attr_iterator_next (iter));
834 pango_attr_iterator_range (iterator: iter, start: &start, end: &end);
835 g_assert_cmpint (start, ==, 20);
836 g_assert_cmpint (end, ==, 30);
837 g_assert_true (pango_attr_iterator_next (iter));
838 pango_attr_iterator_range (iterator: iter, start: &start, end: &end);
839 g_assert_cmpint (start, ==, 30);
840 g_assert_cmpint (end, ==, G_MAXINT);
841 g_assert_true (pango_attr_iterator_next (iter));
842 pango_attr_iterator_range (iterator: iter, start: &start, end: &end);
843 g_assert_cmpint (start, ==, G_MAXINT);
844 g_assert_cmpint (end, ==, G_MAXINT);
845 g_assert_true (!pango_attr_iterator_next (iter));
846
847 pango_attr_iterator_destroy (iterator: iter);
848
849 pango_attr_iterator_range (iterator: copy, start: &start, end: &end);
850 g_assert_cmpint (start, ==, 0);
851 g_assert_cmpint (end, ==, 10);
852 pango_attr_iterator_destroy (iterator: copy);
853
854 pango_attr_list_unref (list);
855}
856
857static void
858test_iter_get (void)
859{
860 PangoAttrList *list;
861 PangoAttribute *attr;
862 PangoAttrIterator *iter;
863
864 list = pango_attr_list_new ();
865 attr = pango_attr_size_new (size: 10);
866 pango_attr_list_insert (list, attr);
867 attr = attribute_from_string (str: "10 30 stretch condensed");
868 pango_attr_list_insert (list, attr);
869 attr = attribute_from_string (str: "20 -1 weight bold");
870 pango_attr_list_insert (list, attr);
871
872 iter = pango_attr_list_get_iterator (list);
873 pango_attr_iterator_next (iterator: iter);
874 attr = pango_attr_iterator_get (iterator: iter, type: PANGO_ATTR_SIZE);
875 g_assert_nonnull (attr);
876 g_assert_cmpuint (attr->start_index, ==, 0);
877 g_assert_cmpuint (attr->end_index, ==, G_MAXUINT);
878 attr = pango_attr_iterator_get (iterator: iter, type: PANGO_ATTR_STRETCH);
879 g_assert_nonnull (attr);
880 g_assert_cmpuint (attr->start_index, ==, 10);
881 g_assert_cmpuint (attr->end_index, ==, 30);
882 attr = pango_attr_iterator_get (iterator: iter, type: PANGO_ATTR_WEIGHT);
883 g_assert_null (attr);
884 attr = pango_attr_iterator_get (iterator: iter, type: PANGO_ATTR_GRAVITY);
885 g_assert_null (attr);
886
887 pango_attr_iterator_destroy (iterator: iter);
888 pango_attr_list_unref (list);
889}
890
891static void
892test_iter_get_font (void)
893{
894 PangoAttrList *list;
895 PangoAttribute *attr;
896 PangoAttrIterator *iter;
897 PangoFontDescription *desc;
898 PangoFontDescription *desc2;
899 PangoLanguage *lang;
900 GSList *attrs;
901
902 list = pango_attr_list_new ();
903 attr = pango_attr_size_new (size: 10 * PANGO_SCALE);
904 pango_attr_list_insert (list, attr);
905 attr = attribute_from_string (str: "0 -1 family Times");
906 pango_attr_list_insert (list, attr);
907 attr = attribute_from_string (str: "10 30 stretch condensed");
908 pango_attr_list_insert (list, attr);
909 attr = attribute_from_string (str: "10 20 absolute-size 10240");
910 pango_attr_list_insert (list, attr);
911 attr = attribute_from_string (str: "10 20 language ja-JP");
912 pango_attr_list_insert (list, attr);
913 attr = attribute_from_string (str: "20 -1 rise 100");
914 pango_attr_list_insert (list, attr);
915 attr = attribute_from_string (str: "20 -1 fallback 0");
916 pango_attr_list_insert (list, attr);
917
918 iter = pango_attr_list_get_iterator (list);
919 desc = pango_font_description_new ();
920 pango_attr_iterator_get_font (iterator: iter, desc, language: &lang, extra_attrs: &attrs);
921 desc2 = pango_font_description_from_string (str: "Times 10");
922 g_assert_true (pango_font_description_equal (desc, desc2));
923 g_assert_null (lang);
924 g_assert_null (attrs);
925 pango_font_description_free (desc);
926 pango_font_description_free (desc: desc2);
927
928 pango_attr_iterator_next (iterator: iter);
929 desc = pango_font_description_new ();
930 pango_attr_iterator_get_font (iterator: iter, desc, language: &lang, extra_attrs: &attrs);
931 desc2 = pango_font_description_from_string (str: "Times Condensed 10px");
932 g_assert_true (pango_font_description_equal (desc, desc2));
933 g_assert_nonnull (lang);
934 g_assert_cmpstr (pango_language_to_string (lang), ==, "ja-jp");
935 g_assert_null (attrs);
936 pango_font_description_free (desc);
937 pango_font_description_free (desc: desc2);
938
939 pango_attr_iterator_next (iterator: iter);
940 desc = pango_font_description_new ();
941 pango_attr_iterator_get_font (iterator: iter, desc, language: &lang, extra_attrs: &attrs);
942 desc2 = pango_font_description_from_string (str: "Times Condensed 10");
943 g_assert_true (pango_font_description_equal (desc, desc2));
944 g_assert_null (lang);
945 assert_attributes (attrs, expected: "20 -1 rise 100\n"
946 "20 -1 fallback false\n");
947 g_slist_free_full (list: attrs, free_func: (GDestroyNotify)pango_attribute_destroy);
948
949 pango_font_description_free (desc);
950 pango_font_description_free (desc: desc2);
951
952 pango_attr_iterator_destroy (iterator: iter);
953 pango_attr_list_unref (list);
954}
955
956static void
957test_iter_get_attrs (void)
958{
959 PangoAttrList *list;
960 PangoAttribute *attr;
961 PangoAttrIterator *iter;
962
963 list = pango_attr_list_new ();
964 attr = pango_attr_size_new (size: 10 * PANGO_SCALE);
965 pango_attr_list_insert (list, attr);
966 attr = attribute_from_string (str: "0 -1 family Times");
967 pango_attr_list_insert (list, attr);
968 attr = attribute_from_string (str: "10 30 stretch condensed");
969 pango_attr_list_insert (list, attr);
970 attr = attribute_from_string (str: "10 20 language ja-JP");
971 pango_attr_list_insert (list, attr);
972 attr = attribute_from_string (str: "20 -1 rise 100");
973 pango_attr_list_insert (list, attr);
974 attr = attribute_from_string (str: "20 -1 fallback 0");
975 pango_attr_list_insert (list, attr);
976
977 iter = pango_attr_list_get_iterator (list);
978 assert_attr_iterator (iter, expected: "0 -1 size 10240\n"
979 "0 -1 family Times\n");
980
981 pango_attr_iterator_next (iterator: iter);
982 assert_attr_iterator (iter, expected: "0 -1 size 10240\n"
983 "0 -1 family Times\n"
984 "10 30 stretch 2\n"
985 "10 20 language ja-jp\n");
986
987 pango_attr_iterator_next (iterator: iter);
988 assert_attr_iterator (iter, expected: "0 -1 size 10240\n"
989 "0 -1 family Times\n"
990 "10 30 stretch 2\n"
991 "20 -1 rise 100\n"
992 "20 -1 fallback 0\n");
993
994 pango_attr_iterator_next (iterator: iter);
995 assert_attr_iterator (iter, expected: "0 -1 size 10240\n"
996 "0 -1 family Times\n"
997 "20 -1 rise 100\n"
998 "20 -1 fallback 0\n");
999
1000 pango_attr_iterator_next (iterator: iter);
1001 g_assert_null (pango_attr_iterator_get_attrs (iter));
1002
1003 pango_attr_iterator_destroy (iterator: iter);
1004 pango_attr_list_unref (list);
1005}
1006
1007static void
1008test_list_update (void)
1009{
1010 PangoAttrList *list;
1011
1012 list = pango_attr_list_from_string (text: "0 200 rise 100\n"
1013 "5 15 family Times\n"
1014 "10 11 size 10240\n"
1015 "11 100 fallback 0\n"
1016 "30 60 stretch 2\n");
1017
1018 pango_attr_list_update (list, pos: 8, remove: 10, add: 20);
1019
1020 assert_attr_list (list, expected: "0 210 rise 100\n"
1021 "5 8 family Times\n"
1022 "28 110 fallback false\n"
1023 "40 70 stretch condensed\n");
1024
1025 pango_attr_list_unref (list);
1026}
1027
1028/* Test that empty lists work in pango_attr_list_update */
1029static void
1030test_list_update2 (void)
1031{
1032 PangoAttrList *list;
1033
1034 list = pango_attr_list_new ();
1035 pango_attr_list_update (list, pos: 8, remove: 10, add: 20);
1036
1037 g_assert_null (pango_attr_list_get_attributes (list));
1038
1039 pango_attr_list_unref (list);
1040}
1041
1042/* test overflow */
1043static void
1044test_list_update3 (void)
1045{
1046 PangoAttrList *list;
1047
1048 list = pango_attr_list_from_string (text: "5 4294967285 family Times\n");
1049
1050 pango_attr_list_update (list, pos: 8, remove: 10, add: 30);
1051
1052 assert_attr_list (list, expected: "5 -1 family Times\n");
1053
1054 pango_attr_list_unref (list);
1055}
1056static void
1057test_list_equal (void)
1058{
1059 PangoAttrList *list1, *list2;
1060 PangoAttribute *attr;
1061
1062 list1 = pango_attr_list_new ();
1063 list2 = pango_attr_list_new ();
1064
1065 g_assert_true (pango_attr_list_equal (NULL, NULL));
1066 g_assert_false (pango_attr_list_equal (list1, NULL));
1067 g_assert_false (pango_attr_list_equal (NULL, list1));
1068 g_assert_true (pango_attr_list_equal (list1, list1));
1069 g_assert_true (pango_attr_list_equal (list1, list2));
1070
1071 attr = attribute_from_string (str: "0 7 size 10240");
1072 pango_attr_list_insert (list: list1, attr: pango_attribute_copy (attr));
1073 pango_attr_list_insert (list: list2, attr: pango_attribute_copy (attr));
1074 pango_attribute_destroy (attr);
1075
1076 g_assert_true (pango_attr_list_equal (list1, list2));
1077
1078 attr = attribute_from_string (str: "0 1 stretch condensed");
1079 pango_attr_list_insert (list: list1, attr: pango_attribute_copy (attr));
1080 g_assert_true (!pango_attr_list_equal (list1, list2));
1081
1082 pango_attr_list_insert (list: list2, attr: pango_attribute_copy (attr));
1083 g_assert_true (pango_attr_list_equal (list1, list2));
1084 pango_attribute_destroy (attr);
1085
1086 /* Same range as the first attribute */
1087 attr = attribute_from_string (str: "0 7 size 30720");
1088 pango_attr_list_insert (list: list2, attr: pango_attribute_copy (attr));
1089 g_assert_true (!pango_attr_list_equal (list1, list2));
1090 pango_attr_list_insert (list: list1, attr: pango_attribute_copy (attr));
1091 g_assert_true (pango_attr_list_equal (list1, list2));
1092 pango_attribute_destroy (attr);
1093
1094 pango_attr_list_unref (list: list1);
1095 pango_attr_list_unref (list: list2);
1096
1097
1098 /* Same range but different order */
1099 {
1100 PangoAttrList *list1, *list2;
1101 PangoAttribute *attr1, *attr2;
1102
1103 list1 = pango_attr_list_new ();
1104 list2 = pango_attr_list_new ();
1105
1106 attr1 = pango_attr_size_new (size: 10 * PANGO_SCALE);
1107 attr2 = pango_attr_stretch_new (stretch: PANGO_STRETCH_CONDENSED);
1108
1109 pango_attr_list_insert (list: list1, attr: pango_attribute_copy (attr: attr1));
1110 pango_attr_list_insert (list: list1, attr: pango_attribute_copy (attr: attr2));
1111
1112 pango_attr_list_insert (list: list2, attr: pango_attribute_copy (attr: attr2));
1113 pango_attr_list_insert (list: list2, attr: pango_attribute_copy (attr: attr1));
1114
1115 pango_attribute_destroy (attr: attr1);
1116 pango_attribute_destroy (attr: attr2);
1117
1118 g_assert_true (pango_attr_list_equal (list1, list2));
1119 g_assert_true (pango_attr_list_equal (list2, list1));
1120
1121 pango_attr_list_unref (list: list1);
1122 pango_attr_list_unref (list: list2);
1123 }
1124}
1125
1126static void
1127test_insert (void)
1128{
1129 PangoAttrList *list;
1130 PangoAttribute *attr;
1131
1132 list = pango_attr_list_from_string (text: "0 200 rise 100\n"
1133 "5 15 family Times\n"
1134 "10 11 size 10240\n"
1135 "11 100 fallback 0\n"
1136 "30 60 stretch 2\n");
1137
1138 attr = attribute_from_string (str: "10 25 family Times");
1139 pango_attr_list_change (list, attr);
1140
1141 assert_attr_list (list, expected: "0 200 rise 100\n"
1142 "5 25 family Times\n"
1143 "10 11 size 10240\n"
1144 "11 100 fallback false\n"
1145 "30 60 stretch condensed\n");
1146
1147 attr = attribute_from_string (str: "11 25 family Futura");
1148 pango_attr_list_insert (list, attr);
1149
1150 assert_attr_list (list, expected: "0 200 rise 100\n"
1151 "5 25 family Times\n"
1152 "10 11 size 10240\n"
1153 "11 100 fallback false\n"
1154 "11 25 family Futura\n"
1155 "30 60 stretch condensed\n");
1156
1157 pango_attr_list_unref (list);
1158}
1159
1160static void
1161test_insert2 (void)
1162{
1163 PangoAttrList *list;
1164 PangoAttribute *attr;
1165
1166 list = pango_attr_list_from_string (text: "0 200 rise 100\n"
1167 "5 15 family Times\n"
1168 "10 11 size 10240\n"
1169 "11 100 fallback 0\n"
1170 "20 30 family Times\n"
1171 "30 40 family Futura\n"
1172 "30 60 stretch 2\n");
1173
1174 attr = attribute_from_string (str: "10 35 family Times");
1175 pango_attr_list_change (list, attr);
1176
1177 assert_attr_list (list, expected: "0 200 rise 100\n"
1178 "5 35 family Times\n"
1179 "10 11 size 10240\n"
1180 "11 100 fallback false\n"
1181 "35 40 family Futura\n"
1182 "30 60 stretch condensed\n");
1183
1184 pango_attr_list_unref (list);
1185}
1186
1187static gboolean
1188attr_list_merge_filter (PangoAttribute *attribute,
1189 gpointer list)
1190{
1191 pango_attr_list_change (list, attr: pango_attribute_copy (attr: attribute));
1192 return FALSE;
1193}
1194
1195/* test something that gtk does */
1196static void
1197test_merge (void)
1198{
1199 PangoAttrList *list;
1200 PangoAttrList *list2;
1201
1202 list = pango_attr_list_from_string (text: "0 200 rise 100\n"
1203 "5 15 family Times\n"
1204 "10 11 size 10240\n"
1205 "11 100 fallback 0\n"
1206 "30 60 stretch 2\n");
1207
1208 list2 = pango_attr_list_from_string (text: "11 13 size 10240\n"
1209 "13 15 size 11264\n"
1210 "40 50 size 12288\n");
1211
1212 pango_attr_list_filter (list: list2, func: attr_list_merge_filter, data: list);
1213
1214 assert_attr_list (list, expected: "0 200 rise 100\n"
1215 "5 15 family Times\n"
1216 "10 13 size 10240\n"
1217 "11 100 fallback false\n"
1218 "13 15 size 11264\n"
1219 "30 60 stretch condensed\n"
1220 "40 50 size 12288\n");
1221
1222 pango_attr_list_unref (list);
1223 pango_attr_list_unref (list: list2);
1224}
1225
1226/* reproduce what the links example in gtk4-demo does
1227 * with the colored Google link
1228 */
1229static void
1230test_merge2 (void)
1231{
1232 PangoAttrList *list;
1233 PangoAttribute *attr;
1234
1235 list = pango_attr_list_from_string (text: "0 10 underline 1\n"
1236 "0 10 foreground #00000000ffff\n");
1237
1238 attr = attribute_from_string (str: "2 3 foreground #ffff00000000");
1239 pango_attr_list_change (list, attr);
1240
1241 assert_attr_list (list, expected: "0 10 underline single\n"
1242 "0 2 foreground #00000000ffff\n"
1243 "2 3 foreground #ffff00000000\n"
1244 "3 10 foreground #00000000ffff");
1245
1246 attr = attribute_from_string (str: "3 4 foreground #0000ffff0000");
1247 pango_attr_list_change (list, attr);
1248
1249 assert_attr_list (list, expected: "0 10 underline single\n"
1250 "0 2 foreground #00000000ffff\n"
1251 "2 3 foreground #ffff00000000\n"
1252 "3 4 foreground #0000ffff0000\n"
1253 "4 10 foreground #00000000ffff");
1254
1255 attr = attribute_from_string (str: "4 5 foreground #00000000ffff");
1256 pango_attr_list_change (list, attr);
1257
1258 assert_attr_list (list, expected: "0 10 underline single\n"
1259 "0 2 foreground #00000000ffff\n"
1260 "2 3 foreground #ffff00000000\n"
1261 "3 4 foreground #0000ffff0000\n"
1262 "4 10 foreground #00000000ffff");
1263
1264 pango_attr_list_unref (list);
1265}
1266
1267/* This only prints rise, size, scale, allow_breaks and line_break,
1268 * which are the only relevant attributes in the tests that use this
1269 * function.
1270 */
1271static void
1272print_tags_for_attributes (PangoAttrIterator *iter,
1273 GString *s)
1274{
1275 PangoAttribute *attr;
1276
1277 attr = pango_attr_iterator_get (iterator: iter, type: PANGO_ATTR_RISE);
1278 if (attr)
1279 g_string_append_printf (string: s, format: "%d %d rise %d\n",
1280 attr->start_index, attr->end_index,
1281 ((PangoAttrInt*)attr)->value);
1282
1283 attr = pango_attr_iterator_get (iterator: iter, type: PANGO_ATTR_SIZE);
1284 if (attr)
1285 g_string_append_printf (string: s, format: "%d %d size %d\n",
1286 attr->start_index, attr->end_index,
1287 ((PangoAttrInt*)attr)->value);
1288
1289 attr = pango_attr_iterator_get (iterator: iter, type: PANGO_ATTR_SCALE);
1290 if (attr)
1291 g_string_append_printf (string: s, format: "%d %d scale %f\n",
1292 attr->start_index, attr->end_index,
1293 ((PangoAttrFloat*)attr)->value);
1294
1295 attr = pango_attr_iterator_get (iterator: iter, type: PANGO_ATTR_ALLOW_BREAKS);
1296 if (attr)
1297 g_string_append_printf (string: s, format: "%d %d allow_breaks %d\n",
1298 attr->start_index, attr->end_index,
1299 ((PangoAttrInt*)attr)->value);
1300}
1301
1302static void
1303test_iter_epsilon_zero (void)
1304{
1305 const char *markup = "𝜀<span rise=\"-6000\" size=\"x-small\" font_desc=\"italic\">0</span> = 𝜔<span rise=\"8000\" size=\"smaller\">𝜔<span rise=\"14000\" size=\"smaller\">𝜔<span rise=\"20000\">.<span rise=\"23000\">.<span rise=\"26000\">.</span></span></span></span></span>";
1306 PangoAttrList *attributes;
1307 PangoAttrIterator *attr;
1308 char *text;
1309 GError *error = NULL;
1310 GString *s;
1311
1312 s = g_string_new (init: "");
1313
1314 pango_parse_markup (markup_text: markup, length: -1, accel_marker: 0, attr_list: &attributes, text: &text, NULL, error: &error);
1315 g_assert_no_error (error);
1316 g_assert_cmpstr (text, ==, "𝜀0 = 𝜔𝜔𝜔...");
1317
1318 attr = pango_attr_list_get_iterator (list: attributes);
1319 do
1320 {
1321 int start, end;
1322
1323 pango_attr_iterator_range (iterator: attr, start: &start, end: &end);
1324
1325 g_string_append_printf (string: s, format: "range: [%d, %d]\n", start, end);
1326
1327 print_tags_for_attributes (iter: attr, s);
1328 }
1329 while (pango_attr_iterator_next (iterator: attr));
1330
1331 g_assert_cmpstr (s->str, ==,
1332 "range: [0, 4]\n"
1333 "range: [4, 5]\n"
1334 "4 5 rise -6000\n"
1335 "4 5 scale 0.694444\n"
1336 "range: [5, 12]\n"
1337 "range: [12, 16]\n"
1338 "12 23 rise 8000\n"
1339 "12 23 scale 0.833333\n"
1340 "range: [16, 20]\n"
1341 "16 23 rise 14000\n"
1342 "16 23 scale 0.694444\n"
1343 "range: [20, 21]\n"
1344 "20 23 rise 20000\n"
1345 "16 23 scale 0.694444\n"
1346 "range: [21, 22]\n"
1347 "21 23 rise 23000\n"
1348 "16 23 scale 0.694444\n"
1349 "range: [22, 23]\n"
1350 "22 23 rise 26000\n"
1351 "16 23 scale 0.694444\n"
1352 "range: [23, 2147483647]\n");
1353
1354 g_free (mem: text);
1355 pango_attr_list_unref (list: attributes);
1356 pango_attr_iterator_destroy (iterator: attr);
1357
1358 g_string_free (string: s, TRUE);
1359}
1360
1361static void
1362test_gnumeric_splice (void)
1363{
1364 PangoAttrList *list, *list2;
1365
1366 list = pango_attr_list_from_string (text: "0 -1 font-desc \"Sans 10\"\n");
1367 list2 = pango_attr_list_from_string (text: "1 2 weight bold\n");
1368
1369 pango_attr_list_splice (list, other: list2, pos: 0, len: 0);
1370
1371 assert_attr_list (list, expected: "0 4294967295 font-desc \"Sans 10\"\n"
1372 "1 2 weight bold\n");
1373
1374 pango_attr_list_unref (list);
1375 pango_attr_list_unref (list: list2);
1376}
1377
1378static void
1379test_change_order (void)
1380{
1381 PangoAttrList *list;
1382 PangoAttribute *attr;
1383
1384 list = pango_attr_list_from_string (text: "1 -1 font-features \"tnum=1\"\n"
1385 "0 20 font-desc \"sans-serif\"\n"
1386 "0 9 size 102400\n");
1387
1388 attr = pango_attr_font_features_new (features: "tnum=2");
1389 attr->end_index = 9;
1390
1391 pango_attr_list_change (list, attr);
1392
1393 assert_attr_list (list, expected: "0 9 font-features \"tnum=2\"\n"
1394 "0 20 font-desc \"sans-serif\"\n"
1395 "0 9 size 102400\n"
1396 "9 4294967295 font-features \"tnum=1\"\n");
1397
1398 pango_attr_list_unref (list);
1399}
1400
1401static void
1402test_pitivi_crash (void)
1403{
1404 PangoAttrList *list;
1405 PangoAttribute *attr;
1406
1407 list = pango_attr_list_from_string (text: "0 8 font-features \"tnum=1\"\n"
1408 "0 20 font-desc \"sans-serif\"\n"
1409 "0 9 size 102400\n");
1410
1411 attr = pango_attr_font_features_new (features: "tnum=2");
1412 attr->end_index = 9;
1413
1414 pango_attr_list_change (list, attr);
1415
1416 assert_attr_list (list, expected: "0 9 font-features \"tnum=2\"\n"
1417 "0 20 font-desc \"sans-serif\"\n"
1418 "0 9 size 102400\n");
1419
1420 pango_attr_list_unref (list);
1421}
1422
1423int
1424main (int argc, char *argv[])
1425{
1426 g_test_init (argc: &argc, argv: &argv, NULL);
1427
1428 g_test_add_func (testpath: "/attributes/basic", test_func: test_attributes_basic);
1429 g_test_add_func (testpath: "/attributes/equal", test_func: test_attributes_equal);
1430 g_test_add_func (testpath: "/attributes/register", test_func: test_attributes_register);
1431 g_test_add_func (testpath: "/attributes/binding-helpers", test_func: test_binding_helpers);
1432 g_test_add_func (testpath: "/attributes/list/basic", test_func: test_list);
1433 g_test_add_func (testpath: "/attributes/list/change", test_func: test_list_change);
1434 g_test_add_func (testpath: "/attributes/list/change2", test_func: test_list_change2);
1435 g_test_add_func (testpath: "/attributes/list/change3", test_func: test_list_change3);
1436 g_test_add_func (testpath: "/attributes/list/change4", test_func: test_list_change4);
1437 g_test_add_func (testpath: "/attributes/list/change5", test_func: test_list_change5);
1438 g_test_add_func (testpath: "/attributes/list/change6", test_func: test_list_change6);
1439 g_test_add_func (testpath: "/attributes/list/change7", test_func: test_list_change7);
1440 g_test_add_func (testpath: "/attributes/list/change8", test_func: test_list_change8);
1441 g_test_add_func (testpath: "/attributes/list/change9", test_func: test_list_change9);
1442 g_test_add_func (testpath: "/attributes/list/change10", test_func: test_list_change10);
1443 g_test_add_func (testpath: "/attributes/list/change11", test_func: test_list_change11);
1444 g_test_add_func (testpath: "/attributes/list/change12", test_func: test_list_change12);
1445 g_test_add_func (testpath: "/attributes/list/splice", test_func: test_list_splice);
1446 g_test_add_func (testpath: "/attributes/list/splice2", test_func: test_list_splice2);
1447 g_test_add_func (testpath: "/attributes/list/splice3", test_func: test_list_splice3);
1448 g_test_add_func (testpath: "/attributes/list/filter", test_func: test_list_filter);
1449 g_test_add_func (testpath: "/attributes/list/update", test_func: test_list_update);
1450 g_test_add_func (testpath: "/attributes/list/update2", test_func: test_list_update2);
1451 g_test_add_func (testpath: "/attributes/list/update3", test_func: test_list_update3);
1452 g_test_add_func (testpath: "/attributes/list/equal", test_func: test_list_equal);
1453 g_test_add_func (testpath: "/attributes/list/insert", test_func: test_insert);
1454 g_test_add_func (testpath: "/attributes/list/insert2", test_func: test_insert2);
1455 g_test_add_func (testpath: "/attributes/list/merge", test_func: test_merge);
1456 g_test_add_func (testpath: "/attributes/list/merge2", test_func: test_merge2);
1457 g_test_add_func (testpath: "/attributes/iter/basic", test_func: test_iter);
1458 g_test_add_func (testpath: "/attributes/iter/get", test_func: test_iter_get);
1459 g_test_add_func (testpath: "/attributes/iter/get_font", test_func: test_iter_get_font);
1460 g_test_add_func (testpath: "/attributes/iter/get_attrs", test_func: test_iter_get_attrs);
1461 g_test_add_func (testpath: "/attributes/iter/epsilon_zero", test_func: test_iter_epsilon_zero);
1462 g_test_add_func (testpath: "/attributes/gnumeric-splice", test_func: test_gnumeric_splice);
1463 g_test_add_func (testpath: "/attributes/list/change_order", test_func: test_change_order);
1464 g_test_add_func (testpath: "/attributes/pitivi-crash", test_func: test_pitivi_crash);
1465
1466 return g_test_run ();
1467}
1468

source code of gtk/subprojects/pango/tests/testattributes.c