1 //
2 // "$Id: utf8.cxx 8629 2011-05-01 12:24:22Z ianmacarthur $"
3 //
4 // UTF-8 test program for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2010 by Bill Spitzak and others.
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Library General Public License for more details.
17 //
18 // You should have received a copy of the GNU Library General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 // USA.
22 //
23 // Please report all bugs and problems on the following page:
24 //
25 // http://www.fltk.org/str.php
26 //
27
28 #include <FL/Fl.H>
29 #include <FL/Fl_Double_Window.H>
30 #include <FL/Fl_Scroll.H>
31 #include <FL/Fl_Choice.H>
32 #include <FL/Fl_Input.H>
33 #include <FL/Fl_Box.H>
34 #include <FL/Fl_Tile.H>
35 #include <FL/Fl_Hold_Browser.H>
36 #include <FL/Fl_Value_Output.H>
37 #include <FL/Fl_Button.H>
38 #include <FL/Fl_Check_Button.H>
39 #include <FL/Fl_Output.H>
40 #include <FL/fl_draw.H>
41 #include <FL/fl_utf8.h>
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <math.h>
47
48 //
49 // Font chooser widget for the Fast Light Tool Kit(FLTK).
50 //
51
52
53 #define DEF_SIZE 16 // default value for the font size picker
54
55
56 static Fl_Double_Window *fnt_chooser_win;
57 static Fl_Hold_Browser *fontobj;
58 static Fl_Hold_Browser *sizeobj;
59
60 static Fl_Value_Output *fnt_cnt;
61 static Fl_Button *refresh_btn;
62 static Fl_Button *choose_btn;
63 static Fl_Output *fix_prop;
64 static Fl_Check_Button *own_face;
65
66 static int **sizes = NULL;
67 static int *numsizes = NULL;
68 static int pickedsize = DEF_SIZE;
69 static char label[1000];
70
71 static Fl_Double_Window *main_win;
72 static Fl_Scroll *thescroll;
73 static Fl_Font extra_font;
74
75 static int font_count = 0;
76 static int first_free = 0;
77
cb_exit(Fl_Button *,void *)78 static void cb_exit(Fl_Button*, void*) {
79 if(fnt_chooser_win) fnt_chooser_win->hide();
80 if(main_win) main_win->hide();
81 } /* cb_exit */
82
83 /*
84 Class for displaying sample fonts.
85 */
86 class FontDisplay : public Fl_Widget
87 {
88 void draw(void);
89
90 public:
91 int font, size;
92
93 int test_fixed_pitch(void);
94
FontDisplay(Fl_Boxtype B,int X,int Y,int W,int H,const char * L=0)95 FontDisplay(Fl_Boxtype B, int X, int Y, int W, int H, const char *L = 0)
96 : Fl_Widget(X, Y, W, H, L)
97 {
98 box(B);
99 font = 0;
100 size = DEF_SIZE;
101 }
102 };
103
104
105 /*
106 Draw the sample text.
107 */
draw(void)108 void FontDisplay::draw(void)
109 {
110 draw_box();
111 fl_font((Fl_Font)font, size);
112 fl_color(FL_BLACK);
113 fl_draw(label(), x() + 3, y() + 3, w() - 6, h() - 6, align());
114 }
115
116
test_fixed_pitch(void)117 int FontDisplay::test_fixed_pitch(void)
118 {
119 int w1, w2;
120 int h1, h2;
121
122 w1 = w2 = 0;
123 h1 = h2 = 0;
124
125 fl_font((Fl_Font)font, size);
126
127 fl_measure("MHMHWWMHMHMHM###WWX__--HUW", w1, h1, 0);
128 fl_measure("iiiiiiiiiiiiiiiiiiiiiiiiii", w2, h2, 0);
129
130 if (w1 == w2) return 1; // exact match - fixed pitch
131
132 // Is the font "nearly" fixed pitch? If it is within 5%, say it is...
133 double f1 = (double)w1;
134 double f2 = (double)w2;
135 double delta = fabs(f1 - f2) * 5.0;
136 if (delta <= f1) return 2; // nearly fixed pitch...
137
138 return 0; // NOT fixed pitch
139 }
140
141
142 static FontDisplay *textobj;
143
144
size_cb(Fl_Widget *,long)145 static void size_cb(Fl_Widget *, long)
146 {
147 int size_idx = sizeobj->value();
148
149 if (!size_idx) return;
150
151 const char *c = sizeobj->text(size_idx);
152
153 while (*c < '0' || *c > '9') c++; // find the first numeric char
154 pickedsize = atoi(c); // convert the number string to a value
155
156 // Now set the font view to the selected size and redraw it.
157 textobj->size = pickedsize;
158 textobj->redraw();
159 }
160
161
font_cb(Fl_Widget *,long)162 static void font_cb(Fl_Widget *, long)
163 {
164 int font_idx = fontobj->value() + first_free;
165
166 if (!font_idx) return;
167 font_idx--;
168
169 textobj->font = font_idx;
170 sizeobj->clear();
171
172 int size_count = numsizes[font_idx-first_free];
173 int *size_array = sizes[font_idx-first_free];
174 if (!size_count)
175 {
176 // no preferred sizes - probably TT fonts etc...
177 }
178 else if (size_array[0] == 0)
179 {
180 // many sizes, probably a scaleable font with preferred sizes
181 int j = 1;
182 for (int i = 1; i <= 64 || i < size_array[size_count - 1]; i++)
183 {
184 char buf[16];
185 if (j < size_count && i == size_array[j])
186 {
187 sprintf(buf, "@b%d", i);
188 j++;
189 }
190 else
191 sprintf(buf, "%d", i);
192 sizeobj->add(buf);
193 }
194 sizeobj->value(pickedsize);
195 }
196 else
197 {
198 // some sizes, probably a font with a few fixed sizes available
199 int w = 0;
200 for (int i = 0; i < size_count; i++)
201 {
202 // find the nearest available size to the current picked size
203 if (size_array[i] <= pickedsize) w = i;
204
205 char buf[16];
206 sprintf(buf, "@b%d", size_array[i]);
207 sizeobj->add(buf);
208 }
209 sizeobj->value(w + 1);
210 }
211 size_cb(sizeobj, 0); // force selection of nearest valid size, then redraw
212
213 // Now check to see if the font looks like a fixed pitch font or not...
214 int looks_fixed = textobj->test_fixed_pitch();
215 if(looks_fixed)
216 {
217 if (looks_fixed > 1)
218 fix_prop->value("near");
219 else
220 fix_prop->value("fixed");
221 }
222 else
223 {
224 fix_prop->value("prop");
225 }
226 }
227
228
choose_cb(Fl_Widget *,long)229 static void choose_cb(Fl_Widget *, long)
230 {
231 int font_idx = fontobj->value() + first_free;
232 if (!font_idx)
233 {
234 puts("No font chosen");
235 }
236 else
237 {
238 int font_type;
239 font_idx -= 1;
240 const char *name = Fl::get_font_name((Fl_Font)font_idx, &font_type);
241 printf("idx %d\nUser name :%s:\n", font_idx, name);
242 printf("FLTK name :%s:\n", Fl::get_font((Fl_Font)font_idx));
243
244 Fl::set_font(extra_font, (Fl_Font)font_idx);
245 // Fl::set_font(extra_font, Fl::get_font((Fl_Font)font_idx));
246 }
247
248 int size_idx = sizeobj->value();
249 if (!size_idx)
250 {
251 puts("No size selected");
252 }
253 else
254 {
255 const char *c = sizeobj->text(size_idx);
256 while (*c < '0' || *c > '9') c++; // find the first numeric char
257 int pickedsize = atoi(c); // convert the number string to a value
258
259 printf("size %d\n\n", pickedsize);
260 }
261
262 fflush(stdout);
263 main_win->redraw();
264 }
265
266
refresh_cb(Fl_Widget *,long)267 static void refresh_cb(Fl_Widget *, long)
268 {
269 main_win->redraw();
270 }
271
272
own_face_cb(Fl_Widget *,void *)273 static void own_face_cb(Fl_Widget *, void *)
274 {
275 int font_idx;
276 int cursor_restore = 0;
277 static int i_was = -1; // used to keep track of where we were in the list...
278
279 if (i_was < 0) { // not been here before
280 i_was = 1;
281 } else {
282 i_was = fontobj->topline(); // record which was the topmost visible line
283 fontobj->clear();
284 // Populating the font widget can be slower than an old dog with three legs
285 // on a bad day, show a wait cursor
286 fnt_chooser_win->cursor(FL_CURSOR_WAIT);
287 cursor_restore = 1;
288 }
289
290
291 // Populate the font list with the names of the fonts found
292 for (font_idx = first_free; font_idx < font_count; font_idx++)
293 {
294 int font_type;
295 const char *name = Fl::get_font_name((Fl_Font)font_idx, &font_type);
296 char buffer[128];
297
298 if(own_face->value() == 0) {
299 char *p = buffer;
300 // if the font is BOLD, set the bold attribute in the list
301 if (font_type & FL_BOLD) {
302 *p++ = '@';
303 *p++ = 'b';
304 }
305 if (font_type & FL_ITALIC) { // ditto for italic fonts
306 *p++ = '@';
307 *p++ = 'i';
308 }
309 // Suppress subsequent formatting - some MS fonts have '@' in their name
310 *p++ = '@';
311 *p++ = '.';
312 strcpy(p, name);
313 } else {
314 // Show font in its own face
315 // this is neat, but really slow on some systems:
316 // uses each font to display its own name
317 sprintf (buffer, "@F%d@.%s", font_idx, name);
318 }
319 fontobj->add(buffer);
320 }
321 // now put the browser position back the way it was... more or less
322 fontobj->topline(i_was);
323 // restore the cursor
324 if(cursor_restore) fnt_chooser_win->cursor(FL_CURSOR_DEFAULT);
325 }
326
327
create_font_widget()328 static void create_font_widget()
329 {
330 // Create the font sample label
331 strcpy(label, "Font Sample\n");
332 int i = 12; // strlen(label);
333 int n = 0;
334 ulong c;
335 for (c = ' '+1; c < 127; c++) {
336 if (!(c&0x1f)) label[i++]='\n';
337 if (c=='@') label[i++]=c;
338 label[i++]=c;
339 }
340 label[i++] = '\n';
341 for (c = 0xA1; c < 0x600; c += 9) {
342 if (!(++n&(0x1f))) label[i++]='\n';
343 i += fl_utf8encode((unsigned int)c, label + i);
344 }
345 label[i] = 0;
346
347 // Create the window layout
348 fnt_chooser_win = new Fl_Double_Window(380, 420, "Font Selector");
349 {
350 Fl_Tile *tile = new Fl_Tile(0, 0, 380, 420);
351 {
352 Fl_Group *textgroup = new Fl_Group(0, 0, 380, 105);
353 {
354
355 textobj = new FontDisplay(FL_FRAME_BOX, 10, 10, 360, 90, label);
356 textobj->align(FL_ALIGN_TOP|FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP);
357 textobj->color(53, 3);
358
359 textgroup->box(FL_FLAT_BOX);
360 textgroup->resizable(textobj);
361 textgroup->end();
362 }
363 Fl_Group *fontgroup = new Fl_Group(0, 105, 380, 315);
364 {
365 fontobj = new Fl_Hold_Browser(10, 110, 290, 270);
366 fontobj->box(FL_FRAME_BOX);
367 fontobj->color(53, 3);
368 fontobj->callback(font_cb);
369 fnt_chooser_win->resizable(fontobj);
370
371 sizeobj = new Fl_Hold_Browser(310, 110, 60, 270);
372 sizeobj->box(FL_FRAME_BOX);
373 sizeobj->color(53, 3);
374 sizeobj->callback(size_cb);
375
376 // Create the status bar
377 Fl_Group *stat_bar = new Fl_Group (10, 385, 380, 30);
378 {
379 fnt_cnt = new Fl_Value_Output(10, 390, 40, 20);
380 fnt_cnt->label("fonts");
381 fnt_cnt->align(FL_ALIGN_RIGHT);
382
383 fix_prop = new Fl_Output(100, 390, 40, 20);
384 fix_prop->color(FL_BACKGROUND_COLOR);
385 fix_prop->value("prop");
386 fix_prop->clear_visible_focus();
387
388 own_face = new Fl_Check_Button(150, 390, 40, 20, "Self");
389 own_face->value(0);
390 own_face->type(FL_TOGGLE_BUTTON);
391 own_face->clear_visible_focus();
392 own_face->callback(own_face_cb);
393 own_face->tooltip("Display font names in their own face");
394
395 Fl_Box * dummy = new Fl_Box(220, 390, 1, 1);
396
397 choose_btn = new Fl_Button(240, 385, 60, 30);
398 choose_btn->label("Select");
399 choose_btn->callback(choose_cb);
400
401 refresh_btn = new Fl_Button(310, 385, 60, 30);
402 refresh_btn->label("Refresh");
403 refresh_btn->callback(refresh_cb);
404
405 stat_bar->resizable (dummy);
406 stat_bar->end();
407 }
408
409 fontgroup->box(FL_FLAT_BOX);
410 fontgroup->resizable(fontobj);
411 fontgroup->end();
412 }
413 tile->end();
414 }
415 fnt_chooser_win->resizable(tile);
416 fnt_chooser_win->end();
417 fnt_chooser_win->callback((Fl_Callback*)cb_exit);
418 }
419 }
420
421
make_font_chooser(void)422 int make_font_chooser(void)
423 {
424 int font_idx;
425
426 // create the widget frame
427 create_font_widget();
428
429 // Load the systems available fonts - ask for everything
430 // font_count = Fl::set_fonts("*");
431 #ifdef WIN32
432 font_count = Fl::set_fonts("*");
433 #elif __APPLE__
434 font_count = Fl::set_fonts("*");
435 #else
436 // Load the systems available fonts - ask for everything that claims to be
437 // iso10646 compatible
438 font_count = Fl::set_fonts("-*-*-*-*-*-*-*-*-*-*-*-*-iso10646-1");
439 #endif
440
441 // allocate space for the sizes and numsizes array, now we know how many
442 // entries it needs
443 sizes = new int*[font_count];
444 numsizes = new int[font_count];
445
446 // Populate the font list with the names of the fonts found
447 first_free = FL_FREE_FONT;
448 for (font_idx = first_free; font_idx < font_count; font_idx++)
449 {
450 // Find out how many sizes are supported for each font face
451 int *size_array;
452 int size_count = Fl::get_font_sizes((Fl_Font)font_idx, size_array);
453 numsizes[font_idx-first_free] = size_count;
454 // if the font has multiple sizes, populate the 2-D sizes array
455 if (size_count)
456 {
457 sizes[font_idx-first_free] = new int[size_count];
458 for (int j = 0; j < size_count; j++)
459 sizes[font_idx-first_free][j] = size_array[j];
460 }
461 } // end of font list filling loop
462
463 // Call this once to get the font browser loaded up
464 own_face_cb(NULL, 0);
465
466 fontobj->value(1);
467 // optional hard-coded font for testing - do not use!
468 // fontobj->textfont(261);
469
470 font_cb(fontobj, 0);
471
472 fnt_cnt->value(font_count);
473
474 return font_count;
475
476 } // make_font_chooser
477
478 /* End of Font Chooser Widget code */
479
480
481
482 /* Unicode Font display widget */
483
box_cb(Fl_Widget * o,void *)484 void box_cb(Fl_Widget* o, void*) {
485 thescroll->box(((Fl_Button*)o)->value() ? FL_DOWN_FRAME : FL_NO_BOX);
486 thescroll->redraw();
487 }
488
489
490 class right_left_input : public Fl_Input
491 {
492 public:
right_left_input(int x,int y,int w,int h)493 right_left_input (int x, int y, int w, int h) : Fl_Input(x, y, w, h) {};
draw()494 void draw() {
495 if (type() == FL_HIDDEN_INPUT) return;
496 Fl_Boxtype b = box();
497 if (damage() & FL_DAMAGE_ALL) draw_box(b, color());
498 drawtext(x()+Fl::box_dx(b)+3, y()+Fl::box_dy(b),
499 w()-Fl::box_dw(b)-6, h()-Fl::box_dh(b));
500 }
drawtext(int X,int Y,int W,int H)501 void drawtext(int X, int Y, int W, int H) {
502 fl_color(textcolor());
503 fl_font(textfont(), textsize());
504 fl_rtl_draw(value(), strlen(value()),
505 X + W, Y + fl_height() -fl_descent());
506 }
507 };
508
509
i7_cb(Fl_Widget * w,void * d)510 void i7_cb(Fl_Widget *w, void *d)
511 {
512 int i = 0;
513 char nb[] = "01234567";
514 Fl_Input *i7 = (Fl_Input*)w;
515 Fl_Input *i8 = (Fl_Input*)d;
516 static char buf[1024];
517 const char *ptr = i7->value();
518 while (ptr && *ptr) {
519 if (*ptr < ' ' || *ptr > 126) {
520 buf[i++] = '\\';
521 buf[i++] = nb[((*ptr >> 6) & 0x3)];
522 buf[i++] = nb[((*ptr >> 3) & 0x7)];
523 buf[i++] = nb[(*ptr & 0x7)];
524 } else {
525 if (*ptr == '\\') buf[i++] = '\\';
526 buf[i++] = *ptr;
527 }
528 ptr++;
529 }
530 buf[i] = 0;
531 i8->value(buf);
532 }
533
534
535 class UCharDropBox : public Fl_Output {
536 public:
UCharDropBox(int x,int y,int w,int h,const char * label=0)537 UCharDropBox(int x, int y, int w, int h, const char *label=0) :
538 Fl_Output(x, y, w, h, label) { }
handle(int event)539 int handle(int event) {
540 switch (event) {
541 case FL_DND_ENTER: return 1;
542 case FL_DND_DRAG: return 1;
543 case FL_DND_RELEASE: return 1;
544 case FL_PASTE:
545 {
546 static const char lut[] = "0123456789abcdef";
547 const char *t = Fl::event_text();
548 int i, n;
549 unsigned int ucode = fl_utf8decode(t, t+Fl::event_length(), &n);
550 if (n==0) {
551 value("");
552 return 1;
553 }
554 char buffer[200], *d = buffer;
555 for (i=0; i<n; i++) *d++ = t[i];
556 *d++ = ' ';
557 for (i=0; i<n; i++) {
558 *d++ = '\\'; *d++ = 'x';
559 *d++ = lut[(t[i]>>4)&0x0f]; *d++ = lut[t[i]&0x0f];
560 }
561 *d++ = ' ';
562 *d++ = '0';
563 *d++ = 'x';
564 *d++ = lut[(ucode>>20)&0x0f]; *d++ = lut[(ucode>>16)&0x0f];
565 *d++ = lut[(ucode>>12)&0x0f]; *d++ = lut[(ucode>>8)&0x0f];
566 *d++ = lut[(ucode>>4)&0x0f]; *d++ = lut[ucode&0x0f];
567 *d++ = 0;
568 value(buffer);
569 }
570 return 1;
571 }
572 return Fl_Output::handle(event);
573 }
574 };
575
576
main(int argc,char ** argv)577 int main(int argc, char** argv)
578 {
579 int l;
580 const char *latin1 =
581 "\x41\x42\x43\x61\x62\x63\xe0\xe8\xe9\xef\xe2\xee\xf6\xfc\xe3\x31\x32\x33";
582 char *utf8 = (char*) malloc(strlen(latin1) * 5 + 1);
583 l = 0;
584 // l = fl_latin12utf((const unsigned char*)latin1, strlen(latin1), utf8);
585 l = fl_utf8froma(utf8, (strlen(latin1) * 5 + 1), latin1, strlen(latin1));
586
587 make_font_chooser();
588 extra_font = FL_TIMES_BOLD_ITALIC;
589
590 /* setup the extra font */
591 Fl::set_font(extra_font,
592 #ifdef WIN32
593 " Arial Unicode MS"
594 #elif __APPLE__
595 "Monaco"
596 #else
597 "-*-*-*-*-*-*-*-*-*-*-*-*-iso10646-1"
598 #endif
599 );
600
601 main_win = new Fl_Double_Window (200 + 5*75, 400, "Unicode Display Test");
602 main_win->begin();
603
604 Fl_Input i1(5, 5, 190, 25);
605 utf8[l] = '\0';
606 i1.value(utf8);
607 Fl_Scroll scroll(200,0,5 * 75,400);
608
609 int off = 2;
610 int end_list = 0x10000 / 16;
611 if (argc > 1) {
612 off = (int)strtoul(argv[1], NULL, 0);
613 end_list = off + 0x10000;
614 off /= 16;
615 end_list /= 16;
616 }
617 argc = 1;
618 for (long y = off; y < end_list; y++) {
619 int o = 0;
620 char bu[25]; // index label
621 char buf[16 * 6]; // utf8 text
622 int i = 16 * y;
623 for (int x = 0; x < 16; x++) {
624 int l;
625 l = fl_utf8encode(i, buf + o);
626 if (l < 1) l = 1;
627 o += l;
628 i++;
629 }
630 buf[o] = '\0';
631 sprintf(bu, "0x%06lX", y * 16);
632 Fl_Input *b = new Fl_Input(200,(y-off)*25,80,25);
633 b->textfont(FL_COURIER);
634 b->value(strdup(bu));
635 b = new Fl_Input(280,(y-off)*25,380,25);
636 b->textfont(extra_font);
637 b->value(strdup(buf));
638 }
639 scroll.end();
640 main_win->resizable(scroll);
641
642 thescroll = &scroll;
643
644 char *utf8l = (char*) malloc(strlen(utf8) * 3 + 1);
645 Fl_Input i2(5, 35, 190, 25);
646 l = fl_utf_tolower((const unsigned char*)utf8, l, utf8l);
647 utf8l[l] = '\0';
648 i2.value(utf8l);
649
650 char *utf8u = (char*) malloc(strlen(utf8l) * 3 + 1);
651 Fl_Input i3(5, 65, 190, 25);
652 l = fl_utf_toupper((const unsigned char*)utf8l, l, utf8u);
653 utf8u[l] = '\0';
654 i3.value(utf8u);
655
656 const char *ltr_txt = "\\->e\xCC\x82=\xC3\xAA";
657 Fl_Input i4(5, 90, 190, 25);
658 i4.value(ltr_txt);
659 i4.textfont(extra_font);
660
661 wchar_t r_to_l_txt[] = {/*8238,*/
662 1610, 1608, 1606, 1604, 1603, 1608, 1583, 0};
663
664 char abuf[40];
665 // l = fl_unicode2utf(r_to_l_txt, 8, abuf);
666 l = fl_utf8fromwc(abuf, 40, r_to_l_txt, 8);
667 abuf[l] = 0;
668
669 right_left_input i5(5, 115, 190, 50);
670 i5.textfont(extra_font);
671 i5.textsize(30);
672 i5.value(abuf);
673
674 Fl_Input i7(5, 230, 190, 25);
675 Fl_Input i8(5, 260, 190, 25);
676 i7.callback(i7_cb, &i8);
677 i7.textsize(20);
678 i7.value(abuf);
679 i7.when(FL_WHEN_CHANGED);
680
681 wchar_t r_to_l_txt1[] = { /*8238,*/
682 1610, 0x20, 1608, 0x20, 1606, 0x20,
683 1604, 0x20, 1603, 0x20, 1608, 0x20, 1583, 0};
684
685 // l = fl_unicode2utf(r_to_l_txt1, 14, abuf);
686 l = fl_utf8fromwc(abuf, 40, r_to_l_txt1, 14);
687 abuf[l] = 0;
688 right_left_input i6(5, 175, 190, 50);
689 i6.textfont(extra_font);
690 i6.textsize(30);
691 i6.value(abuf);
692
693 // Now try Greg Ercolano's Japanese test sequence
694 // SOME JAPANESE UTF-8 TEXT
695 const char *utfstr =
696 "\xe4\xbd\x95\xe3\x82\x82\xe8\xa1"
697 "\x8c\xe3\x82\x8b\xe3\x80\x82";
698
699 UCharDropBox db(5, 300, 190, 30);
700 db.textsize(16);
701 db.value("unichar drop box");
702
703 Fl_Output o9(5, 330, 190, 45);
704 o9.textfont(extra_font);
705 o9.textsize(30);
706 o9.value(utfstr);
707
708 main_win->end();
709 main_win->callback((Fl_Callback*)cb_exit);
710
711 fl_set_status(0, 370, 100, 30);
712
713 main_win->show(argc,argv);
714
715 fnt_chooser_win->show();
716
717 int ret = Fl::run();
718
719 // Free up the sizes arrays we allocated
720 if(numsizes) {delete [] numsizes;}
721 if(sizes) {delete [] sizes;}
722
723 return ret;
724 }
725
726 //
727 // End of "$Id: utf8.cxx 8629 2011-05-01 12:24:22Z ianmacarthur $".
728 //
729