forgotten commit. disabled until egl is adapted.
[AROS-Contrib.git] / scalos / common / FontSampleMCC / FontSampleMCC.c
blob12e833e2c377b4461a31cee5882f0921d82eea64
1 // FontSampleMCC.c
2 // $Date$
3 // $Revision$
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <libraries/mui.h>
10 #include <libraries/ttengine.h>
11 #include <graphics/text.h>
13 #define __USE_SYSBASE
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>
30 #include <defs.h>
31 #include "FontSampleMCC.h"
33 /* ------------------------------------------------------------------------- */
35 struct FsMCCInstance
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;
43 BYTE fsm_AntiAlias;
44 WORD fsm_Gamma;
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));
78 do {
79 struct FsMCCInstance *inst;
80 struct opSet *ops;
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));
86 if (NULL == obj)
87 break;
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;
101 } while (0);
103 d1(KPrintF("%s/%ld: END obj=%08lx\n", __FUNC__, __LINE__, obj));
105 return((IPTR)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;
152 mi->MinWidth += 100;
153 mi->MinHeight += 4 + inst->fsm_TextExtent.te_Height;
154 mi->DefWidth += 120;
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 */
162 return(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)
174 APTR ClipHandle;
175 LONG x, y;
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)
186 default:
187 case FONTSAMPLE_HALIGN_LEFT:
188 x = _mleft(obj) + 10;
189 break;
190 case FONTSAMPLE_HALIGN_CENTER:
191 x = _mleft(obj) + (_mwidth(obj) - inst->fsm_TextExtent.te_Width) / 2;
192 break;
193 case FONTSAMPLE_HALIGN_RIGHT:
194 x = _mright(obj) - 10 - inst->fsm_TextExtent.te_Width;
195 break;
198 switch (inst->fsm_VAlign)
200 default:
201 case FONTSAMPLE_VALIGN_TOP:
202 y = _mtop(obj) + 2 + inst->fsm_FontBaseLine;
203 break;
204 case FONTSAMPLE_VALIGN_CENTER:
205 y = _mtop(obj) + (_mheight(obj) - inst->fsm_TextExtent.te_Height) / 2 + inst->fsm_FontBaseLine;
206 break;
207 case FONTSAMPLE_VALIGN_BOTTOM:
208 y = _mbottom(obj) - 2 - inst->fsm_TextExtent.te_Height + inst->fsm_FontBaseLine;
209 break;
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,
223 TAG_END);
225 TT_Text(_rp(obj), (STRPTR) inst->fsm_String, strlen(inst->fsm_String));
227 TT_DoneRastPort(_rp(obj));
229 else
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);
242 return(0);
246 static ULONG mSet(struct IClass *cl,Object *obj, struct opSet *ops)
248 struct FsMCCInstance *inst = INST_DATA(cl,obj);
249 BOOL NeedRedraw;
251 DoSuperMethodA(cl, obj, (Msg) ops);
253 NeedRedraw = SetInstanceData(inst, ops->ops_AttrList);
255 if (inst->fsm_NeedRelayout)
256 ForceRelayout(cl, obj);
258 if (NeedRedraw)
259 MUI_Redraw(obj, MADF_DRAWOBJECT);
261 return 1;
265 DISPATCHER(FontSampleMCC)
267 ULONG Result;
269 d1(KPrintF("%s/%ld: START MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID));
271 switch (msg->MethodID)
273 case OM_NEW:
274 d1(kprintf("%s/%s/%ld: OM_NEW\n", __FILE__, __FUNC__, __LINE__));
275 Result = mNew(cl, obj, (APTR)msg);
276 break;
278 case OM_DISPOSE:
279 d1(kprintf("%s/%s/%ld: OM_DISPOSE\n", __FILE__, __FUNC__, __LINE__));
280 Result = mDispose(cl,obj,(APTR)msg);
281 break;
283 case OM_SET:
284 d1(kprintf("%s/%s/%ld: OM_SET\n", __FILE__, __FUNC__, __LINE__));
285 Result = mSet(cl, obj, (struct opSet *) msg);
286 break;
288 case MUIM_AskMinMax:
289 d1(kprintf("%s/%s/%ld: MUIM_AskMinMax\n", __FILE__, __FUNC__, __LINE__));
290 Result = mAskMinMax(cl,obj,(APTR)msg);
291 break;
293 case MUIM_Draw:
294 d1(kprintf("%s/%s/%ld: MUIM_Draw\n", __FILE__, __FUNC__, __LINE__));
295 Result = mDraw(cl,obj,(APTR)msg);
296 break;
298 default:
299 d1(kprintf("%s/%s/%ld: MethodID=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->MethodID));
300 Result = DoSuperMethodA(cl,obj,msg);
301 break;
304 d1(KPrintF("%s/%ld: END Result=%08lx\n", __FUNC__, __LINE__, Result));
306 return Result;
308 DISPATCHER_END
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)
324 struct TagItem *tag;
325 BOOL Redraw = FALSE;
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);
335 if (tag)
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);
343 if (tag)
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);
351 if (tag)
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)
370 Redraw = TRUE;
372 if (inst->fsm_TTFontHandle)
374 struct RastPort rp;
375 WORD OldHeight;
378 OldHeight = inst->fsm_TextExtent.te_Height;
380 InitRastPort(&rp);
382 TT_SetFont(&rp, inst->fsm_TTFontHandle);
384 TT_GetAttrs(&rp, TT_FontAccentedAscender, (IPTR) &inst->fsm_FontBaseLine,
385 TAG_END);
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);
394 Redraw = TRUE;
396 if (OldHeight != inst->fsm_TextExtent.te_Height)
397 inst->fsm_NeedRelayout = TRUE;
400 else if (inst->fsm_StdFontDesc)
402 struct RastPort rp;
403 WORD OldHeight;
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;
415 InitRastPort(&rp);
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));
429 Redraw = TRUE;
431 if (OldHeight != inst->fsm_TextExtent.te_Height)
432 inst->fsm_NeedRelayout = TRUE;
435 return Redraw;
439 static APTR OpenTTFontFromDesc(CONST_STRPTR FontDesc)
441 ULONG FontStyle;
442 ULONG FontWeight;
443 ULONG FontSize;
444 CONST_STRPTR lp;
445 char NameSpace[MAX_TTFONTDESC];
446 STRPTR FamilyTable[2];
447 APTR TTFont;
448 long long1, long2, long3;
450 // Font Desc format:
451 // "style/weight/size/fontname"
453 if (NULL == FontDesc)
454 return NULL;
456 if (3 != sscanf(FontDesc, "%ld/%ld/%ld", &long1, &long2, &long3))
457 return NULL;
459 FontStyle = long1;
460 FontWeight = long2;
461 FontSize = long3;
463 lp = strchr(FontDesc, '/'); // Find "/" between style and weight
464 if (NULL == lp)
465 return NULL;
467 lp = strchr(lp + 1, '/'); // Find "/" between weight and size
468 if (NULL == lp)
469 return NULL;
471 lp = strchr(lp + 1, '/'); // Find "/" between size and name
472 if (NULL == lp)
473 return NULL;
475 // copy font name
476 stccpy(NameSpace, 1 + lp, sizeof(NameSpace));
477 FamilyTable[0] = NameSpace;
478 FamilyTable[1] = NULL;
480 //TT_OpenFontA()
481 TTFont = TT_OpenFont(TT_FamilyTable, (IPTR) FamilyTable,
482 TT_FontSize, FontSize,
483 TT_FontStyle, FontStyle,
484 TT_FontWeight, FontWeight,
485 TAG_END);
487 return TTFont;
491 static struct TextFont *OpenDiskFontFromDesc(CONST_STRPTR FontDesc)
493 // Font Desc format:
494 // "fontname/size"
495 struct TextFont *Font;
496 struct TextAttr ta;
497 CONST_STRPTR fp;
498 size_t fnLen;
499 STRPTR FontName;
500 LONG l;
502 for (fp=FontDesc, fnLen=0; *fp && '/' != *fp; fnLen++)
503 fp++;
505 ta.ta_Name = FontName = malloc(fnLen + 5 + 1);
506 if (NULL == FontName)
507 return NULL;
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");
516 if ('/' == *fp)
517 fp++;
519 if (StrToLong(fp, &l))
520 ta.ta_YSize = l;
521 else
522 ta.ta_YSize = 8;
524 ta.ta_Style = FS_NORMAL;
525 ta.ta_Flags = 0;
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));
531 free(FontName);
533 return Font;
537 static void ForceRelayout(struct IClass *cl, Object *obj)
539 struct FsMCCInstance *inst = INST_DATA(cl,obj);
540 Object *WindowObj;
541 Object *RootObj = NULL;
543 inst->fsm_NeedRelayout = FALSE;
545 if (muiRenderInfo(obj))
547 WindowObj = _win(obj);
548 get(WindowObj, MUIA_Window_RootObject, &RootObj);
550 if (RootObj)
552 // force relayout
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)
578 size_t Count = 0;
580 while (*src && MaxLen > 1)
582 *dest++ = *src++;
583 MaxLen--;
584 Count++;
586 *dest = '\0';
587 Count++;
589 return Count;
592 #endif /* !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) */