~ubuntu-branches/ubuntu/trusty/gtkhtml3.14/trusty-proposed

« back to all changes in this revision

Viewing changes to gtkhtml/htmltext.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2010-11-02 14:34:48 UTC
  • mfrom: (1.6.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20101102143448-3cxzy1h4oh5v7igz
Tags: 1:3.32.0-0ubuntu1
* New upstream release 3.32.0
  - Crash after closing inline view of text attachment (LP: #178959, #284060)
  - Translations not working in Emoticons, Find/Replace dialogs (LP: #562633)
* debian/patches/gtkhtml3.14_ftbfs.patch: dropped.
* debian/rules: append API_VER for libgtkhtml-editor chrpath as well
* debian/libgtkhtml-editor-dev.install: append api version to pkgconfig
  file name.
* debian/*.shlibs: update shlibs files for new version with same soname, also
  rename libgtkhtml-editor to libgtkhtml-editor-3.14
* debian/control: Replaces/Conflicts gtkhtml3.14 (<< 3.32.0)
* debian/control: bump libgtk2.0-dev and libgail-dev Build-Depends to 2.20
* debian/rules: disable deprecation warnings so the build completes

Show diffs side-by-side

added added

removed removed

Lines of Context:
105
105
{
106
106
        gint i;
107
107
 
108
 
        for (i = 0; i < pi->n; i ++) {
109
 
                pango_item_free (pi->entries [i].glyph_item.item);
110
 
                if (pi->entries [i].glyph_item.glyphs)
111
 
                        pango_glyph_string_free (pi->entries [i].glyph_item.glyphs);
112
 
                g_free (pi->entries [i].widths);
 
108
        for (i = 0; i < pi->n; i++) {
 
109
                pango_item_free (pi->entries[i].glyph_item.item);
 
110
                if (pi->entries[i].glyph_item.glyphs)
 
111
                        pango_glyph_string_free (pi->entries[i].glyph_item.glyphs);
 
112
                g_free (pi->entries[i].widths);
113
113
        }
114
114
        g_free (pi->entries);
115
115
        g_free (pi->attrs);
197
197
        guint i;
198
198
 
199
199
        printf ("words: %d | ", t->words);
200
 
        for (i = 0; i < t->words; i ++)
 
200
        for (i = 0; i < t->words; i++)
201
201
                printf ("%d ", t->word_width [i]);
202
202
        printf ("\n");
203
203
}
218
218
                coff += s ? g_utf8_pointer_to_offset (ls, s) : g_utf8_strlen (ls, -1);
219
219
                (*word_out) ++;
220
220
                if (s)
221
 
                        s ++;
 
221
                        s++;
222
222
        } while (s && coff < off);
223
223
 
224
224
        *left_out  = off - loff;
405
405
                begin_index = html_text_get_index (text, begin);
406
406
                end_index = tail - text->text;
407
407
                text->text_bytes -= tail - (text->text + begin_index);
408
 
                text->text [begin_index] = 0;
 
408
                text->text[begin_index] = 0;
409
409
                cut_attr_list (text, begin_index, end_index);
410
410
                if (end_index < rvt->text_bytes)
411
411
                        cut_attr_list (rvt, end_index, rvt->text_bytes);
799
799
                *line_offset  += skip;
800
800
                if (*line_offset != -1)
801
801
                        sum_skip += skip - 1;
802
 
                l ++;
 
802
                l++;
803
803
                if (tabs)
804
804
                        (*tabs) ++;
805
805
        }
834
834
                                if (*s == '\t')
835
835
                                        line_offset += 8 - (line_offset % 8);
836
836
                                else
837
 
                                        line_offset ++;
 
837
                                        line_offset++;
838
838
                                s = g_utf8_next_char (s);
839
 
                                offset --;
 
839
                                offset--;
840
840
                        }
841
841
                }
842
842
        }
851
851
        gint idx = 0;
852
852
 
853
853
        if (pi->n > 0) {
854
 
                while (idx < pi->n - 1 && offset >= pi->entries [idx].glyph_item.item->num_chars) {
855
 
                        offset -= pi->entries [idx].glyph_item.item->num_chars;
856
 
                        idx ++;
 
854
                while (idx < pi->n - 1 && offset >= pi->entries[idx].glyph_item.item->num_chars) {
 
855
                        offset -= pi->entries[idx].glyph_item.item->num_chars;
 
856
                        idx++;
857
857
                }
858
858
 
859
859
                *item_offset = offset;
975
975
 
976
976
        idx = html_text_get_item_index (text, painter, offset, &offset);
977
977
        if (need_ascent_descent) {
978
 
                update_asc_dsc (painter, pi->entries [idx].glyph_item.item, &ascent, &descent);
979
 
                font = pi->entries [idx].glyph_item.item->analysis.font;
980
 
                language = pi->entries [idx].glyph_item.item->analysis.language;
 
978
                update_asc_dsc (painter, pi->entries[idx].glyph_item.item, &ascent, &descent);
 
979
                font = pi->entries[idx].glyph_item.item->analysis.font;
 
980
                language = pi->entries[idx].glyph_item.item->analysis.language;
981
981
        }
982
982
        while (len > 0) {
983
983
                gint old_idx;
984
984
 
985
985
                if (*s == '\t') {
986
986
                        gint skip = 8 - (line_offset % 8);
987
 
                        width += skip*pi->entries [idx].widths [offset];
 
987
                        width += skip*pi->entries[idx].widths[offset];
988
988
                        line_offset += skip;
989
989
                } else {
990
 
                        width += pi->entries [idx].widths [offset];
991
 
                        line_offset ++;
 
990
                        width += pi->entries[idx].widths[offset];
 
991
                        line_offset++;
992
992
                }
993
 
                len --;
 
993
                len--;
994
994
 
995
995
                old_idx = idx;
996
996
                if (html_text_pi_forward (pi, &idx, &offset) && idx != old_idx)
997
 
                        if (len > 0 && (need_ascent_descent) && (pi->entries [idx].glyph_item.item->analysis.font != font
998
 
                                                                 || pi->entries [idx].glyph_item.item->analysis.language != language)) {
999
 
                                update_asc_dsc (painter, pi->entries [idx].glyph_item.item, &ascent, &descent);
 
997
                        if (len > 0 && (need_ascent_descent) && (pi->entries[idx].glyph_item.item->analysis.font != font
 
998
                                                                 || pi->entries[idx].glyph_item.item->analysis.language != language)) {
 
999
                                update_asc_dsc (painter, pi->entries[idx].glyph_item.item, &ascent, &descent);
1000
1000
                        }
1001
1001
 
1002
1002
                s = g_utf8_next_char (s);
1138
1138
gint
1139
1139
html_text_pango_info_get_index (HTMLTextPangoInfo *pi, gint byte_offset, gint idx)
1140
1140
{
1141
 
        while (idx < pi->n && pi->entries [idx].glyph_item.item->offset + pi->entries [idx].glyph_item.item->length <= byte_offset)
1142
 
                idx ++;
 
1141
        while (idx < pi->n && pi->entries[idx].glyph_item.item->offset + pi->entries[idx].glyph_item.item->length <= byte_offset)
 
1142
                idx++;
1143
1143
 
1144
1144
        return idx;
1145
1145
}
1165
1165
        gint i;
1166
1166
        gunichar last_uc = 0;
1167
1167
 
1168
 
        for (i = 0; i < len; i ++) {
 
1168
        for (i = 0; i < len; i++) {
1169
1169
                gunichar uc = g_utf8_get_char (s);
1170
1170
 
1171
 
                if (attrs [i].is_line_break) {
 
1171
                if (attrs[i].is_line_break) {
1172
1172
                        if (last_uc == '.' || last_uc == '/' ||
1173
1173
                            last_uc == '-' || last_uc == '$' ||
1174
1174
                            last_uc == '+' || last_uc == '?' ||
1176
1176
                            last_uc == '}' ||
1177
1177
                            last_uc == ']' ||
1178
1178
                            last_uc == '>')
1179
 
                                attrs [i].is_line_break = 0;
 
1179
                                attrs[i].is_line_break = 0;
1180
1180
                        else if ((uc == '(' ||
1181
1181
                                  uc == '{' ||
1182
1182
                                  uc == '[' ||
1183
1183
                                  uc == '<'
1184
1184
                                  )
1185
 
                                 && i > 0 && !attrs [i - 1].is_white)
1186
 
                                attrs [i].is_line_break = 0;
 
1185
                                 && i > 0 && !attrs[i - 1].is_white)
 
1186
                                attrs[i].is_line_break = 0;
1187
1187
                }
1188
1188
                s = g_utf8_next_char (s);
1189
1189
                last_uc = uc;
1435
1435
                if (text->pi && text->pi->attrs)
1436
1436
                        html_text_remove_unwanted_line_breaks (text->text, text->text_len, text->pi->attrs);
1437
1437
 
1438
 
                for (i = 0, cur = items; i < text->pi->n; i ++, cur = cur->next)
1439
 
                        text->pi->entries [i].glyph_item.item = (PangoItem *) cur->data;
 
1438
                for (i = 0, cur = items; i < text->pi->n; i++, cur = cur->next)
 
1439
                        text->pi->entries[i].glyph_item.item = (PangoItem *) cur->data;
1440
1440
 
1441
 
                for (i = 0; i < text->pi->n; i ++) {
 
1441
                for (i = 0; i < text->pi->n; i++) {
1442
1442
                        PangoItem *item;
1443
1443
                        PangoGlyphString *glyphs;
1444
1444
 
1445
 
                        item = text->pi->entries [i].glyph_item.item;
1446
 
                        glyphs = text->pi->entries [i].glyph_item.glyphs = pango_glyph_string_new ();
 
1445
                        item = text->pi->entries[i].glyph_item.item;
 
1446
                        glyphs = text->pi->entries[i].glyph_item.glyphs = pango_glyph_string_new ();
1447
1447
 
1448
1448
                        /* printf ("item pos %d len %d\n", item->offset, item->length); */
1449
1449
 
1450
 
                        text->pi->entries [i].widths = g_new (PangoGlyphUnit, item->num_chars);
1451
 
                        if (text->text [item->offset] == '\t')
 
1450
                        text->pi->entries[i].widths = g_new (PangoGlyphUnit, item->num_chars);
 
1451
                        if (text->text[item->offset] == '\t')
1452
1452
                                html_text_shape_tab (text, glyphs);
1453
1453
                        else
1454
1454
                                pango_shape (text->text + item->offset, item->length, &item->analysis, glyphs);
1455
1455
                        html_tmp_fix_pango_glyph_string_get_logical_widths (glyphs, text->text + item->offset, item->length,
1456
 
                                                                            item->analysis.level, text->pi->entries [i].widths);
 
1456
                                                                            item->analysis.level, text->pi->entries[i].widths);
1457
1457
                }
1458
1458
 
1459
1459
                g_list_free (items);
1478
1478
gboolean
1479
1479
html_text_pi_forward (HTMLTextPangoInfo *pi, gint *ii, gint *io)
1480
1480
{
1481
 
        if (*io >= pi->entries [*ii].glyph_item.item->num_chars - 1) {
 
1481
        if (*io >= pi->entries[*ii].glyph_item.item->num_chars - 1) {
1482
1482
                if (*ii >= pi->n -1)
1483
1483
                        return FALSE;
1484
1484
                (*ii) ++;
1513
1513
 
1514
1514
        if (html_text_pi_backward (pi, &ii, &io)) {
1515
1515
                s = g_utf8_prev_char (s);
1516
 
                offset --;
1517
 
                if (pi->attrs [offset].is_white) {
 
1516
                offset--;
 
1517
                if (pi->attrs[offset].is_white) {
1518
1518
                        if (*s == '\t' && offset > 1) {
1519
1519
                                gint skip = 8, co = offset - 1;
1520
1520
 
1521
1521
                                do {
1522
1522
                                        s = g_utf8_prev_char (s);
1523
 
                                        co --;
 
1523
                                        co--;
1524
1524
                                        if (*s != '\t')
1525
 
                                                skip --;
 
1525
                                                skip--;
1526
1526
                                } while (s && co > 0 && *s != '\t');
1527
1527
 
1528
 
                                ww += skip*pi->entries [ii].widths [io];
 
1528
                                ww += skip*pi->entries[ii].widths[io];
1529
1529
                        } else {
1530
 
                                ww += pi->entries [ii].widths [io];
 
1530
                                ww += pi->entries[ii].widths[io];
1531
1531
                        }
1532
 
                        wl ++;
 
1532
                        wl++;
1533
1533
                }
1534
1534
        }
1535
1535
 
1571
1571
        line_offset = html_text_get_line_offset (text, painter, 0);
1572
1572
        s = text->text;
1573
1573
        while (offset < text->text_len) {
1574
 
                if (offset > 0 && html_text_is_line_break (pi->attrs [offset]))
 
1574
                if (offset > 0 && html_text_is_line_break (pi->attrs[offset]))
1575
1575
                        update_mw (text, painter, offset, &last_offset, &ww, &mw, ii, io, s, line_offset);
1576
1576
 
1577
1577
                if (*s == '\t') {
1578
1578
                        gint skip = 8 - (line_offset % 8);
1579
 
                        ww += skip*pi->entries [ii].widths [io];
 
1579
                        ww += skip*pi->entries[ii].widths[io];
1580
1580
                        line_offset += skip;
1581
1581
                } else {
1582
 
                        ww += pi->entries [ii].widths [io];
1583
 
                        line_offset ++;
 
1582
                        ww += pi->entries[ii].widths[io];
 
1583
                        line_offset++;
1584
1584
                }
1585
1585
 
1586
1586
                s = g_utf8_next_char (s);
1587
 
                offset ++;
 
1587
                offset++;
1588
1588
 
1589
1589
                html_text_pi_forward (pi, &ii, &io);
1590
1590
        }
1923
1923
 
1924
1924
                if (uc == ENTITY_NBSP || uc == ' ') {
1925
1925
                        change = check_prev_white (white_space, last_white, delta_out);
1926
 
                        white_space ++;
 
1926
                        white_space++;
1927
1927
                        last_white = uc;
1928
1928
                } else {
1929
1929
                        change = check_last_white (white_space, last_white, delta_out);
1991
1991
 
1992
1992
                if (uc == ENTITY_NBSP || uc == ' ') {
1993
1993
                        write_prev_white_space (white_space, &fill);
1994
 
                        white_space ++;
 
1994
                        white_space++;
1995
1995
                } else {
1996
1996
                        write_last_white_space (white_space, &fill);
1997
1997
                        white_space = 0;
2339
2339
                length = HTML_TEXT (self)->text_len - offset;
2340
2340
 
2341
2341
        /* extend to cursor positions */
2342
 
        while (offset > 0 && !pi->attrs [offset].is_cursor_position) {
2343
 
                offset --;
2344
 
                length ++;
 
2342
        while (offset > 0 && !pi->attrs[offset].is_cursor_position) {
 
2343
                offset--;
 
2344
                length++;
2345
2345
        }
2346
2346
 
2347
 
        while (offset + length < text->text_len && !pi->attrs [offset + length].is_cursor_position)
2348
 
                length ++;
 
2347
        while (offset + length < text->text_len && !pi->attrs[offset + length].is_cursor_position)
 
2348
                length++;
2349
2349
 
2350
2350
        /* printf ("updated offset: %d length: %d (end offset %d)\n", offset, length, offset + length); */
2351
2351
 
2874
2874
        parent_class = &html_object_class;
2875
2875
}
2876
2876
 
 
2877
/* almost identical copy of glib's _g_utf8_make_valid() */
2877
2878
static gchar *
2878
 
offset_to_pointer_validated (const gchar *str, glong offset, gint *chars_out)
 
2879
_html_text_utf8_make_valid (const gchar *name, gint len)
2879
2880
{
2880
 
        const gchar *s = str;
2881
 
        glong chars = 0;
2882
 
 
2883
 
        if (offset < 0) {
2884
 
                while (*s) {
2885
 
                        gunichar wc = g_utf8_get_char_validated (s, -1);
2886
 
                        if (wc == (gunichar)-1 || wc == (gunichar)-2)
2887
 
                                return NULL;
2888
 
                        s = g_utf8_next_char (s);
2889
 
                        chars++;
2890
 
                }
2891
 
 
 
2881
        GString *string;
 
2882
        const gchar *remainder, *invalid;
 
2883
        gint remaining_bytes, valid_bytes, total_bytes;
 
2884
 
 
2885
        g_return_val_if_fail (name != NULL, NULL);
 
2886
 
 
2887
        string = NULL;
 
2888
        remainder = name;
 
2889
        if (len == -1) {
 
2890
                remaining_bytes = strlen (name);
2892
2891
        } else {
2893
 
                while (offset-- && *s) {
2894
 
                        gunichar wc = g_utf8_get_char_validated (s, -1);
2895
 
                        if (wc == (gunichar)-1 || wc == (gunichar)-2)
2896
 
                                return NULL;
2897
 
                        s = g_utf8_next_char (s);
2898
 
                        chars++;
 
2892
                const gchar *start = name, *end = name;
 
2893
 
 
2894
                while (len > 0) {
 
2895
                        gunichar uc = g_utf8_get_char_validated (end, -1);
 
2896
 
 
2897
                        if (uc == (gunichar) -2 || uc == (gunichar) -1) {
 
2898
                                end++;
 
2899
                        } else if (uc == 0) {
 
2900
                                break;
 
2901
                        } else {
 
2902
                                end = g_utf8_next_char (end);
 
2903
                        }
 
2904
 
 
2905
                        len--;
2899
2906
                }
2900
 
        }
2901
 
 
2902
 
        *chars_out = chars;
2903
 
 
2904
 
        return (gchar *)s;
 
2907
 
 
2908
                remaining_bytes = end - start;
 
2909
        }
 
2910
 
 
2911
        total_bytes = remaining_bytes;
 
2912
 
 
2913
        while (remaining_bytes != 0) {
 
2914
                if (g_utf8_validate (remainder, remaining_bytes, &invalid))
 
2915
                        break;
 
2916
                valid_bytes = invalid - remainder;
 
2917
 
 
2918
                if (string == NULL)
 
2919
                        string = g_string_sized_new (remaining_bytes);
 
2920
 
 
2921
                g_string_append_len (string, remainder, valid_bytes);
 
2922
                /* append U+FFFD REPLACEMENT CHARACTER */
 
2923
                g_string_append (string, "\357\277\275");
 
2924
 
 
2925
                remaining_bytes -= valid_bytes + 1;
 
2926
                remainder = invalid + 1;
 
2927
        }
 
2928
 
 
2929
        if (string == NULL)
 
2930
                return g_strndup (name, total_bytes);
 
2931
 
 
2932
        g_string_append (string, remainder);
 
2933
 
 
2934
        g_assert (g_utf8_validate (string->str, -1, NULL));
 
2935
 
 
2936
        return g_string_free (string, FALSE);
2905
2937
}
2906
2938
 
2907
2939
/**
2908
2940
 * html_text_sanitize:
2909
 
 * @str: text string (in/out)
 
2941
 * @str_in: text string to sanitize (in)
 
2942
 * @str_out: newly allocated text string sanitized (out)
2910
2943
 * @len: length of text, in characters (in/out). (A value of
2911
2944
 *       -1 on input means to use all characters in @str)
2912
2945
 *
2913
 
 * Validates a UTF-8 string up to the given number of characters;
2914
 
 * if the string is invalid, on output, "[?]" will be stored in
2915
 
 * @str and 3 in @len, otherwise @str will be left unchanged,
2916
 
 * and @len will be left unchanged if non-negative, otherwise
2917
 
 * replaced with the number of characters in @str.
 
2946
 * Validates a UTF-8 string up to the given number of characters.
2918
2947
 *
2919
2948
 * Return value: number of bytes in the output value of @str
2920
2949
 **/
2921
2950
gsize
2922
 
html_text_sanitize (const gchar **str, gint *len)
 
2951
html_text_sanitize (const gchar *str_in, gchar **str_out, gint *len)
2923
2952
{
2924
 
        gchar *end;
2925
 
 
2926
 
        g_return_val_if_fail (str != NULL, 0);
 
2953
        g_return_val_if_fail (str_in != NULL, 0);
 
2954
        g_return_val_if_fail (str_out != NULL, 0);
2927
2955
        g_return_val_if_fail (len != NULL, 0);
2928
2956
 
2929
 
        end = offset_to_pointer_validated (*str, *len, len);
2930
 
        if (end) {
2931
 
                return end - *str;
2932
 
        } else {
2933
 
                *str = "[?]";
2934
 
                *len = 3;
2935
 
                return 3;
2936
 
        }
 
2957
        *str_out = _html_text_utf8_make_valid (str_in, *len);
 
2958
        g_return_val_if_fail (*str_out != NULL, 0);
 
2959
 
 
2960
        *len = g_utf8_strlen (*str_out, -1);
 
2961
        return strlen (*str_out);
2937
2962
}
2938
2963
 
2939
2964
void
2948
2973
 
2949
2974
        html_object_init (HTML_OBJECT (text), HTML_OBJECT_CLASS (klass));
2950
2975
 
2951
 
        text->text_bytes = html_text_sanitize (&str, &len);
 
2976
        text->text_bytes = html_text_sanitize (str, &text->text, &len);
2952
2977
        text->text_len = len;
2953
 
        text->text = g_memdup (str, text->text_bytes + 1);
2954
 
        text->text [text->text_bytes] = '\0';
2955
2978
 
2956
2979
        text->font_style    = font_style;
2957
2980
        text->face          = NULL;
3030
3053
html_text_set_text (HTMLText *text, const gchar *new_text)
3031
3054
{
3032
3055
        g_free (text->text);
 
3056
        text->text = NULL;
3033
3057
        text->text_len = -1;
3034
 
        text->text_bytes = html_text_sanitize (&new_text,
 
3058
        text->text_bytes = html_text_sanitize (new_text, &text->text,
3035
3059
                                               (gint *)&text->text_len);
3036
 
        text->text = g_memdup (new_text, text->text_bytes + 1);
3037
 
        text->text [text->text_bytes] = '\0';
3038
3060
        html_object_change_set (HTML_OBJECT (text), HTML_CHANGE_ALL);
3039
3061
}
3040
3062
 
3144
3166
 
3145
3167
typedef struct _HTMLMagicInsertMatch HTMLMagicInsertMatch;
3146
3168
 
3147
 
static HTMLMagicInsertMatch mim [] = {
 
3169
static HTMLMagicInsertMatch mim[] = {
3148
3170
        /* prefixed expressions */
3149
3171
        { "(news|telnet|nntp|file|http|ftp|sftp|https|webcal)://([-a-z0-9]+(:[-a-z0-9]+)?@)?[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(([.])?/[-a-z0-9_$.+!*(),;:@%&=?/~#']*[^]'.}>\\) ,?!;:\"]?)?", NULL, NULL },
3150
3172
        { "(sip|h323|callto):([-_a-z0-9.'\\+]+(:[0-9]{1,5})?(/[-_a-z0-9.']+)?)(@([-_a-z0-9.%=?]+|([0-9]{1,3}.){3}[0-9]{1,3})?)?(:[0-9]{1,5})?", NULL, NULL },
3161
3183
        gint i;
3162
3184
 
3163
3185
        for (i = 0; i < G_N_ELEMENTS (mim); i++) {
3164
 
                mim [i].preg = g_new0 (regex_t, 1);
3165
 
                if (regcomp (mim [i].preg, mim [i].regex, REG_EXTENDED | REG_ICASE)) {
 
3186
                mim[i].preg = g_new0 (regex_t, 1);
 
3187
                if (regcomp (mim[i].preg, mim[i].regex, REG_EXTENDED | REG_ICASE)) {
3166
3188
                        /* error */
3167
 
                        g_free (mim [i].preg);
3168
 
                        mim [i].preg = 0;
 
3189
                        g_free (mim[i].preg);
 
3190
                        mim[i].preg = 0;
3169
3191
                }
3170
3192
        }
3171
3193
}
3187
3209
gboolean
3188
3210
html_text_magic_link (HTMLText *text, HTMLEngine *engine, guint offset)
3189
3211
{
3190
 
        regmatch_t pmatch [2];
 
3212
        regmatch_t pmatch[2];
3191
3213
        gint i;
3192
3214
        gboolean rv = FALSE, exec = TRUE;
3193
3215
        gint saved_position;
3206
3228
        cur = str = html_text_get_text (text, offset);
3207
3229
 
3208
3230
        /* check forward to ensure chars are < 0x80, could be removed once we have utf8 regex */
3209
 
        while (TRUE) {
 
3231
        while (cur && *cur) {
3210
3232
                cur = g_utf8_next_char (cur);
3211
3233
                if (!*cur)
3212
3234
                        break;
3234
3256
                str = g_utf8_next_char (str);
3235
3257
 
3236
3258
        if (exec) {
3237
 
                for (i = 0; i < G_N_ELEMENTS (mim); i++) {
3238
 
                        if (mim [i].preg && !regexec (mim [i].preg, str, 2, pmatch, 0)) {
3239
 
                                paste_link (engine, text,
3240
 
                                            g_utf8_pointer_to_offset (text->text, str + pmatch [0].rm_so),
3241
 
                                            g_utf8_pointer_to_offset (text->text, str + pmatch [0].rm_eo), mim [i].prefix);
3242
 
                                        rv = TRUE;
3243
 
                                        break;
 
3259
                gboolean done = FALSE;
 
3260
                guint32 str_offset = 0, str_length = strlen (str);
 
3261
 
 
3262
                while (!done) {
 
3263
                        done = TRUE;
 
3264
                        for (i = 0; i < G_N_ELEMENTS (mim); i++) {
 
3265
                                if (mim[i].preg && !regexec (mim[i].preg, str + str_offset, 2, pmatch, 0)) {
 
3266
                                        paste_link (engine, text,
 
3267
                                                    g_utf8_pointer_to_offset (text->text, str + str_offset + pmatch[0].rm_so),
 
3268
                                                    g_utf8_pointer_to_offset (text->text, str + str_offset + pmatch[0].rm_eo), mim[i].prefix);
 
3269
                                                rv = TRUE;
 
3270
                                                str_offset += pmatch[0].rm_eo + 1;
 
3271
                                                done = str_offset >= str_length;
 
3272
                                                break;
 
3273
                                }
3244
3274
                        }
3245
3275
                }
3246
3276
        }
3247
3277
 
3248
 
        html_undo_level_end (engine->undo);
 
3278
        html_undo_level_end (engine->undo, engine);
3249
3279
        html_cursor_jump_to_position_no_spell (engine->cursor, engine, saved_position);
3250
3280
 
3251
3281
        return rv;
3263
3293
}
3264
3294
 
3265
3295
void
3266
 
html_text_append (HTMLText *text, const gchar *str, gint len)
 
3296
html_text_append (HTMLText *text, const gchar *pstr, gint len)
3267
3297
{
3268
 
        gchar *to_delete;
 
3298
        gchar *to_delete, *str = NULL;
3269
3299
        guint bytes;
3270
3300
 
3271
3301
        to_delete       = text->text;
3272
 
        bytes = html_text_sanitize (&str, &len);
 
3302
        bytes = html_text_sanitize (pstr, &str, &len);
3273
3303
        text->text_len += len;
3274
3304
        text->text      = g_malloc (text->text_bytes + bytes + 1);
3275
3305
 
3279
3309
        text->text[text->text_bytes] = '\0';
3280
3310
 
3281
3311
        g_free (to_delete);
 
3312
        g_free (str);
3282
3313
 
3283
3314
        html_object_change_set (HTML_OBJECT (text), HTML_CHANGE_ALL);
3284
3315
}