Skip to content

Commit

Permalink
fully functional, very speedy, not yet global variable, missing docum…
Browse files Browse the repository at this point in the history
…entation
  • Loading branch information
Dusan Popovic committed Sep 28, 2021
1 parent be01090 commit a00791c
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 9 deletions.
95 changes: 86 additions & 9 deletions src/gui_gtk_x11.c
Expand Up @@ -5595,18 +5595,11 @@ draw_under(int flags, int row, int col, int cells)
int
gui_gtk2_draw_string(int row, int col, char_u *s, int len, int flags)
{
GdkRectangle area; // area for clip mask
PangoGlyphString *glyphs; // glyphs of current item
int column_offset = 0; // column offset in cells
int i;
char_u *conv_buf = NULL; // result of UTF-8 conversion
char_u *new_conv_buf;
int convlen;
char_u *sp, *bp;
int plen;
#if GTK_CHECK_VERSION(3,0,0)
cairo_t *cr;
#endif

if (gui.text_context == NULL || gtk_widget_get_window(gui.drawarea) == NULL)
return len;
Expand Down Expand Up @@ -5651,7 +5644,91 @@ gui_gtk2_draw_string(int row, int col, char_u *s, int len, int flags)
s = conv_buf;
len = convlen;
}
vim_free(conv_buf);

// String may contain ascii, utf-8 chars or ligatures. Group them together to speed up output.

// currently fixed list, move it to global set something = 'character list'
// also map to record array to speed up lookup
char *ligatures = "!\"#$%&'()*+-./:;<=>?@[\\]^_`{|}~"; // removed comma char, does any ligature use it?
int ligatures_size = 31;

int lensum = 0; // return value needs to add up since we are printing substrings
char_u *cs = s; // current *s pointer
int needs_pango = ((*cs & 0x80) || (memchr(ligatures, *cs, ligatures_size) != NULL) && 1); // look ahead, 0=ascii 1=unicode/ligatures
int should_need_pango;

// split string into ascii and non-ascii (ligatures + utf-8) substrings, print glyphs or use Pango
while (cs < s + len)
{
int slen = 0;
while (slen < len - lensum)
{
int is_ligature = memchr(ligatures, *(cs + slen), ligatures_size) != NULL;
int is_utf8 = *(cs + slen) & 0x80;
should_need_pango = (is_ligature || is_utf8) && 1;
if (needs_pango != should_need_pango) break; // mode switch
if (needs_pango)
{
if (is_ligature)
{
slen++; // ligature char by char
}
else
{
if (*(cs + slen) & 0xE0 == 0xC0) // + one byte utf8
{
slen++;
}
else if (*(cs + slen) & 0xF0 == 0xE0) // + two bytes utf8
{
slen += 2;
}
else if (*(cs + slen) & 0xF8 == 0xF0) // + three bytes utf8
{
slen += 3;
}
else if (*(cs + slen) & 0xC0 == 0x80) // a continuation, find 0xB0 == 0x80 but don't include it
{
while ((slen < len - lensum) && (*(cs + slen) & 0x80 == 0x80)) slen++;
slen--;
}
else // this should not happen, try moving forward, Pango will catch it
{
slen++;
}
}
}
else
{
slen++; // ascii
}
}
// temporarily zero terminate substring, print, restore char, wrap
char_u backup_ch = *(cs + slen);
*(cs + slen) = 0;
//debug: uncomment to see splits in terminal
//printf("substr needs pango: %i: \n!%s@\n", needs_pango, cs);
//fflush(stdout);
int l = gui_gtk2_draw_string_ext(row, col + lensum, cs, slen, flags, needs_pango);
*(cs + slen) = backup_ch;
cs += slen;
needs_pango = should_need_pango;
lensum += l;
}
return lensum;
}

int
gui_gtk2_draw_string_ext(int row, int col, char_u *s, int len, int flags, int force_pango)
{
GdkRectangle area; // area for clip mask
PangoGlyphString *glyphs; // glyphs of current item
int column_offset = 0; // column offset in cells
int i;
#if GTK_CHECK_VERSION(3,0,0)
cairo_t *cr;
#endif
/*
* Restrict all drawing to the current screen line in order to prevent
* fuzzy font lookups from messing up the screen.
Expand Down Expand Up @@ -5679,7 +5756,8 @@ gui_gtk2_draw_string(int row, int col, char_u *s, int len, int flags)
*/
if (!(flags & DRAW_ITALIC)
&& !((flags & DRAW_BOLD) && gui.font_can_bold)
&& gui.ascii_glyphs != NULL)
&& gui.ascii_glyphs != NULL
&& !force_pango)
{
char_u *p;

Expand Down Expand Up @@ -5883,7 +5961,6 @@ gui_gtk2_draw_string(int row, int col, char_u *s, int len, int flags)
#endif

pango_glyph_string_free(glyphs);
vim_free(conv_buf);

#if GTK_CHECK_VERSION(3,0,0)
cairo_destroy(cr);
Expand Down
1 change: 1 addition & 0 deletions src/proto/gui_gtk_x11.pro
Expand Up @@ -43,6 +43,7 @@ void gui_mch_set_fg_color(guicolor_T color);
void gui_mch_set_bg_color(guicolor_T color);
void gui_mch_set_sp_color(guicolor_T color);
int gui_gtk2_draw_string(int row, int col, char_u *s, int len, int flags);
int gui_gtk2_draw_string_ext(int row, int col, char_u *s, int len, int flags, int force_pango);
int gui_mch_haskey(char_u *name);
int gui_get_x11_windis(Window *win, Display **dis);
Display *gui_mch_get_display(void);
Expand Down

0 comments on commit a00791c

Please sign in to comment.