9 #include <libraries/mui.h>
10 #include <libraries/ttengine.h>
11 #include <graphics/text.h>
15 #include <proto/dos.h>
16 #include <proto/exec.h>
17 #include <proto/dos.h>
18 #include <proto/utility.h>
19 #include <proto/intuition.h>
20 #include <proto/graphics.h>
21 #include <proto/diskfont.h>
22 #define USE_INLINE_STDARG
23 #include <proto/ttengine.h>
24 #undef USE_INLINE_STDARG
25 #define NO_INLINE_STDARG
26 #include <proto/muimaster.h>
28 #include <clib/alib_protos.h>
31 #include "FontSampleMCC.h"
33 /* ------------------------------------------------------------------------- */
37 APTR fsm_TTFontHandle
; // Font handle from TT_OpenFontA()
38 struct TextFont
*fsm_StdFont
; // Font handle from OpenDiskFont()
39 STRPTR fsm_String
; // Demo text that displays in area
40 STRPTR fsm_TTFontDesc
; // TT Font descriptor
41 STRPTR fsm_StdFontDesc
; // Standard Font descriptor
42 ULONG fsm_FontBaseLine
;
45 BOOL fsm_NeedRelayout
;
46 ULONG fsm_HAlign
; // horizontal alignment
47 ULONG fsm_VAlign
; // vertical alignment
48 struct TextExtent fsm_TextExtent
;
51 /* ------------------------------------------------------------------------- */
53 extern struct Library
*TTEngineBase
;
55 /* ------------------------------------------------------------------------- */
57 static IPTR
mNew(struct IClass
*cl
,Object
*obj
,Msg msg
);
58 static ULONG
mDispose(struct IClass
*cl
, Object
*obj
, Msg msg
);
59 static ULONG
mAskMinMax(struct IClass
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
);
60 static ULONG
mDraw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
);
61 static ULONG
mSet(struct IClass
*cl
, Object
*obj
, struct opSet
*ops
);
62 DISPATCHERPROTO(FontSampleMCC
);
63 static void ClearInstanceData(struct FsMCCInstance
*inst
);
64 static BOOL
SetInstanceData(struct FsMCCInstance
*inst
, struct TagItem
*TagList
);
65 static APTR
OpenTTFontFromDesc(CONST_STRPTR FontDesc
);
66 static struct TextFont
*OpenDiskFontFromDesc(CONST_STRPTR FontDesc
);
67 static void ForceRelayout(struct IClass
*cl
, Object
*obj
);
68 #if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__)
69 static size_t stccpy(char *dest
, const char *src
, size_t MaxLen
);
70 #endif /* !__SASC && !__MORPHOS__ && !__amigaos4__ */
72 /* ------------------------------------------------------------------------- */
74 static IPTR
mNew(struct IClass
*cl
,Object
*obj
,Msg msg
)
76 d1(KPrintF("%s/%ld: START obj=%08lx\n", __FUNC__
, __LINE__
, obj
));
79 struct FsMCCInstance
*inst
;
82 d1(KPrintF("%s/%ld: cl=%08lx obj=%08lx msg=%08lx\n", __FUNC__
, __LINE__
, cl
, obj
, msg
));
84 obj
= (Object
*) DoSuperMethodA(cl
, obj
, msg
);
85 d1(KPrintF("%s/%ld: obj=%08lx\n", __FUNC__
, __LINE__
, obj
));
89 inst
= INST_DATA(cl
,obj
);
90 ClearInstanceData(inst
);
92 inst
->fsm_String
= strdup("The quick brown fox jumps over the lazy dog");
94 set(obj
, MUIA_FillArea
, TRUE
);
96 ops
= (struct opSet
*) msg
;
98 SetInstanceData(inst
, ops
->ops_AttrList
);
100 inst
->fsm_NeedRelayout
= FALSE
;
103 d1(KPrintF("%s/%ld: END obj=%08lx\n", __FUNC__
, __LINE__
, obj
));
109 static ULONG
mDispose(struct IClass
*cl
,Object
*obj
,Msg msg
)
111 struct FsMCCInstance
*inst
= INST_DATA(cl
,obj
);
113 if (TTEngineBase
&& inst
->fsm_TTFontHandle
)
115 TT_CloseFont(inst
->fsm_TTFontHandle
);
116 inst
->fsm_TTFontHandle
= NULL
;
118 if (inst
->fsm_StdFont
)
120 CloseFont(inst
->fsm_StdFont
);
121 inst
->fsm_StdFont
= NULL
;
123 if (inst
->fsm_TTFontDesc
)
125 free(inst
->fsm_TTFontDesc
);
126 inst
->fsm_TTFontDesc
= NULL
;
128 if (inst
->fsm_StdFontDesc
)
130 free(inst
->fsm_StdFontDesc
);
131 inst
->fsm_StdFontDesc
= NULL
;
133 if (inst
->fsm_String
)
135 free(inst
->fsm_String
);
136 inst
->fsm_String
= NULL
;
139 return DoSuperMethodA(cl
, obj
, msg
);
143 static ULONG
mAskMinMax(struct IClass
*cl
,Object
*obj
,struct MUIP_AskMinMax
*msg
)
145 struct FsMCCInstance
*inst
= INST_DATA(cl
,obj
);
146 struct MUI_MinMax
*mi
;
148 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
150 mi
= msg
->MinMaxInfo
;
153 mi
->MinHeight
+= 4 + inst
->fsm_TextExtent
.te_Height
;
155 mi
->DefHeight
+= 4 + inst
->fsm_TextExtent
.te_Height
;
157 mi
->MaxWidth
= MUI_MAXMAX
;
158 mi
->MaxHeight
= MUI_MAXMAX
;
160 /* if we cannot show TT text, our minimal size will be 0 */
166 static ULONG
mDraw(struct IClass
*cl
,Object
*obj
,struct MUIP_Draw
*msg
)
168 struct FsMCCInstance
*inst
= INST_DATA(cl
,obj
);
170 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
172 if (msg
->flags
& MADF_DRAWOBJECT
)
177 d1(kprintf("%s/%s/%ld: TTEngineBase=%08lx fsm_TTFontHandle=%08lx\n", \
178 __FILE__
, __FUNC__
, __LINE__
, TTEngineBase
, inst
->fsm_TTFontHandle
));
179 d1(kprintf("%s/%s/%ld: width=%ld height=%ld\n", __FILE__
, __FUNC__
, __LINE__
, _mwidth(obj
), _mheight(obj
)));
180 d1(kprintf("%s/%s/%ld: subwidth=%ld subheight=%ld\n", __FILE__
, __FUNC__
, __LINE__
, _subwidth(obj
), _subheight(obj
)));
182 ClipHandle
= MUI_AddClipping(muiRenderInfo(obj
), _mleft(obj
), _mtop(obj
), _mwidth(obj
), _mheight(obj
));
184 switch (inst
->fsm_HAlign
)
187 case FONTSAMPLE_HALIGN_LEFT
:
188 x
= _mleft(obj
) + 10;
190 case FONTSAMPLE_HALIGN_CENTER
:
191 x
= _mleft(obj
) + (_mwidth(obj
) - inst
->fsm_TextExtent
.te_Width
) / 2;
193 case FONTSAMPLE_HALIGN_RIGHT
:
194 x
= _mright(obj
) - 10 - inst
->fsm_TextExtent
.te_Width
;
198 switch (inst
->fsm_VAlign
)
201 case FONTSAMPLE_VALIGN_TOP
:
202 y
= _mtop(obj
) + 2 + inst
->fsm_FontBaseLine
;
204 case FONTSAMPLE_VALIGN_CENTER
:
205 y
= _mtop(obj
) + (_mheight(obj
) - inst
->fsm_TextExtent
.te_Height
) / 2 + inst
->fsm_FontBaseLine
;
207 case FONTSAMPLE_VALIGN_BOTTOM
:
208 y
= _mbottom(obj
) - 2 - inst
->fsm_TextExtent
.te_Height
+ inst
->fsm_FontBaseLine
;
212 Move(_rp(obj
), x
, y
);
213 SetAPen(_rp(obj
), _pens(obj
)[MPEN_TEXT
]);
215 if (TTEngineBase
&& inst
->fsm_TTFontHandle
)
217 TT_SetFont(_rp(obj
), inst
->fsm_TTFontHandle
);
219 TT_SetAttrs(_rp(obj
),
220 TT_Window
, (IPTR
) _window(obj
),
221 TT_Antialias
, inst
->fsm_AntiAlias
,
222 TT_Gamma
, inst
->fsm_Gamma
,
225 TT_Text(_rp(obj
), (STRPTR
) inst
->fsm_String
, strlen(inst
->fsm_String
));
227 TT_DoneRastPort(_rp(obj
));
231 if (inst
->fsm_StdFont
)
232 SetFont(_rp(obj
), inst
->fsm_StdFont
);
234 SetSoftStyle(_rp(obj
), FS_NORMAL
, FSF_BOLD
| FSF_ITALIC
| FSF_UNDERLINED
| FSF_EXTENDED
);
236 Text(_rp(obj
), (STRPTR
) inst
->fsm_String
, strlen(inst
->fsm_String
));
239 MUI_RemoveClipping(muiRenderInfo(obj
), ClipHandle
);
246 static ULONG
mSet(struct IClass
*cl
,Object
*obj
, struct opSet
*ops
)
248 struct FsMCCInstance
*inst
= INST_DATA(cl
,obj
);
251 DoSuperMethodA(cl
, obj
, (Msg
) ops
);
253 NeedRedraw
= SetInstanceData(inst
, ops
->ops_AttrList
);
255 if (inst
->fsm_NeedRelayout
)
256 ForceRelayout(cl
, obj
);
259 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
265 DISPATCHER(FontSampleMCC
)
269 d1(KPrintF("%s/%ld: START MethodID=%08lx\n", __FUNC__
, __LINE__
, msg
->MethodID
));
271 switch (msg
->MethodID
)
274 d1(kprintf("%s/%s/%ld: OM_NEW\n", __FILE__
, __FUNC__
, __LINE__
));
275 Result
= mNew(cl
, obj
, (APTR
)msg
);
279 d1(kprintf("%s/%s/%ld: OM_DISPOSE\n", __FILE__
, __FUNC__
, __LINE__
));
280 Result
= mDispose(cl
,obj
,(APTR
)msg
);
284 d1(kprintf("%s/%s/%ld: OM_SET\n", __FILE__
, __FUNC__
, __LINE__
));
285 Result
= mSet(cl
, obj
, (struct opSet
*) msg
);
289 d1(kprintf("%s/%s/%ld: MUIM_AskMinMax\n", __FILE__
, __FUNC__
, __LINE__
));
290 Result
= mAskMinMax(cl
,obj
,(APTR
)msg
);
294 d1(kprintf("%s/%s/%ld: MUIM_Draw\n", __FILE__
, __FUNC__
, __LINE__
));
295 Result
= mDraw(cl
,obj
,(APTR
)msg
);
299 d1(kprintf("%s/%s/%ld: MethodID=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, msg
->MethodID
));
300 Result
= DoSuperMethodA(cl
,obj
,msg
);
304 d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__
, __LINE__
, Result
));
311 static void ClearInstanceData(struct FsMCCInstance
*inst
)
313 memset(inst
, 0, sizeof(struct FsMCCInstance
));
315 inst
->fsm_AntiAlias
= TT_Antialias_On
;
316 inst
->fsm_Gamma
= 2500;
317 inst
->fsm_HAlign
= FONTSAMPLE_HALIGN_CENTER
;
318 inst
->fsm_VAlign
= FONTSAMPLE_VALIGN_CENTER
;
322 static BOOL
SetInstanceData(struct FsMCCInstance
*inst
, struct TagItem
*TagList
)
326 BYTE OldAntiAlias
= inst
->fsm_AntiAlias
;
327 WORD OldGamma
= inst
->fsm_Gamma
;
329 inst
->fsm_AntiAlias
= (BYTE
) GetTagData(MUIA_FontSample_Antialias
, (IPTR
) inst
->fsm_AntiAlias
, TagList
);
330 inst
->fsm_Gamma
= (WORD
) GetTagData(MUIA_FontSample_Gamma
, (IPTR
) inst
->fsm_Gamma
, TagList
);
331 inst
->fsm_HAlign
= (WORD
) GetTagData(MUIA_FontSample_HAlign
, (IPTR
) inst
->fsm_HAlign
, TagList
);
332 inst
->fsm_VAlign
= (WORD
) GetTagData(MUIA_FontSample_VAlign
, (IPTR
) inst
->fsm_VAlign
, TagList
);
334 tag
= FindTagItem(MUIA_FontSample_DemoString
, TagList
);
337 if (inst
->fsm_String
)
338 free(inst
->fsm_String
);
339 inst
->fsm_String
= strdup((STRPTR
) tag
->ti_Data
);
342 tag
= FindTagItem(MUIA_FontSample_TTFontDesc
, TagList
);
345 if (inst
->fsm_TTFontDesc
)
346 free(inst
->fsm_TTFontDesc
);
347 inst
->fsm_TTFontDesc
= strdup((STRPTR
) tag
->ti_Data
);
350 tag
= FindTagItem(MUIA_FontSample_StdFontDesc
, TagList
);
353 if (inst
->fsm_StdFontDesc
)
354 free(inst
->fsm_StdFontDesc
);
355 inst
->fsm_StdFontDesc
= strdup((STRPTR
) tag
->ti_Data
);
358 if (TTEngineBase
&& inst
->fsm_TTFontDesc
)
360 if (inst
->fsm_TTFontHandle
)
361 TT_CloseFont(inst
->fsm_TTFontHandle
);
363 inst
->fsm_TTFontHandle
= OpenTTFontFromDesc(inst
->fsm_TTFontDesc
);
365 d1(kprintf("%s/%s/%ld: fsm_TTFontHandle = %08lx FontDesc=<%s>\n", \
366 _ __FILE__
, __FUNC__
, _LINE__
, inst
->fsm_TTFontHandle
, inst
->fsm_TTFontDesc
? inst
->fsm_TTFontDesc
: (STRPTR
) ""));
368 // Force redraw if antialias or gamma has changed
369 if (OldGamma
!= inst
->fsm_Gamma
|| OldAntiAlias
!= inst
->fsm_AntiAlias
)
372 if (inst
->fsm_TTFontHandle
)
378 OldHeight
= inst
->fsm_TextExtent
.te_Height
;
382 TT_SetFont(&rp
, inst
->fsm_TTFontHandle
);
384 TT_GetAttrs(&rp
, TT_FontAccentedAscender
, (IPTR
) &inst
->fsm_FontBaseLine
,
387 TT_TextExtent(&rp
, (STRPTR
) inst
->fsm_String
, strlen(inst
->fsm_String
), &inst
->fsm_TextExtent
);
389 d1(kprintf("%s/%s/%ld: fsm_TextExtent width=%ld height=%ld\n", \
390 __FILE__
, __FUNC__
, __LINE__
, inst
->fsm_TextExtent
.te_Width
, inst
->fsm_TextExtent
.te_Height
));
392 TT_DoneRastPort(&rp
);
396 if (OldHeight
!= inst
->fsm_TextExtent
.te_Height
)
397 inst
->fsm_NeedRelayout
= TRUE
;
400 else if (inst
->fsm_StdFontDesc
)
405 if (inst
->fsm_StdFont
)
406 CloseFont(inst
->fsm_StdFont
);
408 inst
->fsm_StdFont
= OpenDiskFontFromDesc(inst
->fsm_StdFontDesc
);
410 d1(kprintf("%s/%s/%ld: fsm_StdFont=%08lx FontDesc=<%s>\n", \
411 __FILE__
, __FUNC__
, __LINE__
, inst
->fsm_StdFont
, inst
->fsm_StdFontDesc
? inst
->fsm_StdFontDesc
: (STRPTR
) ""));
413 OldHeight
= inst
->fsm_TextExtent
.te_Height
;
417 if (inst
->fsm_StdFont
)
419 SetFont(&rp
, inst
->fsm_StdFont
);
421 inst
->fsm_FontBaseLine
= inst
->fsm_StdFont
->tf_Baseline
;
424 TextExtent(&rp
, (STRPTR
) inst
->fsm_String
, strlen(inst
->fsm_String
), &inst
->fsm_TextExtent
);
426 d1(kprintf("%s/%s/%ld: fsm_TextExtent width=%ld height=%ld\n", \
427 __FILE__
, __FUNC__
, __LINE__
, inst
->fsm_TextExtent
.te_Width
, inst
->fsm_TextExtent
.te_Height
));
431 if (OldHeight
!= inst
->fsm_TextExtent
.te_Height
)
432 inst
->fsm_NeedRelayout
= TRUE
;
439 static APTR
OpenTTFontFromDesc(CONST_STRPTR FontDesc
)
445 char NameSpace
[MAX_TTFONTDESC
];
446 STRPTR FamilyTable
[2];
448 long long1
, long2
, long3
;
451 // "style/weight/size/fontname"
453 if (NULL
== FontDesc
)
456 if (3 != sscanf(FontDesc
, "%ld/%ld/%ld", &long1
, &long2
, &long3
))
463 lp
= strchr(FontDesc
, '/'); // Find "/" between style and weight
467 lp
= strchr(lp
+ 1, '/'); // Find "/" between weight and size
471 lp
= strchr(lp
+ 1, '/'); // Find "/" between size and name
476 stccpy(NameSpace
, 1 + lp
, sizeof(NameSpace
));
477 FamilyTable
[0] = NameSpace
;
478 FamilyTable
[1] = NULL
;
481 TTFont
= TT_OpenFont(TT_FamilyTable
, (IPTR
) FamilyTable
,
482 TT_FontSize
, FontSize
,
483 TT_FontStyle
, FontStyle
,
484 TT_FontWeight
, FontWeight
,
491 static struct TextFont
*OpenDiskFontFromDesc(CONST_STRPTR FontDesc
)
495 struct TextFont
*Font
;
502 for (fp
=FontDesc
, fnLen
=0; *fp
&& '/' != *fp
; fnLen
++)
505 ta
.ta_Name
= FontName
= malloc(fnLen
+ 5 + 1);
506 if (NULL
== FontName
)
509 stccpy(ta
.ta_Name
, FontDesc
, 1 + fnLen
);
510 if ((strlen(ta
.ta_Name
) < strlen(".font")) ||
511 (0 != stricmp(ta
.ta_Name
+ strlen(ta
.ta_Name
) - strlen(".font"), ".font")))
513 strcat(ta
.ta_Name
, ".font");
519 if (StrToLong(fp
, &l
))
524 ta
.ta_Style
= FS_NORMAL
;
527 Font
= OpenDiskFont(&ta
);
529 d1(kprintf("%s/%s/%ld: Font=%08lx FontName=<%s> Size=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Font
, FontName
, ta
.ta_YSize
));
537 static void ForceRelayout(struct IClass
*cl
, Object
*obj
)
539 struct FsMCCInstance
*inst
= INST_DATA(cl
,obj
);
541 Object
*RootObj
= NULL
;
543 inst
->fsm_NeedRelayout
= FALSE
;
545 if (muiRenderInfo(obj
))
547 WindowObj
= _win(obj
);
548 get(WindowObj
, MUIA_Window_RootObject
, &RootObj
);
553 DoMethod(RootObj
, MUIM_Group_InitChange
);
554 DoMethod(RootObj
, MUIM_Group_ExitChange
);
559 /* ------------------------------------------------------------------------- */
561 struct MUI_CustomClass
*InitFontSampleClass(void)
563 return MUI_CreateCustomClass(NULL
, MUIC_Area
, NULL
, sizeof(struct FsMCCInstance
), DISPATCHER_REF(FontSampleMCC
));
566 void CleanupFontSampleClass(struct MUI_CustomClass
*mcc
)
568 MUI_DeleteCustomClass(mcc
);
571 /* ------------------------------------------------------------------------- */
573 #if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__)
574 // Replacement for SAS/C library functions
576 static size_t stccpy(char *dest
, const char *src
, size_t MaxLen
)
580 while (*src
&& MaxLen
> 1)
592 #endif /* !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) */