Created
March 13, 2015 08:55
-
-
Save ynkdir/6eff3903cc417a933d61 to your computer and use it in GitHub Desktop.
vim patches
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ynkdir-imoverthespot | |
gtk2: Changed Input Method editing style from on-the-spot to over-the-spot. On-the-spot implementation is buggy and has problems detailed in mbyte.c:im_preedit_changed_cb(). | |
ynkdir-imactivatekey | |
gtk2: Removed 'imactivatekey' option and related code because it doesn't work. | |
ynkdir-imcursorhold | |
x11: Changed to not fire CursorHold? autocmd event while IM pre-editing. It may cause trouble. | |
ynkdir-pangolineheight | |
gtk2: Fixed that default line height is too small in ja_JP locale. Use pango_language_get_sample_string() and calculate height for the text ("locale's sample" + "C's sample"). FIXME: What is the correct way? | |
pango_font_metrics_get_ascent() and pango_font_metrics_get_descent() returns small height in ja_JP locale. | |
For example, for "Monospace 10": | |
LC_ALL=C ascent:13px + descent:4px = 17px | |
LC_ALL=ja_JP.UTF-8 ascent:12px + descent:2px = 14px | |
So some characters are displayed shortly and underscore is not shown. It is required to :set linespace=4 to show underscore. | |
Ubuntu 11.04 | |
$ pkg-config --modversion pango | |
1.28.4 | |
$ pkg-config --modversion cairo | |
1.10.2 | |
test code: https://gist.github.com/849071 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r 03e6a768a028 -r 4f8b66f4c1dc src/fileio.c | |
--- a/src/fileio.c Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/fileio.c Fri Mar 13 16:20:54 2015 +0900 | |
@@ -9132,6 +9132,9 @@ | |
#ifdef FEAT_INS_EXPAND | |
&& !ins_compl_active() | |
#endif | |
+#ifdef FEAT_XIM | |
+ && !im_is_preediting() | |
+#endif | |
) | |
{ | |
state = get_real_state(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r 03e6a768a028 -r 269048781420 src/edit.c | |
--- a/src/edit.c Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/edit.c Fri Mar 13 16:21:44 2015 +0900 | |
@@ -9369,12 +9369,7 @@ | |
tpos = curwin->w_cursor; | |
if (oneleft() == OK) | |
{ | |
-#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
- /* Only call start_arrow() when not busy with preediting, it will | |
- * break undo. K_LEFT is inserted in im_correct_cursor(). */ | |
- if (!im_is_preediting()) | |
-#endif | |
- start_arrow(&tpos); | |
+ start_arrow(&tpos); | |
#ifdef FEAT_RIGHTLEFT | |
/* If exit reversed string, position is fixed */ | |
if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol) | |
diff -r 03e6a768a028 -r 269048781420 src/ex_getln.c | |
--- a/src/ex_getln.c Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/ex_getln.c Fri Mar 13 16:21:44 2015 +0900 | |
@@ -94,9 +94,6 @@ | |
static void save_cmdline __ARGS((struct cmdline_info *ccp)); | |
static void restore_cmdline __ARGS((struct cmdline_info *ccp)); | |
static int cmdline_paste __ARGS((int regname, int literally, int remcr)); | |
-#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
-static void redrawcmd_preedit __ARGS((void)); | |
-#endif | |
#ifdef FEAT_WILDMENU | |
static void cmdline_del __ARGS((int from)); | |
#endif | |
@@ -2484,106 +2481,6 @@ | |
} | |
#endif | |
-#if (defined(FEAT_XIM) && (defined(FEAT_GUI_GTK))) || defined(PROTO) | |
-/* | |
- * Return the virtual column number at the current cursor position. | |
- * This is used by the IM code to obtain the start of the preedit string. | |
- */ | |
- colnr_T | |
-cmdline_getvcol_cursor() | |
-{ | |
- if (ccline.cmdbuff == NULL || ccline.cmdpos > ccline.cmdlen) | |
- return MAXCOL; | |
- | |
-# ifdef FEAT_MBYTE | |
- if (has_mbyte) | |
- { | |
- colnr_T col; | |
- int i = 0; | |
- | |
- for (col = 0; i < ccline.cmdpos; ++col) | |
- i += (*mb_ptr2len)(ccline.cmdbuff + i); | |
- | |
- return col; | |
- } | |
- else | |
-# endif | |
- return ccline.cmdpos; | |
-} | |
-#endif | |
- | |
-#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
-/* | |
- * If part of the command line is an IM preedit string, redraw it with | |
- * IM feedback attributes. The cursor position is restored after drawing. | |
- */ | |
- static void | |
-redrawcmd_preedit() | |
-{ | |
- if ((State & CMDLINE) | |
- && xic != NULL | |
- /* && im_get_status() doesn't work when using SCIM */ | |
- && !p_imdisable | |
- && im_is_preediting()) | |
- { | |
- int cmdpos = 0; | |
- int cmdspos; | |
- int old_row; | |
- int old_col; | |
- colnr_T col; | |
- | |
- old_row = msg_row; | |
- old_col = msg_col; | |
- cmdspos = ((ccline.cmdfirstc != NUL) ? 1 : 0) + ccline.cmdindent; | |
- | |
-# ifdef FEAT_MBYTE | |
- if (has_mbyte) | |
- { | |
- for (col = 0; col < preedit_start_col | |
- && cmdpos < ccline.cmdlen; ++col) | |
- { | |
- cmdspos += (*mb_ptr2cells)(ccline.cmdbuff + cmdpos); | |
- cmdpos += (*mb_ptr2len)(ccline.cmdbuff + cmdpos); | |
- } | |
- } | |
- else | |
-# endif | |
- { | |
- cmdspos += preedit_start_col; | |
- cmdpos += preedit_start_col; | |
- } | |
- | |
- msg_row = cmdline_row + (cmdspos / (int)Columns); | |
- msg_col = cmdspos % (int)Columns; | |
- if (msg_row >= Rows) | |
- msg_row = Rows - 1; | |
- | |
- for (col = 0; cmdpos < ccline.cmdlen; ++col) | |
- { | |
- int char_len; | |
- int char_attr; | |
- | |
- char_attr = im_get_feedback_attr(col); | |
- if (char_attr < 0) | |
- break; /* end of preedit string */ | |
- | |
-# ifdef FEAT_MBYTE | |
- if (has_mbyte) | |
- char_len = (*mb_ptr2len)(ccline.cmdbuff + cmdpos); | |
- else | |
-# endif | |
- char_len = 1; | |
- | |
- msg_outtrans_len_attr(ccline.cmdbuff + cmdpos, char_len, char_attr); | |
- cmdpos += char_len; | |
- } | |
- | |
- msg_row = old_row; | |
- msg_col = old_col; | |
- } | |
-} | |
-#endif /* FEAT_XIM && FEAT_GUI_GTK */ | |
- | |
/* | |
* Allocate a new command line buffer. | |
* Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen. | |
@@ -3318,9 +3215,6 @@ | |
} | |
windgoto(msg_row, msg_col); | |
-#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
- redrawcmd_preedit(); | |
-#endif | |
#ifdef MCH_CURSOR_SHAPE | |
mch_update_cursor(); | |
#endif | |
diff -r 03e6a768a028 -r 269048781420 src/globals.h | |
--- a/src/globals.h Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/globals.h Fri Mar 13 16:21:44 2015 +0900 | |
@@ -872,19 +872,6 @@ | |
#ifdef FEAT_XIM | |
# ifdef FEAT_GUI_GTK | |
EXTERN GtkIMContext *xic INIT(= NULL); | |
-/* | |
- * Start and end column of the preedit area in virtual columns from the start | |
- * of the text line. When there is no preedit area they are set to MAXCOL. | |
- * "preedit_end_col" is needed for coloring the preedited string. Drawing the | |
- * color between "preedit_start_col" and curpos did not work, because some XIM | |
- * set the cursor position to the first char of the string. | |
- */ | |
-EXTERN colnr_T preedit_start_col INIT(= MAXCOL); | |
-EXTERN colnr_T preedit_end_col INIT(= MAXCOL); | |
- | |
-/* "xim_changed_while_preediting" is set when changed() can set the 'modified' | |
- * flag even while preediting. */ | |
-EXTERN int xim_changed_while_preediting INIT(= FALSE); | |
# else | |
EXTERN XIC xic INIT(= NULL); | |
# endif | |
diff -r 03e6a768a028 -r 269048781420 src/mbyte.c | |
--- a/src/mbyte.c Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/mbyte.c Fri Mar 13 16:21:44 2015 +0900 | |
@@ -4499,29 +4499,18 @@ | |
# if defined(FEAT_GUI_GTK) || defined(PROTO) | |
static int xim_has_preediting INIT(= FALSE); /* IM current status */ | |
-/* | |
- * Set preedit_start_col to the current cursor position. | |
- */ | |
- static void | |
-init_preedit_start_col(void) | |
-{ | |
- if (State & CMDLINE) | |
- preedit_start_col = cmdline_getvcol_cursor(); | |
- else if (curwin != NULL) | |
- getvcol(curwin, &curwin->w_cursor, &preedit_start_col, NULL, NULL); | |
- /* Prevent that preediting marks the buffer as changed. */ | |
- xim_changed_while_preediting = curbuf->b_changed; | |
-} | |
- | |
static int im_is_active = FALSE; /* IM is enabled for current mode */ | |
static int preedit_is_active = FALSE; | |
-static int im_preedit_cursor = 0; /* cursor offset in characters */ | |
-static int im_preedit_trailing = 0; /* number of characters after cursor */ | |
static unsigned long im_commit_handler_id = 0; | |
static unsigned int im_activatekey_keyval = GDK_VoidSymbol; | |
static unsigned int im_activatekey_state = 0; | |
+static GtkWidget *preedit_window = NULL; | |
+static GtkWidget *preedit_label = NULL; | |
+ | |
+static void im_preedit_window_set_position(void); | |
+ | |
void | |
im_set_active(int active) | |
{ | |
@@ -4559,6 +4548,8 @@ | |
area.height = gui.char_height; | |
gtk_im_context_set_cursor_location(xic, &area); | |
+ | |
+ im_preedit_window_set_position(); | |
} | |
} | |
@@ -4589,42 +4580,95 @@ | |
gui_mch_mousehide(TRUE); | |
} | |
+ static void | |
+im_preedit_window_set_position(void) | |
+{ | |
+ int x, y, w, h, sw, sh; | |
+ | |
+ if (preedit_window == NULL) | |
+ return; | |
+ | |
+ sw = gdk_screen_get_width(gtk_widget_get_screen(preedit_window)); | |
+ sh = gdk_screen_get_height(gtk_widget_get_screen(preedit_window)); | |
+ gdk_window_get_origin(gui.drawarea->window, &x, &y); | |
+ gtk_window_get_size(GTK_WINDOW(preedit_window), &w, &h); | |
+ x = x + FILL_X(gui.col); | |
+ y = y + FILL_Y(gui.row); | |
+ if (x + w > sw) | |
+ x = sw - w; | |
+ if (y + h > sh) | |
+ y = sh - h; | |
+ gtk_window_move(GTK_WINDOW(preedit_window), x, y); | |
+} | |
+ | |
+ static void | |
+im_preedit_window_open() | |
+{ | |
+ char *preedit_string; | |
+ char buf[8]; | |
+ PangoAttrList *attr_list; | |
+ PangoLayout *layout; | |
+ GdkColor color; | |
+ gint w, h; | |
+ | |
+ if (preedit_window == NULL) | |
+ { | |
+ preedit_window = gtk_window_new(GTK_WINDOW_POPUP); | |
+ preedit_label = gtk_label_new(""); | |
+ gtk_container_add(GTK_CONTAINER(preedit_window), preedit_label); | |
+ } | |
+ | |
+ gtk_widget_modify_font(preedit_label, gui.norm_font); | |
+ | |
+ vim_snprintf(buf, sizeof(buf), "#%06X", gui.norm_pixel); | |
+ gdk_color_parse(buf, &color); | |
+ gtk_widget_modify_fg(preedit_label, GTK_STATE_NORMAL, &color); | |
+ | |
+ vim_snprintf(buf, sizeof(buf), "#%06X", gui.back_pixel); | |
+ gdk_color_parse(buf, &color); | |
+ gtk_widget_modify_bg(preedit_window, GTK_STATE_NORMAL, &color); | |
+ | |
+ gtk_im_context_get_preedit_string(xic, &preedit_string, &attr_list, NULL); | |
+ | |
+ if (preedit_string[0] != NUL) | |
+ { | |
+ gtk_label_set_text(GTK_LABEL(preedit_label), preedit_string); | |
+ gtk_label_set_attributes(GTK_LABEL(preedit_label), attr_list); | |
+ | |
+ layout = gtk_label_get_layout(GTK_LABEL(preedit_label)); | |
+ pango_layout_get_pixel_size(layout, &w, &h); | |
+ h = MAX(h, gui.char_height); | |
+ gtk_window_resize(GTK_WINDOW(preedit_window), w, h); | |
+ | |
+ gtk_widget_show_all(preedit_window); | |
+ | |
+ im_preedit_window_set_position(); | |
+ } | |
+ | |
+ g_free(preedit_string); | |
+ pango_attr_list_unref(attr_list); | |
+} | |
+ | |
+ static void | |
+im_preedit_window_close() | |
+{ | |
+ if (preedit_window != NULL) | |
+ gtk_widget_hide(preedit_window); | |
+} | |
+ | |
+ static void | |
+im_show_preedit() | |
+{ | |
+ im_preedit_window_open(); | |
+ | |
+ if (p_mh) /* blank out the pointer if necessary */ | |
+ gui_mch_mousehide(TRUE); | |
+} | |
+ | |
static void | |
im_delete_preedit(void) | |
{ | |
- char_u bskey[] = {CSI, 'k', 'b'}; | |
- char_u delkey[] = {CSI, 'k', 'D'}; | |
- | |
- if (State & NORMAL) | |
- { | |
- im_preedit_cursor = 0; | |
- return; | |
- } | |
- for (; im_preedit_cursor > 0; --im_preedit_cursor) | |
- add_to_input_buf(bskey, (int)sizeof(bskey)); | |
- | |
- for (; im_preedit_trailing > 0; --im_preedit_trailing) | |
- add_to_input_buf(delkey, (int)sizeof(delkey)); | |
-} | |
- | |
-/* | |
- * Move the cursor left by "num_move_back" characters. | |
- * Note that ins_left() checks im_is_preediting() to avoid breaking undo for | |
- * these K_LEFT keys. | |
- */ | |
- static void | |
-im_correct_cursor(int num_move_back) | |
-{ | |
- char_u backkey[] = {CSI, 'k', 'l'}; | |
- | |
- if (State & NORMAL) | |
- return; | |
-# ifdef FEAT_RIGHTLEFT | |
- if ((State & CMDLINE) == 0 && curwin != NULL && curwin->w_p_rl) | |
- backkey[2] = 'r'; | |
-# endif | |
- for (; num_move_back > 0; --num_move_back) | |
- add_to_input_buf(backkey, (int)sizeof(backkey)); | |
+ im_preedit_window_close(); | |
} | |
static int xim_expected_char = NUL; | |
@@ -4637,6 +4681,8 @@ | |
im_show_info(void) | |
{ | |
int old_vgetc_busy; | |
+ int old_row = gui.row; | |
+ int old_col = gui.col; | |
old_vgetc_busy = vgetc_busy; | |
vgetc_busy = TRUE; | |
@@ -4645,6 +4691,8 @@ | |
if ((State & NORMAL) || (State & INSERT)) | |
setcursor(); | |
out_flush(); | |
+ gui.row = old_row; | |
+ gui.col = old_col; | |
} | |
/* | |
@@ -4658,49 +4706,11 @@ | |
{ | |
int slen = (int)STRLEN(str); | |
int add_to_input = TRUE; | |
- int clen; | |
- int len = slen; | |
- int commit_with_preedit = TRUE; | |
- char_u *im_str; | |
#ifdef XIM_DEBUG | |
xim_log("im_commit_cb(): %s\n", str); | |
#endif | |
- /* The imhangul module doesn't reset the preedit string before | |
- * committing. Call im_delete_preedit() to work around that. */ | |
- im_delete_preedit(); | |
- | |
- /* Indicate that preediting has finished. */ | |
- if (preedit_start_col == MAXCOL) | |
- { | |
- init_preedit_start_col(); | |
- commit_with_preedit = FALSE; | |
- } | |
- | |
- /* The thing which setting "preedit_start_col" to MAXCOL means that | |
- * "preedit_start_col" will be set forcedly when calling | |
- * preedit_changed_cb() next time. | |
- * "preedit_start_col" should not reset with MAXCOL on this part. Vim | |
- * is simulating the preediting by using add_to_input_str(). when | |
- * preedit begin immediately before committed, the typebuf is not | |
- * flushed to screen, then it can't get correct "preedit_start_col". | |
- * Thus, it should calculate the cells by adding cells of the committed | |
- * string. */ | |
- if (input_conv.vc_type != CONV_NONE) | |
- { | |
- im_str = string_convert(&input_conv, (char_u *)str, &len); | |
- g_return_if_fail(im_str != NULL); | |
- } | |
- else | |
- im_str = (char_u *)str; | |
- | |
- clen = mb_string2cells(im_str, len); | |
- | |
- if (input_conv.vc_type != CONV_NONE) | |
- vim_free(im_str); | |
- preedit_start_col += clen; | |
- | |
/* Is this a single character that matches a keypad key that's just | |
* been pressed? If so, we don't want it to be entered as such - let | |
* us carry on processing the raw keycode so that it may be used in | |
@@ -4724,15 +4734,6 @@ | |
if (add_to_input) | |
im_add_to_input((char_u *)str, slen); | |
- /* Inserting chars while "im_is_active" is set does not cause a change of | |
- * buffer. When the chars are committed the buffer must be marked as | |
- * changed. */ | |
- if (!commit_with_preedit) | |
- preedit_start_col = MAXCOL; | |
- | |
- /* This flag is used in changed() at next call. */ | |
- xim_changed_while_preediting = TRUE; | |
- | |
if (gtk_main_level() > 0) | |
gtk_main_quit(); | |
} | |
@@ -4765,7 +4766,6 @@ | |
im_delete_preedit(); | |
/* Indicate that preediting has finished */ | |
- preedit_start_col = MAXCOL; | |
xim_has_preediting = FALSE; | |
#if 0 | |
@@ -4820,15 +4820,8 @@ | |
im_preedit_changed_cb(GtkIMContext *context, gpointer data UNUSED) | |
{ | |
char *preedit_string = NULL; | |
- int cursor_index = 0; | |
- int num_move_back = 0; | |
- char_u *str; | |
- char_u *p; | |
- int i; | |
- | |
- gtk_im_context_get_preedit_string(context, | |
- &preedit_string, NULL, | |
- &cursor_index); | |
+ | |
+ gtk_im_context_get_preedit_string(context, &preedit_string, NULL, NULL); | |
#ifdef XIM_DEBUG | |
xim_log("im_preedit_changed_cb(): %s\n", preedit_string); | |
@@ -4836,66 +4829,15 @@ | |
g_return_if_fail(preedit_string != NULL); /* just in case */ | |
- /* If preedit_start_col is MAXCOL set it to the current cursor position. */ | |
- if (preedit_start_col == MAXCOL && preedit_string[0] != '\0') | |
+ if (preedit_string[0] == NUL) | |
+ { | |
+ xim_has_preediting = FALSE; | |
+ im_delete_preedit(); | |
+ } | |
+ else | |
{ | |
xim_has_preediting = TRUE; | |
- | |
- /* Urgh, this breaks if the input buffer isn't empty now */ | |
- init_preedit_start_col(); | |
- } | |
- else if (cursor_index == 0 && preedit_string[0] == '\0') | |
- { | |
- xim_has_preediting = FALSE; | |
- | |
- /* If at the start position (after typing backspace) | |
- * preedit_start_col must be reset. */ | |
- preedit_start_col = MAXCOL; | |
- } | |
- | |
- im_delete_preedit(); | |
- | |
- /* | |
- * Compute the end of the preediting area: "preedit_end_col". | |
- * According to the documentation of gtk_im_context_get_preedit_string(), | |
- * the cursor_pos output argument returns the offset in bytes. This is | |
- * unfortunately not true -- real life shows the offset is in characters, | |
- * and the GTK+ source code agrees with me. Will file a bug later. | |
- */ | |
- if (preedit_start_col != MAXCOL) | |
- preedit_end_col = preedit_start_col; | |
- str = (char_u *)preedit_string; | |
- for (p = str, i = 0; *p != NUL; p += utf_byte2len(*p), ++i) | |
- { | |
- int is_composing; | |
- | |
- is_composing = ((*p & 0x80) != 0 && utf_iscomposing(utf_ptr2char(p))); | |
- /* | |
- * These offsets are used as counters when generating <BS> and <Del> | |
- * to delete the preedit string. So don't count composing characters | |
- * unless 'delcombine' is enabled. | |
- */ | |
- if (!is_composing || p_deco) | |
- { | |
- if (i < cursor_index) | |
- ++im_preedit_cursor; | |
- else | |
- ++im_preedit_trailing; | |
- } | |
- if (!is_composing && i >= cursor_index) | |
- { | |
- /* This is essentially the same as im_preedit_trailing, except | |
- * composing characters are not counted even if p_deco is set. */ | |
- ++num_move_back; | |
- } | |
- if (preedit_start_col != MAXCOL) | |
- preedit_end_col += utf_ptr2cells(p); | |
- } | |
- | |
- if (p > str) | |
- { | |
- im_add_to_input(str, (int)(p - str)); | |
- im_correct_cursor(num_move_back); | |
+ im_show_preedit(); | |
} | |
g_free(preedit_string); | |
@@ -4904,98 +4846,6 @@ | |
gtk_main_quit(); | |
} | |
-/* | |
- * Translate the Pango attributes at iter to Vim highlighting attributes. | |
- * Ignore attributes not supported by Vim highlighting. This shouldn't have | |
- * too much impact -- right now we handle even more attributes than necessary | |
- * for the IM modules I tested with. | |
- */ | |
- static int | |
-translate_pango_attributes(PangoAttrIterator *iter) | |
-{ | |
- PangoAttribute *attr; | |
- int char_attr = HL_NORMAL; | |
- | |
- attr = pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE); | |
- if (attr != NULL && ((PangoAttrInt *)attr)->value | |
- != (int)PANGO_UNDERLINE_NONE) | |
- char_attr |= HL_UNDERLINE; | |
- | |
- attr = pango_attr_iterator_get(iter, PANGO_ATTR_WEIGHT); | |
- if (attr != NULL && ((PangoAttrInt *)attr)->value >= (int)PANGO_WEIGHT_BOLD) | |
- char_attr |= HL_BOLD; | |
- | |
- attr = pango_attr_iterator_get(iter, PANGO_ATTR_STYLE); | |
- if (attr != NULL && ((PangoAttrInt *)attr)->value | |
- != (int)PANGO_STYLE_NORMAL) | |
- char_attr |= HL_ITALIC; | |
- | |
- attr = pango_attr_iterator_get(iter, PANGO_ATTR_BACKGROUND); | |
- if (attr != NULL) | |
- { | |
- const PangoColor *color = &((PangoAttrColor *)attr)->color; | |
- | |
- /* Assume inverse if black background is requested */ | |
- if ((color->red | color->green | color->blue) == 0) | |
- char_attr |= HL_INVERSE; | |
- } | |
- | |
- return char_attr; | |
-} | |
- | |
-/* | |
- * Retrieve the highlighting attributes at column col in the preedit string. | |
- * Return -1 if not in preediting mode or if col is out of range. | |
- */ | |
- int | |
-im_get_feedback_attr(int col) | |
-{ | |
- char *preedit_string = NULL; | |
- PangoAttrList *attr_list = NULL; | |
- int char_attr = -1; | |
- | |
- if (xic == NULL) | |
- return char_attr; | |
- | |
- gtk_im_context_get_preedit_string(xic, &preedit_string, &attr_list, NULL); | |
- | |
- if (preedit_string != NULL && attr_list != NULL) | |
- { | |
- int idx; | |
- | |
- /* Get the byte index as used by PangoAttrIterator */ | |
- for (idx = 0; col > 0 && preedit_string[idx] != '\0'; --col) | |
- idx += utfc_ptr2len((char_u *)preedit_string + idx); | |
- | |
- if (preedit_string[idx] != '\0') | |
- { | |
- PangoAttrIterator *iter; | |
- int start, end; | |
- | |
- char_attr = HL_NORMAL; | |
- iter = pango_attr_list_get_iterator(attr_list); | |
- | |
- /* Extract all relevant attributes from the list. */ | |
- do | |
- { | |
- pango_attr_iterator_range(iter, &start, &end); | |
- | |
- if (idx >= start && idx < end) | |
- char_attr |= translate_pango_attributes(iter); | |
- } | |
- while (pango_attr_iterator_next(iter)); | |
- | |
- pango_attr_iterator_destroy(iter); | |
- } | |
- } | |
- | |
- if (attr_list != NULL) | |
- pango_attr_list_unref(attr_list); | |
- g_free(preedit_string); | |
- | |
- return char_attr; | |
-} | |
- | |
void | |
xim_init(void) | |
{ | |
@@ -5036,7 +4886,6 @@ | |
} | |
im_is_active = FALSE; | |
im_commit_handler_id = 0; | |
- preedit_start_col = MAXCOL; | |
xim_has_preediting = FALSE; | |
} | |
@@ -5191,7 +5040,6 @@ | |
} | |
} | |
- preedit_start_col = MAXCOL; | |
xim_has_preediting = FALSE; | |
} | |
@@ -5296,21 +5144,6 @@ | |
{ | |
int imresult = gtk_im_context_filter_keypress(xic, event); | |
- /* Some XIM send following sequence: | |
- * 1. preedited string. | |
- * 2. committed string. | |
- * 3. line changed key. | |
- * 4. preedited string. | |
- * 5. remove preedited string. | |
- * if 3, Vim can't move back the above line for 5. | |
- * thus, this part should not parse the key. */ | |
- if (!imresult && preedit_start_col != MAXCOL | |
- && event->keyval == GDK_Return) | |
- { | |
- im_synthesize_keypress(GDK_Return, 0U); | |
- return FALSE; | |
- } | |
- | |
/* If XIM tried to commit a keypad key as a single char., | |
* ignore it so we can use the keypad key 'raw', for mappings. */ | |
if (xim_expected_char != NUL && xim_ignored_char) | |
diff -r 03e6a768a028 -r 269048781420 src/misc1.c | |
--- a/src/misc1.c Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/misc1.c Fri Mar 13 16:21:44 2015 +0900 | |
@@ -2753,15 +2753,6 @@ | |
void | |
changed() | |
{ | |
-#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
- /* The text of the preediting area is inserted, but this doesn't | |
- * mean a change of the buffer yet. That is delayed until the | |
- * text is committed. (this means preedit becomes empty) */ | |
- if (im_is_preediting() && !xim_changed_while_preediting) | |
- return; | |
- xim_changed_while_preediting = FALSE; | |
-#endif | |
- | |
if (!curbuf->b_changed) | |
{ | |
int save_msg_scroll = msg_scroll; | |
diff -r 03e6a768a028 -r 269048781420 src/proto/ex_getln.pro | |
--- a/src/proto/ex_getln.pro Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/proto/ex_getln.pro Fri Mar 13 16:21:44 2015 +0900 | |
@@ -9,7 +9,6 @@ | |
char_u *getexmodeline __ARGS((int promptc, void *cookie, int indent)); | |
int cmdline_overstrike __ARGS((void)); | |
int cmdline_at_end __ARGS((void)); | |
-colnr_T cmdline_getvcol_cursor __ARGS((void)); | |
void free_cmdline_buf __ARGS((void)); | |
void putcmdline __ARGS((int c, int shift)); | |
void unputcmdline __ARGS((void)); | |
diff -r 03e6a768a028 -r 269048781420 src/proto/mbyte.pro | |
--- a/src/proto/mbyte.pro Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/proto/mbyte.pro Fri Mar 13 16:21:44 2015 +0900 | |
@@ -76,7 +76,6 @@ | |
void xim_set_focus __ARGS((int focus)); | |
void im_set_position __ARGS((int row, int col)); | |
void xim_set_preedit __ARGS((void)); | |
-int im_get_feedback_attr __ARGS((int col)); | |
void xim_init __ARGS((void)); | |
void im_shutdown __ARGS((void)); | |
int im_xim_isvalid_imactivate __ARGS((void)); | |
diff -r 03e6a768a028 -r 269048781420 src/screen.c | |
--- a/src/screen.c Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/screen.c Fri Mar 13 16:21:44 2015 +0900 | |
@@ -3010,10 +3010,6 @@ | |
#endif | |
#define WL_LINE WL_SBR + 1 /* text in the line */ | |
int draw_state = WL_START; /* what to draw next */ | |
-#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
- int feedback_col = 0; | |
- int feedback_old_attr = -1; | |
-#endif | |
#ifdef FEAT_CONCEAL | |
int syntax_flags = 0; | |
@@ -4923,43 +4919,6 @@ | |
&& !attr_pri) | |
char_attr = extra_attr; | |
-#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
- /* XIM don't send preedit_start and preedit_end, but they send | |
- * preedit_changed and commit. Thus Vim can't set "im_is_active", use | |
- * im_is_preediting() here. */ | |
- if (xic != NULL | |
- && lnum == wp->w_cursor.lnum | |
- && (State & INSERT) | |
- && !p_imdisable | |
- && im_is_preediting() | |
- && draw_state == WL_LINE) | |
- { | |
- colnr_T tcol; | |
- | |
- if (preedit_end_col == MAXCOL) | |
- getvcol(curwin, &(wp->w_cursor), &tcol, NULL, NULL); | |
- else | |
- tcol = preedit_end_col; | |
- if ((long)preedit_start_col <= vcol && vcol < (long)tcol) | |
- { | |
- if (feedback_old_attr < 0) | |
- { | |
- feedback_col = 0; | |
- feedback_old_attr = char_attr; | |
- } | |
- char_attr = im_get_feedback_attr(feedback_col); | |
- if (char_attr < 0) | |
- char_attr = feedback_old_attr; | |
- feedback_col++; | |
- } | |
- else if (feedback_old_attr >= 0) | |
- { | |
- char_attr = feedback_old_attr; | |
- feedback_old_attr = -1; | |
- feedback_col = 0; | |
- } | |
- } | |
-#endif | |
/* | |
* Handle the case where we are in column 0 but not on the first | |
* character of the line and the user wants us to show us a | |
diff -r 03e6a768a028 -r 269048781420 src/undo.c | |
--- a/src/undo.c Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/undo.c Fri Mar 13 16:21:44 2015 +0900 | |
@@ -3022,10 +3022,6 @@ | |
/* Skip it when already synced or syncing is disabled. */ | |
if (curbuf->b_u_synced || (!force && no_u_sync > 0)) | |
return; | |
-#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
- if (im_is_preediting()) | |
- return; /* XIM is busy, don't break an undo sequence */ | |
-#endif | |
if (get_undolevel() < 0) | |
curbuf->b_u_synced = TRUE; /* no entries, nothing to do */ | |
else |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r 03e6a768a028 -r 2ab7cf549c7b src/gui.c | |
--- a/src/gui.c Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/gui.c Fri Mar 13 17:34:37 2015 +0900 | |
@@ -764,10 +764,6 @@ | |
gui_mch_disable_beval_area(balloonEval); | |
#endif | |
-#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
- if (!im_xim_isvalid_imactivate()) | |
- EMSG(_("E599: Value of 'imactivatekey' is invalid")); | |
-#endif | |
/* When 'cmdheight' was set during startup it may not have taken | |
* effect yet. */ | |
if (p_ch != 1L) | |
@@ -1124,13 +1120,7 @@ | |
static int iid; | |
guicolor_T fg, bg; | |
- if ( | |
-# if defined(FEAT_GUI_GTK) && !defined(FEAT_HANGULIN) | |
- preedit_get_status() | |
-# else | |
- im_get_status() | |
-# endif | |
- ) | |
+ if (im_get_status()) | |
{ | |
iid = syn_name2id((char_u *)"CursorIM"); | |
if (iid > 0) | |
diff -r 03e6a768a028 -r 2ab7cf549c7b src/mbyte.c | |
--- a/src/mbyte.c Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/mbyte.c Fri Mar 13 17:34:37 2015 +0900 | |
@@ -4514,13 +4514,10 @@ | |
} | |
static int im_is_active = FALSE; /* IM is enabled for current mode */ | |
-static int preedit_is_active = FALSE; | |
static int im_preedit_cursor = 0; /* cursor offset in characters */ | |
static int im_preedit_trailing = 0; /* number of characters after cursor */ | |
static unsigned long im_commit_handler_id = 0; | |
-static unsigned int im_activatekey_keyval = GDK_VoidSymbol; | |
-static unsigned int im_activatekey_state = 0; | |
void | |
im_set_active(int active) | |
@@ -4642,8 +4639,7 @@ | |
vgetc_busy = TRUE; | |
showmode(); | |
vgetc_busy = old_vgetc_busy; | |
- if ((State & NORMAL) || (State & INSERT)) | |
- setcursor(); | |
+ setcursor(); | |
out_flush(); | |
} | |
@@ -4746,11 +4742,6 @@ | |
#ifdef XIM_DEBUG | |
xim_log("im_preedit_start_cb()\n"); | |
#endif | |
- | |
- im_is_active = TRUE; | |
- preedit_is_active = TRUE; | |
- gui_update_cursor(TRUE, FALSE); | |
- im_show_info(); | |
} | |
/* | |
@@ -4767,16 +4758,6 @@ | |
/* Indicate that preediting has finished */ | |
preedit_start_col = MAXCOL; | |
xim_has_preediting = FALSE; | |
- | |
-#if 0 | |
- /* Removal of this line suggested by Takuhiro Nishioka. Fixes that IM was | |
- * switched off unintentionally. We now use preedit_is_active (added by | |
- * SungHyun Nam). */ | |
- im_is_active = FALSE; | |
-#endif | |
- preedit_is_active = FALSE; | |
- gui_update_cursor(TRUE, FALSE); | |
- im_show_info(); | |
} | |
/* | |
@@ -5040,112 +5021,6 @@ | |
xim_has_preediting = FALSE; | |
} | |
-/* | |
- * Convert the string argument to keyval and state for GdkEventKey. | |
- * If str is valid return TRUE, otherwise FALSE. | |
- * | |
- * See 'imactivatekey' for documentation of the format. | |
- */ | |
- static int | |
-im_string_to_keyval(const char *str, unsigned int *keyval, unsigned int *state) | |
-{ | |
- const char *mods_end; | |
- unsigned tmp_keyval; | |
- unsigned tmp_state = 0; | |
- | |
- mods_end = strrchr(str, '-'); | |
- mods_end = (mods_end != NULL) ? mods_end + 1 : str; | |
- | |
- /* Parse modifier keys */ | |
- while (str < mods_end) | |
- switch (*str++) | |
- { | |
- case '-': break; | |
- case 'S': case 's': tmp_state |= (unsigned)GDK_SHIFT_MASK; break; | |
- case 'L': case 'l': tmp_state |= (unsigned)GDK_LOCK_MASK; break; | |
- case 'C': case 'c': tmp_state |= (unsigned)GDK_CONTROL_MASK;break; | |
- case '1': tmp_state |= (unsigned)GDK_MOD1_MASK; break; | |
- case '2': tmp_state |= (unsigned)GDK_MOD2_MASK; break; | |
- case '3': tmp_state |= (unsigned)GDK_MOD3_MASK; break; | |
- case '4': tmp_state |= (unsigned)GDK_MOD4_MASK; break; | |
- case '5': tmp_state |= (unsigned)GDK_MOD5_MASK; break; | |
- default: | |
- return FALSE; | |
- } | |
- | |
- tmp_keyval = gdk_keyval_from_name(str); | |
- | |
- if (tmp_keyval == 0 || tmp_keyval == GDK_VoidSymbol) | |
- return FALSE; | |
- | |
- if (keyval != NULL) | |
- *keyval = tmp_keyval; | |
- if (state != NULL) | |
- *state = tmp_state; | |
- | |
- return TRUE; | |
-} | |
- | |
-/* | |
- * Return TRUE if p_imak is valid, otherwise FALSE. As a special case, an | |
- * empty string is also regarded as valid. | |
- * | |
- * Note: The numerical key value of p_imak is cached if it was valid; thus | |
- * boldly assuming im_xim_isvalid_imactivate() will always be called whenever | |
- * 'imak' changes. This is currently the case but not obvious -- should | |
- * probably rename the function for clarity. | |
- */ | |
- int | |
-im_xim_isvalid_imactivate(void) | |
-{ | |
- if (p_imak[0] == NUL) | |
- { | |
- im_activatekey_keyval = GDK_VoidSymbol; | |
- im_activatekey_state = 0; | |
- return TRUE; | |
- } | |
- | |
- return im_string_to_keyval((const char *)p_imak, | |
- &im_activatekey_keyval, | |
- &im_activatekey_state); | |
-} | |
- | |
- static void | |
-im_synthesize_keypress(unsigned int keyval, unsigned int state) | |
-{ | |
- GdkEventKey *event; | |
- | |
-# ifdef HAVE_GTK_MULTIHEAD | |
- event = (GdkEventKey *)gdk_event_new(GDK_KEY_PRESS); | |
- g_object_ref(gui.drawarea->window); /* unreffed by gdk_event_free() */ | |
-# else | |
- event = (GdkEventKey *)g_malloc0((gulong)sizeof(GdkEvent)); | |
- event->type = GDK_KEY_PRESS; | |
-# endif | |
- event->window = gui.drawarea->window; | |
- event->send_event = TRUE; | |
- event->time = GDK_CURRENT_TIME; | |
- event->state = state; | |
- event->keyval = keyval; | |
- event->hardware_keycode = /* needed for XIM */ | |
- XKeysymToKeycode(GDK_WINDOW_XDISPLAY(event->window), (KeySym)keyval); | |
- event->length = 0; | |
- event->string = NULL; | |
- | |
- gtk_im_context_filter_keypress(xic, event); | |
- | |
- /* For consistency, also send the corresponding release event. */ | |
- event->type = GDK_KEY_RELEASE; | |
- event->send_event = FALSE; | |
- gtk_im_context_filter_keypress(xic, event); | |
- | |
-# ifdef HAVE_GTK_MULTIHEAD | |
- gdk_event_free((GdkEvent *)event); | |
-# else | |
- g_free(event); | |
-# endif | |
-} | |
- | |
void | |
xim_reset(void) | |
{ | |
@@ -5240,90 +5115,21 @@ | |
* gtk_im_context_filter_keypress() in Normal mode. | |
* And while doing :sh too. | |
*/ | |
- if (xic != NULL && !p_imdisable | |
- && (State & (INSERT | CMDLINE | NORMAL | EXTERNCMD)) != 0) | |
+ if (xic != NULL && !p_imdisable) | |
{ | |
- /* | |
- * Filter 'imactivatekey' and map it to CTRL-^. This way, Vim is | |
- * always aware of the current status of IM, and can even emulate | |
- * the activation key for modules that don't support one. | |
- */ | |
- if (event->keyval == im_activatekey_keyval | |
- && (event->state & im_activatekey_state) == im_activatekey_state) | |
- { | |
- unsigned int state_mask; | |
- | |
- /* Require the state of the 3 most used modifiers to match exactly. | |
- * Otherwise e.g. <S-C-space> would be unusable for other purposes | |
- * if the IM activate key is <S-space>. */ | |
- state_mask = im_activatekey_state; | |
- state_mask |= ((int)GDK_SHIFT_MASK | (int)GDK_CONTROL_MASK | |
- | (int)GDK_MOD1_MASK); | |
- | |
- if ((event->state & state_mask) != im_activatekey_state) | |
- return FALSE; | |
- | |
- /* Don't send it a second time on GDK_KEY_RELEASE. */ | |
- if (event->type != GDK_KEY_PRESS) | |
- return TRUE; | |
- | |
- if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE)) | |
- { | |
- im_set_active(FALSE); | |
- | |
- /* ":lmap" mappings exists, toggle use of mappings. */ | |
- State ^= LANGMAP; | |
- if (State & LANGMAP) | |
- { | |
- curbuf->b_p_iminsert = B_IMODE_NONE; | |
- State &= ~LANGMAP; | |
- } | |
- else | |
- { | |
- curbuf->b_p_iminsert = B_IMODE_LMAP; | |
- State |= LANGMAP; | |
- } | |
- return TRUE; | |
- } | |
- | |
- return gtk_im_context_filter_keypress(xic, event); | |
- } | |
- | |
- /* Don't filter events through the IM context if IM isn't active | |
- * right now. Unlike with GTK+ 1.2 we cannot rely on the IM module | |
- * not doing anything before the activation key was sent. */ | |
- if (im_activatekey_keyval == GDK_VoidSymbol || im_is_active) | |
- { | |
- int imresult = gtk_im_context_filter_keypress(xic, event); | |
- | |
- /* Some XIM send following sequence: | |
- * 1. preedited string. | |
- * 2. committed string. | |
- * 3. line changed key. | |
- * 4. preedited string. | |
- * 5. remove preedited string. | |
- * if 3, Vim can't move back the above line for 5. | |
- * thus, this part should not parse the key. */ | |
- if (!imresult && preedit_start_col != MAXCOL | |
- && event->keyval == GDK_Return) | |
- { | |
- im_synthesize_keypress(GDK_Return, 0U); | |
- return FALSE; | |
- } | |
- | |
- /* If XIM tried to commit a keypad key as a single char., | |
- * ignore it so we can use the keypad key 'raw', for mappings. */ | |
- if (xim_expected_char != NUL && xim_ignored_char) | |
- /* We had a keypad key, and XIM tried to thieve it */ | |
- return FALSE; | |
- | |
- /* This is supposed to fix a problem with iBus, that space | |
- * characters don't work in input mode. */ | |
- xim_expected_char = NUL; | |
- | |
- /* Normal processing */ | |
- return imresult; | |
- } | |
+ int imresult = gtk_im_context_filter_keypress(xic, event); | |
+ | |
+ /* If XIM tried to commit a keypad key as a single char., | |
+ * ignore it so we can use the keypad key 'raw', for mappings. */ | |
+ if (xim_expected_char != NUL && xim_ignored_char) | |
+ /* We had a keypad key, and XIM tried to thieve it */ | |
+ return FALSE; | |
+ | |
+ /* This is supposed to fix a problem with iBus, that space | |
+ * characters don't work in input mode. */ | |
+ xim_expected_char = NUL; | |
+ | |
+ return imresult; | |
} | |
return FALSE; | |
@@ -5356,12 +5162,6 @@ | |
} | |
int | |
-preedit_get_status(void) | |
-{ | |
- return preedit_is_active; | |
-} | |
- | |
- int | |
im_is_preediting() | |
{ | |
return xim_has_preediting; | |
diff -r 03e6a768a028 -r 2ab7cf549c7b src/option.c | |
--- a/src/option.c Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/option.c Fri Mar 13 17:34:37 2015 +0900 | |
@@ -6067,14 +6067,6 @@ | |
} | |
#endif | |
-#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
- else if (varp == &p_imak) | |
- { | |
- if (gui.in_use && !im_xim_isvalid_imactivate()) | |
- errmsg = e_invarg; | |
- } | |
-#endif | |
- | |
#ifdef FEAT_KEYMAP | |
else if (varp == &curbuf->b_p_keymap) | |
{ | |
diff -r 03e6a768a028 -r 2ab7cf549c7b src/option.h | |
--- a/src/option.h Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/option.h Fri Mar 13 17:34:37 2015 +0900 | |
@@ -558,7 +558,6 @@ | |
#endif | |
EXTERN int p_ic; /* 'ignorecase' */ | |
#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) | |
-EXTERN char_u *p_imak; /* 'imactivatekey' */ | |
EXTERN char_u *p_imaf; /* 'imactivatefunc' */ | |
EXTERN char_u *p_imsf; /* 'imstatusfunc' */ | |
#endif | |
diff -r 03e6a768a028 -r 2ab7cf549c7b src/proto/mbyte.pro | |
--- a/src/proto/mbyte.pro Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/proto/mbyte.pro Fri Mar 13 17:34:37 2015 +0900 | |
@@ -79,11 +79,9 @@ | |
int im_get_feedback_attr __ARGS((int col)); | |
void xim_init __ARGS((void)); | |
void im_shutdown __ARGS((void)); | |
-int im_xim_isvalid_imactivate __ARGS((void)); | |
void xim_reset __ARGS((void)); | |
int xim_queue_key_press_event __ARGS((GdkEventKey *event, int down)); | |
int im_get_status __ARGS((void)); | |
-int preedit_get_status __ARGS((void)); | |
int im_is_preediting __ARGS((void)); | |
void xim_set_status_area __ARGS((void)); | |
int xim_get_status_area_height __ARGS((void)); | |
diff -r 03e6a768a028 -r 2ab7cf549c7b src/screen.c | |
--- a/src/screen.c Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/screen.c Fri Mar 13 17:34:37 2015 +0900 | |
@@ -9971,13 +9971,7 @@ | |
{ | |
MSG_PUTS_ATTR("--", attr); | |
#if defined(FEAT_XIM) | |
- if ( | |
-# ifdef FEAT_GUI_GTK | |
- preedit_get_status() | |
-# else | |
- im_get_status() | |
-# endif | |
- ) | |
+ if (im_get_status()) | |
# ifdef FEAT_GUI_GTK /* most of the time, it's not XIM being used */ | |
MSG_PUTS_ATTR(" IM", attr); | |
# else |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r 03e6a768a028 -r 87ae595f97e3 src/gui_gtk_x11.c | |
--- a/src/gui_gtk_x11.c Sun Mar 08 14:48:49 2015 +0100 | |
+++ b/src/gui_gtk_x11.c Fri Mar 13 16:22:33 2015 +0900 | |
@@ -4159,21 +4159,31 @@ | |
int | |
gui_mch_adjust_charheight(void) | |
{ | |
- PangoFontMetrics *metrics; | |
+ PangoLayout *layout; | |
int ascent; | |
- int descent; | |
- | |
- metrics = pango_context_get_metrics(gui.text_context, gui.norm_font, | |
- pango_context_get_language(gui.text_context)); | |
- ascent = pango_font_metrics_get_ascent(metrics); | |
- descent = pango_font_metrics_get_descent(metrics); | |
- | |
- pango_font_metrics_unref(metrics); | |
- | |
- gui.char_height = (ascent + descent + PANGO_SCALE - 1) / PANGO_SCALE | |
- + p_linespace; | |
+ int height; | |
+ int linespace; | |
+ garray_T ga; | |
+ | |
+ ga_init2(&ga, (int)sizeof(char_u), 100); | |
+ ga_concat(&ga, (char_u *)pango_language_get_sample_string(NULL)); | |
+ ga_concat(&ga, (char_u *)pango_language_get_sample_string( | |
+ pango_language_from_string("c"))); | |
+ ga_append(&ga, NUL); | |
+ | |
+ layout = pango_layout_new(gui.text_context); | |
+ pango_layout_set_markup(layout, (char *)ga.ga_data, -1); | |
+ pango_layout_get_size(layout, NULL, &height); | |
+ ascent = pango_layout_get_baseline(layout); | |
+ | |
+ g_object_unref(layout); | |
+ ga_clear(&ga); | |
+ | |
+ linespace = p_linespace * PANGO_SCALE; | |
+ | |
+ gui.char_height = PANGO_PIXELS_CEIL(height + linespace); | |
/* LINTED: avoid warning: bitwise operation on signed value */ | |
- gui.char_ascent = PANGO_PIXELS(ascent + p_linespace * PANGO_SCALE / 2); | |
+ gui.char_ascent = PANGO_PIXELS(ascent + linespace / 2); | |
/* A not-positive value of char_height may crash Vim. Only happens | |
* if 'linespace' is negative (which does make sense sometimes). */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment