--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+
+#define PIPE_IN "/tmp/mimdemo-in"
+#define PIPE_OUT "/tmp/mimdemo-out"
+
+int
+main ()
+{
+ FILE *in, *out;
+ mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+ int c;
+
+ umask (0);
+ if (mkfifo (PIPE_IN, mode) < 0 && errno != EEXIST)
+ {
+ fprintf (stderr, "Failed to make a named pipe.\n");
+ exit (1);
+ }
+
+ if (mkfifo (PIPE_OUT, mode) < 0 && errno != EEXIST)
+ {
+ fprintf (stderr, "Failed to make a named pipe.\n");
+ exit (1);
+ }
+
+ do {
+ printf ("accepting...");
+ fflush (stdout);
+ in = fopen (PIPE_IN, "r");
+ printf ("\nconnecting...");
+ fflush (stdout);
+ out = fopen (PIPE_OUT, "w");
+ printf ("done\n");
+ if (! in || ! out)
+ {
+ fprintf (stderr, "Failed to open a named pipe.\n");
+ exit (1);
+ }
+ while ((c = getc (in)) != EOF && c != '!')
+ {
+ putchar (c);
+ putc (toupper (c), out);
+ fflush (out);
+ }
+ fclose (in);
+ fclose (out);
+ } while (c != '!');
+
+ unlink (PIPE_IN);
+ unlink (PIPE_OUT);
+ exit (0);
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define PIPE_IN "/tmp/mimdemo-in"
+#define PIPE_OUT "/tmp/mimdemo-out"
+
+int
+main (int argc, char **argv)
+{
+ FILE *out = fopen (PIPE_IN, "w");
+ FILE *in = fopen (PIPE_OUT, "r");
+ int c;
+
+ fprintf (out, "%s %s %s", argv[1], argv[2], argv[3]);
+ fclose (out);
+
+ while ((c = getc (in)) != EOF)
+ putchar (c);
+ fclose (in);
+ exit (0);
+}
{
MSymbol family, foundry, weight, slant, stretch;
char *weight_name, *slant_name, *stretch_name;
- int len;
char style_name[1024];
family = mfont_get_prop (font, Mfamily);
{
MPlist *plist, *p;
MFrame *frame;
- char buf[256];
M17N_INIT ();
else if (argc == 2)
{
MFont *font = parse_font_name (argv[1]);
- MPlist *p0;
plist = mfont_list (frame, font, Mnil, 0);
free (font);
int array_size, num_glyphs;
MPlist *family_list;
int family_name_len;
- char *p;
memset (&control, 0, sizeof (control));
control.anti_alias = 1;
- metric.x, - metric.y,
mt, 0, mtext_len (mt), &control);
m17n_object_unref (frame);
- m17n_object_unref (mt);
if (family_list)
{
attr_list = pango_attr_list_new ();
attr_size = pango_attr_size_new (FONT_PT_SIZE * PANGO_SCALE);
attr_family = family_names ? pango_attr_family_new (family_names) : NULL;
- pango_attr_list_insert (attr_list, attr_size);
+#if 0
if (attr_family)
- pango_attr_list_insert (attr_list, attr_family);
+ pango_attr_list_change (attr_list, attr_family);
+#endif
+ pango_attr_list_change (attr_list, attr_size);
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 0, 8,
metric.width, metric.height);
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+
+#include <m17n.h>
+#include <m17n-misc.h>
+
+MSymbol utf8;
+
+void
+show_description (MText *mt, int indent)
+{
+ if (mt)
+ {
+ printf ("\n%*sdescription: ", indent, "");
+ mconv_encode_stream (utf8, mt, stdout);
+ }
+ else
+ printf ("\n%*sno-description", indent, "");
+}
+
+void
+show_input_method (MSymbol lang, MSymbol name, int indent)
+{
+ MText *mt;
+ MSymbol language;
+
+ if (lang == Mt)
+ language = msymbol ("generic");
+ else if ((language = msymbol_get (lang, Mlanguage)) == Mnil)
+ language = lang;
+ printf ("\n%*slanguage: %s name: %s",
+ indent, "", msymbol_name (language), msymbol_name (name));
+ mt = minput_get_description (lang, name);
+ show_description (mt, indent + 2);
+ if (mt)
+ m17n_object_unref (mt);
+}
+
+void
+show_command (MSymbol cmd, MPlist *p, int indent)
+{
+ printf ("\n%*sname: %s", indent, "", msymbol_name (cmd));
+ indent += 2;
+ show_description (mplist_value (p), indent);
+ p = mplist_next (p);
+ if (mplist_key (p) == Mnil)
+ printf ("\n%*skey-sequence: global assignments are effective", indent, "");
+ else
+ for (; mplist_key (p) != Mnil; p = mplist_next (p))
+ if (mplist_key (p) == Mplist)
+ {
+ MPlist *p0 = mplist_value (p);
+
+ if (mplist_key (p0) != Mnil)
+ {
+ printf ("\n%*skey-sequence:", indent, "");
+ for (; mplist_key (p0) != Mnil; p0 = mplist_next (p0))
+ printf (" %s", msymbol_name ((MSymbol) mplist_value (p0)));
+ }
+ }
+}
+
+void
+show_variable (MSymbol var, MPlist *p, int indent)
+{
+ MSymbol type;
+
+ printf ("\n%*sname: %s", indent, "", msymbol_name (var));
+ indent += 2;
+ show_description (mplist_value (p), indent);
+ p = mplist_next (p);
+ printf ("\n%*sinitial-value: ", indent, "");
+ type = mplist_key (p);
+ if (type == Minteger)
+ printf ("%d", (int) mplist_value (p));
+ else if (type == Msymbol)
+ printf ("%s", msymbol_name ((MSymbol) mplist_value (p)));
+ else /* type == Mtext */
+ {
+ printf ("\"");
+ mconv_encode_stream (utf8, (MText *) mplist_value (p), stdout);
+ printf ("\"");
+ }
+ p = mplist_next (p);
+ printf ("\n%*svalid-value:", indent, "");
+ if (mplist_key (p) == Mnil)
+ printf (" any value of type %s", msymbol_name (type));
+ else
+ for (; mplist_key (p) != Mnil; p = mplist_next (p))
+ {
+ MSymbol this_type = mplist_key (p);
+
+ if (type != this_type && (type != Minteger || this_type != Mplist))
+ /* This shouldn't happen. */
+ continue;
+ if (this_type == Minteger)
+ printf (" %d", (int) mplist_value (p));
+ else if (this_type == Msymbol)
+ printf (" %s", msymbol_name ((MSymbol) mplist_value (p)));
+ else if (this_type == Mtext)
+ {
+ printf (" \"");
+ mconv_encode_stream (utf8, (MText *) mplist_value (p), stdout);
+ printf ("\"");
+ }
+ else /* type == Mplist */
+ {
+ MPlist *p0 = mplist_value (p);
+
+ printf (" %d", (int) mplist_value (p0));
+ p0 = mplist_next (p0);
+ printf ("-%d", (int) mplist_value (p0));
+ }
+ }
+}
+
+#if 0
+MPlist *im_list = NULL;
+
+MInputMethod *
+get_im (MSymbol lang, MSymbol name)
+{
+ MInputMethod *im;
+ MPlist *p;
+
+ if (! im_list)
+ im_list = mplist ();
+ for (p = im_list; mplist_key (p) != Mnil; p = mplist_next (p))
+ {
+ im = mplist_value (p);
+ if (im->language == lang && im->name == name)
+ return im;
+ }
+ im = minput_open_im (lang, name, NULL);
+ if (! im)
+ return NULL;
+ mplist_push (im_list, Mt, im);
+ return im;
+}
+
+void
+close_ims ()
+{
+ MInputMethod *im;
+ MPlist *p;
+
+ if (! im_list)
+ return;
+ for (p = im_list; mplist_key (p) != Mnil; p = mplist_next (p))
+ {
+ im = mplist_value (p);
+ minput_close_im (im);
+ }
+ m17n_object_unref (im_list);
+}
+
+void
+show_preedit (MInputContext *ic)
+{
+ int len = mtext_len (ic->preedit);
+ int i;
+
+ printf ("preedit:");
+ for (i = 0; i < len; i++)
+ printf (" U+%04X", mtext_ref_char (ic->preedit, i));
+ printf ("\n");
+ fflush (stdout);
+}
+
+void
+show_candidates (MInputContext *ic)
+{
+ MPlist *plist = ic->candidate_list;
+ int idx = ic->candidate_index;
+ int items;
+ int i, j, len;
+ MText *mt;
+
+ printf ("candidates:");
+ while (1)
+ {
+ if (mplist_key (plist) == Mtext)
+ items = mtext_len ((MText *) mplist_value (plist));
+ else
+ items = mplist_length ((MPlist *) mplist_value (plist));
+ if (idx < items)
+ break;
+ idx -= items;
+ plist = mplist_next (plist);
+ }
+ if (mplist_key (plist) == Mtext)
+ {
+ mt = (MText *) mplist_value (plist);
+ for (i = 0; i < items; i++)
+ {
+ if (i == idx)
+ printf ("[U+%04X]", mtext_ref_char (mt, i));
+ else
+ printf (" U+%04X ", mtext_ref_char (mt, i));
+ }
+ }
+ else
+ {
+ plist = (MPlist *) mplist_value (plist);
+ for (i = 0; i < items; i++, plist = mplist_next (plist))
+ {
+ mt = (MText *) mplist_value (plist);
+ len = mtext_len (mt);
+ if (i == idx)
+ printf ("[");
+ else
+ printf (" ");
+ for (j = 0; j < len; j++)
+ {
+ if (j > 0)
+ printf (",");
+ printf ("U+%04X", mtext_ref_char (mt, j));
+ }
+ if (i == idx)
+ printf ("[");
+ else
+ printf (" ");
+ }
+ }
+ printf ("\n");
+ fflush (stdout);
+}
+
+void
+show_produced (MText *mt)
+{
+ int len = mtext_len (mt);
+ int i;
+
+ printf ("produced:");
+ for (i = 0; i < len; i++)
+ printf (" U+%04X", mtext_ref_char (mt, i));
+ printf ("\n");
+ fflush (stdout);
+}
+
+int
+main (int argc, char **argv)
+{
+ char line[256];
+ MSymbol lang, name;
+ MInputMethod *im = NULL;
+ MInputContext *ic = NULL;
+
+ M17N_INIT ();
+
+ while (fgets (line, 256, stdin))
+ {
+ if (strncmp (line, "open", 4) == 0)
+ {
+ char langstr[16], namestr[16];
+
+ if (ic)
+ minput_destroy_ic (ic);
+ if (sscanf (line + 4, "%s %s", langstr, namestr) != 2)
+ continue;
+ lang = msymbol (langstr);
+ name = msymbol (namestr);
+ printf ("opening im \"%s\" \"%s\" ...", langstr, namestr);
+ im = get_im (lang, name);
+ if (! im)
+ {
+ printf (" failed\n");
+ fflush (stdout);
+ continue;
+ }
+ printf (" done\n");
+ printf ("creating context ...");
+ ic = minput_create_ic (im, NULL);
+ if (! ic)
+ {
+ printf ("failed\n");
+ fflush (stdout);
+ minput_close_im (im);
+ im = NULL;
+ continue;
+ }
+ printf (" done\n");
+ fflush (stdout);
+ }
+ else if (! ic)
+ {
+ printf ("no input method is available\n");
+ fflush (stdout);
+ continue;
+ }
+ else
+ {
+ int i;
+ char keystr[4];
+ MSymbol key;
+
+ for (i = 0; line[i] != '\n'; i++)
+ {
+ int c = line[i];
+ int result;
+ MText *mt;
+
+ if (c < 32)
+ sprintf (keystr, "C-%c", c + 64);
+ else
+ sprintf (keystr, "%c", c);
+ key = msymbol (keystr);
+ result = minput_filter (ic, key, NULL);
+ if (ic->preedit_changed)
+ show_preedit (ic);
+ if (ic->candidates_changed && ic->candidate_show
+ && ic->candidate_list)
+ show_candidates (ic);
+ if (result > 0)
+ continue;
+ mt = mtext ();
+ minput_lookup (ic, key, NULL, mt);
+ show_produced (mt);
+ m17n_object_unref (mt);
+ }
+ }
+ }
+
+ if (ic)
+ minput_destroy_ic (ic);
+ close_ims ();
+ M17N_FINI ();
+ exit (0);
+}
+
+#else
+int
+main (int argc, char **argv)
+{
+ MPlist *plist, *pl;
+ MSymbol unicode, test, commit;
+ MPlist *keyseq;
+ int test_input_method_found = 0;
+
+ /* To make database module find test.mim in this directory. */
+ mdatabase_dir = ".";
+
+ M17N_INIT ();
+ utf8 = msymbol ("utf-8");
+ unicode = msymbol ("unicode");
+ test = msymbol ("test");
+ commit = msymbol ("commit");
+
+ mdatabase_define (msymbol ("input"), msymbol ("command"), Mnil, Mnil,
+ NULL, "im-cmd.tbl");
+ printf ("List all available input methods:");
+ plist = mdatabase_list (msymbol ("input-method"), Mnil, Mnil, Mnil);
+ if (! plist)
+ goto err;
+ for (pl = plist; mplist_key (pl) != Mnil; pl = mplist_next (pl))
+ {
+ MDatabase *mdb = mplist_value (pl);
+ MSymbol *tag = mdatabase_tag (mdb);
+
+ show_input_method (tag[1], tag[2], 2);
+ if (tag[1] == Mt && tag[2] == test)
+ test_input_method_found = 1;
+ }
+ printf ("\n");
+ m17n_object_unref (plist);
+
+ printf ("Is test input method found?\n");
+ if (! test_input_method_found)
+ goto err;
+ printf (" Found\n");
+
+ printf ("Describe commit command and its global key assignment:");
+ plist = minput_get_commands (Mnil, Mnil);
+ if (! plist || ! (plist = mplist_get (plist, commit)))
+ goto err;
+ show_command (commit, plist, 2);
+ printf ("\n");
+
+ /* Assign S-space to the command "commit" globally. */
+ printf ("Assign S-space to commit globally:");
+ keyseq = mplist ();
+ mplist_add (keyseq, Msymbol, msymbol ("S-space"));
+ if (minput_assign_command_keys (Mnil, Mnil, commit, keyseq) < 0)
+ goto err;
+ /* Check the above assignment. */
+ plist = minput_get_commands (Mnil, Mnil);
+ plist = mplist_get (plist, commit);
+ show_command (commit, plist, 2);
+ printf ("\n");
+
+ printf ("Describe commit command and its local key assignment in \"test\":");
+ plist = minput_get_commands (Mt, test);
+ if (! plist
+ || ! (plist = mplist_get (plist, commit)))
+ goto err;
+ show_command (commit, plist, 2);
+ printf ("\n");
+
+ printf ("Assign A-space to commit locally in \"test\":");
+ mplist_put (keyseq, Msymbol, msymbol ("A-space"));
+ if (minput_assign_command_keys (Mt, test, commit, keyseq) < 0
+ || ! (plist = minput_get_commands (Mt, test))
+ || ! (plist = mplist_get (plist, commit)))
+ goto err;
+ show_command (commit, plist, 2);
+ printf ("\n");
+
+ printf ("Cancel the above locale assignment:");
+ if (minput_assign_command_keys (Mt, test, commit, NULL) < 0
+ || ! (plist = minput_get_commands (Mt, test))
+ || ! (plist = mplist_get (plist, commit)))
+ goto err;
+ show_command (commit, plist, 2);
+ printf ("\n");
+
+ printf ("Assign A-space in addition to global assignments to commit:");
+ minput_assign_command_keys (Mt, test, commit, keyseq);
+ plist = mplist_next (mplist_get (minput_get_commands (Mnil, Mnil), commit));
+ for (; mplist_key (plist) != Mnil; plist = mplist_next (plist))
+ minput_assign_command_keys (Mt, test, commit, mplist_value (plist));
+
+ if (! (plist = minput_get_commands (Mt, test))
+ || ! (plist = mplist_get (plist, commit)))
+ goto err;
+ show_command (commit, plist, 2);
+ printf ("\n");
+
+ printf ("Cancel the assignment without making global assignment effective:");
+ /* Make KEYSEQ an empty plist. */
+ mplist_pop (keyseq);
+ minput_assign_command_keys (Mt, test, commit, NULL);
+ minput_assign_command_keys (Mt, test, commit, keyseq);
+ if (! (plist = minput_get_commands (Mt, test))
+ || ! (plist = mplist_get (plist, commit)))
+ goto err;
+ show_command (commit, plist, 2);
+ printf ("\n");
+ m17n_object_unref (keyseq);
+
+ printf ("List variables used in \"test\":");
+ plist = minput_get_variables (Mt, test);
+ if (! plist)
+ goto err;
+ for (; mplist_key (plist) != Mnil; plist = mplist_next (plist))
+ show_variable (mplist_key (plist), mplist_value (plist), 2);
+ printf ("\n");
+
+ printf ("Set the first variable to hello ... should fail:\n");
+ plist = minput_get_variables (Mt, test);
+ if (minput_set_variable (Mt, test, mplist_key (plist), msymbol ("hello")) < 0)
+ printf (" Correctly failed\n");
+ else
+ printf (" Incorrectly succeeded\n");
+
+ printf ("Set the first variable to no ... should succeed:\n");
+ if (minput_set_variable (Mt, test, mplist_key (plist), msymbol ("no")) < 0)
+ printf (" Incorrectly failed\n");
+ else
+ printf (" Correctly succeeded\n");
+
+ plist = mplist_next (plist);
+ printf ("Set the second variable to 5 ... should fail:\n");
+ if (minput_set_variable (Mt, test, mplist_key (plist), (void *) 5) < 0)
+ printf (" Correctly failed\n");
+ else
+ printf (" Incorrectly succeeded\n");
+ printf ("Set the second variable to 10 ... should succeeded:\n");
+ if (minput_set_variable (Mt, test, mplist_key (plist), (void *) 10) < 0)
+ printf (" Incorrectly failed\n");
+ else
+ printf (" Correctly succeeded\n");
+
+ plist = mplist_next (plist);
+ {
+ char *str = "hello";
+ MText *mt = mtext_from_data (str, strlen (str), MTEXT_FORMAT_US_ASCII);
+
+ printf ("Set the third variable to \"hello\" ... should succeed:\n");
+ if (minput_set_variable (Mt, test, mplist_key (plist), mt) < 0)
+ printf (" Incorrectly failed\n");
+ else
+ printf (" Correctly succeeded\n");
+ m17n_object_unref (mt);
+ }
+
+ printf ("List variables used in \"test\" again:");
+ plist = minput_get_variables (Mt, test);
+ if (! plist)
+ goto err;
+ for (; mplist_key (plist) != Mnil; plist = mplist_next (plist))
+ show_variable (mplist_key (plist), mplist_value (plist), 2);
+ printf ("\n");
+
+ M17N_FINI ();
+ exit (0);
+
+ err:
+ printf (" ...failed!\n");
+ exit (1);
+}
+#endif
+
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+
+#include <gd.h>
+
+#include <m17n-gui.h>
+#include <m17n-misc.h>
+
+#define PIPE_IN "/tmp/mimdemo-in"
+#define PIPE_OUT "/tmp/mimdemo-out"
+
+/* Format MSG by FMT and print the result to the stderr, and exit. */
+
+#define FATAL_ERROR(fmt, arg) \
+ do { \
+ fprintf (out, "0\n"); \
+ fprintf (out, fmt, arg); \
+ fprintf (out, "\n"); \
+ goto err; \
+ } while (0)
+
+char base64_encode_table[] =
+ { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+ 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', '+', '/' };
+
+void
+base64_encode (const unsigned char *src, int length, FILE *fp)
+{
+ int i = 0;
+ int c;
+ unsigned int value;
+
+ while (i < length)
+ {
+ c = src[i++];
+ putc (base64_encode_table[0x3f & c >> 2], fp);
+ value = (0x03 & c) << 4;
+ if (i == length)
+ {
+ putc (base64_encode_table[value], fp);
+ putc ('=', fp);
+ putc ('=', fp);
+ break;
+ }
+ c = src[i++];
+ putc (base64_encode_table[value | (0x0f & c >> 4)], fp);
+ value = (0x0f & c) << 2;
+ if (i == length)
+ {
+ putc (base64_encode_table[value], fp);
+ putc ('=', fp);
+ break;
+ }
+ c = src[i++];
+ putc (base64_encode_table[value | (0x03 & c >> 6)], fp);
+ putc (base64_encode_table[0x3f & c], fp);
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ FILE *in, *out;
+ mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+ int c;
+
+ int fontsize = 240;
+ int dpi = 100;
+
+ MText *mt;
+ int i;
+ MSymbol lang, name;
+ MInputMethod *im;
+ MInputContext *ic;
+
+ int len, from, to;
+ MConverter *converter;
+ MFrame *frame;
+ MDrawControl control;
+ MDrawMetric ink, logical;
+ int ascent, descent, height, width;
+#if 0
+ int indent = 0;
+ int left_adjust;
+#endif
+ gdImagePtr work;
+ int work_white;
+
+ umask (0);
+ if (mkfifo (PIPE_IN, mode) < 0 && errno != EEXIST)
+ {
+ fprintf (stderr, "Failed to make a named pipe.\n");
+ exit (1);
+ }
+
+ if (mkfifo (PIPE_OUT, mode) < 0 && errno != EEXIST)
+ {
+ fprintf (stderr, "Failed to make a named pipe.\n");
+ exit (1);
+ }
+
+ M17N_INIT ();
+ if (merror_code != MERROR_NONE)
+ {
+ fprintf (stderr, "Failed to initialize the m17n library.\n");
+ exit (1);
+ }
+
+ {
+ MPlist *plist = mplist (), *p;
+ MFontset *fontset = mfontset ("generic");
+ MFace *face = mface ();
+
+ mface_put_prop (face, Mfontset, fontset);
+ mface_put_prop (face, Msize, (void *) (fontsize * dpi / 100));
+ p = mplist_add (plist, Mdevice, msymbol ("gd"));
+ p = mplist_add (p, Mface, face);
+ m17n_object_unref (face);
+ frame = mframe (plist);
+ m17n_object_unref (plist);
+ if (! frame)
+ {
+ fprintf (stderr, "Failed to open a frame.\n");
+ exit (1);
+ }
+ }
+
+ while (1)
+ {
+ char langname[256], imname[256];
+
+ printf ("accepting...");
+ fflush (stdout);
+ in = fopen (PIPE_IN, "r");
+ printf ("\nconnecting...");
+ fflush (stdout);
+ out = fopen (PIPE_OUT, "w");
+ if (! in || ! out)
+ {
+ fprintf (stderr, "Failed to open a named pipe.\n");
+ exit (1);
+ }
+ printf ("done\nreading...");
+ fflush (stdout);
+
+ memset (langname, 0, 256);
+ memset (imname, 0, 256);
+
+ i = 0;
+ while ((c = getc (in)) != EOF && c != '-')
+ {
+ if (i == 255)
+ FATAL_ERROR ("Too long lang name: %s.", langname);
+ langname[i++] = c;
+ }
+ if (c != '-')
+ FATAL_ERROR ("No input method name for %s.", langname);
+ i = 0;
+ while ((c = getc (in)) != EOF && c != ' ')
+ {
+ if (i == 255)
+ FATAL_ERROR ("Too long input method name: %s", imname);
+ imname[i++] = c;
+ }
+ if (c != ' ')
+ FATAL_ERROR ("%s", "No key sequence");
+
+ lang = msymbol (langname);
+ name = msymbol (imname);
+
+ im = minput_open_im (lang, name, NULL);
+ if (! im)
+ FATAL_ERROR ("Failed to open input method \"%s\".", imname);
+ ic = minput_create_ic (im, NULL);
+ if (! im)
+ FATAL_ERROR ("%s", "Failed to create the input context.");
+ mt = mtext ();
+ while ((c = getc (in)) != EOF)
+ {
+ char keybuf[2];
+ MSymbol key;
+
+ keybuf[0] = c;
+ keybuf[1] = '\0';
+ key = msymbol (keybuf);
+ if (minput_filter (ic, key, NULL) == 1)
+ continue;
+ if (minput_lookup (ic, key, NULL, mt) < 0)
+ {
+ mtext_cat_char (mt, c);
+ }
+ }
+ if (ic->preedit)
+ mtext_cat (mt, ic->preedit);
+ minput_destroy_ic (ic);
+ minput_close_im (im);
+
+ len = mtext_len (mt);
+ if (len == 0)
+ {
+ m17n_object_unref (mt);
+ goto err;
+ }
+
+ mtext_put_prop (mt, 0, len, Mlanguage, lang);
+
+ memset (&control, 0, sizeof control);
+ control.enable_bidi = 1;
+
+ mdraw_text_extents (frame, mt, 0, len, &control, &ink, &logical, NULL);
+ ascent = - logical.y;
+ if (ascent < - ink.y)
+ ascent = -ink.y;
+ descent = logical.height + logical.y;
+ if (descent < ink.height + ink.y)
+ descent = ink.height + ink.y;
+ height = ascent + descent;
+ width = logical.width;
+ if (height == 0 || width == 0)
+ {
+ m17n_object_unref (mt);
+ goto err;
+ }
+
+ work = gdImageCreate (width, height);
+ work_white = gdImageColorAllocate (work, 255, 255, 255);
+ gdImageColorTransparent (work, work_white);
+ gdImageFilledRectangle (work, 0, 0, width - 1, height - 1, work_white);
+ mdraw_text_with_control (frame, work, 0, ascent, mt, 0, len, &control);
+
+ converter = mconv_stream_converter (msymbol ("utf-8"), out);
+
+ fprintf (out, "1\n");
+ from = 0;
+ {
+ MDrawMetric *ink_array, *logical_array;
+ int array_size = len * 2;
+ int num_chars;
+ unsigned char *buf;
+ int size;
+
+ ink_array = malloc (sizeof (MDrawMetric) * array_size);
+ logical_array = malloc (sizeof (MDrawMetric) * array_size);
+
+ if (mdraw_text_per_char_extents (frame, mt, 0, len, &control,
+ ink_array, logical_array,
+ array_size, &num_chars, NULL, NULL) < 0)
+ {
+ ink_array = realloc (ink_array, sizeof (MDrawMetric) * num_chars);
+ logical_array = realloc (logical_array, sizeof (MDrawMetric) * num_chars);
+ mdraw_text_per_char_extents (frame, mt, 0, len, &control,
+ ink_array, logical_array,
+ num_chars, &num_chars, NULL, NULL);
+ }
+
+ for (from = 0, i = 0; i < num_chars;)
+ {
+ gdImagePtr image;
+ int white;
+ int x = logical_array[i].x;
+
+ image = gdImageCreate (logical_array[i].width, height);
+ white = gdImageColorAllocate (image, 255, 255, 255);
+ gdImageColorTransparent (image, white);
+ gdImageCopy (image, work, 0, 0,
+ logical_array[i].x, 0, logical_array[i].width, height);
+ fprintf (out, "<img src=\"data:image/png;base64,");
+ buf = gdImagePngPtr (image, &size);
+ base64_encode (buf, size, out);
+ gdFree (buf);
+ gdImageDestroy (image);
+
+ while (++i < num_chars && logical_array[i].x == x);
+ if (i == num_chars)
+ to = len;
+ else
+ to = mdraw_coordinates_position (frame, mt, 0, len,
+ logical_array[i].x, 0, &control);
+ fprintf (out, "\" alt=\"");
+ mconv_encode_range (converter, mt, from, to);
+ fprintf (out, "\">");
+ from = to;
+ }
+ free (ink_array);
+ free (logical_array);
+ }
+ fprintf (out, "\n");
+ gdImageDestroy (work);
+ m17n_object_unref (mt);
+
+ err:
+ fclose (in);
+ fclose (out);
+ }
+
+ M17N_FINI ();
+ unlink (PIPE_IN);
+ unlink (PIPE_OUT);
+ exit (0);
+}
+
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <libgen.h>
+
+#include <gd.h>
+
+#include <m17n-gui.h>
+#include <m17n-misc.h>
+
+/* Format MSG by FMT and print the result to the stderr, and exit. */
+
+#define FATAL_ERROR(fmt, arg) \
+ do { \
+ printf ("0\n"); \
+ printf (fmt, arg); \
+ exit (0); \
+ } while (0)
+
+char base64_encode_table[] =
+ { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+ 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', '+', '/' };
+
+void
+base64_encode (const unsigned char *src, int length, FILE *fp)
+{
+ int i = 0;
+ int c;
+ unsigned int value;
+
+ while (i < length)
+ {
+ c = src[i++];
+ putc (base64_encode_table[0x3f & c >> 2], fp);
+ value = (0x03 & c) << 4;
+ if (i == length)
+ {
+ putc (base64_encode_table[value], fp);
+ putc ('=', fp);
+ putc ('=', fp);
+ break;
+ }
+ c = src[i++];
+ putc (base64_encode_table[value | (0x0f & c >> 4)], fp);
+ value = (0x0f & c) << 2;
+ if (i == length)
+ {
+ putc (base64_encode_table[value], fp);
+ putc ('=', fp);
+ break;
+ }
+ c = src[i++];
+ putc (base64_encode_table[value | (0x03 & c >> 6)], fp);
+ putc (base64_encode_table[0x3f & c], fp);
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ int fontsize = 240;
+ int dpi = 100;
+
+ MText *mt;
+ int i;
+ MSymbol lang, name;
+ MInputMethod *im;
+ MInputContext *ic;
+
+ int len, from, to;
+ MConverter *converter;
+ MFrame *frame;
+ MDrawControl control;
+ MDrawMetric ink, logical;
+ int ascent, descent, height, width;
+#if 0
+ int indent = 0;
+ int left_adjust;
+#endif
+ gdImagePtr work;
+ int work_white;
+
+ if (argc != 4)
+ FATAL_ERROR ("Number of arguments %d must be 4\n", argc);
+
+ M17N_INIT ();
+ if (merror_code != MERROR_NONE)
+ FATAL_ERROR ("%s\n", "Failed to initialize the m17n library.");
+
+ lang = msymbol (argv[1]);
+ name = msymbol (argv[2]);
+ im = minput_open_im (lang, name, NULL);
+ if (! im)
+ FATAL_ERROR ("%s\n", "Failed to open the input method.");
+ ic = minput_create_ic (im, NULL);
+ if (! im)
+ FATAL_ERROR ("%s\n", "Failed to create the input context.");
+ mt = mtext ();
+ for (i = 0; argv[3][i]; i++)
+ {
+ char keybuf[2];
+ MSymbol key;
+
+ keybuf[0] = argv[3][i];
+ keybuf[1] = '\0';
+ key = msymbol (keybuf);
+ if (minput_filter (ic, key, NULL) == 1)
+ continue;
+ minput_lookup (ic, key, NULL, mt);
+ }
+ if (ic->preedit)
+ mtext_cat (mt, ic->preedit);
+ len = mtext_len (mt);
+
+ mtext_put_prop (mt, 0, len, Mlanguage, lang);
+
+ {
+ MPlist *plist = mplist (), *p;
+ MFontset *fontset = mfontset ("generic");
+ MFace *face = mface ();
+
+ mface_put_prop (face, Mfontset, fontset);
+ mface_put_prop (face, Msize, (void *) (fontsize * dpi / 100));
+ p = mplist_add (plist, Mdevice, msymbol ("gd"));
+ p = mplist_add (p, Mface, face);
+ m17n_object_unref (face);
+ frame = mframe (plist);
+ m17n_object_unref (plist);
+ if (! frame)
+ FATAL_ERROR ("%s\n", "Failed to open a frame.");
+ }
+
+ memset (&control, 0, sizeof control);
+ control.enable_bidi = 1;
+
+ mdraw_text_extents (frame, mt, 0, len, &control, &ink, &logical, NULL);
+ ascent = - logical.y;
+ if (ascent < - ink.y)
+ ascent = -ink.y;
+ descent = logical.height + logical.y;
+ if (descent < ink.height + ink.y)
+ descent = ink.height + ink.y;
+ height = ascent + descent;
+ width = logical.width;
+
+ work = gdImageCreate (width, height);
+ work_white = gdImageColorAllocate (work, 255, 255, 255);
+ gdImageColorTransparent (work, work_white);
+ gdImageFilledRectangle (work, 0, 0, width - 1, height - 1, work_white);
+ mdraw_text_with_control (frame, work, 0, ascent, mt, 0, len, &control);
+
+ converter = mconv_stream_converter (msymbol ("utf-8"), stdout);
+
+ printf ("1\n");
+ from = 0;
+ {
+ MDrawMetric *ink_array, *logical_array;
+ int array_size = len * 2;
+ int num_chars;
+ unsigned char *buf;
+ int size;
+
+ ink_array = malloc (sizeof (MDrawMetric) * array_size);
+ logical_array = malloc (sizeof (MDrawMetric) * array_size);
+
+ if (mdraw_text_per_char_extents (frame, mt, 0, len, &control,
+ ink_array, logical_array,
+ array_size, &num_chars, NULL, NULL) < 0)
+ {
+ ink_array = realloc (ink_array, sizeof (MDrawMetric) * num_chars);
+ logical_array = realloc (logical_array, sizeof (MDrawMetric) * num_chars);
+ mdraw_text_per_char_extents (frame, mt, 0, len, &control,
+ ink_array, logical_array,
+ num_chars, &num_chars, NULL, NULL);
+ }
+
+ for (from = 0, i = 0; i < num_chars;)
+ {
+ gdImagePtr image;
+ int white;
+ int x = logical_array[i].x;
+
+ image = gdImageCreate (logical_array[i].width, height);
+ white = gdImageColorAllocate (image, 255, 255, 255);
+ gdImageColorTransparent (image, white);
+ gdImageCopy (image, work, 0, 0,
+ logical_array[i].x, 0, logical_array[i].width, height);
+ printf ("<img src=\"data:image/png;base64,");
+ buf = gdImagePngPtr (image, &size);
+ base64_encode (buf, size, stdout);
+ gdFree (buf);
+ gdImageDestroy (image);
+
+ while (++i < num_chars && logical_array[i].x == x);
+ if (i == num_chars)
+ to = len;
+ else
+ to = mdraw_coordinates_position (frame, mt, 0, len,
+ logical_array[i].x, 0, &control);
+ printf ("\" alt=\"");
+ mconv_encode_range (converter, mt, from, to);
+ printf ("\">");
+ from = to;
+ }
+ }
+ printf ("\n");
+
+ M17N_FINI ();
+ exit (0);
+}
+