Skip to content

Commit 275b5d4

Browse files
author
Yuuki Harano
committed
preedit をテキストで渡すようにした
1 parent cc5a650 commit 275b5d4

File tree

3 files changed

+86
-94
lines changed

3 files changed

+86
-94
lines changed

lisp/term/pgtk-win.el

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -442,18 +442,35 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.")
442442
&context (window-system pgtk))
443443
(pgtk-get-selection-internal selection-symbol target-type))
444444

445-
(setq pgtk-preedit-overlay nil)
445+
(defvar pgtk-preedit-overlay nil)
446+
446447
(defun pgtk-preedit-text (e)
447448
(interactive "e")
448449
(when pgtk-preedit-overlay
449-
(delete-overlay pgtk-preedit-overlay)
450-
(setq pgtk-preedit-overlay nil))
451-
(let ((image-data (nth 1 e))
452-
img)
453-
(when image-data
454-
(setq img (create-image image-data 'pbm t))
455-
(setq pgtk-preedit-overlay (put-image img (point)))
456-
)))
450+
(delete-overlay pgtk-preedit-overlay))
451+
(setq pgtk-preedit-overlay nil)
452+
453+
(let (ov (ovstr "") str color (idx 0) face-name (atts nil))
454+
(dolist (part (nth 1 e))
455+
(setq str (car part))
456+
(setq face-name (intern (format "pgtk-im-%d" idx)))
457+
(eval
458+
`(defface ,face-name (list (cons t nil)) "face of input method preedit"))
459+
(setq atts nil)
460+
(when (setq color (cdr-safe (assq 'fg (cdr part))))
461+
(setq atts (cons :foreground (cons color atts))))
462+
(when (setq color (cdr-safe (assq 'bg (cdr part))))
463+
(setq atts (cons :background (cons color atts))))
464+
(when (setq color (cdr-safe (assq 'ul (cdr part))))
465+
(setq atts (cons :underline (cons color atts))))
466+
(face-spec-set face-name `((t . ,atts)))
467+
(add-text-properties 0 (length str) `(face ,face-name) str)
468+
(setq ovstr (concat ovstr str))
469+
(setq idx (1+ idx)))
470+
471+
(setq ov (make-overlay (point) (point)))
472+
(overlay-put ov 'before-string ovstr)
473+
(setq pgtk-preedit-overlay ov)))
457474

458475
(provide 'pgtk-win)
459476
(provide 'term/pgtk-win)

src/pgtkim.c

Lines changed: 58 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -63,103 +63,78 @@ static void im_context_preedit_changed_cb(GtkIMContext *imc, gpointer user_data)
6363

6464
gtk_im_context_get_preedit_string(imc, &str, &attrs, &pos);
6565

66+
67+
/*
68+
* (
69+
* (TEXT (ul . COLOR) (bg . COLOR) (fg . COLOR))
70+
* ...
71+
* )
72+
*/
73+
Lisp_Object list = Qnil;
74+
6675
PangoAttrIterator* iter;
6776
iter = pango_attr_list_get_iterator(attrs);
6877
do {
6978
int st, ed;
79+
int has_underline = 0;
80+
Lisp_Object part = Qnil;
81+
7082
pango_attr_iterator_range(iter, &st, &ed);
71-
printf("pango: %d..%d\n", st, ed);
72-
PangoAttrInt *ul = pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE);
83+
84+
if (ed > strlen(str))
85+
ed = strlen(str);
86+
if (st >= ed)
87+
continue;
88+
89+
Lisp_Object text = make_string(str + st, ed - st);
90+
part = Fcons(text, part);
91+
92+
PangoAttrInt *ul = (PangoAttrInt *) pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE);
7393
if (ul != NULL) {
74-
printf("pango: has underline ");
75-
switch (ul->value) {
76-
case PANGO_UNDERLINE_NONE:
77-
printf("none\n");
78-
break;
79-
case PANGO_UNDERLINE_DOUBLE:
80-
printf("double\n");
81-
break;
82-
case PANGO_UNDERLINE_ERROR:
83-
printf("error\n");
84-
break;
85-
case PANGO_UNDERLINE_SINGLE:
86-
printf("single\n");
87-
break;
88-
case PANGO_UNDERLINE_LOW:
89-
printf("low\n");
90-
break;
91-
default:
92-
break;
93-
}
94-
}
95-
PangoAttrColor *ulc = pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE_COLOR);
96-
if (ulc != NULL) {
97-
printf("pango: has underline color %02x%02x%02x\n",
98-
ulc->color.red >> 8, ulc->color.green >> 8, ulc->color.blue >> 8);
99-
}
100-
PangoAttrColor *fore = pango_attr_iterator_get(iter, PANGO_ATTR_FOREGROUND);
101-
if (fore != NULL) {
102-
printf("pango: has foreground %02x%02x%02x\n",
103-
fore->color.red >> 8, fore->color.green >> 8, fore->color.blue >> 8);
94+
if (ul->value != PANGO_UNDERLINE_NONE)
95+
has_underline = 1;
10496
}
105-
PangoAttrColor *back = pango_attr_iterator_get(iter, PANGO_ATTR_BACKGROUND);
106-
if (back != NULL) {
107-
printf("pango: has background %02x%02x%02x\n",
108-
back->color.red >> 8, back->color.green >> 8, back->color.blue >> 8);
109-
}
110-
} while (pango_attr_iterator_next(iter));
11197

112-
113-
/* get size */
114-
PangoLayout *layout = gtk_widget_create_pango_layout(FRAME_GTK_WIDGET(f), str);
115-
pango_layout_set_attributes(layout, attrs);
116-
int width, height;
117-
pango_layout_get_pixel_size(layout, &width, &height);
118-
119-
Lisp_Object image_data;
120-
if (width != 0 && height != 0) {
121-
char *buf = g_new0(char, 5 + 20 + 20 + 10 + 3 * width * height);
122-
sprintf(buf, "P6\n%d %d\n255\n", width, height);
123-
124-
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, width);
125-
unsigned char *crbuf = g_new0(unsigned char, stride * height);
126-
cairo_surface_t *surface = cairo_image_surface_create_for_data(crbuf, CAIRO_FORMAT_RGB24, width, height, stride);
127-
128-
cairo_t *cr = cairo_create(surface);
129-
cairo_set_source_rgb(cr, 0, 0, 0);
130-
cairo_rectangle(cr, 0, 0, width, height);
131-
cairo_fill(cr);
132-
cairo_set_source_rgb(cr, 1, 1, 1);
133-
pango_cairo_update_layout(cr, layout);
134-
pango_cairo_show_layout(cr, layout);
135-
cairo_destroy(cr);
136-
137-
cairo_surface_flush(surface);
138-
cairo_surface_destroy(surface);
139-
140-
unsigned char *sp = crbuf;
141-
unsigned char *dp = (unsigned char *) buf + strlen(buf);
142-
for (int y = 0; y < height; y++) {
143-
for (int x = 0; x < width; x++) {
144-
unsigned int rgb = *(unsigned int *) sp;
145-
*dp++ = (rgb >> 16) & 0xff;
146-
*dp++ = (rgb >> 8) & 0xff;
147-
*dp++ = (rgb >> 0) & 0xff;
148-
sp += 4;
98+
if (has_underline) {
99+
PangoAttrColor *ulc = (PangoAttrColor *) pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE_COLOR);
100+
if (ulc != NULL) {
101+
char *str = g_strdup_printf("#%02x%02x%02x",
102+
ulc->color.red >> 8,
103+
ulc->color.green >> 8,
104+
ulc->color.blue >> 8);
105+
part = Fcons(Fcons(intern("ul"), make_string(str, strlen(str))), part);
106+
g_free(str);
107+
} else {
108+
part = Fcons(Fcons(intern("ul"), Qt), part);
149109
}
150110
}
151111

152-
image_data = make_unibyte_string(buf, dp - (unsigned char *) buf);
112+
PangoAttrColor *fore = (PangoAttrColor *) pango_attr_iterator_get(iter, PANGO_ATTR_FOREGROUND);
113+
if (fore != NULL) {
114+
char *str = g_strdup_printf("#%02x%02x%02x",
115+
fore->color.red >> 8,
116+
fore->color.green >> 8,
117+
fore->color.blue >> 8);
118+
part = Fcons(Fcons(intern("fg"), make_string(str, strlen(str))), part);
119+
g_free(str);
120+
}
153121

154-
g_free(crbuf);
155-
g_free(buf);
156-
} else
157-
image_data = Qnil;
122+
PangoAttrColor *back = (PangoAttrColor *) pango_attr_iterator_get(iter, PANGO_ATTR_BACKGROUND);
123+
if (back != NULL) {
124+
char *str = g_strdup_printf("#%02x%02x%02x",
125+
back->color.red >> 8,
126+
back->color.green >> 8,
127+
back->color.blue >> 8);
128+
part = Fcons(Fcons(intern("bg"), make_string(str, strlen(str))), part);
129+
g_free(str);
130+
}
158131

159-
pgtk_enqueue_preedit(f, image_data);
132+
part = Freverse(part);
133+
list = Fcons(part, list);
134+
} while (pango_attr_iterator_next(iter));
160135

161-
g_object_unref(layout);
162-
pango_font_description_free(font_desc);
136+
list = Freverse(list);
137+
pgtk_enqueue_preedit(f, list);
163138

164139
if (dpyinfo->im.preedit_str != NULL)
165140
g_free(dpyinfo->im.preedit_str);

src/pgtkterm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4994,12 +4994,12 @@ pgtk_enqueue_string(struct frame *f, gchar *str)
49944994
}
49954995

49964996
void
4997-
pgtk_enqueue_preedit(struct frame *f, Lisp_Object image_data)
4997+
pgtk_enqueue_preedit(struct frame *f, Lisp_Object preedit)
49984998
{
49994999
union buffered_input_event inev;
50005000
EVENT_INIT (inev.ie);
50015001
inev.ie.kind = PGTK_PREEDIT_TEXT_EVENT;
5002-
inev.ie.arg = image_data;
5002+
inev.ie.arg = preedit;
50035003
inev.ie.code = 0;
50045004
XSETFRAME (inev.ie.frame_or_window, f);
50055005
inev.ie.modifiers = 0;

0 commit comments

Comments
 (0)