13 #include <m17n-misc.h>
15 #define PIPE_IN "/tmp/mimdemo-in"
16 #define PIPE_OUT "/tmp/mimdemo-out"
18 /* Format MSG by FMT and print the result to the stderr, and exit. */
20 #define FATAL_ERROR(fmt, arg) \
22 fprintf (out, "0\n"); \
23 fprintf (out, fmt, arg); \
24 fprintf (out, "\n"); \
28 char base64_encode_table[] =
29 { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
30 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
31 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
32 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
33 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
34 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
38 base64_encode (const unsigned char *src, int length, FILE *fp)
47 putc (base64_encode_table[0x3f & c >> 2], fp);
48 value = (0x03 & c) << 4;
51 putc (base64_encode_table[value], fp);
57 putc (base64_encode_table[value | (0x0f & c >> 4)], fp);
58 value = (0x0f & c) << 2;
61 putc (base64_encode_table[value], fp);
66 putc (base64_encode_table[value | (0x03 & c >> 6)], fp);
67 putc (base64_encode_table[0x3f & c], fp);
72 main (int argc, char **argv)
75 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
88 MConverter *converter;
91 MDrawMetric ink, logical;
92 int ascent, descent, height, width;
101 if (mkfifo (PIPE_IN, mode) < 0 && errno != EEXIST)
103 fprintf (stderr, "Failed to make a named pipe.\n");
107 if (mkfifo (PIPE_OUT, mode) < 0 && errno != EEXIST)
109 fprintf (stderr, "Failed to make a named pipe.\n");
114 if (merror_code != MERROR_NONE)
116 fprintf (stderr, "Failed to initialize the m17n library.\n");
121 MPlist *plist = mplist (), *p;
122 MFontset *fontset = mfontset ("generic");
123 MFace *face = mface ();
125 mface_put_prop (face, Mfontset, fontset);
126 mface_put_prop (face, Msize, (void *) (fontsize * dpi / 100));
127 p = mplist_add (plist, Mdevice, msymbol ("gd"));
128 p = mplist_add (p, Mface, face);
129 m17n_object_unref (face);
130 frame = mframe (plist);
131 m17n_object_unref (plist);
134 fprintf (stderr, "Failed to open a frame.\n");
141 char langname[256], imname[256];
143 printf ("accepting...");
145 in = fopen (PIPE_IN, "r");
146 printf ("\nconnecting...");
148 out = fopen (PIPE_OUT, "w");
151 fprintf (stderr, "Failed to open a named pipe.\n");
154 printf ("done\nreading...");
157 memset (langname, 0, 256);
158 memset (imname, 0, 256);
161 while ((c = getc (in)) != EOF && c != '-')
164 FATAL_ERROR ("Too long lang name: %s.", langname);
168 FATAL_ERROR ("No input method name for %s.", langname);
170 while ((c = getc (in)) != EOF && c != ' ')
173 FATAL_ERROR ("Too long input method name: %s", imname);
177 FATAL_ERROR ("%s", "No key sequence");
179 lang = msymbol (langname);
180 name = msymbol (imname);
182 im = minput_open_im (lang, name, NULL);
184 FATAL_ERROR ("Failed to open input method \"%s\".", imname);
185 ic = minput_create_ic (im, NULL);
187 FATAL_ERROR ("%s", "Failed to create the input context.");
189 while ((c = getc (in)) != EOF)
196 key = msymbol (keybuf);
197 if (minput_filter (ic, key, NULL) == 1)
199 if (minput_lookup (ic, key, NULL, mt) < 0)
201 mtext_cat_char (mt, c);
205 mtext_cat (mt, ic->preedit);
206 minput_destroy_ic (ic);
207 minput_close_im (im);
209 len = mtext_len (mt);
212 m17n_object_unref (mt);
216 mtext_put_prop (mt, 0, len, Mlanguage, lang);
218 memset (&control, 0, sizeof control);
219 control.enable_bidi = 1;
221 mdraw_text_extents (frame, mt, 0, len, &control, &ink, &logical, NULL);
222 ascent = - logical.y;
223 if (ascent < - ink.y)
225 descent = logical.height + logical.y;
226 if (descent < ink.height + ink.y)
227 descent = ink.height + ink.y;
228 height = ascent + descent;
229 width = logical.width;
230 if (height == 0 || width == 0)
232 m17n_object_unref (mt);
236 work = gdImageCreate (width, height);
237 work_white = gdImageColorAllocate (work, 255, 255, 255);
238 gdImageColorTransparent (work, work_white);
239 gdImageFilledRectangle (work, 0, 0, width - 1, height - 1, work_white);
240 mdraw_text_with_control (frame, work, 0, ascent, mt, 0, len, &control);
242 converter = mconv_stream_converter (msymbol ("utf-8"), out);
244 fprintf (out, "1\n");
247 MDrawMetric *ink_array, *logical_array;
248 int array_size = len * 2;
253 ink_array = malloc (sizeof (MDrawMetric) * array_size);
254 logical_array = malloc (sizeof (MDrawMetric) * array_size);
256 if (mdraw_text_per_char_extents (frame, mt, 0, len, &control,
257 ink_array, logical_array,
258 array_size, &num_chars, NULL, NULL) < 0)
260 ink_array = realloc (ink_array, sizeof (MDrawMetric) * num_chars);
261 logical_array = realloc (logical_array, sizeof (MDrawMetric) * num_chars);
262 mdraw_text_per_char_extents (frame, mt, 0, len, &control,
263 ink_array, logical_array,
264 num_chars, &num_chars, NULL, NULL);
267 for (from = 0, i = 0; i < num_chars;)
271 int x = logical_array[i].x;
273 image = gdImageCreate (logical_array[i].width, height);
274 white = gdImageColorAllocate (image, 255, 255, 255);
275 gdImageColorTransparent (image, white);
276 gdImageCopy (image, work, 0, 0,
277 logical_array[i].x, 0, logical_array[i].width, height);
278 fprintf (out, "<img src=\"data:image/png;base64,");
279 buf = gdImagePngPtr (image, &size);
280 base64_encode (buf, size, out);
282 gdImageDestroy (image);
284 while (++i < num_chars && logical_array[i].x == x);
288 to = mdraw_coordinates_position (frame, mt, 0, len,
289 logical_array[i].x, 0, &control);
290 fprintf (out, "\" alt=\"");
291 mconv_encode_range (converter, mt, from, to);
292 fprintf (out, "\">");
296 free (logical_array);
299 gdImageDestroy (work);
300 m17n_object_unref (mt);