*** empty log message ***
[m17n/m17n-test.git] / mimdemo.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <libgen.h>
6
7 #include <gd.h>
8
9 #include <m17n-gui.h>
10 #include <m17n-misc.h>
11
12 /* Format MSG by FMT and print the result to the stderr, and exit.  */
13
14 #define FATAL_ERROR(fmt, arg)   \
15   do {                          \
16     printf ("0\n");             \
17     printf (fmt, arg);          \
18     exit (0);                   \
19   } while (0)
20
21 char base64_encode_table[] =
22   { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
23     'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
24     'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
25     'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
26     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
27     'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
28     '8', '9', '+', '/' };
29
30 void
31 base64_encode (const unsigned char *src, int length, FILE *fp)
32 {
33   int i = 0;
34   int c;
35   unsigned int value;
36
37   while (i < length)
38     {
39       c = src[i++];
40       putc (base64_encode_table[0x3f & c >> 2], fp);
41       value = (0x03 & c) << 4;
42       if (i == length)
43         {
44           putc (base64_encode_table[value], fp);
45           putc ('=', fp);
46           putc ('=', fp);
47           break;
48         }
49       c = src[i++];
50       putc (base64_encode_table[value | (0x0f & c >> 4)], fp);
51       value = (0x0f & c) << 2;
52       if (i == length)
53         {
54           putc (base64_encode_table[value], fp);
55           putc ('=', fp);
56           break;
57         }
58       c = src[i++];
59       putc (base64_encode_table[value | (0x03 & c >> 6)], fp);
60       putc (base64_encode_table[0x3f & c], fp);
61     }
62 }
63   
64 int
65 main (int argc, char **argv)
66 {
67   int fontsize = 240;
68   int dpi = 100;
69
70   MText *mt;
71   int i;
72   MSymbol lang, name;
73   MInputMethod *im;
74   MInputContext *ic;
75
76   int len, from, to;
77   MConverter *converter;
78   MFrame *frame;
79   MDrawControl control;
80   MDrawMetric ink, logical;
81   int ascent, descent, height, width;
82 #if 0
83   int indent = 0;
84   int left_adjust;
85 #endif
86   gdImagePtr work;
87   int work_white;
88
89   if (argc != 4)
90     FATAL_ERROR ("Number of arguments %d must be 4\n", argc);
91
92   M17N_INIT ();
93   if (merror_code != MERROR_NONE)
94     FATAL_ERROR ("%s\n", "Failed to initialize the m17n library.");
95
96   lang = msymbol (argv[1]);
97   name = msymbol (argv[2]);
98   im = minput_open_im (lang, name, NULL);
99   if (! im)
100     FATAL_ERROR ("%s\n", "Failed to open the input method.");
101   ic = minput_create_ic (im, NULL);
102   if (! im)
103     FATAL_ERROR ("%s\n", "Failed to create the input context.");
104   mt = mtext ();
105   for (i = 0; argv[3][i]; i++)
106     {
107       char keybuf[2];
108       MSymbol key;
109
110       keybuf[0] = argv[3][i];
111       keybuf[1] = '\0';
112       key = msymbol (keybuf);
113       if (minput_filter (ic, key, NULL) == 1)
114         continue;
115       minput_lookup (ic, key, NULL, mt);
116     }
117   if (ic->preedit)
118     mtext_cat (mt, ic->preedit);
119   len = mtext_len (mt);
120
121   mtext_put_prop (mt, 0, len, Mlanguage, lang);
122
123   {
124     MPlist *plist = mplist (), *p;
125     MFontset *fontset = mfontset ("generic");
126     MFace *face = mface ();
127
128     mface_put_prop (face, Mfontset, fontset);
129     mface_put_prop (face, Msize, (void *) (fontsize * dpi / 100));
130     p = mplist_add (plist, Mdevice, msymbol ("gd"));
131     p = mplist_add (p, Mface, face);
132     m17n_object_unref (face);
133     frame = mframe (plist);
134     m17n_object_unref (plist);
135     if (! frame)
136       FATAL_ERROR ("%s\n", "Failed to open a frame.");
137   }
138
139   memset (&control, 0, sizeof control);
140   control.enable_bidi = 1;
141
142   mdraw_text_extents (frame, mt, 0, len, &control, &ink, &logical, NULL);
143   ascent = - logical.y;
144   if (ascent < - ink.y)
145     ascent = -ink.y;
146   descent = logical.height + logical.y;
147   if (descent < ink.height + ink.y)
148     descent = ink.height + ink.y;
149   height = ascent + descent;
150   width = logical.width;
151
152   work = gdImageCreate (width, height);
153   work_white = gdImageColorAllocate (work, 255, 255, 255); 
154   gdImageColorTransparent (work, work_white);
155   gdImageFilledRectangle (work, 0, 0, width - 1, height - 1, work_white);
156   mdraw_text_with_control (frame, work, 0, ascent, mt, 0, len, &control);
157
158   converter = mconv_stream_converter (msymbol ("utf-8"), stdout);
159
160   printf ("1\n");
161   from = 0;
162   {
163     MDrawMetric *ink_array, *logical_array;
164     int array_size = len * 2;
165     int num_chars;
166     unsigned char *buf;
167     int size;
168     
169     ink_array = malloc (sizeof (MDrawMetric) * array_size);
170     logical_array = malloc (sizeof (MDrawMetric) * array_size);
171
172     if (mdraw_text_per_char_extents (frame, mt, 0, len, &control,
173                                      ink_array, logical_array,
174                                      array_size, &num_chars, NULL, NULL) < 0)
175       {
176         ink_array = realloc (ink_array, sizeof (MDrawMetric) * num_chars);
177         logical_array = realloc (logical_array, sizeof (MDrawMetric) * num_chars);
178         mdraw_text_per_char_extents (frame, mt, 0, len, &control,
179                                      ink_array, logical_array,
180                                      num_chars, &num_chars, NULL, NULL);
181       }
182
183     for (from = 0, i = 0; i < num_chars;)
184       {
185         gdImagePtr image;
186         int white;
187         int x = logical_array[i].x;
188
189         image = gdImageCreate (logical_array[i].width, height);
190         white = gdImageColorAllocate (image, 255, 255, 255); 
191         gdImageColorTransparent (image, white);
192         gdImageCopy (image, work, 0, 0,
193                      logical_array[i].x, 0, logical_array[i].width, height);
194         printf ("<img src=\"data:image/png;base64,");
195         buf = gdImagePngPtr (image, &size);
196         base64_encode (buf, size, stdout);
197         gdFree (buf);
198         gdImageDestroy (image);
199
200         while (++i < num_chars && logical_array[i].x == x);
201         if (i == num_chars)
202           to = len;
203         else
204           to = mdraw_coordinates_position (frame, mt, 0, len,
205                                            logical_array[i].x, 0, &control);
206         printf ("\" alt=\"");
207         mconv_encode_range (converter, mt, from, to);
208         printf ("\">");
209         from = to;
210       }
211   }
212   printf ("\n");
213
214   M17N_FINI ();
215   exit (0);
216 }
217