*** empty log message ***
[m17n/m17n-test.git] / gdkdraw.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <gd.h>
5 #include <gtk/gtk.h>
6 #include <gdk-pixbuf/gdk-pixbuf.h>
7 #include <m17n-gui.h>
8 #include <m17n-misc.h>
9
10 #define FONT_PT_SIZE 60
11
12 gint
13 delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
14 {
15   return FALSE; 
16 }
17
18 void
19 destroy (GtkWidget *widget, gpointer data)
20 {
21   gtk_main_quit ();
22 }
23
24 int
25 main (int argc, char **argv)
26 {
27   MSymbol lang;
28   MText *mt;
29   int nchars;
30   MFrame *frame;
31   MDrawMetric metric;
32   gdImagePtr image;
33   int bg_color;
34   unsigned char *title;
35   int allocated, len;
36   MSymbol utf8;
37   char *family_names = NULL;
38
39   if (argc < 2)
40     {
41       fprintf (stderr, "Usage: gdkdraw LANGUAGE\n");
42       exit (1);
43     }
44
45   M17N_INIT ();
46   lang = msymbol (argv[1]);
47   mt = mlanguage_text (lang);
48   if (! mt)
49     {
50       fprintf (stderr, "No native name for the language \"%s\".\n", argv[1]);
51       exit (1);
52     }
53
54   nchars = mtext_len (mt);
55
56   /* Encode native language name in MT into the buffer TITLE.  */
57   merror_code = 0;
58   utf8 = msymbol ("utf-8");
59   allocated = nchars * 4;       /* Usually this is enough.  */
60   title = malloc (allocated);
61   len = mconv_encode_buffer (utf8, mt, title, allocated);
62   while (len < 0 && merror_code == MCONVERSION_RESULT_INSUFFICIENT_DST)
63     {
64       allocated += allocated;
65       title = realloc (title, allocated);
66       len = mconv_encode_buffer (utf8, mt, title, allocated);
67     }
68   if (len < 0)
69     {
70       fprintf (stderr, "Encoding of native language name failed.");
71       exit (1);
72     }
73   title[len] = '\0';
74
75   {
76     MPlist *param = mplist ();
77     MFace *face = mface ();
78     MFontset *fontset = mfontset ("generic");
79
80     mface_put_prop (face, Msize, (void *) (FONT_PT_SIZE * -10));
81     mface_put_prop (face, Mfontset, fontset);
82     if (argc > 2)
83       mface_put_prop (face, Mfamily, msymbol (argv[2]));
84     mplist_add (param, Mdevice, msymbol ("gd"));
85     mplist_add (param, Mface, face);
86     frame = mframe (param);
87     m17n_object_unref (face);
88     m17n_object_unref (param);
89
90     if (! frame)
91       {
92         fprintf (stderr, "Frame creation failed.  Perhaps no GD library.\n");
93         exit (1);
94       }
95   }
96
97   /* Build GD image and draw MT on it while listing up font families
98      used for drawing.  */
99   {
100     MDrawControl control;
101     MDrawGlyph *glyphs;
102     int array_size, num_glyphs;
103     MPlist *family_list;
104     int family_name_len;
105
106     memset (&control, 0, sizeof (control));
107     control.anti_alias = 1;
108     control.enable_bidi = 1;
109     mdraw_text_extents (frame, mt, 0, mtext_len (mt), &control,
110                         &metric, NULL, NULL);
111
112     image = gdImageCreateTrueColor (metric.width, metric.height);
113     bg_color = gdImageColorAllocate (image, 255, 255, 255);
114     gdImageFilledRectangle (image, 0, 0, metric.width - 1, metric.height - 1,
115                             bg_color);
116
117     array_size = nchars * 2; /* Usually this is enough. */
118     glyphs = malloc (sizeof (MDrawGlyph) * array_size);
119     if (mdraw_glyph_list (frame, mt, 0, nchars, &control, glyphs, array_size,
120                           &num_glyphs) < 0)
121       {
122         array_size = num_glyphs;
123         glyphs = realloc (glyphs, sizeof (MDrawGlyph) * array_size);
124         mdraw_glyph_list (frame, mt, 0, nchars, &control, glyphs, array_size,
125                           &num_glyphs);
126       }
127     
128     family_list = NULL;
129     family_name_len = 0;
130     while (num_glyphs-- > 0)
131       if (glyphs[num_glyphs].font)
132         {
133           MSymbol family = mfont_get_prop (glyphs[num_glyphs].font, Mfamily);
134
135           if (! family_list)
136             {
137               family_list = mplist ();
138               mplist_add (family_list, Msymbol, family);
139               family_name_len = strlen (msymbol_name (family));
140             }
141           else if (! mplist_find_by_value (family_list, family))
142             {
143               mplist_push (family_list, Msymbol, family);
144               family_name_len += strlen (msymbol_name (family)) + 1;
145             }
146         }
147
148     mdraw_text_with_control (frame, (MDrawWindow) image,
149                              - metric.x, - metric.y,
150                              mt, 0, mtext_len (mt), &control);
151     m17n_object_unref (frame);
152
153     if (family_list)
154       {
155         char *p = alloca (family_name_len + 1);
156         MPlist *pl = family_list;
157
158         family_names = p;
159         p += sprintf (p, "%s", msymbol_name (mplist_value (pl)));
160         for (pl = mplist_next (pl); mplist_key (pl) != Mnil;
161              pl = mplist_next (pl))
162           p += sprintf (p, ",%s", msymbol_name (mplist_value (pl)));
163       }
164     m17n_object_unref (family_list);
165   }
166
167   M17N_FINI ();
168
169   {
170     GdkPixbuf *pixbuf;
171     GtkWidget *window, *box, *text, *label;
172     int n_channels, rowstride;
173     guchar *pixels, *p;
174     int x, y;
175     PangoAttrList *attr_list;
176     PangoAttribute *attr_size, *attr_family;
177
178     gtk_init (&argc, &argv);
179
180     attr_list = pango_attr_list_new ();
181     attr_size = pango_attr_size_new (FONT_PT_SIZE * PANGO_SCALE);
182     attr_family = family_names ? pango_attr_family_new (family_names) : NULL;
183 #if 0
184     if (attr_family)
185       pango_attr_list_change (attr_list, attr_family);
186 #endif
187     pango_attr_list_change (attr_list, attr_size);
188
189     pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 0, 8,
190                              metric.width, metric.height);
191     n_channels = gdk_pixbuf_get_n_channels (pixbuf);
192     rowstride = gdk_pixbuf_get_rowstride (pixbuf);
193     pixels = gdk_pixbuf_get_pixels (pixbuf);
194
195     for (y = 0; y < metric.height; y++)
196       for (x = 0; x < metric.width; x++)
197         {
198           int cid = gdImageGetPixel (image, x, y);
199           p = pixels + y * rowstride + x * n_channels;
200
201           p[0] = gdImageRed (image, cid);
202           p[1] = gdImageGreen (image, cid);
203           p[2] = gdImageBlue (image, cid);
204         }
205     gdImageDestroy (image);
206
207     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
208     box = gtk_vbox_new (FALSE, 0);
209     text = gtk_image_new_from_pixbuf (pixbuf);
210     label = gtk_label_new ((gchar *) title);
211     gtk_label_set_attributes (GTK_LABEL (label), attr_list);
212     gtk_box_pack_start (GTK_BOX (box), text, TRUE, FALSE, 0);
213     gtk_box_pack_start (GTK_BOX (box), label, TRUE, FALSE, 0);
214
215     gtk_container_add (GTK_CONTAINER (window), box);
216     gtk_signal_connect (GTK_OBJECT (window), "delete_event",
217                         GTK_SIGNAL_FUNC (delete_event), NULL);
218     gtk_signal_connect (GTK_OBJECT (window), "destroy",
219                         GTK_SIGNAL_FUNC (destroy), NULL);
220     gtk_widget_show (text);
221     gtk_widget_show (label);
222     gtk_widget_show (box);
223     gtk_widget_show (window);
224     gtk_main ();
225   }
226
227   free (title);
228
229   exit (0);
230 }