From 7b413f1a95d407062adc30771bb82d5e3111deac Mon Sep 17 00:00:00 2001 From: handa Date: Wed, 19 Jul 2006 07:28:03 +0000 Subject: [PATCH] *** empty log message *** --- fifotest1.c | 58 +++++++ fifotest2.c | 25 +++ findfont.c | 3 - gdkdraw.c | 8 +- imtest.c | 503 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mimdaemon.c | 312 ++++++++++++++++++++++++++++++++++++ mimdemo.c | 217 ++++++++++++++++++++++++++ 7 files changed, 1119 insertions(+), 7 deletions(-) create mode 100644 fifotest1.c create mode 100644 fifotest2.c create mode 100644 imtest.c create mode 100644 mimdaemon.c create mode 100644 mimdemo.c diff --git a/fifotest1.c b/fifotest1.c new file mode 100644 index 0000000..5a8aee9 --- /dev/null +++ b/fifotest1.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include +#include + +#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); +} diff --git a/fifotest2.c b/fifotest2.c new file mode 100644 index 0000000..7d6d88f --- /dev/null +++ b/fifotest2.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include +#include +#include + +#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); +} diff --git a/findfont.c b/findfont.c index e942cc4..d12de2f 100644 --- a/findfont.c +++ b/findfont.c @@ -72,7 +72,6 @@ print_font (MFont *font) { 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); @@ -94,7 +93,6 @@ main (int argc, char **argv) { MPlist *plist, *p; MFrame *frame; - char buf[256]; M17N_INIT (); @@ -114,7 +112,6 @@ main (int argc, char **argv) else if (argc == 2) { MFont *font = parse_font_name (argv[1]); - MPlist *p0; plist = mfont_list (frame, font, Mnil, 0); free (font); diff --git a/gdkdraw.c b/gdkdraw.c index 710817b..e66b710 100644 --- a/gdkdraw.c +++ b/gdkdraw.c @@ -102,7 +102,6 @@ main (int argc, char **argv) int array_size, num_glyphs; MPlist *family_list; int family_name_len; - char *p; memset (&control, 0, sizeof (control)); control.anti_alias = 1; @@ -150,7 +149,6 @@ main (int argc, char **argv) - metric.x, - metric.y, mt, 0, mtext_len (mt), &control); m17n_object_unref (frame); - m17n_object_unref (mt); if (family_list) { @@ -182,9 +180,11 @@ main (int argc, char **argv) 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); diff --git a/imtest.c b/imtest.c new file mode 100644 index 0000000..10f5ed4 --- /dev/null +++ b/imtest.c @@ -0,0 +1,503 @@ +#include +#include + +#include +#include + +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 + diff --git a/mimdaemon.c b/mimdaemon.c new file mode 100644 index 0000000..268fc2a --- /dev/null +++ b/mimdaemon.c @@ -0,0 +1,312 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#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, "\"");"); + 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); +} + diff --git a/mimdemo.c b/mimdemo.c new file mode 100644 index 0000000..7a51754 --- /dev/null +++ b/mimdemo.c @@ -0,0 +1,217 @@ +#include +#include +#include +#include +#include + +#include + +#include +#include + +/* 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 ("\"");"); + from = to; + } + } + printf ("\n"); + + M17N_FINI (); + exit (0); +} + -- 1.7.10.4