GNOME Bugzilla – Bug 313181
color changes break arabic shaping
Last modified: 2018-05-22 12:10:57 UTC
not quite sure if this is a bug or programmer error -- but either way, two separate tests i've done with similar results. the first: trying to write arabic text in a gtk_text_buffer, where some characters are in a different color than other characters. i tried the following: tb = gtk_text_buffer_new(NULL); gtk_text_buffer_get_start_iter(tb, &textIter); tag = gtk_text_buffer_create_tag(tb, "black_settings", "justification", GTK_JUSTIFY_RIGHT, "wrap-mode", GTK_WRAP_WORD, "font", "Verdana 24", "foreground", "black", NULL); tag2 = gtk_text_buffer_create_tag(tb, "blue_settings", "justification", GTK_JUSTIFY_RIGHT, "wrap-mode", GTK_WRAP_WORD, "font", "Verdana 24", "foreground", "blue", NULL); gtk_text_buffer_insert(tb, &textIter, "Correct:\n", strlen("Correct:\n")); gtk_text_buffer_insert_with_tags(tb, &textIter, str, -1, tag, NULL); gtk_text_buffer_insert(tb, &textIter, "\n\nNow:\n", strlen("\n\nNow:\n")); gtk_text_buffer_insert_with_tags(tb, &textIter, str, 33, tag, NULL); gtk_text_buffer_insert_with_tags(tb, &textIter, str+33, -1, tag2, NULL); the output of this is broken shaping, as can be seen in this screenshot taking of a gtk# version of the above program: http://piousity.net/images/arabic_html-04.29.2005.png the second thing i tried was due to me thinking that the above might be an error on my understanding of the apis. so i tried something simpler - populating a label and changing some of the colors of the label. there are two subcases, one works, and one doesn't: str = readArabicTextFromXML(); asprintf(&s2, "<span size=\"x-large\" foreground=\"blue\">%s</span><span size=\"x-large\" foreground=\"red\">%s</span>", substr(str, 0, 33), substr(str, 33, strlen(str))); pango_parse_markup(s2, -1, 0, &attrList, NULL, NULL, NULL); window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window1), _("window1")); label1 = gtk_label_new (str); gtk_label_set_attributes(GTK_LABEL(label1), attrList); in this case, although the substr splits it into two strings, where the first letter of the second word is part of the first string and the remainder of the second word is part of the second string, the first word comes up blue and the second comes up red [rather than the first word and first letter of second word being blue and the rest being red]. alternately, if you change the asprintf to be identical with the exception of the fact that you remove the color being red from the second half, it works as expected. what i really want to do is be able to insert arabic text in a gtk_text_buffer, being able to have different colors amongst some of the letters, without breaking shaping. any help would be appreciated. thanks.
Thanks Ahmed for the report. It would have been easier to test if you have had attached source code. For example my first suspection was that you are cutting the string in an invalid position... Anyway, I can confirm that using gtk_text_buffer_apply_tag (or gtk_text_buffer_insert_with_tags which uses that indirectly) does break Arabic joining no matter what the tag does, but for me, the pango_parse_markup+gtk_label_set_attributes works like a charm. I'm attaching test case and screenshot.
Created attachment 50627 [details] Test case used
Created attachment 50628 [details] screenshot of the test case running The label at the bottom of the shot is the correct rendering. The two lines in the text buffer are broken.
The problem is that GtkTextAttrAppearance is causing shaping to be interrupted It seems to me that in pangolayout.c:no_shape_filter_func(), we could just check for attributes that break shaping rather than vice-versa. I'll attach a patch that does that, but it's only half the solution - since GtkTextView adds separate PANGO_ATTR_FONT_DESC for each text tag, whether it needs to or not. The simple fix would be to use pango_attr_list_change() rather than pango_attr_list_insert() in gtktextlayout.c, but that would have some serious performance impacts, since pango_attr_list_change() is O(N).... it's probably necessary to add some more complicated custom logic and remember the last font attribute that was added to the line and extend it as necessary. In pseudo-code: if (last_font_attr && pango_font_description_equal (last_font_attr, new_font)) last_font_attr->end_index += length; else { last_font_attr = /* create a new font attr */; } I'd like to see some testing of the patch I'm attaching here and a working GtkTextView patch before we commit this patch to CVS.
Created attachment 50734 [details] [review] Proposed patch for Pango
Marking patch as needs-work, since it needs an accompanying Gtk+ patch.
We still should take this patch I think. In the mean time, I added pango_shape_full() that fixes this for most simple cases.
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/pango/issues/28.