Added memory-stored debug output to safe mode.
[cake.git] / workbench / libs / diskfont / bullet.c
blob7bd284129e072e187c946c879c69acce0c73a009
1 /*
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
3 $Id$
5 Functions for reading .font files
6 */
8 /****************************************************************************************/
10 #include <dos/dos.h>
11 #include <diskfont/diskfont.h>
12 #include <diskfont/diskfonttag.h>
13 #include <diskfont/oterrors.h>
14 #include <diskfont/glyph.h>
15 #include <aros/macros.h>
16 #include <aros/debug.h>
18 #include <proto/exec.h>
19 #include <proto/dos.h>
20 #include <proto/utility.h>
21 #include <proto/bullet.h>
22 #include <proto/graphics.h>
24 #include <string.h>
26 #include "diskfont_intern.h"
28 /****************************************************************************************/
30 /* bold -> {OT_EmboldenX, 0xE75}, {OT_EmboldenY, 0x99E} */
31 /* italic -> {OT_ShearSin, 0x4690}, {OT_ShearCos, 0xF615} */
33 /* only if OT_InhibitAlgoStyle has corresponding bit cleared! */
35 /****************************************************************************************/
37 STRPTR OTAG_MakeFileName(CONST_STRPTR filename, struct DiskfontBase_intern *DiskfontBase)
39 STRPTR retval;
40 LONG l;
42 l = strlen(filename) + 1;
43 if (l < 7) return NULL;
45 retval = AllocVec(l, MEMF_ANY);
46 if (retval)
48 memcpy(retval, filename, l - 5);
49 strcpy(retval + l - 5, "otag");
52 return retval;
55 /****************************************************************************************/
57 VOID OTAG_FreeFileName(STRPTR filename, struct DiskfontBase_intern *DiskfontBase)
59 if (filename) FreeVec(filename);
62 /****************************************************************************************/
64 #ifdef __AROS__
65 #warning This needs to be reworked for systems where sizeof(TagItem) is > 8!
66 #endif
68 /****************************************************************************************/
70 struct OTagList *OTAG_GetFile(CONST_STRPTR filename, struct DiskfontBase_intern *DiskfontBase)
72 struct FileInfoBlock *fib;
73 struct OTagList *otaglist;
74 struct TagItem *ti;
75 STRPTR otagfilename;
76 BPTR otagfile;
77 LONG l;
78 BOOL ok;
80 otagfilename = OTAG_MakeFileName(filename, DiskfontBase);
81 if (!otagfilename) return NULL;
83 otagfile = Open(otagfilename, MODE_OLDFILE);
84 if (!otagfile)
86 OTAG_FreeFileName(otagfilename, DiskfontBase);
87 return NULL;
90 fib = AllocDosObject(DOS_FIB, NULL);
91 if (!fib)
93 OTAG_FreeFileName(otagfilename, DiskfontBase);
94 Close(otagfile);
95 return NULL;
98 ok = ExamineFH(otagfile, fib);
99 l = fib->fib_Size;
100 FreeDosObject(DOS_FIB, fib);
102 if (!ok)
104 OTAG_FreeFileName(otagfilename, DiskfontBase);
105 Close(otagfile);
106 return NULL;
109 otaglist = AllocVec(sizeof(struct OTagList) + l, MEMF_PUBLIC | MEMF_CLEAR);
110 if (!otaglist)
112 OTAG_FreeFileName(otagfilename, DiskfontBase);
113 Close(otagfile);
114 return NULL;
117 ok = (Read(otagfile, otaglist->tags, l) == l);
118 Close(otagfile);
120 if (AROS_LONG2BE(otaglist->tags[0].ti_Tag) != OT_FileIdent) ok = FALSE;
121 if (AROS_LONG2BE(otaglist->tags[0].ti_Data) != l) ok = FALSE;
123 if (!ok)
125 OTAG_FreeFileName(otagfilename, DiskfontBase);
126 FreeVec(otaglist);
127 return NULL;
130 ti = otaglist->tags;
134 ti->ti_Tag = AROS_LONG2BE(ti->ti_Tag);
135 ti->ti_Data = AROS_LONG2BE(ti->ti_Data);
137 if (ti->ti_Tag & OT_Indirect)
139 ti->ti_Data = (IPTR)otaglist->tags + ti->ti_Data;
142 } while ((ti++)->ti_Tag != TAG_DONE);
144 otaglist->filename = otagfilename;
146 return otaglist;
150 /****************************************************************************************/
152 VOID OTAG_KillFile(struct OTagList *otaglist, struct DiskfontBase_intern *DiskfontBase)
154 if (otaglist)
156 if (otaglist->filename) OTAG_FreeFileName(otaglist->filename, DiskfontBase);
157 FreeVec(otaglist);
161 /****************************************************************************************/
163 UBYTE OTAG_GetFontStyle(struct OTagList *otaglist, struct DiskfontBase_intern *DiskfontBase)
165 UBYTE style = 0;
167 /* A font becomes FSF_BOLD if OT_StemWeight >= 0x90 */
169 if (GetTagData(OT_StemWeight, 0, otaglist->tags) >= 0x90)
171 style |= FSF_BOLD;
174 /* A font becomes FSF_ITALIC if OT_SlantStyle != OTS_Upright */
176 if (GetTagData(OT_SlantStyle, OTS_Upright, otaglist->tags) != OTS_Upright)
178 style |= FSF_ITALIC;
181 /* A font becomes FSF_EXTENDED if OT_HorizStyle >= 0xA0 */
183 if (GetTagData(OT_HorizStyle, 0, otaglist->tags) >= 0xA0)
185 style |= FSF_EXTENDED;
188 return style;
191 /****************************************************************************************/
193 UBYTE OTAG_GetSupportedStyles(struct OTagList *otaglist,
194 struct DiskfontBase_intern *DiskfontBase)
196 UBYTE inhibit, supported;
198 #define STYLES (FSF_BOLD | FSF_ITALIC | FSF_UNDERLINED)
201 ** If a style bit is set in OT_InhibitAlgoStyle, then this
202 ** style cannot be handled/calculated/created by the font engine.
204 ** If it is, then the font engine can handle/calculate/create it
207 inhibit = GetTagData(OT_InhibitAlgoStyle, 0, otaglist->tags);
208 supported = (inhibit & STYLES) ^ STYLES;
210 return supported;
213 /****************************************************************************************/
215 UBYTE OTAG_GetFontFlags(struct OTagList *otaglist, struct DiskfontBase_intern *DiskfontBase)
217 UBYTE flags;
219 flags = FONTTYPE_OUTLINEFONT;
220 if (GetTagData(OT_IsFixed, FALSE, otaglist->tags) == FALSE)
222 flags |= FPF_PROPORTIONAL;
225 return flags;
228 /****************************************************************************************/
230 static BOOL OTAG_SetupFontEngine(struct TTextAttr *ta,
231 struct TTextAttr *ra,
232 struct OTagList *otag,
233 struct GlyphEngine *ge,
234 LONG *xdpi_ptr,
235 LONG *ydpi_ptr,
236 struct Library *BulletBase,
237 struct DiskfontBase_intern *DiskfontBase)
239 struct TagItem maintags[] =
241 {OT_OTagList, (IPTR)otag->tags },
242 {OT_OTagPath, (IPTR)otag->filename },
243 {TAG_DONE }
245 struct TagItem sizetags[] =
247 {OT_PointHeight, 0 },
248 {OT_DeviceDPI , 0 },
249 {OT_DotSize , 0 },
250 {TAG_DONE }
252 LONG pointheight, xdot, ydot;
253 LONG xdpi, ydpi, taxdpi, taydpi;
254 LONG ysizefactor, ysizefactor_low, ysizefactor_high;
256 ysizefactor = GetTagData(OT_YSizeFactor, 0x10001, otag->tags);
257 ysizefactor_low = ysizefactor & 0xFFFF;
258 ysizefactor_high = (ysizefactor >> 16) & 0xFFFF;
260 if (!ysizefactor_low)
262 ysizefactor_low = ysizefactor_high = 1;
265 if ((ra->tta_Style & FSF_TAGGED) && ra->tta_Tags)
267 ULONG devicedpi;
269 devicedpi = GetTagData(TA_DeviceDPI, 0x10001, ra->tta_Tags);
270 taxdpi = (devicedpi >> 16) & 0xFFFF;
271 taydpi = devicedpi & 0xFFFF;
273 if (!taydpi)
275 taxdpi = taydpi = 1;
278 else
280 taxdpi = taydpi = 1;
283 xdpi = 72 * ysizefactor_high / ysizefactor_low * taxdpi / taydpi;
284 ydpi = 72 * ysizefactor_high / ysizefactor_low;
286 *xdpi_ptr = xdpi;
287 *ydpi_ptr = ydpi;
289 pointheight = ra->tta_YSize << 16;
290 xdot = ydot = 100;
292 sizetags[0].ti_Data = pointheight;
293 sizetags[1].ti_Data = (xdpi << 16) | ydpi;
294 sizetags[2].ti_Data = (xdot << 16) | ydot;
296 if (SetInfoA(ge, maintags) != OTERR_Success)
298 return FALSE;
301 return (SetInfoA(ge, sizetags) == OTERR_Success);
305 /****************************************************************************************/
307 static VOID OTAG_FreeAAGlyphMaps(struct GlyphEngine *ge,
308 struct GlyphMap **gm,
309 struct Library *BulletBase,
310 struct DiskfontBase_intern *DiskfontBase)
312 UWORD i;
314 for(i = 0; i < 257; i++)
316 if (gm[i])
318 struct TagItem releasetags[] =
320 {OT_GlyphMap8Bits, (IPTR)gm[i]},
321 {TAG_DONE }
324 ReleaseInfoA(ge, releasetags);
326 gm[i] = NULL;
331 /****************************************************************************************/
333 static VOID OTAG_FreeGlyphMaps(struct GlyphEngine *ge,
334 struct GlyphMap **gm,
335 struct Library *BulletBase,
336 struct DiskfontBase_intern *DiskfontBase)
338 UWORD i;
340 for(i = 0; i < 257; i++)
342 if (gm[i])
344 struct TagItem releasetags[] =
346 {OT_GlyphMap, (IPTR)gm[i]},
347 {TAG_DONE }
350 ReleaseInfoA(ge, releasetags);
352 gm[i] = NULL;
357 /****************************************************************************************/
359 static BOOL OTAG_GetGlyphMaps(struct GlyphEngine *ge,
360 struct GlyphMap **gm,
361 UWORD fontheight,
362 WORD *lochar,
363 WORD *hichar,
364 WORD *baseline,
365 LONG *gfxwidth,
366 struct Library *BulletBase,
367 struct DiskfontBase_intern *DiskfontBase)
369 UWORD i;
371 *lochar = -1;
372 *hichar = 0;
373 *baseline = 0;
374 *gfxwidth = 0;
376 for(i = 0; i < 257; i++)
378 struct TagItem settags[] =
380 {OT_GlyphCode, (i < 256) ? i : 0x25A1},
381 {TAG_DONE }
383 struct TagItem obtaintags[] =
385 {OT_GlyphMap, (IPTR)&gm[i] },
386 {TAG_DONE }
389 SetInfoA(ge, settags);
390 ObtainInfoA(ge, obtaintags);
392 if (gm[i])
394 if (i < 256)
396 if (*lochar == -1) *lochar = i;
397 *hichar = i;
400 if (gm[i]->glm_Y0/* - (WORD)gm[i]->glm_BlackTop*/ > *baseline)
402 *baseline = gm[i]->glm_Y0/* - (WORD)gm[i]->glm_BlackTop*/;
405 *gfxwidth += gm[i]->glm_BlackWidth;
409 if (*baseline >= fontheight) *baseline = fontheight;
410 if (*lochar > 32) *lochar = 32;
412 return (*lochar == -1) ? FALSE : TRUE;
415 /****************************************************************************************/
417 static BOOL OTAG_GetAAGlyphMaps(struct GlyphEngine *ge,
418 struct GlyphMap **gm,
419 struct Library *BulletBase,
420 struct DiskfontBase_intern *DiskfontBase)
422 UWORD i;
424 for(i = 0; i < 257; i++)
426 LONG rc;
428 struct TagItem settags[] =
430 {OT_GlyphCode, (i < 256) ? i : 0x25A1},
431 {TAG_DONE }
433 struct TagItem obtaintags[] =
435 {OT_GlyphMap8Bits, (IPTR)&gm[i] },
436 {TAG_DONE }
439 SetInfoA(ge, settags);
440 rc = ObtainInfoA(ge, obtaintags);
442 if (i == 0 && rc == OTERR_UnknownTag)
443 return FALSE;
446 return TRUE;
449 /****************************************************************************************/
451 struct AADiskFontHeader *OTAG_AllocFontStruct(STRPTR name, UWORD numchars, LONG gfxwidth,
452 LONG fontheight, struct DiskfontBase_intern *DiskfontBase)
454 struct AADiskFontHeader *dfh;
455 APTR charkern;
456 APTR charspace;
457 APTR charloc;
458 APTR chardata;
459 APTR prevsegment = NULL;
460 BOOL ok = FALSE;
462 dfh = prevsegment = AllocSegment(prevsegment,
463 sizeof(*dfh) + sizeof(struct TagItem) * 5,
464 MEMF_ANY | MEMF_CLEAR,
465 DiskfontBase);
467 if (dfh)
469 charkern = prevsegment = AllocSegment(prevsegment,
470 numchars * sizeof(WORD),
471 MEMF_ANY | MEMF_CLEAR,
472 DiskfontBase);
473 if (charkern)
475 charspace = prevsegment = AllocSegment(prevsegment,
476 numchars * sizeof(WORD),
477 MEMF_ANY | MEMF_CLEAR,
478 DiskfontBase);
480 if (charspace)
482 charloc = prevsegment = AllocSegment(prevsegment,
483 numchars * sizeof(LONG),
484 MEMF_ANY | MEMF_CLEAR,
485 DiskfontBase);
487 if (charloc)
489 gfxwidth = (gfxwidth + 15) & ~15;
491 chardata = prevsegment = AllocSegment(prevsegment,
492 gfxwidth / 8 * fontheight,
493 MEMF_ANY | MEMF_CLEAR,
494 DiskfontBase);
496 if (chardata)
498 WORD i;
500 dfh->dfh_FileID = DFH_ID;
501 dfh->dfh_DF.ln_Name = dfh->dfh_Name;
502 dfh->dfh_Segment = (LONG)MAKE_REAL_SEGMENT(dfh);
504 i = strlen(FilePart(name)) + 1;
505 if (i >= sizeof(dfh->dfh_Name)) i = sizeof(dfh->dfh_Name) - 1;
506 CopyMem(FilePart(name), dfh->dfh_Name, i);
508 dfh->dfh_TF.ctf_TF.tf_Message.mn_Node.ln_Name = dfh->dfh_Name;
509 dfh->dfh_TF.ctf_TF.tf_Message.mn_Node.ln_Type = NT_FONT;
511 dfh->dfh_TF.ctf_TF.tf_YSize = fontheight;
512 dfh->dfh_TF.ctf_TF.tf_CharKern = charkern;
513 dfh->dfh_TF.ctf_TF.tf_CharSpace = charspace;
514 dfh->dfh_TF.ctf_TF.tf_CharLoc = charloc;
515 dfh->dfh_TF.ctf_TF.tf_CharData = chardata;
516 dfh->dfh_TF.ctf_TF.tf_Modulo = gfxwidth / 8;
517 dfh->dfh_TF.ctf_TF.tf_BoldSmear = 1;
519 ok = TRUE;
522 } /* if (charloc) */
524 } /* if (charspace) */
526 } /* if (charkern) */
528 } /* if (dfh) */
530 if (!ok)
532 if (dfh) UnLoadSeg(MAKE_REAL_SEGMENT(dfh));
533 dfh = NULL;
536 return dfh;
539 /****************************************************************************************/
541 static LONG OTAG_AllocAAData(struct ColorTextFont *ctf,
542 struct DiskfontBase_intern *DiskfontBase)
544 UBYTE *aadata;
545 int k;
546 int gfxwidth, fontheight;
548 gfxwidth = ctf->ctf_TF.tf_Modulo * 8;
549 fontheight = ctf->ctf_TF.tf_YSize;
551 aadata = AllocSegment(ctf->ctf_TF.tf_CharData,
552 gfxwidth * fontheight,
553 MEMF_ANY | MEMF_CLEAR,
554 DiskfontBase);
555 if (!aadata)
556 return FALSE;
558 ctf->ctf_TF.tf_Style |= FSF_COLORFONT;
559 ctf->ctf_Flags = CT_ANTIALIAS;
560 ctf->ctf_Depth = 8;
561 ctf->ctf_High = 0xff;
563 for (k = 0; k < 8; ++k)
564 ctf->ctf_CharData[k] = aadata;
566 return TRUE;
569 /****************************************************************************************/
571 static VOID OTAG_CalcMetrics(struct GlyphMap **gm, struct TextFont *tf)
573 WORD *charspace = (UWORD *)tf->tf_CharSpace;
574 WORD *charkern = (UWORD *)tf->tf_CharKern;
575 UWORD lochar = tf->tf_LoChar;
576 UWORD hichar = tf->tf_HiChar;
577 UWORD i;
579 for(i = lochar; i <= hichar + 1; i++)
581 struct GlyphMap *g;
582 WORD index;
584 index = (i <= hichar) ? i : 256;
586 g = gm[index];
587 if (!g && (i != 32)) g = gm[256];
589 if (g)
591 charkern [i - lochar] = ((WORD)g->glm_BlackLeft) - g->glm_X0;
592 charspace[i - lochar] = g->glm_X1 - (WORD)g->glm_BlackLeft;
594 if ((tf->tf_Flags & FPF_PROPORTIONAL) == 0)
597 In a fixed font (charkern + charspace) must always equal
598 calculated fontwidth.
600 x = propspace - propkern
601 fixedkern = (fontwidth - x + 1) / 2
602 fixedspace = fontwidth - fixedkern
605 LONG w = charspace[i - lochar] - charkern[i - lochar];
607 charkern[i - lochar] = ((LONG)tf->tf_XSize - w + 1) / 2;
608 charspace[i - lochar] = (LONG)tf->tf_XSize - charkern[i - lochar];
613 else if ((i == 32) || ((tf->tf_Flags & FPF_PROPORTIONAL) == 0))
615 charkern[i - lochar] = 0;
616 charspace[i - lochar] = tf->tf_XSize;
619 } /* for(i = lochar; i <= hichar + 1; i++) */
622 /****************************************************************************************/
624 static VOID OTAG_BlitGlyph(struct GlyphMap *gm, struct TextFont *tf, LONG xpos,
625 LONG ypos, struct DiskfontBase_intern *DiskfontBase)
627 UBYTE *src, *dest;
628 LONG x, y, width, height;
629 LONG srcx, destx, srcy;
631 srcx = gm->glm_BlackLeft & 7;
632 srcy = gm->glm_BlackTop;
633 destx = xpos & 7;
634 width = gm->glm_BlackWidth;
635 height = gm->glm_BlackHeight;
637 if ((width < 1) || (height < 1)) return;
639 #warning whats the best thing to do here
641 /* Check if glyph is bigger/elsewhere than expected,
642 ie. extends outside the bounding box vertically:
644 possible cases:
647 ****
648 ** **
649 ** **
650 ** **
651 ***** ***** ** **
652 ** ** ** ** ****
653 +--**---**--+ +-----------+ +--**---**--+ +----------+ +----------+
654 | ** ** | | | | ** ** | | | | |
655 | ** ** | | | | ** ** | | | | |
656 | ***** | | | | ** ** | | | | |
657 | | | | | ** ** | | | | |
658 | | | ***** | | ** ** | | | | |
659 | | | ** ** | | ** ** | | | | |
660 | | | ** ** | | ** ** | | | | |
661 +-----------+ +--**---**--+ +--**---**--+ +----------+ +----------+
662 ** ** ** ** ****
663 ***** ***** ** **
664 ** **
665 ** **
666 ** **
667 ****
671 if (ypos < 0)
673 if (height <= tf->tf_YSize)
675 ypos = 0;
677 else
679 srcy += (height - tf->tf_YSize) / 2;
680 height = tf->tf_YSize;
681 ypos = 0;
684 else if (ypos + height > tf->tf_YSize)
686 if (height <= tf->tf_YSize)
688 ypos = tf->tf_YSize - height;
690 else
692 srcy += (height - tf->tf_YSize) / 2;
693 height = tf->tf_YSize;
694 ypos = 0;
698 src = gm->glm_BitMap +
699 gm->glm_BMModulo * srcy +
700 gm->glm_BlackLeft / 8 +
701 srcx / 8;
703 dest = (UBYTE *)tf->tf_CharData +
704 ypos * tf->tf_Modulo +
705 xpos / 8 +
706 destx / 8;
708 for(y = 0; y < height; y++)
710 LONG smask = 0x80 >> (srcx & 7);
711 LONG dmask = 0x80 >> (destx & 7);
712 UBYTE *srcxp = src;
713 UBYTE *destxp = dest;
715 for(x = 0; x < width; x++)
717 if (*srcxp & smask)
719 *destxp |= dmask;
722 smask >>= 1;
723 if (!smask)
725 smask = 0x80;
726 srcxp++;
729 dmask >>= 1;
730 if (!dmask)
732 dmask = 0x80;
733 destxp++;
736 src += gm->glm_BMModulo;
737 dest += tf->tf_Modulo;
741 /****************************************************************************************/
743 static VOID OTAG_MakeCharData(struct GlyphMap **gm, struct TextFont *tf,
744 struct DiskfontBase_intern *DiskfontBase)
746 ULONG *charloc = (ULONG *)tf->tf_CharLoc;
747 LONG xpos = 0;
748 UWORD lochar = tf->tf_LoChar;
749 UWORD hichar = tf->tf_HiChar;
750 UWORD i;
752 for(i = lochar; i <= hichar + 1; i++)
754 struct GlyphMap *g;
755 WORD index;
757 index = (i <= hichar) ? i : 256;
758 g = gm[index];
759 if (g)
761 LONG ypos;
763 ypos = (LONG)tf->tf_Baseline + 1 - (g->glm_Y0/* - (WORD)g->glm_BlackTop*/);
765 OTAG_BlitGlyph(g, tf, xpos, ypos, DiskfontBase);
767 charloc[i - lochar] = (xpos << 16) + g->glm_BlackWidth;
768 xpos += g->glm_BlackWidth;
774 /****************************************************************************************/
776 static VOID OTAG_BlitAAGlyph(struct GlyphMap *gm, struct ColorTextFont *tf, LONG xpos,
777 LONG ypos, struct DiskfontBase_intern *DiskfontBase)
779 UBYTE *src, *dest;
780 LONG x, y, width, height;
781 LONG srcx, srcy;
783 srcx = gm->glm_BlackLeft;
784 srcy = gm->glm_BlackTop;
785 width = gm->glm_BlackWidth;
786 height = gm->glm_BlackHeight;
788 if ((width < 1) || (height < 1)) return;
790 if (ypos < 0)
792 srcy -= ypos;
793 height += ypos;
794 ypos = 0;
796 if (ypos + height > tf->ctf_TF.tf_YSize)
797 height = tf->ctf_TF.tf_YSize - ypos;
799 src = gm->glm_BitMap +
800 gm->glm_BMModulo * srcy +
801 srcx;
803 dest = (UBYTE *)tf->ctf_CharData[0] +
804 ypos * tf->ctf_TF.tf_Modulo * 8 +
805 xpos;
807 for(y = 0; y < height; y++)
809 UBYTE *srcxp = src;
810 UBYTE *destxp = dest;
812 for(x = 0; x < width; x++)
814 *destxp++ = *srcxp++;
817 src += gm->glm_BMModulo;
818 dest += tf->ctf_TF.tf_Modulo * 8;
822 /****************************************************************************************/
824 static VOID OTAG_MakeAAData(struct GlyphMap **gm, struct ColorTextFont *tf,
825 struct DiskfontBase_intern *DiskfontBase)
827 //ULONG *charloc = (ULONG *)tf->ctf_TF.tf_CharLoc;
828 LONG xpos = 0;
829 UWORD lochar = tf->ctf_TF.tf_LoChar;
830 UWORD hichar = tf->ctf_TF.tf_HiChar;
831 UWORD i;
833 for(i = lochar; i <= hichar + 1; i++)
835 struct GlyphMap *g;
836 WORD index;
838 index = (i <= hichar) ? i : 256;
839 g = gm[index];
840 if (g)
842 LONG ypos;
844 ypos = (LONG)tf->ctf_TF.tf_Baseline + 1 - (g->glm_Y0/* - (WORD)g->glm_BlackTop*/);
846 OTAG_BlitAAGlyph(g, tf, xpos, ypos, DiskfontBase);
848 xpos += g->glm_BlackWidth;
854 /****************************************************************************************/
856 struct TextFont *OTAG_ReadOutlineFont(struct TTextAttr *attr, struct TTextAttr *reqattr,
857 struct OTagList *otag, struct DiskfontBase_intern *DiskfontBase)
859 struct Library *BulletBase;
860 struct GlyphEngine *ge;
861 struct GlyphMap **gm;
862 struct AADiskFontHeader *dfh = NULL;
863 STRPTR enginename, enginenamebuf;
865 LONG gfxwidth, spacewidth, xdpi, ydpi;
866 WORD lochar, hichar, baseline;
867 UBYTE fontstyle, supportedstyle;
869 enginename = (STRPTR)GetTagData(OT_Engine, (IPTR) NULL, otag->tags);
870 if (!enginename) return NULL;
872 enginenamebuf = AllocVec(strlen(enginename) + sizeof(".library") + 1, MEMF_ANY);
873 if (!enginenamebuf) return NULL;
875 strcpy(enginenamebuf, enginename);
876 strcat(enginenamebuf, ".library");
878 BulletBase = OpenLibrary(enginenamebuf, 0);
879 FreeVec(enginenamebuf);
881 if (!BulletBase) return NULL;
883 ge = OpenEngine();
884 if (!ge)
886 D(bug("Error opening engine %s\n", enginename));
887 CloseLibrary(BulletBase);
888 return NULL;
891 if (!OTAG_SetupFontEngine(attr, reqattr, otag, ge, &xdpi, &ydpi, BulletBase, DiskfontBase))
893 D(bug("Error calling SetupFontengine %s\n", enginename));
894 CloseEngine(ge);
895 CloseLibrary(BulletBase);
896 return NULL;
899 fontstyle = OTAG_GetFontStyle(otag, DiskfontBase);
900 supportedstyle = OTAG_GetSupportedStyles(otag, DiskfontBase);
902 if ((reqattr->tta_Style & FSF_BOLD) && !(fontstyle & FSF_BOLD) && (supportedstyle & FSF_BOLD))
904 struct TagItem bold_tags[] =
906 {OT_EmboldenX, 0xE75},
907 {OT_EmboldenY, 0x99E},
908 {TAG_DONE }
911 if (SetInfoA(ge, bold_tags) == OTERR_Success)
913 fontstyle |= FSF_BOLD;
917 if ((reqattr->tta_Style & FSF_ITALIC) && !(fontstyle & FSF_ITALIC) && (supportedstyle & FSF_ITALIC))
919 struct TagItem italic_tags[] =
921 {OT_ShearSin, 0x4690},
922 {OT_ShearCos, 0xF615},
923 {TAG_DONE }
926 if (SetInfoA(ge, italic_tags) == OTERR_Success)
928 fontstyle |= FSF_ITALIC;
932 gm = (struct GlyphMap **)AllocVec(sizeof(struct GlyhpMap *) * 257, MEMF_ANY | MEMF_CLEAR);
933 if (!gm)
935 CloseEngine(ge);
936 CloseLibrary(BulletBase);
937 return NULL;
940 if (!OTAG_GetGlyphMaps(ge,
942 reqattr->tta_YSize,
943 &lochar,
944 &hichar,
945 &baseline,
946 &gfxwidth,
947 BulletBase,
948 DiskfontBase))
950 D(bug("Error getting GlyphMaps\n"));
951 FreeVec(gm);
952 CloseEngine(ge);
953 CloseLibrary(BulletBase);
954 return NULL;
957 dfh = OTAG_AllocFontStruct(reqattr->tta_Name,
958 hichar - lochar + 2,
959 gfxwidth,
960 reqattr->tta_YSize,
961 DiskfontBase);
962 if (!dfh)
964 OTAG_FreeGlyphMaps(ge, gm, BulletBase, DiskfontBase);
965 FreeVec(gm);
966 CloseEngine(ge);
967 CloseLibrary(BulletBase);
968 return NULL;
971 spacewidth = GetTagData(OT_SpaceWidth, 3000, otag->tags);
975 OT_SpaceWidth pointsize
976 -------------- * --------- * xdpi
977 2540 250
980 #warning maybe should do 64 bit calculations (long long)
981 spacewidth = spacewidth * reqattr->tta_YSize / 250 * xdpi / 2540;
983 dfh->dfh_TF.ctf_TF.tf_Style = fontstyle;
984 dfh->dfh_TF.ctf_TF.tf_Flags = OTAG_GetFontFlags(otag, DiskfontBase) & ~FPF_ROMFONT;
985 dfh->dfh_TF.ctf_TF.tf_LoChar = lochar;
986 dfh->dfh_TF.ctf_TF.tf_HiChar = hichar;
987 dfh->dfh_TF.ctf_TF.tf_Baseline = baseline - 1; /* CHECKME */
988 dfh->dfh_TF.ctf_TF.tf_XSize = spacewidth;
990 OTAG_CalcMetrics(gm, &dfh->dfh_TF.ctf_TF);
991 OTAG_MakeCharData(gm, &dfh->dfh_TF.ctf_TF, DiskfontBase);
993 OTAG_FreeGlyphMaps(ge, gm, BulletBase, DiskfontBase);
995 if (OTAG_GetAAGlyphMaps(ge,
997 BulletBase,
998 DiskfontBase))
1000 if (OTAG_AllocAAData(&dfh->dfh_TF, DiskfontBase))
1001 OTAG_MakeAAData(gm, &dfh->dfh_TF, DiskfontBase);
1002 OTAG_FreeAAGlyphMaps(ge, gm, BulletBase, DiskfontBase);
1005 FreeVec(gm);
1006 CloseEngine(ge);
1007 CloseLibrary(BulletBase);
1010 /* TagItems were allocated in OTAG_AllocFontStruct */
1012 struct TagItem *tags = (struct TagItem *)(dfh + 1);
1014 tags[0].ti_Tag = OT_PointHeight;
1015 tags[0].ti_Data = reqattr->tta_YSize << 16;
1016 tags[1].ti_Tag = OT_DeviceDPI;
1017 tags[1].ti_Data = (xdpi << 16) | ydpi;
1018 tags[2].ti_Tag = OT_DotSize;
1019 tags[2].ti_Data = (100 << 16) | 100;
1020 tags[3].ti_Tag = TAG_DONE;
1021 tags[3].ti_Data = 0;
1023 ExtendFont(&dfh->dfh_TF.ctf_TF, tags);
1026 return &dfh->dfh_TF.ctf_TF;
1030 /****************************************************************************************/