Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / system / ftmanager / ftmanager.c
blob620f1923cdb005c65b03372aeaa740fb8de4682f
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 struct Library *CodesetsBase;
101 Object *app;
102 FT_Library ftlibrary;
103 BPTR destdir;
104 UWORD codepage[256];
105 STRPTR *codesetentries;
106 STRPTR *codesetsupported;
107 BOOL IsDefaultCodePage(void);
109 /***********************************************************************/
110 /***********************************************************************/
111 /***********************************************************************/
112 /***********************************************************************/
113 /***********************************************************************/
115 struct FontBitmapData
117 int Width, Height;
118 struct BitMap BitMap;
119 struct BitMap *GrayBitMap;
121 typedef struct FontBitmapData FontBitmapData;
123 #define FONTBITMAP_BASE TAG_USER
124 #define MUIA_FontBitmap_Filename (FONTBITMAP_BASE + 1)
125 #define MUIA_FontBitmap_OTags (FONTBITMAP_BASE + 2)
126 #define MUIA_FontBitmap_Size (FONTBITMAP_BASE + 3)
127 #define MUIA_FontBitmap_String (FONTBITMAP_BASE + 4)
128 #define MUIA_FontBitmap_Gray (FONTBITMAP_BASE + 5)
130 struct MUI_CustomClass *FontBitmapClass;
132 #define FontBitmapObject NewObject(FontBitmapClass->mcc_Class, NULL //)
135 ULONG fbNew(Class *cl, Object *o, struct opSet *msg)
137 struct opSet method;
138 struct TagItem tags[5];
139 STRPTR filename = (STRPTR)GetTagData(MUIA_FontBitmap_Filename, (IPTR) NULL, msg->ops_AttrList);
140 STRPTR string = (STRPTR)GetTagData(MUIA_FontBitmap_String, (ULONG) "?", msg->ops_AttrList);
141 struct TagItem *otags = (struct TagItem *)GetTagData(MUIA_FontBitmap_OTags,
142 (IPTR) NULL, msg->ops_AttrList);
143 struct
145 struct GlyphMap *glyph;
146 int x;
147 int y;
148 } *info;
149 APTR engine;
150 struct BitMap bitmap;
151 struct BitMap *gray_bitmap = NULL;
152 int width, height;
153 int length = strlen(string);
154 int x, y, k;
155 int xmin, xmax, ymin, ymax;
156 int space_width, size, gray;
157 int previous;
158 Tag tag;
160 if (filename == NULL)
162 DEBUG_FONTBITMAP(dprintf("FontBitmap: no filename.\n"));
163 return 0;
166 engine = OpenEngine();
167 if (engine == NULL)
169 DEBUG_FONTBITMAP(dprintf("FontBitmap: no engine.\n"));
170 return 0;
173 size = GetTagData(MUIA_FontBitmap_Size, 30, msg->ops_AttrList);
174 gray = GetTagData(MUIA_FontBitmap_Gray, FALSE, msg->ops_AttrList);
176 SetInfo(engine,
177 OT_OTagList, (ULONG) otags,
178 OT_DeviceDPI, 72 | (72 << 16),
179 OT_PointHeight, size << 16,
180 TAG_END);
182 space_width = (int)(GetTagData(OT_SpaceWidth, 0, otags) / 65536.0 * size) ;
184 info = AllocVec(length * sizeof(*info), MEMF_CLEAR);
185 if (info == NULL)
187 DEBUG_FONTBITMAP(dprintf("FontBitmap: can't alloc glyphs.\n"));
188 length = 0;
191 x = 0;
192 y = 0;
193 previous = 0;
194 xmin = ymin = 0x7fffffff;
195 xmax = ymax = -0x80000000;
196 tag = gray ? OT_GlyphMap8Bit : OT_GlyphMap;
198 for (k = 0; k < length; ++k)
200 int code = string[k];
201 int x1, y1, x2, y2;
202 struct GlyphMap *g;
204 if (previous)
206 ULONG kerning;
208 SetInfo(engine,
209 OT_GlyphCode, previous,
210 OT_GlyphCode2, code,
211 TAG_END);
212 ObtainInfo(engine,
213 OT_TextKernPair, (ULONG)&kerning,
214 TAG_END);
216 x -= (int)(kerning / 65536.0 * size);
219 info[k].x = x;
220 info[k].y = y;
222 SetInfo(engine,
223 OT_GlyphCode, code,
224 TAG_END);
225 ObtainInfo(engine,
226 tag, (ULONG)&info[k].glyph,
227 TAG_END);
229 g = info[k].glyph;
231 if (!g)
233 x += space_width;
234 continue;
237 x1 = x - g->glm_X0 + g->glm_BlackLeft;
238 y1 = y - g->glm_Y0 + g->glm_BlackTop;
239 x2 = x1 + g->glm_BlackWidth;
240 y2 = y1 + g->glm_BlackHeight;
242 if (x1 < xmin)
243 xmin = x1;
244 if (y1 < ymin)
245 ymin = y1;
246 if (x2 > xmax)
247 xmax = x2;
248 if (y2 > ymax)
249 ymax = y2;
251 x += g->glm_X1 - g->glm_X0;
252 y += g->glm_Y1 - g->glm_Y0;
254 previous = code;
257 width = xmax - xmin + 1;
258 height = ymax - ymin + 1;
260 DEBUG_FONTBITMAP(dprintf("FontBitmap: bbox %d %d %d %d\n", xmin, ymin, xmax, ymax));
261 DEBUG_FONTBITMAP(dprintf("FontBitmap: width %d height %d\n", width, height));
263 if (width > 0 && height > 0 && width < 32000 && height < 32000)
265 if (gray)
267 UBYTE *array;
268 int width1 = (width + 15) & ~15;
270 array = AllocVec(width1 * height, MEMF_CLEAR);
271 if (array)
273 for (k = 0; k < length; ++k)
275 struct GlyphMap *g = info[k].glyph;
276 int x1, x2, y1, y2;
277 UBYTE *p;
279 if (!g)
281 x += space_width;
282 continue;
285 x = info[k].x - xmin;
286 y = info[k].y - ymin;
287 x -= g->glm_X0;
288 y -= g->glm_Y0;
289 x += g->glm_BlackLeft;
290 y += g->glm_BlackTop;
292 p = g->glm_BitMap;
293 x1 = x;
294 y1 = y;
295 x2 = x + g->glm_BlackWidth;
296 y2 = y + g->glm_BlackHeight;
298 if (x1 > width || x2 < 0 || y1 > height || y2 < 0)
299 continue;
301 if (x1 < 0)
303 p -= x1;
304 x1 = 0;
306 if (y1 < 0)
308 p -= y1 * g->glm_BMModulo;
309 y1 = 0;
311 if (x2 > width)
313 x2 = width;
315 if (y2 > height)
317 y2 = height;
320 while (y1 < y2)
322 int x;
324 for (x = x1; x < x2; ++x)
326 int t = array[width1 * y1 + x] + p[x - x1];
327 if (t > 255)
328 t = 255;
329 array[width1 * y1 + x] = t;
331 p += g->glm_BMModulo;
332 ++y1;
336 gray_bitmap = AllocBitMap(width, height, 8, 0, NULL);
337 if (gray_bitmap)
339 struct RastPort rp, tmp_rp;
341 InitRastPort(&rp);
342 InitRastPort(&tmp_rp);
344 rp.BitMap = gray_bitmap;
345 tmp_rp.BitMap = AllocBitMap(width, 1, 8, 0, NULL);
347 if (tmp_rp.BitMap)
349 WritePixelArray8(&rp,
352 width - 1,
353 height - 1,
354 array,
355 &tmp_rp);
356 FreeBitMap(tmp_rp.BitMap);
360 FreeVec(array);
363 else
365 InitBitMap(&bitmap, 1, width, height);
366 bitmap.Planes[0] = AllocRaster(width, height);
368 if (bitmap.Planes[0])
370 struct RastPort rp;
372 InitRastPort(&rp);
373 rp.BitMap = &bitmap;
374 SetRast(&rp, 0);
375 SetAPen(&rp, 1);
376 SetDrMd(&rp, JAM1);
378 for (k = 0; k < length; ++k)
380 struct GlyphMap *g = info[k].glyph;
382 if (!g)
383 continue;
385 x = info[k].x - xmin;
386 y = info[k].y - ymin;
387 x -= g->glm_X0;
388 y -= g->glm_Y0;
389 x += g->glm_BlackLeft;
390 y += g->glm_BlackTop;
392 /* glm_BitMap is not in chip mem.
393 * Oh well.
395 BltTemplate((const PLANEPTR)(g->glm_BitMap +
396 g->glm_BMModulo *
397 g->glm_BlackTop),
398 g->glm_BlackLeft,
399 g->glm_BMModulo,
400 &rp,
401 x, y,
402 g->glm_BlackWidth,
403 g->glm_BlackHeight);
408 tags[0].ti_Tag = MUIA_Bitmap_Width;
409 tags[0].ti_Data = width;
410 tags[1].ti_Tag = MUIA_Bitmap_Height;
411 tags[1].ti_Data = height;
412 tags[2].ti_Tag = MUIA_FixWidth;
413 tags[2].ti_Data = width;
414 tags[3].ti_Tag = MUIA_FixHeight;
415 tags[3].ti_Data = height;
416 tags[4].ti_Tag = TAG_MORE;
417 tags[4].ti_Data = (ULONG)msg->ops_AttrList;
419 method.MethodID = OM_NEW;
420 method.ops_AttrList = tags;
421 method.ops_GInfo = NULL;
423 o = (Object *)DoSuperMethodA(cl, o, (Msg)&method);
425 if (o)
427 FontBitmapData *dat = INST_DATA(cl, o);
429 dat->Width = width;
430 dat->Height = height;
431 dat->GrayBitMap = gray_bitmap;
433 if (gray)
435 static ULONG colors[256 * 3];
436 static BOOL init;
438 if (!init)
440 int k;
441 ULONG *p = colors;
442 for (k = 256; --k >= 0; p += 3)
444 p[0] = p[1] = p[2] = k * 0x01010101;
446 init = TRUE;
449 SetAttrs(o,
450 MUIA_Bitmap_Bitmap, gray_bitmap,
451 MUIA_Bitmap_SourceColors, colors,
452 TAG_END);
454 else
456 dat->BitMap = bitmap;
457 set(o, MUIA_Bitmap_Bitmap, &dat->BitMap);
460 else
462 if (gray)
464 FreeBitMap(gray_bitmap);
466 else if (bitmap.Planes[0])
468 FreeRaster(bitmap.Planes[0], width, height);
472 else
474 o = NULL;
477 for (k = 0; k < length; ++k)
479 if (info[k].glyph)
481 ReleaseInfo(engine,
482 tag, (ULONG)info[k].glyph,
483 TAG_END);
487 FreeVec(info);
489 CloseEngine(engine);
491 DEBUG_FONTBITMAP(dprintf("FontBitmap: created object 0x%lx.\n", o));
493 return (ULONG)o;
496 ULONG fbDispose(Class *cl, Object *o)
498 FontBitmapData *dat = INST_DATA(cl, o);
500 DEBUG_FONTBITMAP(dprintf("FontBitmap: destroy object 0x%lx.\n", o));
502 if (dat->GrayBitMap)
504 FreeBitMap(dat->GrayBitMap);
506 else if (dat->BitMap.Planes[0])
508 FreeRaster(dat->BitMap.Planes[0], dat->Width, dat->Height);
511 return DoSuperMethod(cl, o, OM_DISPOSE);
514 AROS_UFH3(ULONG, FontBitmapDispatch,
515 AROS_UFHA(Class *, cl, A0),
516 AROS_UFHA(Object *, o, A2),
517 AROS_UFHA(Msg, msg, A1))
519 AROS_USERFUNC_INIT
521 ULONG ret;
523 switch (msg->MethodID)
525 case OM_NEW:
526 ret = fbNew(cl, o, (struct opSet *)msg);
527 break;
529 case OM_DISPOSE:
530 ret = fbDispose(cl, o);
531 break;
533 default:
534 ret = DoSuperMethodA(cl, o, msg);
535 break;
538 return ret;
540 AROS_USERFUNC_EXIT
544 void CleanupFontBitmapClass(void)
546 if (FontBitmapClass)
548 MUI_DeleteCustomClass(FontBitmapClass);
549 FontBitmapClass = NULL;
553 int InitFontBitmapClass(void)
555 FontBitmapClass = MUI_CreateCustomClass(NULL, MUIC_Bitmap, NULL,
556 sizeof(FontBitmapData), UFHN(FontBitmapDispatch));
557 return FontBitmapClass != NULL;
560 /***********************************************************************/
561 /***********************************************************************/
562 /***********************************************************************/
563 /***********************************************************************/
564 /***********************************************************************/
566 struct FontInfoData
568 STRPTR Filename;
569 FT_Face Face;
570 Object *AttachedFile;
571 Object *Name;
572 Object *YSizeFactorHigh;
573 Object *YSizeFactorLow;
574 Object *StemWeight;
575 Object *SlantStyle;
576 Object *HorizStyle;
577 Object *Family;
578 Object *Fixed;
579 Object *Serif;
580 //Object *AlgoStyle;
581 Object *FaceNum;
582 Object *Metric;
583 Object *BBoxYMin;
584 Object *BBoxYMax;
585 Object *SpaceWidth;
586 Object *Preview;
587 Object *PreviewGroup;
588 Object *Gray;
589 Object *TestSize;
590 Object *TestString;
591 struct TagItem OTags[26];
592 UWORD AvailSizes[OT_MAXAVAILSIZES];
594 typedef struct FontInfoData FontInfoData;
596 #define FONTINFO_BASE TAG_USER
597 #define MUIA_FontInfo_Filename (FONTINFO_BASE + 1)
598 #define MUIA_FontInfo_Face (FONTINFO_BASE + 2)
600 #define FONTINFO_MBASE TAG_USER
601 #define MUIM_FontInfo_UpdatePreview (FONTINFO_MBASE + 1)
602 #define MUIM_FontInfo_SetOTags (FONTINFO_MBASE + 2)
603 #define MUIM_FontInfo_WriteFiles (FONTINFO_MBASE + 3)
605 struct MUI_CustomClass *FontInfoClass;
607 #define FontInfoObject NewObject(FontInfoClass->mcc_Class, NULL //)
609 struct CycleToStringP
611 Object *String;
612 int NumValues;
613 const UBYTE *Values;
616 AROS_UFH3(void, CycleToString,
617 AROS_UFHA(struct Hook *, hook, A0),
618 AROS_UFHA(Object *, cycle, A2),
619 AROS_UFHA(struct CycleToStringP *, p, A1))
621 AROS_USERFUNC_INIT
623 ULONG entry;
624 Object *str = p->String;
625 get(cycle, MUIA_Cycle_Active, &entry);
626 if (entry == p->NumValues)
628 set(str, MUIA_Disabled, FALSE);
630 else
632 SetAttrs(str,
633 MUIA_Disabled, TRUE,
634 MUIA_String_Integer, p->Values[entry],
635 TAG_END);
638 AROS_USERFUNC_EXIT
642 struct Hook CycleToStringHook = { {NULL, NULL}, UFHN(CycleToString) };
645 struct IntegerBoundsP
647 LONG Min;
648 LONG Max;
651 AROS_UFH3(void, IntegerBounds,
652 AROS_UFHA(struct Hook *, hook, A0),
653 AROS_UFHA(Object *, obj, A2),
654 AROS_UFHA(struct IntegerBoundsP *, p, A1))
656 AROS_USERFUNC_INIT
658 LONG t;
659 get(obj, MUIA_String_Integer, &t);
660 if (t < p->Min)
662 set(obj, MUIA_String_Integer, p->Min);
664 else if (t > p->Max)
666 set(obj, MUIA_String_Integer, p->Max);
669 AROS_USERFUNC_EXIT
673 struct Hook IntegerBoundsHook = { {NULL, NULL}, UFHN(IntegerBounds) };
676 AROS_UFH3(void, Metric,
677 AROS_UFHA(struct Hook *, hook, A0),
678 AROS_UFHA(Object *, obj, A2),
679 AROS_UFHA(Object **, p, A1))
681 AROS_USERFUNC_INIT
683 ULONG t;
684 ULONG state;
685 int k;
687 get(obj, MUIA_Cycle_Active, &t);
688 state = t != 5;
689 for (k = 0; k < 2; ++k)
691 set(p[k], MUIA_Disabled, state);
694 AROS_USERFUNC_EXIT
698 struct Hook MetricHook = { {NULL, NULL}, UFHN(Metric) };
701 ULONG fiNew(Class *cl, Object *o, struct opSet *msg)
703 struct opSet method;
704 struct TagItem tags[3];
705 STRPTR filename = (STRPTR)GetTagData(MUIA_FontInfo_Filename, (IPTR) NULL, msg->ops_AttrList);
706 FT_Face face = (FT_Face)GetTagData(MUIA_FontInfo_Face, (IPTR) NULL, msg->ops_AttrList);
707 TT_Postscript *postscript;
708 TT_OS2 *os2;
709 Object *name, *attached_file, *size_factor_low, *size_factor_high;
710 Object *stem_weight, *slant_style, *horiz_style, *stem_weight_cycle, *horiz_style_cycle;
711 Object *family, *fixed, /**algo_style,*/ *face_num, *preview, *preview_group;
712 Object *gray, *test_string, *test_size, *serif, *space_width;
713 Object *metric, *bbox_ymin, *bbox_ymax;
714 char name_buf[27];
715 int k, l;
716 const char *q, *r;
718 static const char * const stem_weight_names[] =
720 "UltraThin",
721 "ExtraThin",
722 "Thin",
723 "ExtraLight",
724 "Light",
725 "DemiLight",
726 "SemiLight",
727 "Book",
728 "Medium",
729 "SemiBold",
730 "DemiBold",
731 "Bold",
732 "ExtraBold",
733 "Black",
734 "ExtraBlack",
735 "UltraBlack",
736 "Custom",
737 NULL
739 static const UBYTE stem_weight_values[] =
741 OTS_UltraThin,
742 OTS_ExtraThin,
743 OTS_Thin,
744 OTS_ExtraLight,
745 OTS_Light,
746 OTS_DemiLight,
747 OTS_SemiLight,
748 OTS_Book,
749 OTS_Medium,
750 OTS_SemiBold,
751 OTS_DemiBold,
752 OTS_Bold,
753 OTS_ExtraBold,
754 OTS_Black,
755 OTS_ExtraBlack,
756 OTS_UltraBlack,
759 static const char * const slant_style_names[] =
761 "Upright",
762 "Italic",
763 "LeftItalic",
764 NULL
767 static const char * const horiz_style_names[] =
769 "UltraCompressed",
770 "ExtraCompressed",
771 "Compressed",
772 "Condensed",
773 "Normal",
774 "SemiExpanded",
775 "Expanded",
776 "ExtraExpanded",
777 "Custom",
778 NULL
780 static const UBYTE horiz_style_values[] =
782 OTH_UltraCompressed,
783 OTH_ExtraCompressed,
784 OTH_Compressed,
785 OTH_Condensed,
786 OTH_Normal,
787 OTH_SemiExpanded,
788 OTH_Expanded,
789 OTH_ExtraExpanded,
792 static const char *metric_names[] =
794 "Global bounding box",
795 "Raw font metric",
796 "Ascender",
797 "Typo ascender",
798 "USWin ascender",
799 "Custom bounding box",
800 //"Bitmap size",
801 NULL,
804 if (!filename || !face)
806 DEBUG_FONTINFO(dprintf("FontInfo: filename 0x%x face 0x%x\n", filename, face));
807 return 0;
810 q = face->family_name;
811 r = face->style_name;
812 k = 0;
813 l = -1;
814 while (k < sizeof(name_buf) - 1)
816 while (*q == ' ')
817 ++q;
818 if (!*q)
820 if (r)
822 q = r;
823 r = NULL;
824 continue;
826 break;
828 if (*q == '.')
829 l = k;
830 name_buf[k] = ToLower(*q);
831 ++k;
832 ++q;
834 if (l > 0)
835 k = l;
836 name_buf[k] = '\0';
838 postscript = FT_Get_Sfnt_Table(face, ft_sfnt_post);
839 os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
841 tags[0].ti_Tag = MUIA_Group_Child;
842 tags[0].ti_Data = (ULONG)ColGroup(2),
843 Child, Label2("Extra file"),
844 Child, attached_file = PopaslObject,
845 MUIA_Popasl_Type, ASL_FileRequest,
846 MUIA_Popstring_String, StringObject,
847 StringFrame,
848 MUIA_String_AdvanceOnCR, TRUE,
849 MUIA_CycleChain, TRUE,
850 End,
851 MUIA_Popstring_Button, PopButton(MUII_PopFile),
852 ASLFR_RejectIcons, TRUE,
853 End,
854 Child, Label2("Face num"),
855 Child, face_num = StringObject,
856 StringFrame,
857 MUIA_String_Integer, 0,
858 MUIA_String_Accept, "0123456789",
859 MUIA_String_AdvanceOnCR, TRUE,
860 MUIA_String_MaxLen, 5,
861 MUIA_CycleChain, TRUE,
862 End,
863 Child, Label2("Name"),
864 Child, name = StringObject,
865 StringFrame,
866 MUIA_String_Contents, name_buf,
867 MUIA_String_AdvanceOnCR, TRUE,
868 MUIA_String_MaxLen, 27,
869 MUIA_CycleChain, TRUE,
870 End,
871 Child, Label2("Family"),
872 Child, family = StringObject,
873 StringFrame,
874 MUIA_String_Contents, face->family_name,
875 MUIA_String_AdvanceOnCR, TRUE,
876 MUIA_CycleChain, TRUE,
877 End,
878 Child, Label2("Metric"),
879 Child, metric = CycleObject,
880 MUIA_Cycle_Entries, metric_names,
881 MUIA_Cycle_Active, 1,
882 MUIA_CycleChain, TRUE,
883 End,
884 Child, Label2("Bounding box"),
885 Child, HGroup,
886 Child, Label2("yMin"),
887 Child, bbox_ymin = StringObject,
888 StringFrame,
889 MUIA_String_Accept, "-0123456789",
890 MUIA_String_AdvanceOnCR, TRUE,
891 MUIA_String_MaxLen, 6,
892 MUIA_String_Integer, face->bbox.yMin,
893 MUIA_CycleChain, TRUE,
894 End,
895 Child, Label2("yMax"),
896 Child, bbox_ymax = StringObject,
897 StringFrame,
898 MUIA_String_Accept, "-0123456789",
899 MUIA_String_AdvanceOnCR, TRUE,
900 MUIA_String_MaxLen, 6,
901 MUIA_String_Integer, face->bbox.yMax,
902 MUIA_CycleChain, TRUE,
903 End,
904 End,
905 Child, Label2("Size factor"),
906 Child, HGroup,
907 Child, size_factor_low = StringObject,
908 StringFrame,
909 MUIA_String_Accept, "0123456789",
910 MUIA_String_AdvanceOnCR, TRUE,
911 MUIA_String_MaxLen, 6,
912 MUIA_String_Integer, 1,
913 MUIA_CycleChain, TRUE,
914 End,
915 Child, TextObject,
916 MUIA_Text_Contents, "/",
917 MUIA_Text_SetMax, TRUE,
918 End,
919 Child, size_factor_high = StringObject,
920 StringFrame,
921 MUIA_String_Accept, "0123456789",
922 MUIA_String_AdvanceOnCR, TRUE,
923 MUIA_String_MaxLen, 6,
924 MUIA_String_Integer, 1,
925 MUIA_CycleChain, TRUE,
926 End,
927 End,
928 Child, Label2("Space width"),
929 Child, space_width = StringObject,
930 StringFrame,
931 MUIA_String_Accept, "0123456789",
932 MUIA_String_AdvanceOnCR, TRUE,
933 MUIA_String_MaxLen, 6,
934 MUIA_String_Integer, (ULONG)(face->max_advance_width * 250.0 / 72.307),
935 MUIA_CycleChain, TRUE,
936 End,
937 Child, Label1("Fixed width"),
938 Child, HGroup,
939 Child, fixed = CheckMark((face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0),
940 Child, RectangleObject,
941 End,
942 End,
943 Child, Label1("Serif"),
944 Child, HGroup,
945 Child, serif = CheckMark(os2 && (unsigned)(((os2->sFamilyClass >> 8) &
946 0xff) - 1) < 5),
947 Child, RectangleObject,
948 End,
949 End,
950 Child, Label2("Stem weight"),
951 Child, HGroup,
952 Child, stem_weight_cycle = CycleObject,
953 MUIA_Cycle_Entries, stem_weight_names,
954 MUIA_CycleChain, TRUE,
955 End,
956 Child, stem_weight = StringObject,
957 StringFrame,
958 MUIA_String_Accept, "0123456789",
959 MUIA_String_AdvanceOnCR, TRUE,
960 MUIA_String_MaxLen, 4,
961 MUIA_String_Integer, 128,
962 MUIA_CycleChain, TRUE,
963 End,
964 End,
965 Child, Label2("Slant style"),
966 Child, slant_style = CycleObject,
967 MUIA_Cycle_Entries, slant_style_names,
968 MUIA_Cycle_Active, face->style_flags & FT_STYLE_FLAG_ITALIC ?
969 (postscript && postscript->italicAngle > 0 ?
970 OTS_LeftItalic : OTS_Italic) : OTS_Upright,
971 MUIA_CycleChain, TRUE,
972 End,
973 Child, Label2("Horiz style"),
974 Child, HGroup,
975 Child, horiz_style_cycle = CycleObject,
976 MUIA_Cycle_Entries, horiz_style_names,
977 MUIA_CycleChain, TRUE,
978 End,
979 Child, horiz_style = StringObject,
980 StringFrame,
981 MUIA_String_Accept, "0123456789",
982 MUIA_String_AdvanceOnCR, TRUE,
983 MUIA_String_MaxLen, 4,
984 MUIA_String_Integer, 128,
985 MUIA_CycleChain, TRUE,
986 End,
987 End,
988 /*Child, Label1("No algo style"),
989 Child, HGroup,
990 Child, algo_style = CheckMark(FALSE),
991 Child, RectangleObject,
992 End,
993 End,*/
994 End;
995 tags[1].ti_Tag = MUIA_Group_Child;
996 tags[1].ti_Data = (ULONG)VGroup,
997 GroupFrameT("Preview"),
998 Child, test_string = StringObject,
999 StringFrame,
1000 MUIA_String_Contents, "The quick brown fox jumped over the lazy dog.",
1001 MUIA_String_AdvanceOnCR, TRUE,
1002 MUIA_CycleChain, TRUE,
1003 End,
1004 Child, HGroup,
1005 Child, Label2("Size"),
1006 Child, test_size = StringObject,
1007 StringFrame,
1008 MUIA_String_Accept, "0123456789",
1009 MUIA_String_Integer, 30,
1010 MUIA_String_AdvanceOnCR, TRUE,
1011 MUIA_CycleChain, TRUE,
1012 End,
1013 Child, Label2("Anti-aliasing"),
1014 Child, gray = CheckMark(FALSE),
1015 End,
1016 Child, ScrollgroupObject,
1017 MUIA_Scrollgroup_Contents, VirtgroupObject,
1018 VirtualFrame,
1019 Child, VCenter(HCenter((preview_group = VGroup,
1020 Child, preview = RectangleObject,
1021 End,
1022 End))),
1023 End,
1024 End,
1025 End;
1026 tags[2].ti_Tag = TAG_MORE;
1027 tags[2].ti_Data = (ULONG)msg->ops_AttrList;
1029 method.MethodID = OM_NEW;
1030 method.ops_AttrList = tags;
1031 method.ops_GInfo = NULL;
1033 o = (Object *)DoSuperMethodA(cl, o, (Msg)&method);
1034 if (o)
1036 FontInfoData *dat = INST_DATA(cl, o);
1038 dat->Filename = filename;
1039 dat->Face = face;
1040 dat->AttachedFile = attached_file;
1041 dat->Name = name;
1042 dat->Family = family;
1043 dat->YSizeFactorLow = size_factor_low;
1044 dat->YSizeFactorHigh = size_factor_high;
1045 dat->StemWeight = stem_weight;
1046 dat->SlantStyle = slant_style;
1047 dat->HorizStyle = horiz_style;
1048 dat->SpaceWidth = space_width;
1049 dat->Fixed = fixed;
1050 dat->Serif = serif;
1051 //dat->AlgoStyle = algo_style;
1052 dat->FaceNum = face_num;
1053 dat->Metric = metric;
1054 dat->BBoxYMin = bbox_ymin;
1055 dat->BBoxYMax = bbox_ymax;
1056 dat->Preview = preview;
1057 dat->PreviewGroup = preview_group;
1058 dat->TestString = test_string;
1059 dat->TestSize = test_size;
1060 dat->Gray = gray;
1062 DoMethod(size_factor_low, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1063 size_factor_low, 4, MUIM_CallHook, &IntegerBoundsHook, 1, 65535);
1064 DoMethod(size_factor_high, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1065 size_factor_high, 4, MUIM_CallHook, &IntegerBoundsHook, 1, 65535);
1067 DoMethod(stem_weight_cycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
1068 stem_weight_cycle, 5, MUIM_CallHook, &CycleToStringHook,
1069 stem_weight, sizeof(stem_weight_values), stem_weight_values);
1070 DoMethod(stem_weight, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1071 stem_weight, 4, MUIM_CallHook, &IntegerBoundsHook, 0, 255);
1073 DoMethod(horiz_style_cycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
1074 horiz_style_cycle, 5, MUIM_CallHook, &CycleToStringHook,
1075 horiz_style, sizeof(horiz_style_values), horiz_style_values);
1076 DoMethod(horiz_style, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1077 horiz_style, 4, MUIM_CallHook, &IntegerBoundsHook, 0, 255);
1079 set(stem_weight_cycle, MUIA_Cycle_Active,
1080 face->style_flags & FT_STYLE_FLAG_BOLD ? 11 : 7);
1081 set(horiz_style_cycle, MUIA_Cycle_Active, 4);
1083 DoMethod(test_string, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1084 o, 1, MUIM_FontInfo_UpdatePreview);
1085 DoMethod(test_size, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1086 o, 1, MUIM_FontInfo_UpdatePreview);
1087 DoMethod(gray, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
1088 o, 1, MUIM_FontInfo_UpdatePreview);
1090 DoMethod(bbox_ymin, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1091 bbox_ymin, 4, MUIM_CallHook, &IntegerBoundsHook, -32768, 32767);
1092 DoMethod(bbox_ymax, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
1093 bbox_ymax, 4, MUIM_CallHook, &IntegerBoundsHook, -32768, 32767);
1095 DoMethod(metric, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
1096 metric, 6, MUIM_CallHook, &MetricHook, bbox_ymin, bbox_ymax);
1098 set(metric, MUIA_Cycle_Active, 0);
1100 if (//!(face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) &&
1101 FT_Set_Char_Size(face, 250 * 64, 250 * 64, 2540, 2540) == 0 &&
1102 FT_Load_Char(face, ' ', FT_LOAD_DEFAULT) == 0)
1104 set(space_width, MUIA_String_Integer, face->glyph->metrics.horiAdvance >> 6);
1107 if (os2)
1109 int weight = os2->usWeightClass;
1110 int value;
1112 value = 0; /* UltraThin */
1113 if (weight < 10) weight *= 100;
1114 if (weight >= 200) value = 2; /* Thin */
1115 if (weight >= 300) value = 4; /* Light */
1116 if (weight >= 400) value = 7; /* Book */
1117 if (weight >= 500) value = 8; /* Medium */
1118 if (weight >= 600) value = 10; /* DemiBold */
1119 if (weight >= 700) value = 11; /* Bold */
1120 if (weight >= 800) value = 13; /* Black */
1121 if (weight >= 900) value = 15; /* UltraBlack */
1122 set(stem_weight_cycle, MUIA_Cycle_Active, value);
1124 set(horiz_style_cycle, MUIA_Cycle_Active, os2->usWidthClass - 1);
1127 DoMethod(o, MUIM_FontInfo_UpdatePreview);
1130 DEBUG_FONTINFO(dprintf("FontInfo: created object 0x%lx\n", o));
1132 return (ULONG)o;
1135 #if 0
1136 ULONG fiDispose(Class *cl, Object *o)
1138 FontInfoData *dat = INST_DATA(cl, o);
1140 return DoSuperMethod(cl, o, OM_DISPOSE);
1142 #endif
1144 ULONG fiSetOTags(Class *cl, Object *o)
1146 FontInfoData *dat = INST_DATA(cl, o);
1147 struct TagItem *tag = dat->OTags;
1148 ULONG x, y;
1150 tag->ti_Tag = OT_FileIdent;
1151 ++tag;
1153 tag->ti_Tag = OT_Engine;
1154 tag->ti_Data = (ULONG)"freetype2";
1155 ++tag;
1157 tag->ti_Tag = OT_Family;
1158 get(dat->Family, MUIA_String_Contents, &tag->ti_Data);
1159 ++tag;
1161 //tag->ti_Tag = OT_BName;
1162 //tag->ti_Tag = OT_IName;
1163 //tag->ti_Tag = OT_BIName;
1164 //tag->ti_Tag = OT_SymbolSet; charmap index
1166 get(dat->YSizeFactorLow, MUIA_String_Integer, &x);
1167 get(dat->YSizeFactorHigh, MUIA_String_Integer, &y);
1168 x = (UWORD)x;
1169 y = (UWORD)y;
1170 if (x == 0) x = 1;
1171 if (y == 0) y = 1;
1172 tag->ti_Tag = OT_YSizeFactor;
1173 tag->ti_Data = x | (y << 16);
1174 ++tag;
1176 tag->ti_Tag = OT_SpaceWidth;
1177 get(dat->SpaceWidth, MUIA_String_Integer, &tag->ti_Data);
1178 ++tag;
1180 tag->ti_Tag = OT_IsFixed;
1181 get(dat->Fixed, MUIA_Selected, &tag->ti_Data);
1182 ++tag;
1184 tag->ti_Tag = OT_SerifFlag;
1185 get(dat->Serif, MUIA_Selected, &tag->ti_Data);
1186 ++tag;
1188 tag->ti_Tag = OT_StemWeight;
1189 get(dat->StemWeight, MUIA_String_Integer, &tag->ti_Data);
1190 ++tag;
1192 tag->ti_Tag = OT_SlantStyle;
1193 get(dat->SlantStyle, MUIA_Cycle_Active, &tag->ti_Data);
1194 ++tag;
1196 tag->ti_Tag = OT_HorizStyle;
1197 get(dat->HorizStyle, MUIA_String_Integer, &tag->ti_Data);
1198 ++tag;
1200 tag->ti_Tag = OT_SpaceFactor;
1201 tag->ti_Data = 0x10000;
1202 ++tag;
1204 tag->ti_Tag = OT_InhibitAlgoStyle;
1205 tag->ti_Data = FSF_UNDERLINED | FSF_BOLD;
1206 //get(dat->AlgoStyle, MUIA_Selected, &tag->ti_Data);
1207 ++tag;
1209 tag->ti_Tag = OT_SpecCount;
1210 tag->ti_Data = 4;
1211 ++tag;
1213 tag->ti_Tag = OT_Spec1_FontFile;
1214 tag->ti_Data = (ULONG)dat->Filename;
1215 ++tag;
1217 tag->ti_Tag = OT_Spec3_AFMFile;
1218 get(dat->AttachedFile, MUIA_String_Contents, &tag->ti_Data);
1219 ++tag;
1221 tag->ti_Tag = OT_Spec4_Metric;
1222 get(dat->Metric, MUIA_Cycle_Active, &tag->ti_Data);
1223 ++tag;
1225 if (tag[-1].ti_Data == METRIC_CUSTOMBBOX)
1227 ULONG ymin, ymax;
1228 get(dat->BBoxYMin, MUIA_String_Integer, &ymin);
1229 get(dat->BBoxYMax, MUIA_String_Integer, &ymax);
1230 tag->ti_Tag = OT_Spec5_BBox;
1231 tag->ti_Data = (ymax << 16) | (UWORD)ymin;
1232 ++tag;
1235 tag->ti_Tag = OT_Spec6_FaceNum;
1236 get(dat->FaceNum, MUIA_String_Integer, &tag->ti_Data);
1237 ++tag;
1239 if (!IsDefaultCodePage())
1241 tag->ti_Tag = OT_Spec2_CodePage;
1242 tag->ti_Data = (ULONG)codepage;
1243 ++tag;
1246 tag->ti_Tag = TAG_END;
1248 dat->AvailSizes[0] = AROS_WORD2BE(2); // <- number of entries...
1249 dat->AvailSizes[1] = AROS_WORD2BE(10);
1250 dat->AvailSizes[2] = AROS_WORD2BE(15);
1252 return tag - dat->OTags;
1255 ULONG fiUpdatePreview(Class *cl, Object *o)
1257 FontInfoData *dat = INST_DATA(cl, o);
1258 Object *preview;
1259 STRPTR str;
1260 ULONG gray;
1261 ULONG size;
1263 fiSetOTags(cl, o);
1265 get(dat->TestString, MUIA_String_Contents, &str);
1266 get(dat->Gray, MUIA_Selected, &gray);
1267 get(dat->TestSize, MUIA_String_Integer, &size);
1269 preview = FontBitmapObject,
1270 MUIA_FontBitmap_Filename, dat->Filename,
1271 MUIA_FontBitmap_OTags, dat->OTags,
1272 MUIA_FontBitmap_String, str,
1273 MUIA_FontBitmap_Gray, gray,
1274 MUIA_FontBitmap_Size, size,
1275 End;
1277 DEBUG_FONTINFO(dprintf("FontInfo::UpdatePreview: new 0x%lx\n", preview));
1279 if (preview)
1281 DoMethod(dat->PreviewGroup, MUIM_Group_InitChange);
1282 if (dat->Preview)
1284 DoMethod(dat->PreviewGroup, OM_REMMEMBER, dat->Preview);
1285 DisposeObject(dat->Preview);
1287 DoMethod(dat->PreviewGroup, OM_ADDMEMBER, preview);
1288 DoMethod(dat->PreviewGroup, MUIM_Group_ExitChange);
1289 dat->Preview = preview;
1292 return preview != NULL;
1295 ULONG fiWriteFiles(Class *cl, Object *o)
1297 FontInfoData *dat = INST_DATA(cl, o);
1298 BPTR file;
1299 char name[32];
1300 STRPTR base;
1301 BPTR olddir;
1303 get(dat->Name, MUIA_String_Contents, &base);
1304 if (!base || !base[0])
1305 return FALSE;
1307 olddir = CurrentDir(destdir);
1309 strcpy(name, base);
1310 strcat(name, ".otag");
1312 file = Open(name, MODE_NEWFILE);
1313 if (file)
1315 struct TagItem *tag;
1316 ULONG size, indirect_size;
1317 UBYTE *buffer;
1318 int num_sizes;
1320 size = sizeof(tag->ti_Tag) + (fiSetOTags(cl, o) + 2) * sizeof(*tag);
1321 indirect_size = 0;
1323 for (tag = dat->OTags; tag->ti_Tag != TAG_END; ++tag)
1325 if (tag->ti_Tag == OT_Spec2_CodePage)
1327 indirect_size += 1;
1328 indirect_size &= ~1;
1329 indirect_size += sizeof(codepage);
1331 else if (tag->ti_Tag & OT_Indirect && tag->ti_Data)
1333 indirect_size += strlen((const char *)tag->ti_Data) + 1;
1337 indirect_size += 1;
1338 indirect_size &= ~1;
1340 num_sizes = 1 + dat->AvailSizes[0];
1341 indirect_size += num_sizes * sizeof(UWORD);
1343 dat->OTags[0].ti_Data = size + indirect_size;
1345 buffer = malloc(indirect_size);
1346 if (buffer)
1348 size_t offset = 0;
1349 struct TagItem *write_tags;
1351 memset(buffer, 0, indirect_size);
1353 for (tag = dat->OTags; tag->ti_Tag != TAG_END; ++tag)
1355 if (tag->ti_Tag == OT_Spec2_CodePage)
1357 offset += 1;
1358 offset &= ~1;
1359 memcpy(buffer + offset, codepage, sizeof(codepage));
1360 tag->ti_Data = size + offset;
1361 offset += sizeof(codepage);
1363 else if (tag->ti_Tag & OT_Indirect && tag->ti_Data)
1365 size_t len = strlen((const char *)tag->ti_Data) + 1;
1366 memcpy(buffer + offset, (const char *)tag->ti_Data, len);
1367 tag->ti_Data = size + offset;
1368 offset += len;
1372 offset += 1;
1373 offset &= ~1;
1375 tag->ti_Tag = OT_AvailSizes;
1376 tag->ti_Data = size + offset;
1377 ++tag;
1379 tag->ti_Tag = TAG_END;
1381 memcpy(buffer + offset, dat->AvailSizes, num_sizes * sizeof(UWORD));
1382 offset += num_sizes * sizeof(UWORD);
1384 write_tags = malloc(size);
1385 memcpy(write_tags, dat->OTags, size);
1386 for (tag = write_tags; tag->ti_Tag != TAG_END; tag++)
1388 tag->ti_Tag = AROS_LONG2BE(tag->ti_Tag);
1389 tag->ti_Data = AROS_LONG2BE(tag->ti_Data);
1391 tag->ti_Tag = AROS_LONG2BE(TAG_END);
1393 Write(file, write_tags, size);
1394 free(write_tags);
1395 Write(file, buffer, offset);
1397 free(buffer);
1400 Close(file);
1403 strcpy(name, base);
1404 strcat(name, ".font");
1406 file = Open(name, MODE_NEWFILE);
1407 if (file)
1409 static UBYTE data[] = {0x0f, 0x03, 0x00, 0x00 };
1410 Write(file, data, sizeof(data));
1411 Close(file);
1414 CurrentDir(olddir);
1416 return 1;
1419 AROS_UFH3(ULONG, FontInfoDispatch,
1420 AROS_UFHA(Class *, cl, A0),
1421 AROS_UFHA(Object *, o, A2),
1422 AROS_UFHA(Msg, msg, A1))
1424 AROS_USERFUNC_INIT
1426 ULONG ret;
1428 switch (msg->MethodID)
1430 case OM_NEW:
1431 ret = fiNew(cl, o, (struct opSet *)msg);
1432 break;
1434 #if 0
1435 case OM_DISPOSE:
1436 ret = fiDispose(cl, o);
1437 break;
1438 #endif
1440 case MUIM_FontInfo_UpdatePreview:
1441 ret = fiUpdatePreview(cl, o);
1442 break;
1444 case MUIM_FontInfo_WriteFiles:
1445 ret = fiWriteFiles(cl, o);
1446 break;
1448 default:
1449 ret = DoSuperMethodA(cl, o, msg);
1450 break;
1453 return ret;
1455 AROS_USERFUNC_EXIT
1459 void CleanupFontInfoClass(void)
1461 if (FontInfoClass)
1463 MUI_DeleteCustomClass(FontInfoClass);
1464 FontInfoClass = NULL;
1468 int InitFontInfoClass(void)
1470 FontInfoClass = MUI_CreateCustomClass(NULL, MUIC_Group, NULL,
1471 sizeof(FontInfoData), UFHN(FontInfoDispatch));
1472 return FontInfoClass != NULL;
1475 /***********************************************************************/
1476 /***********************************************************************/
1477 /***********************************************************************/
1478 /***********************************************************************/
1479 /***********************************************************************/
1481 struct FontWindowData
1483 FT_Face Face;
1485 typedef struct FontWindowData FontWindowData;
1487 #define FONTWINDOW_BASE TAG_USER
1488 #define MUIA_FontWindow_Filename (FONTWINDOW_BASE + 1)
1490 struct MUI_CustomClass *FontWindowClass;
1492 #define FontWindowObject NewObject(FontWindowClass->mcc_Class, NULL //)
1494 AROS_UFH3(void, CloseWinFunc,
1495 AROS_UFHA(struct Hook *, hook, A0),
1496 AROS_UFHA(Object *, app, A2),
1497 AROS_UFHA(Object **, winp, A1))
1499 AROS_USERFUNC_INIT
1501 set(*winp, MUIA_Window_Open, FALSE);
1502 DoMethod(app, OM_REMMEMBER, *winp);
1503 MUI_DisposeObject(*winp);
1505 AROS_USERFUNC_EXIT
1508 struct Hook CloseWinHook = {{NULL, NULL}, UFHN(CloseWinFunc) };
1510 ULONG fwNew(Class *cl, Object *o, struct opSet *msg)
1512 struct opSet method;
1513 struct TagItem tags[4];
1514 STRPTR filename = (STRPTR)GetTagData(MUIA_FontWindow_Filename, (IPTR) NULL, msg->ops_AttrList);
1515 FT_Face face;
1516 FT_Error error;
1517 Object *install, *close, *info, *app;
1519 if (filename == NULL)
1521 DEBUG_FONTWINDOW(dprintf("FontWindow: no filename.\n"));
1522 return 0;
1525 error = FT_New_Face(ftlibrary, filename, 0, &face);
1526 if (error)
1528 DEBUG_FONTWINDOW(dprintf("FontWindow: New_Face error %d.\n", error));
1529 return 0;
1532 app = (Object *)GetTagData(MUIA_UserData, 0,
1533 msg->ops_AttrList);
1534 if (NULL == app)
1536 DEBUG_FONTWINDOW(dprintf("FontWindow: no app ptr.\n"));
1537 return 0;
1540 tags[0].ti_Tag = MUIA_Window_ID;
1541 tags[0].ti_Data = MAKE_ID('F','O','N','T');
1542 tags[1].ti_Tag = MUIA_Window_Title;
1543 tags[1].ti_Data = (ULONG)filename;
1544 tags[2].ti_Tag = MUIA_Window_RootObject;
1545 tags[2].ti_Data = (ULONG)VGroup,
1546 Child, info = FontInfoObject,
1547 MUIA_FontInfo_Filename, filename,
1548 MUIA_FontInfo_Face, face,
1549 End,
1550 Child, HGroup,
1551 Child, install = SimpleButton("_Install"),
1552 Child, RectangleObject,
1553 End,
1554 Child, close = SimpleButton("_Close"),
1555 End,
1556 End;
1557 tags[3].ti_Tag = TAG_MORE;
1558 tags[3].ti_Data = (ULONG)msg->ops_AttrList;
1560 method.MethodID = OM_NEW;
1561 method.ops_AttrList = tags;
1562 method.ops_GInfo = NULL;
1564 o = (Object *)DoSuperMethodA(cl, o, (Msg)&method);
1565 if (o)
1567 FontWindowData *dat = INST_DATA(cl, o);
1568 dat->Face = face;
1570 DoMethod(install, MUIM_Notify, MUIA_Pressed, FALSE,
1571 info, 1, MUIM_FontInfo_WriteFiles);
1572 DoMethod(close, MUIM_Notify, MUIA_Pressed, FALSE,
1573 app, 6, MUIM_Application_PushMethod, app, 3,
1574 MUIM_CallHook, &CloseWinHook, o);
1577 else
1579 FT_Done_Face(face);
1582 DEBUG_FONTWINDOW(dprintf("FontWindow: created object 0x%lx.\n", o));
1584 return (ULONG)o;
1587 ULONG fwDispose(Class *cl, Object *o)
1589 FontWindowData *dat = INST_DATA(cl, o);
1591 DEBUG_FONTWINDOW(dprintf("FontWindow: destroy object 0x%lx\n", o));
1593 FT_Done_Face(dat->Face);
1595 return DoSuperMethod(cl, o, OM_DISPOSE);
1598 AROS_UFH3(ULONG, FontWindowDispatch,
1599 AROS_UFHA(Class *, cl, A0),
1600 AROS_UFHA(Object *, o, A2),
1601 AROS_UFHA(Msg, msg, A1))
1603 AROS_USERFUNC_INIT
1605 ULONG ret;
1607 switch (msg->MethodID)
1609 case OM_NEW:
1610 ret = fwNew(cl, o, (struct opSet *)msg);
1611 break;
1613 case OM_DISPOSE:
1614 ret = fwDispose(cl, o);
1615 break;
1617 default:
1618 ret = DoSuperMethodA(cl, o, msg);
1619 break;
1622 return ret;
1624 AROS_USERFUNC_EXIT
1628 void CleanupFontWindowClass(void)
1630 if (FontWindowClass)
1632 MUI_DeleteCustomClass(FontWindowClass);
1633 FontWindowClass = NULL;
1637 int InitFontWindowClass(void)
1639 FontWindowClass = MUI_CreateCustomClass(NULL, MUIC_Window, NULL,
1640 sizeof(FontWindowData), UFHN(FontWindowDispatch));
1641 return FontWindowClass != NULL;
1644 /***********************************************************************/
1645 /***********************************************************************/
1646 /***********************************************************************/
1647 /***********************************************************************/
1648 /***********************************************************************/
1650 struct FontListData
1652 struct MinList ScanDirTasks;
1654 typedef struct FontListData FontListData;
1656 struct ScanDirTaskInfo
1658 struct MinNode Node;
1659 struct Process *Proc;
1660 STRPTR DirName;
1661 char NameBuf[256];
1662 char Buffer[4096];
1665 #define FONTLIST_MBASE TAG_USER
1666 #define MUIM_FontList_AddDir (FONTLIST_MBASE + 1)
1667 #define MUIM_FontList_AddEntry (FONTLIST_MBASE + 2)
1669 struct MUI_CustomClass *FontListClass;
1671 #define FontListObject NewObject(FontListClass->mcc_Class, NULL //)
1673 struct MUIS_FontList_Entry
1675 STRPTR FileName;
1676 STRPTR FamilyName;
1677 STRPTR StyleName;
1680 AROS_UFH3(APTR, flConstructFunc,
1681 AROS_UFHA(struct Hook *, hook, A0),
1682 AROS_UFHA(APTR, pool, A2),
1683 AROS_UFHA(struct MUIS_FontList_Entry *, entry, A1))
1685 AROS_USERFUNC_INIT
1687 struct MUIS_FontList_Entry *new_entry;
1688 size_t len1 = strlen(entry->FileName) + 1;
1689 size_t len2 = strlen(entry->FamilyName) + 1;
1690 size_t len3 = strlen(entry->StyleName) + 1;
1692 new_entry = AllocPooled(pool, sizeof(*entry) + len1 + len2 + len3);
1693 if (new_entry)
1695 STRPTR p = (STRPTR)(new_entry + 1);
1696 new_entry->FileName = p;
1697 memcpy(p, entry->FileName, len1);
1698 p += len1;
1699 new_entry->FamilyName = p;
1700 memcpy(p, entry->FamilyName, len2);
1701 p += len2;
1702 new_entry->StyleName = p;
1703 memcpy(p, entry->StyleName, len3);
1706 return new_entry;
1708 AROS_USERFUNC_EXIT
1712 struct Hook flConstructHook = {{NULL, NULL}, UFHN(flConstructFunc) };
1714 AROS_UFH3(void, flDestructFunc,
1715 AROS_UFHA(struct Hook *, hook, A0),
1716 AROS_UFHA(APTR, pool, A2),
1717 AROS_UFHA(struct MUIS_FontList_Entry *, entry, A1))
1719 AROS_USERFUNC_INIT
1721 size_t len1 = strlen(entry->FileName) + 1;
1722 size_t len2 = strlen(entry->FamilyName) + 1;
1723 size_t len3 = strlen(entry->StyleName) + 1;
1725 FreePooled(pool, entry, sizeof(*entry) + len1 + len2 + len3);
1727 AROS_USERFUNC_EXIT
1731 struct Hook flDestructHook = {{NULL, NULL}, UFHN(flDestructFunc) };
1733 AROS_UFH3(ULONG, flDisplayFunc,
1734 AROS_UFHA(struct Hook *, hook, A0),
1735 AROS_UFHA(STRPTR *, array, A2),
1736 AROS_UFHA(struct MUIS_FontList_Entry *, entry, A1))
1738 AROS_USERFUNC_INIT
1740 array[0] = entry->FamilyName;
1741 array[1] = entry->StyleName;
1742 return 0;
1744 AROS_USERFUNC_EXIT
1748 struct Hook flDisplayHook = {{NULL, NULL}, UFHN(flDisplayFunc) };
1750 AROS_UFH3(LONG, flCompareFunc,
1751 AROS_UFHA(struct Hook *, hook, A0),
1752 AROS_UFHA(struct MUIS_FontList_Entry *, entry2, A2),
1753 AROS_UFHA(struct MUIS_FontList_Entry *, entry1, A1))
1755 AROS_USERFUNC_INIT
1757 LONG ret = strcmp(entry1->FamilyName, entry2->FamilyName);
1758 if (ret == 0)
1759 ret = strcmp(entry1->StyleName, entry2->StyleName);
1760 return ret;
1762 AROS_USERFUNC_EXIT
1766 struct Hook flCompareHook = {{NULL, NULL}, UFHN(flCompareFunc) };
1769 ULONG flNew(Class *cl, Object *o, struct opSet *msg)
1771 struct opSet method;
1772 struct TagItem tags[8];
1774 tags[0].ti_Tag = MUIA_Frame;
1775 tags[0].ti_Data = MUIV_Frame_InputList;
1776 tags[1].ti_Tag = MUIA_Background;
1777 tags[1].ti_Data = MUII_ListBack;
1778 tags[2].ti_Tag = MUIA_List_ConstructHook;
1779 tags[2].ti_Data = (ULONG)&flConstructHook;
1780 tags[3].ti_Tag = MUIA_List_DestructHook;
1781 tags[3].ti_Data = (ULONG)&flDestructHook;
1782 tags[4].ti_Tag = MUIA_List_DisplayHook;
1783 tags[4].ti_Data = (ULONG)&flDisplayHook;
1784 tags[4].ti_Tag = MUIA_List_DisplayHook;
1785 tags[4].ti_Data = (ULONG)&flDisplayHook;
1786 tags[5].ti_Tag = MUIA_List_CompareHook;
1787 tags[5].ti_Data = (ULONG)&flCompareHook;
1788 tags[6].ti_Tag = MUIA_List_Format;
1789 tags[6].ti_Data = (ULONG)",";
1790 tags[7].ti_Tag = TAG_MORE;
1791 tags[7].ti_Data = (ULONG)msg->ops_AttrList;
1793 method.MethodID = OM_NEW;
1794 method.ops_AttrList = tags;
1795 method.ops_GInfo = NULL;
1797 o = (Object *)DoSuperMethodA(cl, o, (Msg)&method);
1798 if (o)
1800 FontListData *dat = INST_DATA(cl, o);
1801 NewList((struct List *) &dat->ScanDirTasks);
1804 DEBUG_FONTWINDOW(dprintf("FontList: created object 0x%lx.\n", o));
1806 return (ULONG)o;
1810 ULONG flDispose(Class *cl, Object *o, Msg msg)
1812 FontListData *dat = INST_DATA(cl, o);
1813 struct ScanDirTaskInfo *info;
1814 BOOL done;
1818 done = TRUE;
1820 Forbid();
1821 for (info = (APTR)dat->ScanDirTasks.mlh_Head; info->Node.mln_Succ; info = (APTR)info->Node.mln_Succ)
1823 done = FALSE;
1824 Signal(&info->Proc->pr_Task, SIGBREAKF_CTRL_C);
1826 Permit();
1828 if (!done)
1829 Wait(SIGBREAKF_CTRL_F);
1831 while (!done);
1833 return DoSuperMethodA(cl, o, msg);
1837 struct MUIP_FontList_AddDir
1839 ULONG MethodID;
1840 STRPTR DirName;
1843 struct ScanDirTaskInfo *_pass_info;
1844 Object *_pass_app;
1845 struct Task *_pass_parent;
1846 Object *_pass_fl;
1848 void ScanDirTask(void)
1850 struct ScanDirTaskInfo *info = _pass_info;
1851 Object *app = _pass_app;
1852 struct Task *parent = _pass_parent;
1853 Object *fl = _pass_fl;
1854 BPTR lock;
1855 struct ExAllControl *eac;
1856 struct ExAllData *ead;
1857 ULONG more;
1858 BPTR olddir;
1859 FT_Library ftlibrary;
1861 #warning FIXME: Possible thread race conflicts not checked !!!
1862 void *test = GetIntETask(parent)->iet_acpd;
1863 GetIntETask(FindTask(NULL))->iet_acpd = test;
1865 Signal(parent, SIGBREAKF_CTRL_F);
1867 DEBUG_ADDDIR(dprintf("flScanDirTask: dir <%s>\n", info->DirName));
1869 if (FT_Init_FreeType(&ftlibrary) == 0)
1871 DEBUG_ADDDIR(dprintf("flScanDirTask: ftlibrary 0x%x\n", ftlibrary));
1873 lock = Lock(info->DirName, ACCESS_READ);
1874 if (lock)
1876 DEBUG_ADDDIR(dprintf("flScanDirTask: lock 0x%lx\n", lock));
1878 olddir = CurrentDir(lock);
1880 eac = AllocDosObject(DOS_EXALLCONTROL, NULL);
1881 if (eac)
1883 DEBUG_ADDDIR(dprintf("flScanDirTask: eac 0x%lx\n", eac));
1885 eac->eac_LastKey = 0;
1889 more = ExAll(lock, (struct ExAllData *) info->Buffer, sizeof(info->Buffer), ED_NAME, eac);
1891 DEBUG_ADDDIR(dprintf("flScanDirTask: more %d entries %d\n", more, eac->eac_Entries));
1894 if (!more && IoErr() != ERROR_NO_MORE_ENTRIES)
1896 DEBUG_ADDDIR(dprintf("flScanDirTask: err %d\n", IoErr()));
1897 break;
1900 if (eac->eac_Entries == 0)
1901 continue;
1903 ead = (APTR)info->Buffer;
1907 FT_Face face;
1908 FT_Error error;
1910 DEBUG_ADDDIR(dprintf("flScanDirTask: ead 0x%x name %x <%s>\n", ead, ead->ed_Name, ead->ed_Name));
1911 error = FT_New_Face(ftlibrary, ead->ed_Name, 0, &face);
1912 DEBUG_ADDDIR(dprintf("flScanDirTask: error %d\n", error));
1913 if (error == 0)
1915 struct MUIS_FontList_Entry *entry;
1916 size_t len1, len2, len3;
1918 DEBUG_ADDDIR(dprintf("flScanDirTask: family 0x <%s> style 0x%x <%s>\n", face->family_name, face->family_name, face->style_name, face->style_name));
1920 strncpy(info->NameBuf, info->DirName, sizeof(info->NameBuf));
1921 AddPart(info->NameBuf, ead->ed_Name, sizeof(info->NameBuf));
1923 len1 = strlen(info->NameBuf) + 1;
1924 len2 = strlen(face->family_name) + 1;
1925 len3 = strlen(face->style_name) + 1;
1927 entry = AllocVec(sizeof(*entry) + len1 + len2 + len3, MEMF_PUBLIC);
1928 if (entry)
1930 char *p = (char *)(entry + 1);
1931 entry->FileName = p;
1932 memcpy(p, info->NameBuf, len1);
1933 p += len1;
1934 entry->FamilyName = p;
1935 memcpy(p, face->family_name, len2);
1936 p += len2;
1937 entry->StyleName = p;
1938 memcpy(p, face->style_name, len3);
1940 if (!DoMethod(app, MUIM_Application_PushMethod,
1941 fl, 2, MUIM_FontList_AddEntry, entry))
1942 FreeVec(entry);
1945 FT_Done_Face(face);
1948 ead = ead->ed_Next;
1950 while (ead);
1952 while (more);
1954 DEBUG_ADDDIR(dprintf("flScanDirTask: done\n"));
1956 FreeDosObject(DOS_EXALLCONTROL, eac);
1959 CurrentDir(olddir);
1960 UnLock(lock);
1963 FT_Done_FreeType(ftlibrary);
1966 Forbid();
1967 REMOVE(&info->Node);
1968 FreeVec(info);
1969 Signal(parent, SIGBREAKF_CTRL_F);
1973 ULONG flAddDir(Class *cl, Object *o, struct MUIP_FontList_AddDir *msg)
1975 FontListData *dat = INST_DATA(cl, o);
1976 struct ScanDirTaskInfo *info;
1977 int dirname_len = strlen(msg->DirName) + 1;
1979 info = AllocVec(sizeof(*info) + dirname_len, MEMF_CLEAR | MEMF_PUBLIC);
1980 if (info)
1982 info->DirName = (STRPTR)(info + 1);
1983 memcpy(info->DirName, msg->DirName, dirname_len);
1985 _pass_info = info;
1986 _pass_app = app;
1987 _pass_parent = FindTask(NULL);
1988 _pass_fl = o;
1989 Forbid();
1990 info->Proc = CreateNewProcTags(
1991 NP_Entry, ScanDirTask,
1992 TAG_END);
1993 if (info->Proc)
1995 ADDTAIL((APTR)&dat->ScanDirTasks, (APTR)info);
1996 Permit();
1998 Wait(SIGBREAKF_CTRL_F);
1999 return TRUE;
2002 Permit();
2003 FreeVec(info);
2006 return FALSE;
2010 struct MUIP_FontList_AddEntry
2012 ULONG MethodID;
2013 struct MUIS_FontList_Entry *Entry;
2016 ULONG flAddEntry(Class *cl, Object *o, struct MUIP_FontList_AddEntry *msg)
2018 DoMethod(o, MUIM_List_InsertSingle, msg->Entry, MUIV_List_Insert_Sorted);
2019 FreeVec(msg->Entry);
2020 return TRUE;
2024 AROS_UFH3(ULONG, FontListDispatch,
2025 AROS_UFHA(Class *, cl, A0),
2026 AROS_UFHA(Object *, o, A2),
2027 AROS_UFHA(Msg, msg, A1))
2029 AROS_USERFUNC_INIT
2031 ULONG ret;
2033 switch (msg->MethodID)
2035 case OM_NEW:
2036 ret = flNew(cl, o, (struct opSet *)msg);
2037 break;
2039 case OM_DISPOSE:
2040 ret = flDispose(cl, o, msg);
2041 break;
2043 case MUIM_FontList_AddDir:
2044 ret = flAddDir(cl, o, (struct MUIP_FontList_AddDir *)msg);
2045 break;
2047 case MUIM_FontList_AddEntry:
2048 ret = flAddEntry(cl, o, (struct MUIP_FontList_AddEntry *)msg);
2049 break;
2051 default:
2052 ret = DoSuperMethodA(cl, o, msg);
2053 break;
2056 return ret;
2058 AROS_USERFUNC_EXIT
2062 void CleanupFontListClass(void)
2064 if (FontListClass)
2066 MUI_DeleteCustomClass(FontListClass);
2067 FontListClass = NULL;
2071 int InitFontListClass(void)
2073 FontListClass = MUI_CreateCustomClass(NULL, MUIC_List, NULL,
2074 sizeof(FontListData), UFHN(FontListDispatch));
2075 return FontListClass != NULL;
2078 /***********************************************************************/
2079 /***********************************************************************/
2080 /***********************************************************************/
2081 /***********************************************************************/
2082 /***********************************************************************/
2084 void Cleanup(void)
2086 CleanupFontListClass();
2087 CleanupFontWindowClass();
2088 CleanupFontInfoClass();
2089 CleanupFontBitmapClass();
2091 FT_Done_Library(ftlibrary);
2093 if (codesetsupported)
2094 CodesetsFreeA(codesetsupported, NULL);
2095 FreeVec(codesetentries);
2096 CloseLibrary(CodesetsBase);
2098 UnLock(destdir);
2101 int Init(void)
2103 FT_Error error;
2105 CodesetsBase = OpenLibrary("codesets.library", 0);
2106 if (!CodesetsBase)
2107 return 0;
2109 error = FT_Init_FreeType(&ftlibrary);
2110 if (error != 0)
2112 DEBUG_MAIN(dprintf("Init_FreeType error %d\n", error));
2113 return 0;
2116 if (!InitFontBitmapClass() ||
2117 !InitFontInfoClass() ||
2118 !InitFontWindowClass() ||
2119 !InitFontListClass())
2121 DEBUG_MAIN(dprintf("Can't create custom classes.\n"));
2122 return 0;
2125 destdir = Lock("Fonts:", ACCESS_READ);
2127 return 1;
2131 void SetDefaultCodePage(void)
2133 int k;
2134 for (k = 0; k < 256; ++k)
2135 codepage[k] = k;
2138 BOOL IsDefaultCodePage(void)
2140 int k;
2141 for (k = 0; k < 256; ++k)
2142 if (codepage[k] != k)
2143 return FALSE;
2144 return TRUE;
2147 BOOL LoadCodePage(int entryindex)
2149 SetDefaultCodePage();
2151 if (entryindex == 0) // 1st entry means keep code page
2153 return TRUE;
2156 struct codeset * cs = CodesetsFind(codesetentries[entryindex],
2157 CSA_FallbackToDefault, FALSE, TAG_DONE);
2159 if (cs)
2161 LONG index;
2162 for (index = 0 ; index < 256 ; index++)
2164 codepage[index] = (UWORD)cs->table[index].ucs4;
2166 return TRUE;
2169 return FALSE;
2173 #define ID_SetSrc 1
2174 #define ID_SetDestDir 2
2175 #define ID_ShowFont 3
2176 #define ID_SetCodePage 4
2178 int main(void)
2180 int ret = RETURN_FAIL;
2181 Object *win, *src, *dest, *fontlist, *fontlv, *codepagecycle, *quit;
2182 int countfrom, countto;
2184 if (!Init())
2185 return RETURN_FAIL;
2187 SetDefaultCodePage();
2189 codesetsupported = CodesetsSupportedA(NULL); // Available codesets
2190 countfrom = 0;
2191 while (codesetsupported[countfrom])
2193 countfrom++;
2195 codesetentries = AllocVec((sizeof (STRPTR)) * (countfrom + 2), MEMF_CLEAR);
2196 if (!codesetentries)
2198 Cleanup();
2199 return RETURN_FAIL;
2201 codesetentries[0] = "----";
2202 countfrom = 0;
2203 countto = 1;
2204 while (codesetsupported[countfrom])
2206 if (strcmp(codesetsupported[countfrom], "UTF-8"))
2208 codesetentries[countto] = codesetsupported[countfrom];
2209 countto++;
2211 countfrom++;
2213 app = ApplicationObject,
2214 MUIA_Application_Title, "FTManager",
2215 MUIA_Application_Version, "$VER: FTManager 1.2 (4.12.2007)",
2216 MUIA_Application_Copyright, "Copyright 2002-2003 by Emmanuel Lesueur",
2217 MUIA_Application_Author, "Emmanuel Lesueur",
2218 MUIA_Application_Description, "FreeType font manager",
2219 MUIA_Application_Base, "FTMANAGER",
2220 SubWindow, win = WindowObject,
2221 MUIA_Window_ID, MAKE_ID('F','T','2','M'),
2222 MUIA_Window_Title, "FreeType Font Manager",
2223 MUIA_Window_Width, 400,
2224 MUIA_Window_RootObject,VGroup,
2225 Child, fontlv = ListviewObject,
2226 MUIA_Listview_List, fontlist = FontListObject,
2227 End,
2228 End,
2229 Child, ColGroup(2),
2230 Child, Label2("Source"),
2231 Child, PopaslObject,
2232 MUIA_Popasl_Type, ASL_FileRequest,
2233 MUIA_Popstring_String, src = StringObject,
2234 StringFrame,
2235 MUIA_String_Contents, "Fonts:TrueType",
2236 MUIA_String_AdvanceOnCR, TRUE,
2237 MUIA_CycleChain, TRUE,
2238 End,
2239 MUIA_Popstring_Button, PopButton(MUII_PopDrawer),
2240 ASLFR_RejectIcons, TRUE,
2241 ASLFR_DrawersOnly, TRUE,
2242 End,
2243 Child, Label2("Destination"),
2244 Child, PopaslObject,
2245 MUIA_Popasl_Type, ASL_FileRequest,
2246 MUIA_Popstring_String, dest = StringObject,
2247 StringFrame,
2248 MUIA_String_Contents, "Fonts:",
2249 MUIA_String_AdvanceOnCR, TRUE,
2250 MUIA_CycleChain, TRUE,
2251 End,
2252 MUIA_Popstring_Button, PopButton(MUII_PopDrawer),
2253 ASLFR_DoSaveMode, TRUE,
2254 ASLFR_DrawersOnly, TRUE,
2255 ASLFR_RejectIcons, TRUE,
2256 End,
2257 Child, Label2("Codepage"),
2258 Child, codepagecycle = CycleObject,
2259 MUIA_Cycle_Entries, codesetentries,
2260 End,
2261 End,
2262 Child, quit = SimpleButton("_Quit"),
2263 End,
2264 End,
2265 End;
2267 if (app)
2269 ULONG t;
2271 ret = RETURN_OK;
2273 DoMethod(src, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
2274 fontlist, 2, MUIM_FontList_AddDir, MUIV_TriggerValue);
2276 DoMethod(dest, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
2277 app, 2, MUIM_Application_ReturnID, ID_SetDestDir);
2279 DoMethod(codepagecycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
2280 app, 2, MUIM_Application_ReturnID, ID_SetCodePage);
2282 DoMethod(fontlv, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
2283 app, 2, MUIM_Application_ReturnID, ID_ShowFont);
2285 DoMethod(win, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
2286 app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
2288 DoMethod(quit, MUIM_Notify, MUIA_Pressed, FALSE,
2289 app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
2291 DoMethod(fontlist, MUIM_FontList_AddDir, XGET(src, MUIA_String_Contents));
2293 set(win, MUIA_Window_Open, TRUE);
2294 get(win, MUIA_Window_Open, &t);
2295 if (t)
2297 BOOL running = TRUE;
2298 ULONG sigs = 0;
2299 ULONG id;
2303 id = DoMethod(app, MUIM_Application_NewInput, &sigs);
2304 switch (id)
2306 case MUIV_Application_ReturnID_Quit:
2307 running = FALSE;
2308 sigs = 0;
2309 break;
2311 case ID_SetDestDir:
2313 STRPTR name;
2314 BPTR newdir;
2316 get(dest, MUIA_String_Contents, &name);
2317 newdir = Lock(name, ACCESS_READ);
2318 if (newdir)
2320 UnLock(destdir);
2321 destdir = newdir;
2324 break;
2326 case ID_ShowFont:
2328 struct MUIS_FontList_Entry *entry;
2329 Object *w;
2331 DoMethod(fontlist, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &entry);
2333 w = FontWindowObject,
2334 MUIA_FontWindow_Filename, entry->FileName,
2335 MUIA_UserData, app,
2336 End;
2338 if (w)
2340 DoMethod(w, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
2341 app, 6, MUIM_Application_PushMethod, app, 3,
2342 MUIM_CallHook, &CloseWinHook, w);
2344 DoMethod(app, OM_ADDMEMBER, w);
2345 set(w, MUIA_Window_Open, TRUE);
2346 get(w, MUIA_Window_Open, &t);
2347 if (!t)
2349 MUI_DisposeObject(w);
2354 break;
2356 case ID_SetCodePage:
2358 IPTR entry;
2359 get(codepagecycle, MUIA_Cycle_Active, &entry);
2360 LoadCodePage(entry);
2362 break;
2365 if (sigs)
2367 sigs = Wait(sigs | SIGBREAKF_CTRL_C);
2368 if (sigs & SIGBREAKF_CTRL_C)
2370 running = FALSE;
2374 while (running);
2376 else
2378 printf("Can't open window.\n");
2381 MUI_DisposeObject(app);
2383 else
2385 printf("Can't create MUI application.\n");
2388 Cleanup();
2390 return ret;