1 #include <gtk/gtk.h>
2
3 void
print_attribute(PangoAttribute * attr,GString * string)4 print_attribute (PangoAttribute *attr, GString *string)
5 {
6 GEnumClass *class;
7 GEnumValue *value;
8
9 g_string_append_printf (string, "[%d,%d]", attr->start_index, attr->end_index);
10
11 class = g_type_class_ref (pango_attr_type_get_type ());
12 value = g_enum_get_value (class, attr->klass->type);
13 g_string_append_printf (string, "%s=", value->value_nick);
14 g_type_class_unref (class);
15
16 switch (attr->klass->type)
17 {
18 case PANGO_ATTR_LANGUAGE:
19 g_string_append (string, pango_language_to_string (((PangoAttrLanguage *)attr)->value));
20 break;
21 case PANGO_ATTR_FAMILY:
22 case PANGO_ATTR_FONT_FEATURES:
23 g_string_append (string, ((PangoAttrString *)attr)->value);
24 break;
25 case PANGO_ATTR_STYLE:
26 case PANGO_ATTR_WEIGHT:
27 case PANGO_ATTR_VARIANT:
28 case PANGO_ATTR_STRETCH:
29 case PANGO_ATTR_SIZE:
30 case PANGO_ATTR_ABSOLUTE_SIZE:
31 case PANGO_ATTR_UNDERLINE:
32 case PANGO_ATTR_OVERLINE:
33 case PANGO_ATTR_STRIKETHROUGH:
34 case PANGO_ATTR_RISE:
35 case PANGO_ATTR_FALLBACK:
36 case PANGO_ATTR_LETTER_SPACING:
37 case PANGO_ATTR_GRAVITY:
38 case PANGO_ATTR_GRAVITY_HINT:
39 case PANGO_ATTR_FOREGROUND_ALPHA:
40 case PANGO_ATTR_BACKGROUND_ALPHA:
41 case PANGO_ATTR_ALLOW_BREAKS:
42 case PANGO_ATTR_INSERT_HYPHENS:
43 case PANGO_ATTR_SHOW:
44 #if PANGO_VERSION_CHECK(1, 49, 0)
45 case PANGO_ATTR_ABSOLUTE_LINE_HEIGHT:
46 case PANGO_ATTR_TEXT_TRANSFORM:
47 case PANGO_ATTR_WORD:
48 case PANGO_ATTR_SENTENCE:
49 case PANGO_ATTR_BASELINE_SHIFT:
50 case PANGO_ATTR_FONT_SCALE:
51 #endif
52 g_string_append_printf (string, "%d", ((PangoAttrInt *)attr)->value);
53 break;
54 case PANGO_ATTR_FONT_DESC:
55 {
56 char *text = pango_font_description_to_string (((PangoAttrFontDesc *)attr)->desc);
57 g_string_append (string, text);
58 g_free (text);
59 }
60 break;
61 case PANGO_ATTR_FOREGROUND:
62 case PANGO_ATTR_BACKGROUND:
63 case PANGO_ATTR_UNDERLINE_COLOR:
64 case PANGO_ATTR_OVERLINE_COLOR:
65 case PANGO_ATTR_STRIKETHROUGH_COLOR:
66 {
67 char *text = pango_color_to_string (&((PangoAttrColor *)attr)->color);
68 g_string_append (string, text);
69 g_free (text);
70 }
71 break;
72 case PANGO_ATTR_SHAPE:
73 g_string_append_printf (string, "shape");
74 break;
75 case PANGO_ATTR_SCALE:
76 #if PANGO_VERSION_CHECK(1, 49, 0)
77 case PANGO_ATTR_LINE_HEIGHT:
78 #endif
79 {
80 char val[20];
81
82 g_ascii_formatd (val, 20, "%f", ((PangoAttrFloat *)attr)->value);
83 g_string_append (string, val);
84 }
85 break;
86 case PANGO_ATTR_INVALID:
87 default:
88 g_assert_not_reached ();
89 break;
90 }
91 }
92
93 void
print_attr_list(PangoAttrList * attrs,GString * string)94 print_attr_list (PangoAttrList *attrs, GString *string)
95 {
96 PangoAttrIterator *iter;
97
98 if (!attrs)
99 return;
100
101 iter = pango_attr_list_get_iterator (attrs);
102 do {
103 int start, end;
104 GSList *list, *l;
105
106 pango_attr_iterator_range (iter, &start, &end);
107 g_string_append_printf (string, "range %d %d\n", start, end);
108 list = pango_attr_iterator_get_attrs (iter);
109 for (l = list; l; l = l->next)
110 {
111 PangoAttribute *attr = l->data;
112 print_attribute (attr, string);
113 g_string_append (string, "\n");
114 }
115 g_slist_free_full (list, (GDestroyNotify)pango_attribute_destroy);
116 } while (pango_attr_iterator_next (iter));
117
118 pango_attr_iterator_destroy (iter);
119 }
120
121 static void
test_label_markup(void)122 test_label_markup (void)
123 {
124 GtkWidget *window;
125 GtkWidget *label;
126 PangoAttrList *attrs;
127 GString *str;
128 const char *text;
129
130 window = gtk_window_new ();
131 label = gtk_label_new ("");
132
133 gtk_window_set_child (GTK_WINDOW (window), label);
134 gtk_window_set_mnemonics_visible (GTK_WINDOW (window), TRUE);
135
136 gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
137 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
138 gtk_label_set_label (GTK_LABEL (label), "<a href=\"test\"><span font_style=\"italic\">abc</span> _def</a>");
139
140 g_assert_cmpuint (gtk_label_get_mnemonic_keyval (GTK_LABEL (label)), ==, 'd');
141
142 text = pango_layout_get_text (gtk_label_get_layout (GTK_LABEL (label)));
143 g_assert_cmpstr (text, ==, "abc def");
144
145 attrs = pango_layout_get_attributes (gtk_label_get_layout (GTK_LABEL (label)));
146 str = g_string_new ("");
147 print_attr_list (attrs, str);
148
149 g_assert_cmpstr (str->str, ==,
150 "range 0 3\n"
151 "[0,4]underline=1\n"
152 "[0,8]foreground=#1b1b6a6acbcb\n"
153 "[0,3]style=2\n"
154 "range 3 4\n"
155 "[0,4]underline=1\n"
156 "[0,8]foreground=#1b1b6a6acbcb\n"
157 "range 4 5\n"
158 "[0,8]foreground=#1b1b6a6acbcb\n"
159 "[4,5]underline=3\n"
160 "range 5 8\n"
161 "[0,8]foreground=#1b1b6a6acbcb\n"
162 "[5,8]underline=1\n"
163 "range 8 2147483647\n");
164
165
166 gtk_window_set_mnemonics_visible (GTK_WINDOW (window), FALSE);
167
168 text = pango_layout_get_text (gtk_label_get_layout (GTK_LABEL (label)));
169 g_assert_cmpstr (text, ==, "abc def");
170
171 attrs = pango_layout_get_attributes (gtk_label_get_layout (GTK_LABEL (label)));
172 g_string_set_size (str, 0);
173 print_attr_list (attrs, str);
174
175 g_assert_cmpstr (str->str, ==,
176 "range 0 3\n"
177 "[0,7]underline=1\n"
178 "[0,7]foreground=#1b1b6a6acbcb\n"
179 "[0,3]style=2\n"
180 "range 3 7\n"
181 "[0,7]underline=1\n"
182 "[0,7]foreground=#1b1b6a6acbcb\n"
183 "range 7 2147483647\n");
184
185 gtk_window_set_mnemonics_visible (GTK_WINDOW (window), TRUE);
186 gtk_label_set_use_underline (GTK_LABEL (label), FALSE);
187
188 text = pango_layout_get_text (gtk_label_get_layout (GTK_LABEL (label)));
189 g_assert_cmpstr (text, ==, "abc _def");
190
191 attrs = pango_layout_get_attributes (gtk_label_get_layout (GTK_LABEL (label)));
192 g_string_set_size (str, 0);
193 print_attr_list (attrs, str);
194
195 g_assert_cmpstr (str->str, ==,
196 "range 0 3\n"
197 "[0,8]underline=1\n"
198 "[0,8]foreground=#1b1b6a6acbcb\n"
199 "[0,3]style=2\n"
200 "range 3 8\n"
201 "[0,8]underline=1\n"
202 "[0,8]foreground=#1b1b6a6acbcb\n"
203 "range 8 2147483647\n");
204
205 g_string_free (str, TRUE);
206
207 gtk_window_destroy (GTK_WINDOW (window));
208 }
209
210 static void
test_label_underline(void)211 test_label_underline (void)
212 {
213 GtkWidget *window;
214 GtkWidget *label;
215
216 window = gtk_window_new ();
217
218 label = gtk_label_new ("");
219
220 gtk_window_set_child (GTK_WINDOW (window), label);
221 gtk_window_set_mnemonics_visible (GTK_WINDOW (window), TRUE);
222
223 gtk_label_set_use_markup (GTK_LABEL (label), FALSE);
224 gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
225 gtk_label_set_label (GTK_LABEL (label), "tes_t & no markup <<");
226
227 g_assert_cmpint (gtk_label_get_mnemonic_keyval (GTK_LABEL (label)), ==, GDK_KEY_t);
228
229 gtk_window_destroy (GTK_WINDOW (window));
230 }
231
232 static void
test_label_parse_more(void)233 test_label_parse_more (void)
234 {
235 struct {
236 const char *input;
237 gboolean use_underline;
238 gboolean use_markup;
239 const char *text;
240 guint accel;
241 } tests[] = {
242 { "tes_t m__e mo_re", TRUE, FALSE, "test m_e more", GDK_KEY_t },
243 { "test m__e mo_re", TRUE, FALSE, "test m_e more", GDK_KEY_r },
244 { "tes_t m__e mo_re", FALSE, FALSE, "tes_t m__e mo_re", GDK_KEY_VoidSymbol },
245 { "<span font='test_font'>test <a href='bla'>w_ith</a> bla</span>", TRUE, TRUE, "test with bla", GDK_KEY_i },
246 { "<span font='test_font'>test <a href='bla'>w_ith</a> bla</span>", FALSE, TRUE, "test w_ith bla", GDK_KEY_VoidSymbol },
247 };
248 GtkWidget *label;
249
250 label = gtk_label_new ("");
251
252 for (int i = 0; i < G_N_ELEMENTS (tests); i++)
253 {
254 gtk_label_set_use_underline (GTK_LABEL (label), tests[i].use_underline);
255 gtk_label_set_use_markup (GTK_LABEL (label), tests[i].use_markup);
256 gtk_label_set_label (GTK_LABEL (label), tests[i].input);
257
258 g_assert_cmpstr (gtk_label_get_label (GTK_LABEL (label)), ==, tests[i].input);
259 g_assert_cmpstr (gtk_label_get_text (GTK_LABEL (label)), ==, tests[i].text);
260 g_assert_cmpuint (gtk_label_get_mnemonic_keyval (GTK_LABEL (label)), ==, tests[i].accel);
261 }
262
263 g_object_ref_sink (label);
264 g_object_unref (label);
265 }
266
267 int
main(int argc,char * argv[])268 main (int argc, char *argv[])
269 {
270 gtk_test_init (&argc, &argv);
271
272 g_test_add_func ("/label/markup-parse", test_label_markup);
273 g_test_add_func ("/label/underline-parse", test_label_underline);
274 g_test_add_func ("/label/parse-more", test_label_parse_more);
275
276 return g_test_run ();
277 }
278