- Fixed a regression in decoding 8-bit images (introduced in my r46589).
[AROS.git] / workbench / system / ftmanager / fontinfo_class.c
blob73b699cd301d071bc62d59463e0be9181c14c607
1 #include <proto/alib.h>
3 #define NO_INLINE_STDARG
5 #include <aros/debug.h>
6 #include <exec/types.h>
7 #include <diskfont/diskfonttag.h>
8 #define MUI_OBSOLETE
9 #include <libraries/mui.h>
11 #include <proto/intuition.h>
12 #include <proto/utility.h>
13 #include <proto/muimaster.h>
14 #include <proto/asl.h>
15 #include <proto/dos.h>
17 #include "fontinfo_class.h"
18 #include "fontbitmap_class.h"
19 #include "globals.h"
20 #include "locale.h"
22 struct FontInfoData
24 STRPTR Filename;
25 FT_Face Face;
26 Object *AttachedFile;
27 Object *Name;
28 Object *YSizeFactorHigh;
29 Object *YSizeFactorLow;
30 Object *StemWeight;
31 Object *SlantStyle;
32 Object *HorizStyle;
33 Object *Family;
34 Object *Fixed;
35 Object *Serif;
36 //Object *AlgoStyle;
37 Object *FaceNum;
38 Object *Metric;
39 Object *BBoxYMin;
40 Object *BBoxYMax;
41 Object *SpaceWidth;
42 Object *Preview;
43 Object *PreviewGroup;
44 Object *Gray;
45 Object *TestSize;
46 Object *TestString;
47 struct TagItem OTags[26];
48 UWORD AvailSizes[OT_MAXAVAILSIZES];
51 typedef struct FontInfoData FontInfoData;
53 struct CycleToStringP
55 Object *String;
56 int NumValues;
57 const UBYTE *Values;
60 AROS_UFH3(void, CycleToString,
61 AROS_UFHA(struct Hook *, hook, A0),
62 AROS_UFHA(Object *, cycle, A2),
63 AROS_UFHA(struct CycleToStringP *, p, A1))
65 AROS_USERFUNC_INIT
67 IPTR entry = 0;
68 Object *str = p->String;
70 get(cycle, MUIA_Cycle_Active, &entry);
71 if (entry == p->NumValues)
73 set(str, MUIA_Disabled, FALSE);
75 else
77 SetAttrs(str,
78 MUIA_Disabled, TRUE,
79 MUIA_String_Integer, p->Values[entry],
80 TAG_END);
83 AROS_USERFUNC_EXIT
87 struct Hook CycleToStringHook = { {NULL, NULL}, UFHN(CycleToString) };
90 struct IntegerBoundsP
92 LONG Min;
93 LONG Max;
96 AROS_UFH3(void, IntegerBounds,
97 AROS_UFHA(struct Hook *, hook, A0),
98 AROS_UFHA(Object *, obj, A2),
99 AROS_UFHA(struct IntegerBoundsP *, p, A1))
101 AROS_USERFUNC_INIT
103 IPTR t = 0;
105 get(obj, MUIA_String_Integer, &t);
106 if (t < p->Min)
108 set(obj, MUIA_String_Integer, p->Min);
110 else if (t > p->Max)
112 set(obj, MUIA_String_Integer, p->Max);
115 AROS_USERFUNC_EXIT
119 struct Hook IntegerBoundsHook = { {NULL, NULL}, UFHN(IntegerBounds) };
122 AROS_UFH3(void, Metric,
123 AROS_UFHA(struct Hook *, hook, A0),
124 AROS_UFHA(Object *, obj, A2),
125 AROS_UFHA(Object **, p, A1))
127 AROS_USERFUNC_INIT
129 IPTR t = 0;
130 ULONG state;
131 int k;
133 get(obj, MUIA_Cycle_Active, &t);
134 state = t != 5;
135 for (k = 0; k < 2; ++k)
137 set(p[k], MUIA_Disabled, state);
140 AROS_USERFUNC_EXIT
144 struct Hook MetricHook = { {NULL, NULL}, UFHN(Metric) };
147 IPTR fiNew(Class *cl, Object *o, struct opSet *msg)
149 struct opSet method;
150 struct TagItem tags[3];
151 STRPTR filename = (STRPTR)GetTagData(MUIA_FontInfo_Filename, (IPTR) NULL, msg->ops_AttrList);
152 FT_Face face = (FT_Face)GetTagData(MUIA_FontInfo_Face, (IPTR) NULL, msg->ops_AttrList);
153 TT_Postscript *postscript;
154 TT_OS2 *os2;
155 Object *name, *attached_file, *size_factor_low, *size_factor_high;
156 Object *stem_weight, *slant_style, *horiz_style, *stem_weight_cycle, *horiz_style_cycle;
157 Object *family, *fixed, /**algo_style,*/ *face_num, *preview, *preview_group;
158 Object *gray, *test_string, *test_size, *serif, *space_width;
159 Object *metric, *bbox_ymin, *bbox_ymax;
160 char name_buf[50];
162 static CONST_STRPTR stem_weight_names[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
163 stem_weight_names[0] =_(MSG_WEIGHT_ULTRATHIN);
164 stem_weight_names[1] =_(MSG_WEIGHT_EXTRATHIN);
165 stem_weight_names[2] =_(MSG_WEIGHT_THIN);
166 stem_weight_names[3] =_(MSG_WEIGHT_EXTRALIGHT);
167 stem_weight_names[4] =_(MSG_WEIGHT_LIGHT);
168 stem_weight_names[5] =_(MSG_WEIGHT_DEMILIGHT);
169 stem_weight_names[6] =_(MSG_WEIGHT_SEMILIGHT);
170 stem_weight_names[7] =_(MSG_WEIGHT_BOOK);
171 stem_weight_names[8] =_(MSG_WEIGHT_MEDIUM);
172 stem_weight_names[9] =_(MSG_WEIGHT_SEMIBOLD);
173 stem_weight_names[10] =_(MSG_WEIGHT_DEMIBOLD);
174 stem_weight_names[11] =_(MSG_WEIGHT_BOLD);
175 stem_weight_names[12] =_(MSG_WEIGHT_EXTRABOLD);
176 stem_weight_names[13] =_(MSG_WEIGHT_BLACK);
177 stem_weight_names[14] =_(MSG_WEIGHT_EXTRABLACK);
178 stem_weight_names[15] =_(MSG_WEIGHT_ULTRABLACK);
179 stem_weight_names[16] =_(MSG_WEIGHT_CUSTOM);
181 static const UBYTE stem_weight_values[] =
183 OTS_UltraThin,
184 OTS_ExtraThin,
185 OTS_Thin,
186 OTS_ExtraLight,
187 OTS_Light,
188 OTS_DemiLight,
189 OTS_SemiLight,
190 OTS_Book,
191 OTS_Medium,
192 OTS_SemiBold,
193 OTS_DemiBold,
194 OTS_Bold,
195 OTS_ExtraBold,
196 OTS_Black,
197 OTS_ExtraBlack,
198 OTS_UltraBlack,
201 static CONST_STRPTR slant_style_names[] = {NULL, NULL, NULL, NULL};
202 slant_style_names[0] = _(MSG_STYLE_UPRIGHT);
203 slant_style_names[1] = _(MSG_STYLE_ITALIC);
204 slant_style_names[2] = _(MSG_STYLE_LEFTITALIC);
206 static CONST_STRPTR horiz_style_names[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
207 horiz_style_names[0] = _(MSG_HSTYLE_ULTRACOMPRESSED);
208 horiz_style_names[1] = _(MSG_HSTYLE_EXTRACOMPRESSED);
209 horiz_style_names[2] = _(MSG_HSTYLE_COMPRESSED);
210 horiz_style_names[3] = _(MSG_HSTYLE_CONDENSED);
211 horiz_style_names[4] = _(MSG_HSTYLE_NORMAL);
212 horiz_style_names[5] = _(MSG_HSTYLE_SEMIEXPANDED);
213 horiz_style_names[6] = _(MSG_HSTYLE_EXPANDED);
214 horiz_style_names[7] = _(MSG_HSTYLE_EXTRAEXPANDED);
215 horiz_style_names[8] = _(MSG_HSTYLE_CUSTOM);
217 static const UBYTE horiz_style_values[] =
219 OTH_UltraCompressed,
220 OTH_ExtraCompressed,
221 OTH_Compressed,
222 OTH_Condensed,
223 OTH_Normal,
224 OTH_SemiExpanded,
225 OTH_Expanded,
226 OTH_ExtraExpanded,
229 static CONST_STRPTR metric_names[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
230 metric_names[0] = _(MSG_METRIC_GLOBALBOUNDINGBOX);
231 metric_names[1] = _(MSG_METRIC_RAWFONTMETRIC);
232 metric_names[2] = _(MSG_METRIC_ASCENDER);
233 metric_names[3] = _(MSG_METRIC_TYPOASCENDER);
234 metric_names[4] = _(MSG_METRIC_USWINASCENDER);
235 metric_names[5] = _(MSG_METRIC_CUSTOMBOUNDINGBOX);
236 //"Bitmap size"
239 if (!filename || !face)
241 DEBUG_FONTINFO(dprintf("FontInfo: filename 0x%x face 0x%x\n", filename, face));
242 return 0;
245 strlcpy(name_buf, face->family_name, sizeof name_buf);
246 strlcat(name_buf, " ", sizeof name_buf);
247 strlcat(name_buf, face->style_name, sizeof name_buf);
249 postscript = FT_Get_Sfnt_Table(face, ft_sfnt_post);
250 os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
252 tags[0].ti_Tag = MUIA_Group_Child;
253 tags[0].ti_Data = (IPTR)ColGroup(2),
254 Child, Label2(_(MSG_LABEL_EXTRAFILE)),
255 Child, attached_file = PopaslObject,
256 MUIA_Popasl_Type, ASL_FileRequest,
257 MUIA_Popstring_String, StringObject,
258 StringFrame,
259 MUIA_String_AdvanceOnCR, TRUE,
260 MUIA_CycleChain, TRUE,
261 End,
262 MUIA_Popstring_Button, PopButton(MUII_PopFile),
263 ASLFR_RejectIcons, TRUE,
264 End,
265 Child, Label2(_(MSG_LABEL_FACENUM)),
266 Child, face_num = StringObject,
267 StringFrame,
268 MUIA_String_Integer, 0,
269 MUIA_String_Accept, "0123456789",
270 MUIA_String_AdvanceOnCR, TRUE,
271 MUIA_String_MaxLen, 5,
272 MUIA_CycleChain, TRUE,
273 End,
274 Child, Label2(_(MSG_LABEL_NAME)),
275 Child, name = StringObject,
276 StringFrame,
277 MUIA_String_Contents, name_buf,
278 MUIA_String_AdvanceOnCR, TRUE,
279 MUIA_String_MaxLen, 50,
280 MUIA_CycleChain, TRUE,
281 End,
282 Child, Label2(_(MSG_LABEL_FAMILY)),
283 Child, family = StringObject,
284 StringFrame,
285 MUIA_String_Contents, face->family_name,
286 MUIA_String_AdvanceOnCR, TRUE,
287 MUIA_CycleChain, TRUE,
288 End,
289 Child, Label2(_(MSG_LABEL_METRIC)),
290 Child, metric = CycleObject,
291 MUIA_Cycle_Entries, metric_names,
292 MUIA_Cycle_Active, 1,
293 MUIA_CycleChain, TRUE,
294 End,
295 Child, Label2(_(MSG_LABEL_BOUNDINGBOX)),
296 Child, HGroup,
297 Child, Label2("yMin"),
298 Child, bbox_ymin = StringObject,
299 StringFrame,
300 MUIA_String_Accept, "-0123456789",
301 MUIA_String_AdvanceOnCR, TRUE,
302 MUIA_String_MaxLen, 6,
303 MUIA_String_Integer, face->bbox.yMin,
304 MUIA_CycleChain, TRUE,
305 End,
306 Child, Label2("yMax"),
307 Child, bbox_ymax = StringObject,
308 StringFrame,
309 MUIA_String_Accept, "-0123456789",
310 MUIA_String_AdvanceOnCR, TRUE,
311 MUIA_String_MaxLen, 6,
312 MUIA_String_Integer, face->bbox.yMax,
313 MUIA_CycleChain, TRUE,
314 End,
315 End,
316 Child, Label2(_(MSG_LABEL_SIZEFACTOR)),
317 Child, HGroup,
318 Child, size_factor_low = StringObject,
319 StringFrame,
320 MUIA_String_Accept, "0123456789",
321 MUIA_String_AdvanceOnCR, TRUE,
322 MUIA_String_MaxLen, 6,
323 MUIA_String_Integer, 1,
324 MUIA_CycleChain, TRUE,
325 End,
326 Child, TextObject,
327 MUIA_Text_Contents, "/",
328 MUIA_Text_SetMax, TRUE,
329 End,
330 Child, size_factor_high = StringObject,
331 StringFrame,
332 MUIA_String_Accept, "0123456789",
333 MUIA_String_AdvanceOnCR, TRUE,
334 MUIA_String_MaxLen, 6,
335 MUIA_String_Integer, 1,
336 MUIA_CycleChain, TRUE,
337 End,
338 End,
339 Child, Label2(_(MSG_LABEL_SPACEWIDTH)),
340 Child, space_width = StringObject,
341 StringFrame,
342 MUIA_String_Accept, "0123456789",
343 MUIA_String_AdvanceOnCR, TRUE,
344 MUIA_String_MaxLen, 6,
345 MUIA_String_Integer, (IPTR)(face->max_advance_width * 250.0 / 72.307),
346 MUIA_CycleChain, TRUE,
347 End,
348 Child, Label1(_(MSG_LABEL_FIXEDWIDTH)),
349 Child, HGroup,
350 Child, fixed = CheckMark((face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0),
351 Child, RectangleObject,
352 End,
353 End,
354 Child, Label1(_(MSG_LABEL_SERIF)),
355 Child, HGroup,
356 Child, serif = CheckMark(os2 && (unsigned)(((os2->sFamilyClass >> 8) &
357 0xff) - 1) < 5),
358 Child, RectangleObject,
359 End,
360 End,
361 Child, Label2(_(MSG_LABEL_STEMWEIGHT)),
362 Child, HGroup,
363 Child, stem_weight_cycle = CycleObject,
364 MUIA_Cycle_Entries, stem_weight_names,
365 MUIA_CycleChain, TRUE,
366 End,
367 Child, stem_weight = StringObject,
368 StringFrame,
369 MUIA_String_Accept, "0123456789",
370 MUIA_String_AdvanceOnCR, TRUE,
371 MUIA_String_MaxLen, 4,
372 MUIA_String_Integer, 128,
373 MUIA_CycleChain, TRUE,
374 End,
375 End,
376 Child, Label2(_(MSG_LABEL_SLANTSTYLE)),
377 Child, slant_style = CycleObject,
378 MUIA_Cycle_Entries, slant_style_names,
379 MUIA_Cycle_Active, face->style_flags & FT_STYLE_FLAG_ITALIC ?
380 (postscript && postscript->italicAngle > 0 ?
381 OTS_LeftItalic : OTS_Italic) : OTS_Upright,
382 MUIA_CycleChain, TRUE,
383 End,
384 Child, Label2(_(MSG_LABEL_HORIZSTYLE)),
385 Child, HGroup,
386 Child, horiz_style_cycle = CycleObject,
387 MUIA_Cycle_Entries, horiz_style_names,
388 MUIA_CycleChain, TRUE,
389 End,
390 Child, horiz_style = StringObject,
391 StringFrame,
392 MUIA_String_Accept, "0123456789",
393 MUIA_String_AdvanceOnCR, TRUE,
394 MUIA_String_MaxLen, 4,
395 MUIA_String_Integer, 128,
396 MUIA_CycleChain, TRUE,
397 End,
398 End,
399 /*Child, Label1("No algo style"),
400 Child, HGroup,
401 Child, algo_style = CheckMark(FALSE),
402 Child, RectangleObject,
403 End,
404 End,*/
405 End;
406 tags[1].ti_Tag = MUIA_Group_Child;
407 tags[1].ti_Data = (IPTR)VGroup,
408 GroupFrameT(_(MSG_FRAME_PREVIEW)),
409 Child, test_string = StringObject,
410 StringFrame,
411 MUIA_String_Contents, _(MSG_PREVIEW_STRING),
412 MUIA_String_AdvanceOnCR, TRUE,
413 MUIA_CycleChain, TRUE,
414 End,
415 Child, HGroup,
416 Child, Label2(_(MSG_LABEL_SIZE)),
417 Child, test_size = StringObject,
418 StringFrame,
419 MUIA_String_Accept, "0123456789",
420 MUIA_String_Integer, 30,
421 MUIA_String_AdvanceOnCR, TRUE,
422 MUIA_CycleChain, TRUE,
423 End,
424 Child, Label2(_(MSG_LABEL_ANTIALIASING)),
425 Child, gray = CheckMark(FALSE),
426 End,
427 Child, ScrollgroupObject,
428 MUIA_Scrollgroup_Contents, VirtgroupObject,
429 VirtualFrame,
430 Child, VCenter(HCenter((preview_group = VGroup,
431 Child, preview = RectangleObject,
432 End,
433 End))),
434 End,
435 End,
436 End;
437 tags[2].ti_Tag = TAG_MORE;
438 tags[2].ti_Data = (IPTR)msg->ops_AttrList;
440 method.MethodID = OM_NEW;
441 method.ops_AttrList = tags;
442 method.ops_GInfo = NULL;
444 o = (Object *)DoSuperMethodA(cl, o, (Msg)&method);
445 if (o)
447 FontInfoData *dat = INST_DATA(cl, o);
449 dat->Filename = filename;
450 dat->Face = face;
451 dat->AttachedFile = attached_file;
452 dat->Name = name;
453 dat->Family = family;
454 dat->YSizeFactorLow = size_factor_low;
455 dat->YSizeFactorHigh = size_factor_high;
456 dat->StemWeight = stem_weight;
457 dat->SlantStyle = slant_style;
458 dat->HorizStyle = horiz_style;
459 dat->SpaceWidth = space_width;
460 dat->Fixed = fixed;
461 dat->Serif = serif;
462 //dat->AlgoStyle = algo_style;
463 dat->FaceNum = face_num;
464 dat->Metric = metric;
465 dat->BBoxYMin = bbox_ymin;
466 dat->BBoxYMax = bbox_ymax;
467 dat->Preview = preview;
468 dat->PreviewGroup = preview_group;
469 dat->TestString = test_string;
470 dat->TestSize = test_size;
471 dat->Gray = gray;
473 DoMethod(size_factor_low, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
474 size_factor_low, 4, MUIM_CallHook, &IntegerBoundsHook, 1, 65535);
475 DoMethod(size_factor_high, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
476 size_factor_high, 4, MUIM_CallHook, &IntegerBoundsHook, 1, 65535);
478 DoMethod(stem_weight_cycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
479 stem_weight_cycle, 5, MUIM_CallHook, &CycleToStringHook,
480 stem_weight, sizeof(stem_weight_values), stem_weight_values);
481 DoMethod(stem_weight, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
482 stem_weight, 4, MUIM_CallHook, &IntegerBoundsHook, 0, 255);
484 DoMethod(horiz_style_cycle, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
485 horiz_style_cycle, 5, MUIM_CallHook, &CycleToStringHook,
486 horiz_style, sizeof(horiz_style_values), horiz_style_values);
487 DoMethod(horiz_style, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
488 horiz_style, 4, MUIM_CallHook, &IntegerBoundsHook, 0, 255);
490 set(stem_weight_cycle, MUIA_Cycle_Active,
491 face->style_flags & FT_STYLE_FLAG_BOLD ? 11 : 7);
492 set(horiz_style_cycle, MUIA_Cycle_Active, 4);
494 DoMethod(test_string, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
495 o, 1, MUIM_FontInfo_UpdatePreview);
496 DoMethod(test_size, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
497 o, 1, MUIM_FontInfo_UpdatePreview);
498 DoMethod(gray, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
499 o, 1, MUIM_FontInfo_UpdatePreview);
501 DoMethod(bbox_ymin, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
502 bbox_ymin, 4, MUIM_CallHook, &IntegerBoundsHook, -32768, 32767);
503 DoMethod(bbox_ymax, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
504 bbox_ymax, 4, MUIM_CallHook, &IntegerBoundsHook, -32768, 32767);
506 DoMethod(metric, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
507 metric, 6, MUIM_CallHook, &MetricHook, bbox_ymin, bbox_ymax);
509 set(metric, MUIA_Cycle_Active, 0);
511 if (//!(face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) &&
512 FT_Set_Char_Size(face, 250 * 64, 250 * 64, 2540, 2540) == 0 &&
513 FT_Load_Char(face, ' ', FT_LOAD_DEFAULT) == 0)
515 set(space_width, MUIA_String_Integer, face->glyph->metrics.horiAdvance >> 6);
518 if (os2)
520 int weight = os2->usWeightClass;
521 int value;
523 value = 0; /* UltraThin */
524 if (weight < 10) weight *= 100;
525 if (weight >= 200) value = 2; /* Thin */
526 if (weight >= 300) value = 4; /* Light */
527 if (weight >= 400) value = 7; /* Book */
528 if (weight >= 500) value = 8; /* Medium */
529 if (weight >= 600) value = 10; /* DemiBold */
530 if (weight >= 700) value = 11; /* Bold */
531 if (weight >= 800) value = 13; /* Black */
532 if (weight >= 900) value = 15; /* UltraBlack */
533 set(stem_weight_cycle, MUIA_Cycle_Active, value);
535 set(horiz_style_cycle, MUIA_Cycle_Active, os2->usWidthClass - 1);
538 DoMethod(o, MUIM_FontInfo_UpdatePreview);
541 DEBUG_FONTINFO(dprintf("FontInfo: created object 0x%lx\n", o));
543 return (IPTR)o;
546 #if 0
547 IPTR fiDispose(Class *cl, Object *o)
549 FontInfoData *dat = INST_DATA(cl, o);
551 return DoSuperMethod(cl, o, OM_DISPOSE);
553 #endif
555 IPTR fiSetOTags(Class *cl, Object *o)
557 FontInfoData *dat = INST_DATA(cl, o);
558 struct TagItem *tag = dat->OTags;
559 IPTR x = 0;
560 IPTR y = 0;
562 tag->ti_Tag = OT_FileIdent;
563 ++tag;
565 tag->ti_Tag = OT_Engine;
566 tag->ti_Data = (IPTR)"freetype2";
567 ++tag;
569 tag->ti_Tag = OT_Family;
570 get(dat->Family, MUIA_String_Contents, &tag->ti_Data);
571 ++tag;
573 //tag->ti_Tag = OT_BName;
574 //tag->ti_Tag = OT_IName;
575 //tag->ti_Tag = OT_BIName;
576 //tag->ti_Tag = OT_SymbolSet; charmap index
578 get(dat->YSizeFactorLow, MUIA_String_Integer, &x);
579 get(dat->YSizeFactorHigh, MUIA_String_Integer, &y);
580 x = (UWORD)x;
581 y = (UWORD)y;
582 if (x == 0) x = 1;
583 if (y == 0) y = 1;
584 tag->ti_Tag = OT_YSizeFactor;
585 tag->ti_Data = x | (y << 16);
586 ++tag;
588 tag->ti_Tag = OT_SpaceWidth;
589 get(dat->SpaceWidth, MUIA_String_Integer, &tag->ti_Data);
590 ++tag;
592 tag->ti_Tag = OT_IsFixed;
593 get(dat->Fixed, MUIA_Selected, &tag->ti_Data);
594 ++tag;
596 tag->ti_Tag = OT_SerifFlag;
597 get(dat->Serif, MUIA_Selected, &tag->ti_Data);
598 ++tag;
600 tag->ti_Tag = OT_StemWeight;
601 get(dat->StemWeight, MUIA_String_Integer, &tag->ti_Data);
602 ++tag;
604 tag->ti_Tag = OT_SlantStyle;
605 get(dat->SlantStyle, MUIA_Cycle_Active, &tag->ti_Data);
606 ++tag;
608 tag->ti_Tag = OT_HorizStyle;
609 get(dat->HorizStyle, MUIA_String_Integer, &tag->ti_Data);
610 ++tag;
612 tag->ti_Tag = OT_SpaceFactor;
613 tag->ti_Data = 0x10000;
614 ++tag;
616 tag->ti_Tag = OT_InhibitAlgoStyle;
617 tag->ti_Data = FSF_UNDERLINED | FSF_BOLD;
618 //get(dat->AlgoStyle, MUIA_Selected, &tag->ti_Data);
619 ++tag;
621 tag->ti_Tag = OT_SpecCount;
622 tag->ti_Data = 4;
623 ++tag;
625 tag->ti_Tag = OT_Spec1_FontFile;
626 tag->ti_Data = (IPTR)dat->Filename;
627 ++tag;
629 tag->ti_Tag = OT_Spec3_AFMFile;
630 get(dat->AttachedFile, MUIA_String_Contents, &tag->ti_Data);
631 ++tag;
633 tag->ti_Tag = OT_Spec4_Metric;
634 get(dat->Metric, MUIA_Cycle_Active, &tag->ti_Data);
635 ++tag;
637 if (tag[-1].ti_Data == METRIC_CUSTOMBBOX)
639 IPTR ymin = 0;
640 IPTR ymax = 0;
642 get(dat->BBoxYMin, MUIA_String_Integer, &ymin);
643 get(dat->BBoxYMax, MUIA_String_Integer, &ymax);
644 tag->ti_Tag = OT_Spec5_BBox;
645 tag->ti_Data = (ymax << 16) | (UWORD)ymin;
646 ++tag;
649 tag->ti_Tag = OT_Spec6_FaceNum;
650 get(dat->FaceNum, MUIA_String_Integer, &tag->ti_Data);
651 ++tag;
653 if (!IsDefaultCodePage())
655 tag->ti_Tag = OT_Spec2_CodePage;
656 tag->ti_Data = (IPTR)codepage;
657 ++tag;
660 tag->ti_Tag = TAG_END;
662 dat->AvailSizes[0] = AROS_WORD2BE(2); // <- number of entries...
663 dat->AvailSizes[1] = AROS_WORD2BE(10);
664 dat->AvailSizes[2] = AROS_WORD2BE(15);
666 return tag - dat->OTags;
669 ULONG fiUpdatePreview(Class *cl, Object *o)
671 FontInfoData *dat = INST_DATA(cl, o);
672 Object *preview;
673 STRPTR str = NULL;
674 IPTR gray = 0;
675 IPTR size = 0;
677 fiSetOTags(cl, o);
679 get(dat->TestString, MUIA_String_Contents, &str);
680 get(dat->Gray, MUIA_Selected, &gray);
681 get(dat->TestSize, MUIA_String_Integer, &size);
683 preview = FontBitmapObject,
684 MUIA_FontBitmap_Filename, dat->Filename,
685 MUIA_FontBitmap_OTags, dat->OTags,
686 MUIA_FontBitmap_String, str,
687 MUIA_FontBitmap_Gray, gray,
688 MUIA_FontBitmap_Size, size,
689 End;
691 DEBUG_FONTINFO(dprintf("FontInfo::UpdatePreview: new 0x%lx\n", preview));
693 if (preview)
695 DoMethod(dat->PreviewGroup, MUIM_Group_InitChange);
696 if (dat->Preview)
698 DoMethod(dat->PreviewGroup, OM_REMMEMBER, dat->Preview);
699 DisposeObject(dat->Preview);
701 DoMethod(dat->PreviewGroup, OM_ADDMEMBER, preview);
702 DoMethod(dat->PreviewGroup, MUIM_Group_ExitChange);
703 dat->Preview = preview;
706 return preview != NULL;
709 ULONG fiWriteFiles(Class *cl, Object *o)
711 FontInfoData *dat = INST_DATA(cl, o);
712 BPTR file;
713 char name[32];
714 STRPTR base = NULL;
715 BPTR olddir;
717 get(dat->Name, MUIA_String_Contents, &base);
718 if (!base || !base[0])
719 return FALSE;
721 olddir = CurrentDir(destdir);
723 strcpy(name, base);
724 strcat(name, ".otag");
726 file = Open(name, MODE_NEWFILE);
727 if (file)
729 struct TagItem *tag;
730 ULONG size, indirect_size;
731 UBYTE *buffer;
732 int num_sizes;
735 * In the file we store 32-bit form of taglist.
736 * Each complete tag can be represented by UQUAD (two ULONGs),
737 * and we also append one ULONG for TAG_DONE terminator
739 size = sizeof(ULONG) + (fiSetOTags(cl, o) + 2) * sizeof(UQUAD);
740 indirect_size = 0;
742 for (tag = dat->OTags; tag->ti_Tag != TAG_END; ++tag)
744 if (tag->ti_Tag == OT_Spec2_CodePage)
746 indirect_size += 1;
747 indirect_size &= ~1;
748 indirect_size += sizeof(codepage);
750 else if (tag->ti_Tag & OT_Indirect && tag->ti_Data)
752 indirect_size += strlen((const char *)tag->ti_Data) + 1;
756 indirect_size += 1;
757 indirect_size &= ~1;
759 num_sizes = 1 + dat->AvailSizes[0];
760 indirect_size += num_sizes * sizeof(UWORD);
762 dat->OTags[0].ti_Data = size + indirect_size;
764 buffer = malloc(indirect_size);
765 if (buffer)
767 size_t offset = 0;
768 ULONG *write_tags;
769 ULONG *dest;
771 memset(buffer, 0, indirect_size);
773 for (tag = dat->OTags; tag->ti_Tag != TAG_END; ++tag)
775 if (tag->ti_Tag == OT_Spec2_CodePage)
777 offset += 1;
778 offset &= ~1;
779 memcpy(buffer + offset, codepage, sizeof(codepage));
780 tag->ti_Data = size + offset;
781 offset += sizeof(codepage);
783 else if (tag->ti_Tag & OT_Indirect && tag->ti_Data)
785 size_t len = strlen((const char *)tag->ti_Data) + 1;
787 memcpy(buffer + offset, (const char *)tag->ti_Data, len);
788 tag->ti_Data = size + offset;
789 offset += len;
793 offset += 1;
794 offset &= ~1;
796 tag->ti_Tag = OT_AvailSizes;
797 tag->ti_Data = size + offset;
798 ++tag;
800 tag->ti_Tag = TAG_END;
802 memcpy(buffer + offset, dat->AvailSizes, num_sizes * sizeof(UWORD));
803 offset += num_sizes * sizeof(UWORD);
805 write_tags = malloc(size);
807 dest = write_tags;
808 for (tag = dat->OTags; tag->ti_Tag != TAG_END; tag++)
810 dest[0] = AROS_LONG2BE(tag->ti_Tag);
811 dest[1] = AROS_LONG2BE(tag->ti_Data);
812 dest += 2;
814 dest[0] = AROS_LONG2BE(TAG_END);
816 Write(file, write_tags, size);
817 free(write_tags);
819 Write(file, buffer, offset);
820 free(buffer);
823 Close(file);
826 strcpy(name, base);
827 strcat(name, ".font");
829 file = Open(name, MODE_NEWFILE);
830 if (file)
832 static UBYTE data[] = {0x0f, 0x03, 0x00, 0x00 };
833 Write(file, data, sizeof(data));
834 Close(file);
837 CurrentDir(olddir);
839 return 1;
842 AROS_UFH3(ULONG, FontInfoDispatch,
843 AROS_UFHA(Class *, cl, A0),
844 AROS_UFHA(Object *, o, A2),
845 AROS_UFHA(Msg, msg, A1))
847 AROS_USERFUNC_INIT
849 ULONG ret;
851 switch (msg->MethodID)
853 case OM_NEW:
854 ret = fiNew(cl, o, (struct opSet *)msg);
855 break;
857 #if 0
858 case OM_DISPOSE:
859 ret = fiDispose(cl, o);
860 break;
861 #endif
863 case MUIM_FontInfo_UpdatePreview:
864 ret = fiUpdatePreview(cl, o);
865 break;
867 case MUIM_FontInfo_WriteFiles:
868 ret = fiWriteFiles(cl, o);
869 break;
871 default:
872 ret = DoSuperMethodA(cl, o, msg);
873 break;
876 return ret;
878 AROS_USERFUNC_EXIT
882 void CleanupFontInfoClass(void)
884 if (FontInfoClass)
886 MUI_DeleteCustomClass(FontInfoClass);
887 FontInfoClass = NULL;
891 int InitFontInfoClass(void)
893 FontInfoClass = MUI_CreateCustomClass(NULL, MUIC_Group, NULL,
894 sizeof(FontInfoData), UFHN(FontInfoDispatch));
895 return FontInfoClass != NULL;