add a missing section header table index conversion
[tangerine.git] / workbench / system / ftmanager / ftmanager.c
bloba7f08b62f95c481bd58d4fa3e8c208377534662b
1 /*
2 * Based on source from ftmanager from MorphOS for their ft2.library
3 */
4 #define NO_INLINE_STDARG
6 #include <stdlib.h>
7 #include <string.h>
8 #include <dos/exall.h>
9 #include <dos/dostags.h>
10 #include <exec/memory.h>
12 #define MUI_OBSOLETE
13 #include <libraries/mui.h>
14 #include <libraries/asl.h>
15 #include <diskfont/diskfonttag.h>
16 #include <diskfont/glyph.h>
17 #include <diskfont/oterrors.h>
18 #include <proto/alib.h>
19 #include <proto/exec.h>
20 #include <proto/dos.h>
21 #include <proto/intuition.h>
22 #include <proto/graphics.h>
23 #include <proto/utility.h>
24 #include <proto/muimaster.h>
25 #undef NO_INLINE_STDARG
26 #include <proto/codesets.h>
27 #include <proto/freetype2.h>
28 #include <aros/debug.h>
29 #include <aros/macros.h>
31 #include "etask.h"
33 #include <ft2build.h>
34 #include FT_FREETYPE_H
35 //#include FT_IMAGE_H
36 //#include FT_RENDER_H
37 //#include FT_OUTLINE_H
38 #include FT_TRUETYPE_TABLES_H
40 #define DEBUG_MAIN(x) x;
41 #define DEBUG_FONTBITMAP(x) x;
42 #define DEBUG_FONTINFO(x) x;
43 #define DEBUG_FONTWINDOW(x) x;
44 #define DEBUG_ADDDIR(x) x;
46 #ifdef __AROS__
47 #define dprintf kprintf
48 #endif
50 #ifndef MAKE_ID
51 # define MAKE_ID(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d))
52 #endif
54 #ifndef OT_GlyphMap8Bit
55 #define OT_GlyphMap8Bit (OT_Level1 | 0x108)
57 #define OT_Spec1_FontFile (OT_Spec1 | OT_Indirect)
58 #define OT_Spec2_CodePage (OT_Level1 | OT_Indirect | 0x102)
59 #define OT_Spec3_AFMFile (OT_Level1 | OT_Indirect | 0x103)
60 #define OT_Spec4_Metric (OT_Level1 | 0x104)
61 #define OT_Spec5_BBox (OT_Level1 | 0x105)
62 #define OT_Spec6_FaceNum (OT_Level1 | 0x106) // index for .ttc files
63 #define OT_Spec7_BMSize (OT_Level1 | 0x107) // embbeded bitmap size
65 // Values for OT_Spec4_Metric
66 #define METRIC_GLOBALBBOX 0 // default
67 #define METRIC_RAW_EM 1
68 #define METRIC_ASCEND 2
69 #define METRIC_TYPOASCEND 3
70 #define METRIC_USWINASCEND 4
71 #define METRIC_CUSTOMBBOX 5
72 #define METRIC_BMSIZE 6
73 #endif
75 #define UFHN(func) ((IPTR (*)())&func)
77 #ifndef __AROS__
79 #define UFH2(rt, func, p1, p2) \
80 rt func(void); \
81 struct EmulLibEntry func##Gate = { TRAP_LIB, 0, (void (*)(void)) func }; \
82 rt func(void) \
83 { \
84 p1; \
85 p2;
87 #define UFH3(rt, func, p1, p2, p3) \
88 rt func(void); \
89 struct EmulLibEntry func##Gate = { TRAP_LIB, 0, (void (*)(void)) func }; \
90 rt func(void) \
91 { \
92 p1; \
93 p2; \
94 p3;
96 #endif
98 /***********************************************************************/
100 Object *app;
101 FT_Library ftlibrary;
102 BPTR destdir;
103 UWORD codepage[256];
104 STRPTR *codesetentries;
105 STRPTR *codesetsupported;
106 BOOL IsDefaultCodePage(void);
108 /***********************************************************************/
109 /***********************************************************************/
110 /***********************************************************************/
111 /***********************************************************************/
112 /***********************************************************************/
114 struct FontBitmapData
116 int Width, Height;
117 struct BitMap BitMap;
118 struct BitMap *GrayBitMap;
120 typedef struct FontBitmapData FontBitmapData;
122 #define FONTBITMAP_BASE TAG_USER
123 #define MUIA_FontBitmap_Filename (FONTBITMAP_BASE + 1)
124 #define MUIA_FontBitmap_OTags (FONTBITMAP_BASE + 2)
125 #define MUIA_FontBitmap_Size (FONTBITMAP_BASE + 3)
126 #define MUIA_FontBitmap_String (FONTBITMAP_BASE + 4)
127 #define MUIA_FontBitmap_Gray (FONTBITMAP_BASE + 5)
129 struct MUI_CustomClass *FontBitmapClass;
131 #define FontBitmapObject NewObject(FontBitmapClass->mcc_Class, NULL //)
134 ULONG fbNew(Class *cl, Object *o, struct opSet *msg)
136 struct opSet method;
137 struct TagItem tags[5];
138 STRPTR filename = (STRPTR)GetTagData(MUIA_FontBitmap_Filename, (IPTR) NULL, msg->ops_AttrList);
139 STRPTR string = (STRPTR)GetTagData(MUIA_FontBitmap_String, (ULONG) "?", msg->ops_AttrList);
140 struct TagItem *otags = (struct TagItem *)GetTagData(MUIA_FontBitmap_OTags,
141 (IPTR) NULL, msg->ops_AttrList);
142 struct
144 struct GlyphMap *glyph;
145 int x;
146 int y;
147 } *info;
148 APTR engine;
149 struct BitMap bitmap;
150 struct BitMap *gray_bitmap = NULL;
151 int width, height;
152 int length = strlen(string);
153 int x, y, k;
154 int xmin, xmax, ymin, ymax;
155 int space_width, size, gray;
156 int previous;
157 Tag tag;
159 if (filename == NULL)
161 DEBUG_FONTBITMAP(dprintf("FontBitmap: no filename.\n"));
162 return 0;
165 engine = OpenEngine();
166 if (engine == NULL)
168 DEBUG_FONTBITMAP(dprintf("FontBitmap: no engine.\n"));
169 return 0;
172 size = GetTagData(MUIA_FontBitmap_Size, 30, msg->ops_AttrList);
173 gray = GetTagData(MUIA_FontBitmap_Gray, FALSE, msg->ops_AttrList);
175 SetInfo(engine,
176 OT_OTagList, (ULONG) otags,
177 OT_DeviceDPI, 72 | (72 << 16),
178 OT_PointHeight, size << 16,
179 TAG_END);
181 space_width = (int)(GetTagData(OT_SpaceWidth, 0, otags) / 65536.0 * size) ;
183 info = AllocVec(length * sizeof(*info), MEMF_CLEAR);
184 if (info == NULL)
186 DEBUG_FONTBITMAP(dprintf("FontBitmap: can't alloc glyphs.\n"));
187 length = 0;
190 x = 0;
191 y = 0;
192 previous = 0;
193 xmin = ymin = 0x7fffffff;
194 xmax = ymax = -0x80000000;
195 tag = gray ? OT_GlyphMap8Bit : OT_GlyphMap;
197 for (k = 0; k < length; ++k)
199 int code = string[k];
200 int x1, y1, x2, y2;
201 struct GlyphMap *g;
203 if (previous)
205 ULONG kerning;
207 SetInfo(engine,
208 OT_GlyphCode, previous,
209 OT_GlyphCode2, code,
210 TAG_END);
211 ObtainInfo(engine,
212 OT_TextKernPair, (ULONG)&kerning,
213 TAG_END);
215 x -= (int)(kerning / 65536.0 * size);
218 info[k].x = x;
219 info[k].y = y;
221 SetInfo(engine,
222 OT_GlyphCode, code,
223 TAG_END);
224 ObtainInfo(engine,
225 tag, (ULONG)&info[k].glyph,
226 TAG_END);
228 g = info[k].glyph;
230 if (!g)
232 x += space_width;
233 continue;
236 x1 = x - g->glm_X0 + g->glm_BlackLeft;
237 y1 = y - g->glm_Y0 + g->glm_BlackTop;
238 x2 = x1 + g->glm_BlackWidth;
239 y2 = y1 + g->glm_BlackHeight;
241 if (x1 < xmin)
242 xmin = x1;
243 if (y1 < ymin)
244 ymin = y1;
245 if (x2 > xmax)
246 xmax = x2;
247 if (y2 > ymax)
248 ymax = y2;
250 x += g->glm_X1 - g->glm_X0;
251 y += g->glm_Y1 - g->glm_Y0;
253 previous = code;
256 width = xmax - xmin + 1;
257 height = ymax - ymin + 1;
259 DEBUG_FONTBITMAP(dprintf("FontBitmap: bbox %d %d %d %d\n", xmin, ymin, xmax, ymax));
260 DEBUG_FONTBITMAP(dprintf("FontBitmap: width %d height %d\n", width, height));
262 if (width > 0 && height > 0 && width < 32000 && height < 32000)
264 if (gray)
266 UBYTE *array;
267 int width1 = (width + 15) & ~15;
269 array = AllocVec(width1 * height, MEMF_CLEAR);
270 if (array)
272 for (k = 0; k < length; ++k)
274 struct GlyphMap *g = info[k].glyph;
275 int x1, x2, y1, y2;
276 UBYTE *p;
278 if (!g)
280 x += space_width;
281 continue;
284 x = info[k].x - xmin;
285 y = info[k].y - ymin;
286 x -= g->glm_X0;
287 y -= g->glm_Y0;
288 x += g->glm_BlackLeft;
289 y += g->glm_BlackTop;
291 p = g->glm_BitMap;
292 x1 = x;
293 y1 = y;
294 x2 = x + g->glm_BlackWidth;
295 y2 = y + g->glm_BlackHeight;
297 if (x1 > width || x2 < 0 || y1 > height || y2 < 0)
298 continue;
300 if (x1 < 0)
302 p -= x1;
303 x1 = 0;
305 if (y1 < 0)
307 p -= y1 * g->glm_BMModulo;
308 y1 = 0;
310 if (x2 > width)
312 x2 = width;
314 if (y2 > height)
316 y2 = height;
319 while (y1 < y2)
321 int x;
323 for (x = x1; x < x2; ++x)
325 int t = array[width1 * y1 + x] + p[x - x1];
326 if (t > 255)
327 t = 255;
328 array[width1 * y1 + x] = t;
330 p += g->glm_BMModulo;
331 ++y1;
335 gray_bitmap = AllocBitMap(width, height, 8, 0, NULL);
336 if (gray_bitmap)
338 struct RastPort rp, tmp_rp;
340 InitRastPort(&rp);
341 InitRastPort(&tmp_rp);
343 rp.BitMap = gray_bitmap;
344 tmp_rp.BitMap = AllocBitMap(width, 1, 8, 0, NULL);
346 if (tmp_rp.BitMap)
348 WritePixelArray8(&rp,
351 width - 1,
352 height - 1,
353 array,
354 &tmp_rp);
355 FreeBitMap(tmp_rp.BitMap);
359 FreeVec(array);
362 else
364 InitBitMap(&bitmap, 1, width, height);
365 bitmap.Planes[0] = AllocRaster(width, height);
367 if (bitmap.Planes[0])
369 struct RastPort rp;
371 InitRastPort(&rp);
372 rp.BitMap = &bitmap;
373 SetRast(&rp, 0);
374 SetAPen(&rp, 1);
375 SetDrMd(&rp, JAM1);
377 for (k = 0; k < length; ++k)
379 struct GlyphMap *g = info[k].glyph;
381 if (!g)
382 continue;
384 x = info[k].x - xmin;
385 y = info[k].y - ymin;
386 x -= g->glm_X0;
387 y -= g->glm_Y0;
388 x += g->glm_BlackLeft;
389 y += g->glm_BlackTop;
391 /* glm_BitMap is not in chip mem.
392 * Oh well.
394 BltTemplate((const PLANEPTR)(g->glm_BitMap +
395 g->glm_BMModulo *
396 g->glm_BlackTop),
397 g->glm_BlackLeft,
398 g->glm_BMModulo,
399 &rp,
400 x, y,
401 g->glm_BlackWidth,
402 g->glm_BlackHeight);
407 tags[0].ti_Tag = MUIA_Bitmap_Width;
408 tags[0].ti_Data = width;
409 tags[1].ti_Tag = MUIA_Bitmap_Height;
410 tags[1].ti_Data = height;
411 tags[2].ti_Tag = MUIA_FixWidth;
412 tags[2].ti_Data = width;
413 tags[3].ti_Tag = MUIA_FixHeight;
414 tags[3].ti_Data = height;
415 tags[4].ti_Tag = TAG_MORE;
416 tags[4].ti_Data = (ULONG)msg->ops_AttrList;
418 method.MethodID = OM_NEW;
419 method.ops_AttrList = tags;
420 method.ops_GInfo = NULL;
422 o = (Object *)DoSuperMethodA(cl, o, (Msg)&method);
424 if (o)
426 FontBitmapData *dat = INST_DATA(cl, o);
428 dat->Width = width;
429 dat->Height = height;
430 dat->GrayBitMap = gray_bitmap;
432 if (gray)
434 static ULONG colors[256 * 3];
435 static BOOL init;
437 if (!init)
439 int k;
440 ULONG *p = colors;
441 for (k = 256; --k >= 0; p += 3)
443 p[0] = p[1] = p[2] = k * 0x01010101;
445 init = TRUE;
448 SetAttrs(o,
449 MUIA_Bitmap_Bitmap, gray_bitmap,
450 MUIA_Bitmap_SourceColors, colors,
451 TAG_END);
453 else
455 dat->BitMap = bitmap;
456 set(o, MUIA_Bitmap_Bitmap, &dat->BitMap);
459 else
461 if (gray)
463 FreeBitMap(gray_bitmap);
465 else if (bitmap.Planes[0])
467 FreeRaster(bitmap.Planes[0], width, height);
471 else
473 o = NULL;
476 for (k = 0; k < length; ++k)
478 if (info[k].glyph)
480 ReleaseInfo(engine,
481 tag, (ULONG)info[k].glyph,
482 TAG_END);
486 FreeVec(info);
488 CloseEngine(engine);
490 DEBUG_FONTBITMAP(dprintf("FontBitmap: created object 0x%lx.\n", o));
492 return (ULONG)o;
495 ULONG fbDispose(Class *cl, Object *o)
497 FontBitmapData *dat = INST_DATA(cl, o);
499 DEBUG_FONTBITMAP(dprintf("FontBitmap: destroy object 0x%lx.\n", o));
501 if (dat->GrayBitMap)
503 FreeBitMap(dat->GrayBitMap);
505 else if (dat->BitMap.Planes[0])
507 FreeRaster(dat->BitMap.Planes[0], dat->Width, dat->Height);
510 return DoSuperMethod(cl, o, OM_DISPOSE);
513 AROS_UFH3(ULONG, FontBitmapDispatch,
514 AROS_UFHA(Class *, cl, A0),
515 AROS_UFHA(Object *, o, A2),
516 AROS_UFHA(Msg, msg, A1))
518 AROS_USERFUNC_INIT
520 ULONG ret;
522 switch (msg->MethodID)
524 case OM_NEW:
525 ret = fbNew(cl, o, (struct opSet *)msg);
526 break;
528 case OM_DISPOSE:
529 ret = fbDispose(cl, o);
530 break;
532 default:
533 ret = DoSuperMethodA(cl, o, msg);
534 break;
537 return ret;
539 AROS_USERFUNC_EXIT
543 void CleanupFontBitmapClass(void)
545 if (FontBitmapClass)
547 MUI_DeleteCustomClass(FontBitmapClass);
548 FontBitmapClass = NULL;
552 int InitFontBitmapClass(void)
554 FontBitmapClass = MUI_CreateCustomClass(NULL, MUIC_Bitmap, NULL,
555 sizeof(FontBitmapData), UFHN(FontBitmapDispatch));
556 return FontBitmapClass != NULL;
559 /***********************************************************************/
560 /***********************************************************************/
561 /***********************************************************************/
562 /***********************************************************************/
563 /***********************************************************************/
565 struct FontInfoData
567 STRPTR Filename;
568 FT_Face Face;
569 Object *AttachedFile;
570 Object *Name;
571 Object *YSizeFactorHigh;
572 Object *YSizeFactorLow;
573 Object *StemWeight;
574 Object *SlantStyle;
575 Object *HorizStyle;
576 Object *Family;
577 Object *Fixed;
578 Object *Serif;
579 //Object *AlgoStyle;
580 Object *FaceNum;
581 Object *Metric;
582 Object *BBoxYMin;
583 Object *BBoxYMax;
584 Object *SpaceWidth;
585 Object *Preview;
586 Object *PreviewGroup;
587 Object *Gray;
588 Object *TestSize;
589 Object *TestString;
590 struct TagItem OTags[26];
591 UWORD AvailSizes[OT_MAXAVAILSIZES];
593 typedef struct FontInfoData FontInfoData;
595 #define FONTINFO_BASE TAG_USER
596 #define MUIA_FontInfo_Filename (FONTINFO_BASE + 1)
597 #define MUIA_FontInfo_Face (FONTINFO_BASE + 2)
599 #define FONTINFO_MBASE TAG_USER
600 #define MUIM_FontInfo_UpdatePreview (FONTINFO_MBASE + 1)
601 #define MUIM_FontInfo_SetOTags (FONTINFO_MBASE + 2)
602 #define MUIM_FontInfo_WriteFiles (FONTINFO_MBASE + 3)
604 struct MUI_CustomClass *FontInfoClass;
606 #define FontInfoObject NewObject(FontInfoClass->mcc_Class, NULL //)
608 struct CycleToStringP
610 Object *String;
611 int NumValues;
612 const UBYTE *Values;
615 AROS_UFH3(void, CycleToString,
616 AROS_UFHA(struct Hook *, hook, A0),
617 AROS_UFHA(Object *, cycle, A2),
618 AROS_UFHA(struct CycleToStringP *, p, A1))
620 AROS_USERFUNC_INIT
622 ULONG entry;
623 Object *str = p->String;
624 get(cycle, MUIA_Cycle_Active, &entry);
625 if (entry == p->NumValues)
627 set(str, MUIA_Disabled, FALSE);
629 else
631 SetAttrs(str,
632 MUIA_Disabled, TRUE,
633 MUIA_String_Integer, p->Values[entry],
634 TAG_END);
637 AROS_USERFUNC_EXIT
641 struct Hook CycleToStringHook = { {NULL, NULL}, UFHN(CycleToString) };
644 struct IntegerBoundsP
646 LONG Min;
647 LONG Max;
650 AROS_UFH3(void, IntegerBounds,
651 AROS_UFHA(struct Hook *, hook, A0),
652 AROS_UFHA(Object *, obj, A2),
653 AROS_UFHA(struct IntegerBoundsP *, p, A1))
655 AROS_USERFUNC_INIT
657 LONG t;
658 get(obj, MUIA_String_Integer, &t);
659 if (t < p->Min)
661 set(obj, MUIA_String_Integer, p->Min);
663 else if (t > p->Max)
665 set(obj, MUIA_String_Integer, p->Max);
668 AROS_USERFUNC_EXIT
672 struct Hook IntegerBoundsHook = { {NULL, NULL}, UFHN(IntegerBounds) };
675 AROS_UFH3(void, Metric,
676 AROS_UFHA(struct Hook *, hook, A0),
677 AROS_UFHA(Object *, obj, A2),
678 AROS_UFHA(Object **, p, A1))
680 AROS_USERFUNC_INIT
682 ULONG t;
683 ULONG state;
684 int k;
686 get(obj, MUIA_Cycle_Active, &t);
687 state = t != 5;
688 for (k = 0; k < 2; ++k)
690 set(p[k], MUIA_Disabled, state);
693 AROS_USERFUNC_EXIT
697 struct Hook MetricHook = { {NULL, NULL}, UFHN(Metric) };
700 ULONG fiNew(Class *cl, Object *o, struct opSet *msg)
702 struct opSet method;
703 struct TagItem tags[3];
704 STRPTR filename = (STRPTR)GetTagData(MUIA_FontInfo_Filename, (IPTR) NULL, msg->ops_AttrList);
705 FT_Face face = (FT_Face)GetTagData(MUIA_FontInfo_Face, (IPTR) NULL, msg->ops_AttrList);
706 TT_Postscript *postscript;
707 TT_OS2 *os2;
708 Object *name, *attached_file, *size_factor_low, *size_factor_high;
709 Object *stem_weight, *slant_style, *horiz_style, *stem_weight_cycle, *horiz_style_cycle;
710 Object *family, *fixed, /**algo_style,*/ *face_num, *preview, *preview_group;
711 Object *gray, *test_string, *test_size, *serif, *space_width;
712 Object *metric, *bbox_ymin, *bbox_ymax;
713 char name_buf[27];
714 int k, l;
715 const char *q, *r;
717 static const char * const stem_weight_names[] =
719 "UltraThin",
720 "ExtraThin",
721 "Thin",
722 "ExtraLight",
723 "Light",
724 "DemiLight",
725 "SemiLight",
726 "Book",
727 "Medium",
728 "SemiBold",
729 "DemiBold",
730 "Bold",
731 "ExtraBold",
732 "Black",
733 "ExtraBlack",
734 "UltraBlack",
735 "Custom",
736 NULL
738 static const UBYTE stem_weight_values[] =
740 OTS_UltraThin,
741 OTS_ExtraThin,
742 OTS_Thin,
743 OTS_ExtraLight,
744 OTS_Light,
745 OTS_DemiLight,
746 OTS_SemiLight,
747 OTS_Book,
748 OTS_Medium,
749 OTS_SemiBold,
750 OTS_DemiBold,
751 OTS_Bold,
752 OTS_ExtraBold,
753 OTS_Black,
754 OTS_ExtraBlack,
755 OTS_UltraBlack,
758 static const char * const slant_style_names[] =
760 "Upright",
761 "Italic",
762 "LeftItalic",
763 NULL
766 static const char * const horiz_style_names[] =
768 "UltraCompressed",
769 "ExtraCompressed",
770 "Compressed",
771 "Condensed",
772 "Normal",
773 "SemiExpanded",
774 "Expanded",
775 "ExtraExpanded",
776 "Custom",
777 NULL
779 static const UBYTE horiz_style_values[] =
781 OTH_UltraCompressed,
782 OTH_ExtraCompressed,
783 OTH_Compressed,
784 OTH_Condensed,
785 OTH_Normal,
786 OTH_SemiExpanded,
787 OTH_Expanded,
788 OTH_ExtraExpanded,
791 static const char *metric_names[] =
793 "Global bounding box",
794 "Raw font metric",
795 "Ascender",
796 "Typo ascender",
797 "USWin ascender",
798 "Custom bounding box",
799 //"Bitmap size",
800 NULL,
803 if (!filename || !face)
805 DEBUG_FONTINFO(dprintf("FontInfo: filename 0x%x face 0x%x\n", filename, face));
806 return 0;
809 q = face->family_name;
810 r = face->style_name;
811 k = 0;
812 l = -1;
813 while (k < sizeof(name_buf) - 1)
815 while (*q == ' ')
816 ++q;
817 if (!*q)
819 if (r)
821 q = r;
822 r = NULL;
823 continue;
825 break;
827 if (*q == '.')
828 l = k;
829 name_buf[k] = ToLower(*q);
830 ++k;
831 ++q;
833 if (l > 0)
834 k = l;
835 name_buf[k] = '\0';
837 postscript = FT_Get_Sfnt_Table(face, ft_sfnt_post);
838 os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
840 tags[0].ti_Tag = MUIA_Group_Child;
841 tags[0].ti_Data = (ULONG)ColGroup(2),
842 Child, Label2("Extra file"),
843 Child, attached_file = PopaslObject,
844 MUIA_Popasl_Type, ASL_FileRequest,
845 MUIA_Popstring_String, StringObject,
846 StringFrame,
847 MUIA_String_AdvanceOnCR, TRUE,
848 MUIA_CycleChain, TRUE,
849 End,
850 MUIA_Popstring_Button, PopButton(MUII_PopFile),
851 ASLFR_RejectIcons, TRUE,
852 End,
853 Child, Label2("Face num"),
854 Child, face_num = StringObject,
855 StringFrame,
856 MUIA_String_Integer, 0,
857 MUIA_String_Accept, "0123456789",
858 MUIA_String_AdvanceOnCR, TRUE,
859 MUIA_String_MaxLen, 5,
860 MUIA_CycleChain, TRUE,
861 End,
862 Child, Label2("Name"),
863 Child, name = StringObject,
864 StringFrame,
865 MUIA_String_Contents, name_buf,
866 MUIA_String_AdvanceOnCR, TRUE,
867 MUIA_String_MaxLen, 27,
868 MUIA_CycleChain, TRUE,
869 End,
870 Child, Label2("Family"),
871 Child, family = StringObject,
872 StringFrame,
873 MUIA_String_Contents, face->family_name,
874 MUIA_String_AdvanceOnCR, TRUE,
875 MUIA_CycleChain, TRUE,
876 End,
877 Child, Label2("Metric"),
878 Child, metric = CycleObject,
879 MUIA_Cycle_Entries, metric_names,
880 MUIA_Cycle_Active, 1,
881 MUIA_CycleChain, TRUE,
882 End,
883 Child, Label2("Bounding box"),
884 Child, HGroup,
885 Child, Label2("yMin"),
886 Child, bbox_ymin = StringObject,
887 StringFrame,
888 MUIA_String_Accept, "-0123456789",
889 MUIA_String_AdvanceOnCR, TRUE,
890 MUIA_String_MaxLen, 6,
891 MUIA_String_Integer, face->bbox.yMin,
892 MUIA_CycleChain, TRUE,
893 End,
894 Child, Label2("yMax"),
895 Child, bbox_ymax = StringObject,
896 StringFrame,
897 MUIA_String_Accept, "-0123456789",
898 MUIA_String_AdvanceOnCR, TRUE,
899 MUIA_String_MaxLen, 6,
900 MUIA_String_Integer, face->bbox.yMax,
901 MUIA_CycleChain, TRUE,
902 End,
903 End,
904 Child, Label2("Size factor"),
905 Child, HGroup,
906 Child, size_factor_low = StringObject,
907 StringFrame,
908 MUIA_String_Accept, "0123456789",
909 MUIA_String_AdvanceOnCR, TRUE,
910 MUIA_String_MaxLen, 6,
911 MUIA_String_Integer, 1,
912 MUIA_CycleChain, TRUE,
913 End,
914 Child, TextObject,
915 MUIA_Text_Contents, "/",
916 MUIA_Text_SetMax, TRUE,
917 End,
918 Child, size_factor_high = StringObject,
919 StringFrame,
920 MUIA_String_Accept, "0123456789",
921 MUIA_String_AdvanceOnCR, TRUE,
922 MUIA_String_MaxLen, 6,
923 MUIA_String_Integer, 1,
924 MUIA_CycleChain, TRUE,
925 End,
926 End,
927 Child, Label2("Space width"),
928 Child, space_width = StringObject,
929 StringFrame,
930 MUIA_String_Accept, "0123456789",
931 MUIA_String_AdvanceOnCR, TRUE,
932 MUIA_String_MaxLen, 6,
933 MUIA_String_Integer, (ULONG)(face->max_advance_width * 250.0 / 72.307),
934 MUIA_CycleChain, TRUE,
935 End,
936 Child, Label1("Fixed width"),
937 Child, HGroup,
938 Child, fixed = CheckMark((face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0),
939 Child, RectangleObject,
940 End,
941 End,
942 Child, Label1("Serif"),
943 Child, HGroup,
944 Child, serif = CheckMark(os2 && (unsigned)(((os2->sFamilyClass >> 8) &
945 0xff) - 1) < 5),
946 Child, RectangleObject,
947 End,
948 End,
949 Child, Label2("Stem weight"),
950 Child, HGroup,
951 Child, stem_weight_cycle = CycleObject,
952 MUIA_Cycle_Entries, stem_weight_names,
953 MUIA_CycleChain, TRUE,
954 End,
955 Child, stem_weight = StringObject,
956 StringFrame,
957 MUIA_String_Accept, "0123456789",
958 MUIA_String_AdvanceOnCR, TRUE,
959 MUIA_String_MaxLen, 4,
960 MUIA_String_Integer, 128,
961 MUIA_CycleChain, TRUE,
962 End,
963 End,
964 Child, Label2("Slant style"),
965 Child, slant_style = CycleObject,
966 MUIA_Cycle_Entries, slant_style_names,
967 MUIA_Cycle_Active, face->style_flags & FT_STYLE_FLAG_ITALIC ?
968 (postscript && postscript->italicAngle > 0 ?
969 OTS_LeftItalic : OTS_Italic) : OTS_Upright,
970 MUIA_CycleChain, TRUE,
971 End,
972 Child, Label2("Horiz style"),
973 Child, HGroup,
974 Child, horiz_style_cycle = CycleObject,
975 MUIA_Cycle_Entries, horiz_style_names,
976 MUIA_CycleChain, TRUE,
977 End,
978 Child, horiz_style = StringObject,
979 StringFrame,
980 MUIA_String_Accept, "0123456789",
981 MUIA_String_AdvanceOnCR, TRUE,
982 MUIA_String_MaxLen, 4,
983 MUIA_String_Integer, 128,
984 MUIA_CycleChain, TRUE,
985 End,
986 End,
987 /*Child, Label1("No algo style"),
988 Child, HGroup,
989 Child, algo_style = CheckMark(FALSE),
990 Child, RectangleObject,
991 End,
992 End,*/
993 End;
994 tags[1].ti_Tag = MUIA_Group_Child;
995 tags[1].ti_Data = (ULONG)VGroup,
996 GroupFrameT("Preview"),
997 Child, test_string = StringObject,
998 StringFrame,
999 MUIA_String_Contents, "The quick brown fox jumped over the lazy dog.",
1000 MUIA_String_AdvanceOnCR, TRUE,
1001 MUIA_CycleChain, TRUE,
1002 End,
1003 Child, HGroup,
1004 Child, Label2("Size"),
1005 Child, test_size = StringObject,
1006 StringFrame,
1007 MUIA_String_Accept, "0123456789",
1008 MUIA_String_Integer, 30,
1009 MUIA_String_AdvanceOnCR, TRUE,
1010 MUIA_CycleChain, TRUE,
1011 End,
1012 Child, Label2("Anti-aliasing"),
1013 Child, gray = CheckMark(FALSE),
1014 End,
1015 Child, ScrollgroupObject,
1016 MUIA_Scrollgroup_Contents, VirtgroupObject,
1017 VirtualFrame,
1018 Child, VCenter(HCenter((preview_group = VGroup,
1019 Child, preview = RectangleObject,
1020 End,
1021 End))),
1022 End,
1023 End,
1024 End;
1025 tags[2].ti_Tag = TAG_MORE;
1026 tags[2].ti_Data = (ULONG)msg->ops_AttrList;
1028 method.MethodID = OM_NEW;
1029 method.ops_AttrList = tags;
1030 method.ops_GInfo = NULL;
1032 o = (Object *)DoSuperMethodA(cl, o, (Msg)&method);
1033 if (o)
1035 FontInfoData *dat = INST_DATA(cl, o);
1037 dat->Filename = filename;
1038 dat->Face = face;
1039 dat->AttachedFile = attached_file;
1040 dat->Name = name;
1041 dat->Family = family;
1042 dat->YSizeFactorLow = size_factor_low;
1043 dat->YSizeFactorHigh = size_factor_high;
1044 dat->StemWeight = stem_weight;
1045 dat->SlantStyle = slant_style;
1046 dat->HorizStyle = horiz_style;
1047 dat->SpaceWidth = space_width;
1048 dat->Fixed = fixed;
1049 dat->Serif = serif;
1050 //dat->AlgoStyle = algo_style;
1051 dat->FaceNum = face_num;
1052 dat->Metric = metric;
1053 dat->BBoxYMin = bbox_ymin;
1054 dat->BBoxYMax = bbox_ymax;
1055 dat->Preview = preview;
1056 dat->PreviewGroup = preview_group;
1057 dat->TestString = test_string;
1058 dat->TestSize = test_size;
1059 dat->Gray = gray;
1061 DoMethod(size_factor_low, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1062 size_factor_low, 4, MUIM_CallHook, &IntegerBoundsHook, 1, 65535);
1063 DoMethod(size_factor_high, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1064 size_factor_high, 4, MUIM_CallHook, &IntegerBoundsHook, 1, 65535);
1066 DoMethod(stem_weight_cycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
1067 stem_weight_cycle, 5, MUIM_CallHook, &CycleToStringHook,
1068 stem_weight, sizeof(stem_weight_values), stem_weight_values);
1069 DoMethod(stem_weight, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1070 stem_weight, 4, MUIM_CallHook, &IntegerBoundsHook, 0, 255);
1072 DoMethod(horiz_style_cycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
1073 horiz_style_cycle, 5, MUIM_CallHook, &CycleToStringHook,
1074 horiz_style, sizeof(horiz_style_values), horiz_style_values);
1075 DoMethod(horiz_style, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1076 horiz_style, 4, MUIM_CallHook, &IntegerBoundsHook, 0, 255);
1078 set(stem_weight_cycle, MUIA_Cycle_Active,
1079 face->style_flags & FT_STYLE_FLAG_BOLD ? 11 : 7);
1080 set(horiz_style_cycle, MUIA_Cycle_Active, 4);
1082 DoMethod(test_string, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1083 o, 1, MUIM_FontInfo_UpdatePreview);
1084 DoMethod(test_size, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1085 o, 1, MUIM_FontInfo_UpdatePreview);
1086 DoMethod(gray, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
1087 o, 1, MUIM_FontInfo_UpdatePreview);
1089 DoMethod(bbox_ymin, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1090 bbox_ymin, 4, MUIM_CallHook, &IntegerBoundsHook, -32768, 32767);
1091 DoMethod(bbox_ymax, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1092 bbox_ymax, 4, MUIM_CallHook, &IntegerBoundsHook, -32768, 32767);
1094 DoMethod(metric, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
1095 metric, 6, MUIM_CallHook, &MetricHook, bbox_ymin, bbox_ymax);
1097 set(metric, MUIA_Cycle_Active, 0);
1099 if (//!(face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) &&
1100 FT_Set_Char_Size(face, 250 * 64, 250 * 64, 2540, 2540) == 0 &&
1101 FT_Load_Char(face, ' ', FT_LOAD_DEFAULT) == 0)
1103 set(space_width, MUIA_String_Integer, face->glyph->metrics.horiAdvance >> 6);
1106 if (os2)
1108 int weight = os2->usWeightClass;
1109 int value;
1111 value = 0; /* UltraThin */
1112 if (weight < 10) weight *= 100;
1113 if (weight >= 200) value = 2; /* Thin */
1114 if (weight >= 300) value = 4; /* Light */
1115 if (weight >= 400) value = 7; /* Book */
1116 if (weight >= 500) value = 8; /* Medium */
1117 if (weight >= 600) value = 10; /* DemiBold */
1118 if (weight >= 700) value = 11; /* Bold */
1119 if (weight >= 800) value = 13; /* Black */
1120 if (weight >= 900) value = 15; /* UltraBlack */
1121 set(stem_weight_cycle, MUIA_Cycle_Active, value);
1123 set(horiz_style_cycle, MUIA_Cycle_Active, os2->usWidthClass - 1);
1126 DoMethod(o, MUIM_FontInfo_UpdatePreview);
1129 DEBUG_FONTINFO(dprintf("FontInfo: created object 0x%lx\n", o));
1131 return (ULONG)o;
1134 #if 0
1135 ULONG fiDispose(Class *cl, Object *o)
1137 FontInfoData *dat = INST_DATA(cl, o);
1139 return DoSuperMethod(cl, o, OM_DISPOSE);
1141 #endif
1143 ULONG fiSetOTags(Class *cl, Object *o)
1145 FontInfoData *dat = INST_DATA(cl, o);
1146 struct TagItem *tag = dat->OTags;
1147 ULONG x, y;
1149 tag->ti_Tag = OT_FileIdent;
1150 ++tag;
1152 tag->ti_Tag = OT_Engine;
1153 tag->ti_Data = (ULONG)"freetype2";
1154 ++tag;
1156 tag->ti_Tag = OT_Family;
1157 get(dat->Family, MUIA_String_Contents, &tag->ti_Data);
1158 ++tag;
1160 //tag->ti_Tag = OT_BName;
1161 //tag->ti_Tag = OT_IName;
1162 //tag->ti_Tag = OT_BIName;
1163 //tag->ti_Tag = OT_SymbolSet; charmap index
1165 get(dat->YSizeFactorLow, MUIA_String_Integer, &x);
1166 get(dat->YSizeFactorHigh, MUIA_String_Integer, &y);
1167 x = (UWORD)x;
1168 y = (UWORD)y;
1169 if (x == 0) x = 1;
1170 if (y == 0) y = 1;
1171 tag->ti_Tag = OT_YSizeFactor;
1172 tag->ti_Data = x | (y << 16);
1173 ++tag;
1175 tag->ti_Tag = OT_SpaceWidth;
1176 get(dat->SpaceWidth, MUIA_String_Integer, &tag->ti_Data);
1177 ++tag;
1179 tag->ti_Tag = OT_IsFixed;
1180 get(dat->Fixed, MUIA_Selected, &tag->ti_Data);
1181 ++tag;
1183 tag->ti_Tag = OT_SerifFlag;
1184 get(dat->Serif, MUIA_Selected, &tag->ti_Data);
1185 ++tag;
1187 tag->ti_Tag = OT_StemWeight;
1188 get(dat->StemWeight, MUIA_String_Integer, &tag->ti_Data);
1189 ++tag;
1191 tag->ti_Tag = OT_SlantStyle;
1192 get(dat->SlantStyle, MUIA_Cycle_Active, &tag->ti_Data);
1193 ++tag;
1195 tag->ti_Tag = OT_HorizStyle;
1196 get(dat->HorizStyle, MUIA_String_Integer, &tag->ti_Data);
1197 ++tag;
1199 tag->ti_Tag = OT_SpaceFactor;
1200 tag->ti_Data = 0x10000;
1201 ++tag;
1203 tag->ti_Tag = OT_InhibitAlgoStyle;
1204 tag->ti_Data = FSF_UNDERLINED | FSF_BOLD;
1205 //get(dat->AlgoStyle, MUIA_Selected, &tag->ti_Data);
1206 ++tag;
1208 tag->ti_Tag = OT_SpecCount;
1209 tag->ti_Data = 4;
1210 ++tag;
1212 tag->ti_Tag = OT_Spec1_FontFile;
1213 tag->ti_Data = (ULONG)dat->Filename;
1214 ++tag;
1216 tag->ti_Tag = OT_Spec3_AFMFile;
1217 get(dat->AttachedFile, MUIA_String_Contents, &tag->ti_Data);
1218 ++tag;
1220 tag->ti_Tag = OT_Spec4_Metric;
1221 get(dat->Metric, MUIA_Cycle_Active, &tag->ti_Data);
1222 ++tag;
1224 if (tag[-1].ti_Data == METRIC_CUSTOMBBOX)
1226 ULONG ymin, ymax;
1227 get(dat->BBoxYMin, MUIA_String_Integer, &ymin);
1228 get(dat->BBoxYMax, MUIA_String_Integer, &ymax);
1229 tag->ti_Tag = OT_Spec5_BBox;
1230 tag->ti_Data = (ymax << 16) | (UWORD)ymin;
1231 ++tag;
1234 tag->ti_Tag = OT_Spec6_FaceNum;
1235 get(dat->FaceNum, MUIA_String_Integer, &tag->ti_Data);
1236 ++tag;
1238 if (!IsDefaultCodePage())
1240 tag->ti_Tag = OT_Spec2_CodePage;
1241 tag->ti_Data = (ULONG)codepage;
1242 ++tag;
1245 tag->ti_Tag = TAG_END;
1247 dat->AvailSizes[0] = AROS_WORD2BE(2); // <- number of entries...
1248 dat->AvailSizes[1] = AROS_WORD2BE(10);
1249 dat->AvailSizes[2] = AROS_WORD2BE(15);
1251 return tag - dat->OTags;
1254 ULONG fiUpdatePreview(Class *cl, Object *o)
1256 FontInfoData *dat = INST_DATA(cl, o);
1257 Object *preview;
1258 STRPTR str;
1259 ULONG gray;
1260 ULONG size;
1262 fiSetOTags(cl, o);
1264 get(dat->TestString, MUIA_String_Contents, &str);
1265 get(dat->Gray, MUIA_Selected, &gray);
1266 get(dat->TestSize, MUIA_String_Integer, &size);
1268 preview = FontBitmapObject,
1269 MUIA_FontBitmap_Filename, dat->Filename,
1270 MUIA_FontBitmap_OTags, dat->OTags,
1271 MUIA_FontBitmap_String, str,
1272 MUIA_FontBitmap_Gray, gray,
1273 MUIA_FontBitmap_Size, size,
1274 End;
1276 DEBUG_FONTINFO(dprintf("FontInfo::UpdatePreview: new 0x%lx\n", preview));
1278 if (preview)
1280 DoMethod(dat->PreviewGroup, MUIM_Group_InitChange);
1281 if (dat->Preview)
1283 DoMethod(dat->PreviewGroup, OM_REMMEMBER, dat->Preview);
1284 DisposeObject(dat->Preview);
1286 DoMethod(dat->PreviewGroup, OM_ADDMEMBER, preview);
1287 DoMethod(dat->PreviewGroup, MUIM_Group_ExitChange);
1288 dat->Preview = preview;
1291 return preview != NULL;
1294 ULONG fiWriteFiles(Class *cl, Object *o)
1296 FontInfoData *dat = INST_DATA(cl, o);
1297 BPTR file;
1298 char name[32];
1299 STRPTR base;
1300 BPTR olddir;
1302 get(dat->Name, MUIA_String_Contents, &base);
1303 if (!base || !base[0])
1304 return FALSE;
1306 olddir = CurrentDir(destdir);
1308 strcpy(name, base);
1309 strcat(name, ".otag");
1311 file = Open(name, MODE_NEWFILE);
1312 if (file)
1314 struct TagItem *tag;
1315 ULONG size, indirect_size;
1316 UBYTE *buffer;
1317 int num_sizes;
1319 size = sizeof(tag->ti_Tag) + (fiSetOTags(cl, o) + 2) * sizeof(*tag);
1320 indirect_size = 0;
1322 for (tag = dat->OTags; tag->ti_Tag != TAG_END; ++tag)
1324 if (tag->ti_Tag == OT_Spec2_CodePage)
1326 indirect_size += 1;
1327 indirect_size &= ~1;
1328 indirect_size += sizeof(codepage);
1330 else if (tag->ti_Tag & OT_Indirect && tag->ti_Data)
1332 indirect_size += strlen((const char *)tag->ti_Data) + 1;
1336 indirect_size += 1;
1337 indirect_size &= ~1;
1339 num_sizes = 1 + dat->AvailSizes[0];
1340 indirect_size += num_sizes * sizeof(UWORD);
1342 dat->OTags[0].ti_Data = size + indirect_size;
1344 buffer = malloc(indirect_size);
1345 if (buffer)
1347 size_t offset = 0;
1348 struct TagItem *write_tags;
1350 memset(buffer, 0, indirect_size);
1352 for (tag = dat->OTags; tag->ti_Tag != TAG_END; ++tag)
1354 if (tag->ti_Tag == OT_Spec2_CodePage)
1356 offset += 1;
1357 offset &= ~1;
1358 memcpy(buffer + offset, codepage, sizeof(codepage));
1359 tag->ti_Data = size + offset;
1360 offset += sizeof(codepage);
1362 else if (tag->ti_Tag & OT_Indirect && tag->ti_Data)
1364 size_t len = strlen((const char *)tag->ti_Data) + 1;
1365 memcpy(buffer + offset, (const char *)tag->ti_Data, len);
1366 tag->ti_Data = size + offset;
1367 offset += len;
1371 offset += 1;
1372 offset &= ~1;
1374 tag->ti_Tag = OT_AvailSizes;
1375 tag->ti_Data = size + offset;
1376 ++tag;
1378 tag->ti_Tag = TAG_END;
1380 memcpy(buffer + offset, dat->AvailSizes, num_sizes * sizeof(UWORD));
1381 offset += num_sizes * sizeof(UWORD);
1383 write_tags = malloc(size);
1384 memcpy(write_tags, dat->OTags, size);
1385 for (tag = write_tags; tag->ti_Tag != TAG_END; tag++)
1387 tag->ti_Tag = AROS_LONG2BE(tag->ti_Tag);
1388 tag->ti_Data = AROS_LONG2BE(tag->ti_Data);
1390 tag->ti_Tag = AROS_LONG2BE(TAG_END);
1392 Write(file, write_tags, size);
1393 free(write_tags);
1394 Write(file, buffer, offset);
1396 free(buffer);
1399 Close(file);
1402 strcpy(name, base);
1403 strcat(name, ".font");
1405 file = Open(name, MODE_NEWFILE);
1406 if (file)
1408 static UBYTE data[] = {0x0f, 0x03, 0x00, 0x00 };
1409 Write(file, data, sizeof(data));
1410 Close(file);
1413 CurrentDir(olddir);
1415 return 1;
1418 AROS_UFH3(ULONG, FontInfoDispatch,
1419 AROS_UFHA(Class *, cl, A0),
1420 AROS_UFHA(Object *, o, A2),
1421 AROS_UFHA(Msg, msg, A1))
1423 AROS_USERFUNC_INIT
1425 ULONG ret;
1427 switch (msg->MethodID)
1429 case OM_NEW:
1430 ret = fiNew(cl, o, (struct opSet *)msg);
1431 break;
1433 #if 0
1434 case OM_DISPOSE:
1435 ret = fiDispose(cl, o);
1436 break;
1437 #endif
1439 case MUIM_FontInfo_UpdatePreview:
1440 ret = fiUpdatePreview(cl, o);
1441 break;
1443 case MUIM_FontInfo_WriteFiles:
1444 ret = fiWriteFiles(cl, o);
1445 break;
1447 default:
1448 ret = DoSuperMethodA(cl, o, msg);
1449 break;
1452 return ret;
1454 AROS_USERFUNC_EXIT
1458 void CleanupFontInfoClass(void)
1460 if (FontInfoClass)
1462 MUI_DeleteCustomClass(FontInfoClass);
1463 FontInfoClass = NULL;
1467 int InitFontInfoClass(void)
1469 FontInfoClass = MUI_CreateCustomClass(NULL, MUIC_Group, NULL,
1470 sizeof(FontInfoData), UFHN(FontInfoDispatch));
1471 return FontInfoClass != NULL;
1474 /***********************************************************************/
1475 /***********************************************************************/
1476 /***********************************************************************/
1477 /***********************************************************************/
1478 /***********************************************************************/
1480 struct FontWindowData
1482 FT_Face Face;
1484 typedef struct FontWindowData FontWindowData;
1486 #define FONTWINDOW_BASE TAG_USER
1487 #define MUIA_FontWindow_Filename (FONTWINDOW_BASE + 1)
1489 struct MUI_CustomClass *FontWindowClass;
1491 #define FontWindowObject NewObject(FontWindowClass->mcc_Class, NULL //)
1493 AROS_UFH3(void, CloseWinFunc,
1494 AROS_UFHA(struct Hook *, hook, A0),
1495 AROS_UFHA(Object *, app, A2),
1496 AROS_UFHA(Object **, winp, A1))
1498 AROS_USERFUNC_INIT
1500 set(*winp, MUIA_Window_Open, FALSE);
1501 DoMethod(app, OM_REMMEMBER, *winp);
1502 MUI_DisposeObject(*winp);
1504 AROS_USERFUNC_EXIT
1507 struct Hook CloseWinHook = {{NULL, NULL}, UFHN(CloseWinFunc) };
1509 ULONG fwNew(Class *cl, Object *o, struct opSet *msg)
1511 struct opSet method;
1512 struct TagItem tags[4];
1513 STRPTR filename = (STRPTR)GetTagData(MUIA_FontWindow_Filename, (IPTR) NULL, msg->ops_AttrList);
1514 FT_Face face;
1515 FT_Error error;
1516 Object *install, *close, *info, *app;
1518 if (filename == NULL)
1520 DEBUG_FONTWINDOW(dprintf("FontWindow: no filename.\n"));
1521 return 0;
1524 error = FT_New_Face(ftlibrary, filename, 0, &face);
1525 if (error)
1527 DEBUG_FONTWINDOW(dprintf("FontWindow: New_Face error %d.\n", error));
1528 return 0;
1531 app = (Object *)GetTagData(MUIA_UserData, 0,
1532 msg->ops_AttrList);
1533 if (NULL == app)
1535 DEBUG_FONTWINDOW(dprintf("FontWindow: no app ptr.\n"));
1536 return 0;
1539 tags[0].ti_Tag = MUIA_Window_ID;
1540 tags[0].ti_Data = MAKE_ID('F','O','N','T');
1541 tags[1].ti_Tag = MUIA_Window_Title;
1542 tags[1].ti_Data = (ULONG)filename;
1543 tags[2].ti_Tag = MUIA_Window_RootObject;
1544 tags[2].ti_Data = (ULONG)VGroup,
1545 Child, info = FontInfoObject,
1546 MUIA_FontInfo_Filename, filename,
1547 MUIA_FontInfo_Face, face,
1548 End,
1549 Child, HGroup,
1550 Child, install = SimpleButton("_Install"),
1551 Child, RectangleObject,
1552 End,
1553 Child, close = SimpleButton("_Close"),
1554 End,
1555 End;
1556 tags[3].ti_Tag = TAG_MORE;
1557 tags[3].ti_Data = (ULONG)msg->ops_AttrList;
1559 method.MethodID = OM_NEW;
1560 method.ops_AttrList = tags;
1561 method.ops_GInfo = NULL;
1563 o = (Object *)DoSuperMethodA(cl, o, (Msg)&method);
1564 if (o)
1566 FontWindowData *dat = INST_DATA(cl, o);
1567 dat->Face = face;
1569 DoMethod(install, MUIM_Notify, MUIA_Pressed, FALSE,
1570 info, 1, MUIM_FontInfo_WriteFiles);
1571 DoMethod(close, MUIM_Notify, MUIA_Pressed, FALSE,
1572 app, 6, MUIM_Application_PushMethod, app, 3,
1573 MUIM_CallHook, &CloseWinHook, o);
1576 else
1578 FT_Done_Face(face);
1581 DEBUG_FONTWINDOW(dprintf("FontWindow: created object 0x%lx.\n", o));
1583 return (ULONG)o;
1586 ULONG fwDispose(Class *cl, Object *o)
1588 FontWindowData *dat = INST_DATA(cl, o);
1590 DEBUG_FONTWINDOW(dprintf("FontWindow: destroy object 0x%lx\n", o));
1592 FT_Done_Face(dat->Face);
1594 return DoSuperMethod(cl, o, OM_DISPOSE);
1597 AROS_UFH3(ULONG, FontWindowDispatch,
1598 AROS_UFHA(Class *, cl, A0),
1599 AROS_UFHA(Object *, o, A2),
1600 AROS_UFHA(Msg, msg, A1))
1602 AROS_USERFUNC_INIT
1604 ULONG ret;
1606 switch (msg->MethodID)
1608 case OM_NEW:
1609 ret = fwNew(cl, o, (struct opSet *)msg);
1610 break;
1612 case OM_DISPOSE:
1613 ret = fwDispose(cl, o);
1614 break;
1616 default:
1617 ret = DoSuperMethodA(cl, o, msg);
1618 break;
1621 return ret;
1623 AROS_USERFUNC_EXIT
1627 void CleanupFontWindowClass(void)
1629 if (FontWindowClass)
1631 MUI_DeleteCustomClass(FontWindowClass);
1632 FontWindowClass = NULL;
1636 int InitFontWindowClass(void)
1638 FontWindowClass = MUI_CreateCustomClass(NULL, MUIC_Window, NULL,
1639 sizeof(FontWindowData), UFHN(FontWindowDispatch));
1640 return FontWindowClass != NULL;
1643 /***********************************************************************/
1644 /***********************************************************************/
1645 /***********************************************************************/
1646 /***********************************************************************/
1647 /***********************************************************************/
1649 struct FontListData
1651 struct MinList ScanDirTasks;
1653 typedef struct FontListData FontListData;
1655 struct ScanDirTaskInfo
1657 struct MinNode Node;
1658 struct Process *Proc;
1659 STRPTR DirName;
1660 char NameBuf[256];
1661 char Buffer[4096];
1664 #define FONTLIST_MBASE TAG_USER
1665 #define MUIM_FontList_AddDir (FONTLIST_MBASE + 1)
1666 #define MUIM_FontList_AddEntry (FONTLIST_MBASE + 2)
1668 struct MUI_CustomClass *FontListClass;
1670 #define FontListObject NewObject(FontListClass->mcc_Class, NULL //)
1672 struct MUIS_FontList_Entry
1674 STRPTR FileName;
1675 STRPTR FamilyName;
1676 STRPTR StyleName;
1679 AROS_UFH3(APTR, flConstructFunc,
1680 AROS_UFHA(struct Hook *, hook, A0),
1681 AROS_UFHA(APTR, pool, A2),
1682 AROS_UFHA(struct MUIS_FontList_Entry *, entry, A1))
1684 AROS_USERFUNC_INIT
1686 struct MUIS_FontList_Entry *new_entry;
1687 size_t len1 = strlen(entry->FileName) + 1;
1688 size_t len2 = strlen(entry->FamilyName) + 1;
1689 size_t len3 = strlen(entry->StyleName) + 1;
1691 new_entry = AllocPooled(pool, sizeof(*entry) + len1 + len2 + len3);
1692 if (new_entry)
1694 STRPTR p = (STRPTR)(new_entry + 1);
1695 new_entry->FileName = p;
1696 memcpy(p, entry->FileName, len1);
1697 p += len1;
1698 new_entry->FamilyName = p;
1699 memcpy(p, entry->FamilyName, len2);
1700 p += len2;
1701 new_entry->StyleName = p;
1702 memcpy(p, entry->StyleName, len3);
1705 return new_entry;
1707 AROS_USERFUNC_EXIT
1711 struct Hook flConstructHook = {{NULL, NULL}, UFHN(flConstructFunc) };
1713 AROS_UFH3(void, flDestructFunc,
1714 AROS_UFHA(struct Hook *, hook, A0),
1715 AROS_UFHA(APTR, pool, A2),
1716 AROS_UFHA(struct MUIS_FontList_Entry *, entry, A1))
1718 AROS_USERFUNC_INIT
1720 size_t len1 = strlen(entry->FileName) + 1;
1721 size_t len2 = strlen(entry->FamilyName) + 1;
1722 size_t len3 = strlen(entry->StyleName) + 1;
1724 FreePooled(pool, entry, sizeof(*entry) + len1 + len2 + len3);
1726 AROS_USERFUNC_EXIT
1730 struct Hook flDestructHook = {{NULL, NULL}, UFHN(flDestructFunc) };
1732 AROS_UFH3(ULONG, flDisplayFunc,
1733 AROS_UFHA(struct Hook *, hook, A0),
1734 AROS_UFHA(STRPTR *, array, A2),
1735 AROS_UFHA(struct MUIS_FontList_Entry *, entry, A1))
1737 AROS_USERFUNC_INIT
1739 array[0] = entry->FamilyName;
1740 array[1] = entry->StyleName;
1741 return 0;
1743 AROS_USERFUNC_EXIT
1747 struct Hook flDisplayHook = {{NULL, NULL}, UFHN(flDisplayFunc) };
1749 AROS_UFH3(LONG, flCompareFunc,
1750 AROS_UFHA(struct Hook *, hook, A0),
1751 AROS_UFHA(struct MUIS_FontList_Entry *, entry2, A2),
1752 AROS_UFHA(struct MUIS_FontList_Entry *, entry1, A1))
1754 AROS_USERFUNC_INIT
1756 LONG ret = strcmp(entry1->FamilyName, entry2->FamilyName);
1757 if (ret == 0)
1758 ret = strcmp(entry1->StyleName, entry2->StyleName);
1759 return ret;
1761 AROS_USERFUNC_EXIT
1765 struct Hook flCompareHook = {{NULL, NULL}, UFHN(flCompareFunc) };
1768 ULONG flNew(Class *cl, Object *o, struct opSet *msg)
1770 struct opSet method;
1771 struct TagItem tags[8];
1773 tags[0].ti_Tag = MUIA_Frame;
1774 tags[0].ti_Data = MUIV_Frame_InputList;
1775 tags[1].ti_Tag = MUIA_Background;
1776 tags[1].ti_Data = MUII_ListBack;
1777 tags[2].ti_Tag = MUIA_List_ConstructHook;
1778 tags[2].ti_Data = (ULONG)&flConstructHook;
1779 tags[3].ti_Tag = MUIA_List_DestructHook;
1780 tags[3].ti_Data = (ULONG)&flDestructHook;
1781 tags[4].ti_Tag = MUIA_List_DisplayHook;
1782 tags[4].ti_Data = (ULONG)&flDisplayHook;
1783 tags[4].ti_Tag = MUIA_List_DisplayHook;
1784 tags[4].ti_Data = (ULONG)&flDisplayHook;
1785 tags[5].ti_Tag = MUIA_List_CompareHook;
1786 tags[5].ti_Data = (ULONG)&flCompareHook;
1787 tags[6].ti_Tag = MUIA_List_Format;
1788 tags[6].ti_Data = (ULONG)",";
1789 tags[7].ti_Tag = TAG_MORE;
1790 tags[7].ti_Data = (ULONG)msg->ops_AttrList;
1792 method.MethodID = OM_NEW;
1793 method.ops_AttrList = tags;
1794 method.ops_GInfo = NULL;
1796 o = (Object *)DoSuperMethodA(cl, o, (Msg)&method);
1797 if (o)
1799 FontListData *dat = INST_DATA(cl, o);
1800 NewList((struct List *) &dat->ScanDirTasks);
1803 DEBUG_FONTWINDOW(dprintf("FontList: created object 0x%lx.\n", o));
1805 return (ULONG)o;
1809 ULONG flDispose(Class *cl, Object *o, Msg msg)
1811 FontListData *dat = INST_DATA(cl, o);
1812 struct ScanDirTaskInfo *info;
1813 BOOL done;
1817 done = TRUE;
1819 Forbid();
1820 for (info = (APTR)dat->ScanDirTasks.mlh_Head; info->Node.mln_Succ; info = (APTR)info->Node.mln_Succ)
1822 done = FALSE;
1823 Signal(&info->Proc->pr_Task, SIGBREAKF_CTRL_C);
1825 Permit();
1827 if (!done)
1828 Wait(SIGBREAKF_CTRL_F);
1830 while (!done);
1832 return DoSuperMethodA(cl, o, msg);
1836 struct MUIP_FontList_AddDir
1838 ULONG MethodID;
1839 STRPTR DirName;
1842 struct ScanDirTaskInfo *_pass_info;
1843 Object *_pass_app;
1844 struct Task *_pass_parent;
1845 Object *_pass_fl;
1847 void ScanDirTask(void)
1849 struct ScanDirTaskInfo *info = _pass_info;
1850 Object *app = _pass_app;
1851 struct Task *parent = _pass_parent;
1852 Object *fl = _pass_fl;
1853 BPTR lock;
1854 struct ExAllControl *eac;
1855 struct ExAllData *ead;
1856 ULONG more;
1857 BPTR olddir;
1858 FT_Library ftlibrary;
1860 #warning FIXME: Possible thread race conflicts not checked !!!
1861 void *test = GetIntETask(parent)->iet_acpd;
1862 GetIntETask(FindTask(NULL))->iet_acpd = test;
1864 Signal(parent, SIGBREAKF_CTRL_F);
1866 DEBUG_ADDDIR(dprintf("flScanDirTask: dir <%s>\n", info->DirName));
1868 if (FT_Init_FreeType(&ftlibrary) == 0)
1870 DEBUG_ADDDIR(dprintf("flScanDirTask: ftlibrary 0x%x\n", ftlibrary));
1872 lock = Lock(info->DirName, ACCESS_READ);
1873 if (lock)
1875 DEBUG_ADDDIR(dprintf("flScanDirTask: lock 0x%lx\n", lock));
1877 olddir = CurrentDir(lock);
1879 eac = AllocDosObject(DOS_EXALLCONTROL, NULL);
1880 if (eac)
1882 DEBUG_ADDDIR(dprintf("flScanDirTask: eac 0x%lx\n", eac));
1884 eac->eac_LastKey = 0;
1888 more = ExAll(lock, (struct ExAllData *) info->Buffer, sizeof(info->Buffer), ED_NAME, eac);
1890 DEBUG_ADDDIR(dprintf("flScanDirTask: more %d entries %d\n", more, eac->eac_Entries));
1893 if (!more && IoErr() != ERROR_NO_MORE_ENTRIES)
1895 DEBUG_ADDDIR(dprintf("flScanDirTask: err %d\n", IoErr()));
1896 break;
1899 if (eac->eac_Entries == 0)
1900 continue;
1902 ead = (APTR)info->Buffer;
1906 FT_Face face;
1907 FT_Error error;
1909 DEBUG_ADDDIR(dprintf("flScanDirTask: ead 0x%x name %x <%s>\n", ead, ead->ed_Name, ead->ed_Name));
1910 error = FT_New_Face(ftlibrary, ead->ed_Name, 0, &face);
1911 DEBUG_ADDDIR(dprintf("flScanDirTask: error %d\n", error));
1912 if (error == 0)
1914 struct MUIS_FontList_Entry *entry;
1915 size_t len1, len2, len3;
1917 DEBUG_ADDDIR(dprintf("flScanDirTask: family 0x <%s> style 0x%x <%s>\n", face->family_name, face->family_name, face->style_name, face->style_name));
1919 strncpy(info->NameBuf, info->DirName, sizeof(info->NameBuf));
1920 AddPart(info->NameBuf, ead->ed_Name, sizeof(info->NameBuf));
1922 len1 = strlen(info->NameBuf) + 1;
1923 len2 = strlen(face->family_name) + 1;
1924 len3 = strlen(face->style_name) + 1;
1926 entry = AllocVec(sizeof(*entry) + len1 + len2 + len3, MEMF_PUBLIC);
1927 if (entry)
1929 char *p = (char *)(entry + 1);
1930 entry->FileName = p;
1931 memcpy(p, info->NameBuf, len1);
1932 p += len1;
1933 entry->FamilyName = p;
1934 memcpy(p, face->family_name, len2);
1935 p += len2;
1936 entry->StyleName = p;
1937 memcpy(p, face->style_name, len3);
1939 if (!DoMethod(app, MUIM_Application_PushMethod,
1940 fl, 2, MUIM_FontList_AddEntry, entry))
1941 FreeVec(entry);
1944 FT_Done_Face(face);
1947 ead = ead->ed_Next;
1949 while (ead);
1951 while (more);
1953 DEBUG_ADDDIR(dprintf("flScanDirTask: done\n"));
1955 FreeDosObject(DOS_EXALLCONTROL, eac);
1958 CurrentDir(olddir);
1959 UnLock(lock);
1962 FT_Done_FreeType(ftlibrary);
1965 Forbid();
1966 REMOVE(&info->Node);
1967 FreeVec(info);
1968 Signal(parent, SIGBREAKF_CTRL_F);
1972 ULONG flAddDir(Class *cl, Object *o, struct MUIP_FontList_AddDir *msg)
1974 FontListData *dat = INST_DATA(cl, o);
1975 struct ScanDirTaskInfo *info;
1976 int dirname_len = strlen(msg->DirName) + 1;
1978 info = AllocVec(sizeof(*info) + dirname_len, MEMF_CLEAR | MEMF_PUBLIC);
1979 if (info)
1981 info->DirName = (STRPTR)(info + 1);
1982 memcpy(info->DirName, msg->DirName, dirname_len);
1984 _pass_info = info;
1985 _pass_app = app;
1986 _pass_parent = FindTask(NULL);
1987 _pass_fl = o;
1988 Forbid();
1989 info->Proc = CreateNewProcTags(
1990 NP_Entry, ScanDirTask,
1991 TAG_END);
1992 if (info->Proc)
1994 ADDTAIL((APTR)&dat->ScanDirTasks, (APTR)info);
1995 Permit();
1997 Wait(SIGBREAKF_CTRL_F);
1998 return TRUE;
2001 Permit();
2002 FreeVec(info);
2005 return FALSE;
2009 struct MUIP_FontList_AddEntry
2011 ULONG MethodID;
2012 struct MUIS_FontList_Entry *Entry;
2015 ULONG flAddEntry(Class *cl, Object *o, struct MUIP_FontList_AddEntry *msg)
2017 #ifdef __AROS__
2018 #warning "MUIV_List_Insert_Sorted not yet working in AROS"
2019 DoMethod(o, MUIM_List_InsertSingle, msg->Entry, MUIV_List_Insert_Bottom);
2020 #else
2021 DoMethod(o, MUIM_List_InsertSingle, msg->Entry, MUIV_List_Insert_Sorted);
2022 #endif
2023 FreeVec(msg->Entry);
2024 return TRUE;
2028 AROS_UFH3(ULONG, FontListDispatch,
2029 AROS_UFHA(Class *, cl, A0),
2030 AROS_UFHA(Object *, o, A2),
2031 AROS_UFHA(Msg, msg, A1))
2033 AROS_USERFUNC_INIT
2035 ULONG ret;
2037 switch (msg->MethodID)
2039 case OM_NEW:
2040 ret = flNew(cl, o, (struct opSet *)msg);
2041 break;
2043 case OM_DISPOSE:
2044 ret = flDispose(cl, o, msg);
2045 break;
2047 case MUIM_FontList_AddDir:
2048 ret = flAddDir(cl, o, (struct MUIP_FontList_AddDir *)msg);
2049 break;
2051 case MUIM_FontList_AddEntry:
2052 ret = flAddEntry(cl, o, (struct MUIP_FontList_AddEntry *)msg);
2053 break;
2055 default:
2056 ret = DoSuperMethodA(cl, o, msg);
2057 break;
2060 return ret;
2062 AROS_USERFUNC_EXIT
2066 void CleanupFontListClass(void)
2068 if (FontListClass)
2070 MUI_DeleteCustomClass(FontListClass);
2071 FontListClass = NULL;
2075 int InitFontListClass(void)
2077 FontListClass = MUI_CreateCustomClass(NULL, MUIC_List, NULL,
2078 sizeof(FontListData), UFHN(FontListDispatch));
2079 return FontListClass != NULL;
2082 /***********************************************************************/
2083 /***********************************************************************/
2084 /***********************************************************************/
2085 /***********************************************************************/
2086 /***********************************************************************/
2088 void Cleanup(void)
2090 CleanupFontListClass();
2091 CleanupFontWindowClass();
2092 CleanupFontInfoClass();
2093 CleanupFontBitmapClass();
2095 FT_Done_Library(ftlibrary);
2097 if (codesetsupported)
2098 CodesetsFreeA(codesetsupported, NULL);
2099 FreeVec(codesetentries);
2101 UnLock(destdir);
2104 int Init(void)
2106 FT_Error error;
2108 error = FT_Init_FreeType(&ftlibrary);
2109 if (error != 0)
2111 DEBUG_MAIN(dprintf("Init_FreeType error %d\n", error));
2112 return 0;
2115 if (!InitFontBitmapClass() ||
2116 !InitFontInfoClass() ||
2117 !InitFontWindowClass() ||
2118 !InitFontListClass())
2120 DEBUG_MAIN(dprintf("Can't create custom classes.\n"));
2121 return 0;
2124 destdir = Lock("Fonts:", ACCESS_READ);
2126 return 1;
2130 void SetDefaultCodePage(void)
2132 int k;
2133 for (k = 0; k < 256; ++k)
2134 codepage[k] = k;
2137 BOOL IsDefaultCodePage(void)
2139 int k;
2140 for (k = 0; k < 256; ++k)
2141 if (codepage[k] != k)
2142 return FALSE;
2143 return TRUE;
2146 BOOL LoadCodePage(int entryindex)
2148 SetDefaultCodePage();
2150 if (entryindex == 0) // 1st entry means keep code page
2152 return TRUE;
2155 struct codeset * cs = CodesetsFind(codesetentries[entryindex],
2156 CSA_FallbackToDefault, FALSE, TAG_DONE);
2158 if (cs)
2160 LONG index;
2161 for (index = 0 ; index < 256 ; index++)
2163 codepage[index] = (UWORD)cs->table[index].ucs4;
2165 return TRUE;
2168 return FALSE;
2172 #define ID_SetSrc 1
2173 #define ID_SetDestDir 2
2174 #define ID_ShowFont 3
2175 #define ID_SetCodePage 4
2177 int main(void)
2179 int ret = RETURN_FAIL;
2180 Object *win, *src, *dest, *fontlist, *fontlv, *codepagecycle, *quit;
2181 int countfrom, countto;
2183 if (!Init())
2184 return RETURN_FAIL;
2186 SetDefaultCodePage();
2188 codesetsupported = CodesetsSupportedA(NULL); // Available codesets
2189 countfrom = 0;
2190 while (codesetsupported[countfrom])
2192 countfrom++;
2194 codesetentries = AllocVec((sizeof (STRPTR)) * (countfrom + 2), MEMF_CLEAR);
2195 if (!codesetentries)
2197 Cleanup();
2198 return RETURN_FAIL;
2200 codesetentries[0] = "----";
2201 countfrom = 0;
2202 countto = 1;
2203 while (codesetsupported[countfrom])
2205 if (strcmp(codesetsupported[countfrom], "UTF-8"))
2207 codesetentries[countto] = codesetsupported[countfrom];
2208 countto++;
2210 countfrom++;
2212 app = ApplicationObject,
2213 MUIA_Application_Title, "FTManager",
2214 MUIA_Application_Version, "$VER: FTManager 1.2 (4.12.2007)",
2215 MUIA_Application_Copyright, "Copyright 2002-2003 by Emmanuel Lesueur",
2216 MUIA_Application_Author, "Emmanuel Lesueur",
2217 MUIA_Application_Description, "FreeType font manager",
2218 MUIA_Application_Base, "FTMANAGER",
2219 SubWindow, win = WindowObject,
2220 MUIA_Window_ID, MAKE_ID('F','T','2','M'),
2221 MUIA_Window_Title, "FreeType Font Manager",
2222 MUIA_Window_Width, 400,
2223 MUIA_Window_RootObject,VGroup,
2224 Child, fontlv = ListviewObject,
2225 MUIA_Listview_List, fontlist = FontListObject,
2226 End,
2227 End,
2228 Child, ColGroup(2),
2229 Child, Label2("Source"),
2230 Child, PopaslObject,
2231 MUIA_Popasl_Type, ASL_FileRequest,
2232 MUIA_Popstring_String, src = StringObject,
2233 StringFrame,
2234 MUIA_String_Contents, "Fonts:TrueType",
2235 MUIA_String_AdvanceOnCR, TRUE,
2236 MUIA_CycleChain, TRUE,
2237 End,
2238 MUIA_Popstring_Button, PopButton(MUII_PopDrawer),
2239 ASLFR_RejectIcons, TRUE,
2240 ASLFR_DrawersOnly, TRUE,
2241 End,
2242 Child, Label2("Destination"),
2243 Child, PopaslObject,
2244 MUIA_Popasl_Type, ASL_FileRequest,
2245 MUIA_Popstring_String, dest = StringObject,
2246 StringFrame,
2247 MUIA_String_Contents, "Fonts:",
2248 MUIA_String_AdvanceOnCR, TRUE,
2249 MUIA_CycleChain, TRUE,
2250 End,
2251 MUIA_Popstring_Button, PopButton(MUII_PopDrawer),
2252 ASLFR_DoSaveMode, TRUE,
2253 ASLFR_DrawersOnly, TRUE,
2254 ASLFR_RejectIcons, TRUE,
2255 End,
2256 Child, Label2("Codepage"),
2257 Child, codepagecycle = CycleObject,
2258 MUIA_Cycle_Entries, codesetentries,
2259 End,
2260 End,
2261 Child, quit = SimpleButton("_Quit"),
2262 End,
2263 End,
2264 End;
2266 if (app)
2268 ULONG t;
2270 ret = RETURN_OK;
2272 DoMethod(src, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
2273 fontlist, 2, MUIM_FontList_AddDir, MUIV_TriggerValue);
2275 DoMethod(dest, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
2276 app, 2, MUIM_Application_ReturnID, ID_SetDestDir);
2278 DoMethod(codepagecycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
2279 app, 2, MUIM_Application_ReturnID, ID_SetCodePage);
2281 DoMethod(fontlv, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
2282 app, 2, MUIM_Application_ReturnID, ID_ShowFont);
2284 DoMethod(win, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
2285 app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
2287 DoMethod(quit, MUIM_Notify, MUIA_Pressed, FALSE,
2288 app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
2290 DoMethod(fontlist, MUIM_FontList_AddDir, XGET(src, MUIA_String_Contents));
2292 set(win, MUIA_Window_Open, TRUE);
2293 get(win, MUIA_Window_Open, &t);
2294 if (t)
2296 BOOL running = TRUE;
2297 ULONG sigs = 0;
2298 ULONG id;
2302 id = DoMethod(app, MUIM_Application_NewInput, &sigs);
2303 switch (id)
2305 case MUIV_Application_ReturnID_Quit:
2306 running = FALSE;
2307 sigs = 0;
2308 break;
2310 case ID_SetDestDir:
2312 STRPTR name;
2313 BPTR newdir;
2315 get(dest, MUIA_String_Contents, &name);
2316 newdir = Lock(name, ACCESS_READ);
2317 if (newdir)
2319 UnLock(destdir);
2320 destdir = newdir;
2323 break;
2325 case ID_ShowFont:
2327 struct MUIS_FontList_Entry *entry;
2328 Object *w;
2330 DoMethod(fontlist, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &entry);
2332 w = FontWindowObject,
2333 MUIA_FontWindow_Filename, entry->FileName,
2334 MUIA_UserData, app,
2335 End;
2337 if (w)
2339 DoMethod(w, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
2340 app, 6, MUIM_Application_PushMethod, app, 3,
2341 MUIM_CallHook, &CloseWinHook, w);
2343 DoMethod(app, OM_ADDMEMBER, w);
2344 set(w, MUIA_Window_Open, TRUE);
2345 get(w, MUIA_Window_Open, &t);
2346 if (!t)
2348 MUI_DisposeObject(w);
2353 break;
2355 case ID_SetCodePage:
2357 IPTR entry;
2358 get(codepagecycle, MUIA_Cycle_Active, &entry);
2359 LoadCodePage(entry);
2361 break;
2364 if (sigs)
2366 sigs = Wait(sigs | SIGBREAKF_CTRL_C);
2367 if (sigs & SIGBREAKF_CTRL_C)
2369 running = FALSE;
2373 while (running);
2375 else
2377 printf("Can't open window.\n");
2380 MUI_DisposeObject(app);
2382 else
2384 printf("Can't create MUI application.\n");
2387 Cleanup();
2389 return ret;