2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Functions for reading .font files
8 /****************************************************************************************/
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>
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
*DiskfontBase
)
42 l
= strlen(filename
) + 1;
43 if (l
< 7) return NULL
;
45 retval
= AllocVec(l
, MEMF_ANY
);
48 memcpy(retval
, filename
, l
- 5);
49 strcpy(retval
+ l
- 5, "otag");
55 /****************************************************************************************/
57 struct OTagList
*OTAG_GetFile(CONST_STRPTR filename
, struct DiskfontBase
*DiskfontBase
)
59 struct FileInfoBlock
*fib
;
60 struct OTagList
*otaglist
;
68 otagfilename
= OTAG_MakeFileName(filename
, DiskfontBase
);
69 if (!otagfilename
) return NULL
;
71 otagfile
= Open(otagfilename
, MODE_OLDFILE
);
74 FreeVec(otagfilename
);
78 fib
= AllocDosObject(DOS_FIB
, NULL
);
81 FreeVec(otagfilename
);
86 ok
= ExamineFH(otagfile
, fib
);
88 FreeDosObject(DOS_FIB
, fib
);
92 FreeVec(otagfilename
);
97 otaglist
= AllocVec(sizeof(struct OTagList
) + l
, MEMF_PUBLIC
| MEMF_CLEAR
);
100 FreeVec(otagfilename
);
105 otaglist
->filename
= otagfilename
;
107 ok
= (Read(otagfile
, otaglist
->data
, l
) == l
);
110 if (AROS_LONG2BE(otaglist
->data
[0]) != OT_FileIdent
)
112 if (AROS_LONG2BE(otaglist
->data
[1]) != l
)
117 OTAG_KillFile(otaglist
, DiskfontBase
);
122 * FIXME: The following suggests that there are no OT_TagList tags in the file.
126 #if (__WORDSIZE == 64)
128 * On 64-bit machines we need to convert otag items from ULONGs to IPTRs.
129 * We do it by allocating a new array and expanding all tags.
130 * Note that we also need to keep original buffer, because
131 * it also contains some supplied data. Pointers to these data are stored
132 * as offsets, we will resolve them too during conversion.
135 /* First count number of tags */
137 for (srctag
= otaglist
->data
; srctag
[0] != TAG_DONE
; srctag
+= 2)
140 /* Then allocate a new buffer for them */
141 otaglist
->tags
= AllocVec(sizeof(struct TagItem
) * l
, MEMF_ANY
);
144 OTAG_KillFile(otaglist
, DiskfontBase
);
149 * On 32-bit machines we save some memory by simply converting
150 * endianess in place.
152 otaglist
->tags
= (struct TagItem
*)otaglist
->data
;
156 for (srctag
= otaglist
->data
;; srctag
+= 2)
158 ti
->ti_Tag
= AROS_LONG2BE(srctag
[0]);
161 * Stop processing immediately when TAG_DONE encountered.
162 * We do it because some files (like ones generated by FTManager ;-))
163 * miss data portion of the final tag, saving four bytes.
164 * If we touch that location, we damage attached data.
166 if (ti
->ti_Tag
== TAG_DONE
)
169 ti
->ti_Data
= AROS_LONG2BE(srctag
[1]);
170 if (ti
->ti_Tag
& OT_Indirect
)
173 * Resolve the indirection. Note that we resolve it
174 * relative to original data buffer, because on 64-bit machines
175 * data and tags point to different regions.
177 ti
->ti_Data
= (IPTR
)otaglist
->data
+ ti
->ti_Data
;
186 /****************************************************************************************/
188 VOID
OTAG_KillFile(struct OTagList
*otaglist
, struct DiskfontBase
*DiskfontBase
)
192 #if (__WORDSIZE == 64)
194 FreeVec(otaglist
->tags
);
197 if (otaglist
->filename
)
198 FreeVec(otaglist
->filename
);
204 /****************************************************************************************/
206 UBYTE
OTAG_GetFontStyle(struct OTagList
*otaglist
, struct DiskfontBase
*DiskfontBase
)
210 /* A font becomes FSF_BOLD if OT_StemWeight >= 0x90 */
212 if (GetTagData(OT_StemWeight
, 0, otaglist
->tags
) >= 0x90)
217 /* A font becomes FSF_ITALIC if OT_SlantStyle != OTS_Upright */
219 if (GetTagData(OT_SlantStyle
, OTS_Upright
, otaglist
->tags
) != OTS_Upright
)
224 /* A font becomes FSF_EXTENDED if OT_HorizStyle >= 0xA0 */
226 if (GetTagData(OT_HorizStyle
, 0, otaglist
->tags
) >= 0xA0)
228 style
|= FSF_EXTENDED
;
234 /****************************************************************************************/
236 UBYTE
OTAG_GetSupportedStyles(struct OTagList
*otaglist
,
237 struct DiskfontBase
*DiskfontBase
)
239 UBYTE inhibit
, supported
;
241 #define STYLES (FSF_BOLD | FSF_ITALIC | FSF_UNDERLINED)
244 ** If a style bit is set in OT_InhibitAlgoStyle, then this
245 ** style cannot be handled/calculated/created by the font engine.
247 ** If it is, then the font engine can handle/calculate/create it
250 inhibit
= GetTagData(OT_InhibitAlgoStyle
, 0, otaglist
->tags
);
251 supported
= (inhibit
& STYLES
) ^ STYLES
;
256 /****************************************************************************************/
258 UBYTE
OTAG_GetFontFlags(struct OTagList
*otaglist
, struct DiskfontBase
*DiskfontBase
)
262 flags
= FONTTYPE_OUTLINEFONT
;
263 if (GetTagData(OT_IsFixed
, FALSE
, otaglist
->tags
) == FALSE
)
265 flags
|= FPF_PROPORTIONAL
;
271 /****************************************************************************************/
273 static BOOL
OTAG_SetupFontEngine(struct TTextAttr
*ta
,
274 struct TTextAttr
*ra
,
275 struct OTagList
*otag
,
276 struct GlyphEngine
*ge
,
279 struct Library
*BulletBase
,
280 struct DiskfontBase
*DiskfontBase
)
282 struct TagItem maintags
[] =
284 {OT_OTagList
, (IPTR
)otag
->tags
},
285 {OT_OTagPath
, (IPTR
)otag
->filename
},
288 struct TagItem sizetags
[] =
290 {OT_PointHeight
, 0 },
295 LONG pointheight
, xdot
, ydot
;
296 LONG xdpi
, ydpi
, taxdpi
, taydpi
;
297 LONG ysizefactor
, ysizefactor_low
, ysizefactor_high
;
299 ysizefactor
= GetTagData(OT_YSizeFactor
, 0x10001, otag
->tags
);
300 ysizefactor_low
= ysizefactor
& 0xFFFF;
301 ysizefactor_high
= (ysizefactor
>> 16) & 0xFFFF;
303 if (!ysizefactor_low
)
305 ysizefactor_low
= ysizefactor_high
= 1;
308 if ((ra
->tta_Style
& FSF_TAGGED
) && ra
->tta_Tags
)
312 devicedpi
= GetTagData(TA_DeviceDPI
, 0x10001, ra
->tta_Tags
);
313 taxdpi
= (devicedpi
>> 16) & 0xFFFF;
314 taydpi
= devicedpi
& 0xFFFF;
326 xdpi
= 72 * ysizefactor_high
/ ysizefactor_low
* taxdpi
/ taydpi
;
327 ydpi
= 72 * ysizefactor_high
/ ysizefactor_low
;
332 pointheight
= ra
->tta_YSize
<< 16;
335 sizetags
[0].ti_Data
= pointheight
;
336 sizetags
[1].ti_Data
= (xdpi
<< 16) | ydpi
;
337 sizetags
[2].ti_Data
= (xdot
<< 16) | ydot
;
339 if (SetInfoA(ge
, maintags
) != OTERR_Success
)
344 return (SetInfoA(ge
, sizetags
) == OTERR_Success
);
348 /****************************************************************************************/
350 static VOID
OTAG_FreeAAGlyphMaps(struct GlyphEngine
*ge
,
351 struct GlyphMap
**gm
,
352 struct Library
*BulletBase
,
353 struct DiskfontBase
*DiskfontBase
)
357 for(i
= 0; i
< 257; i
++)
361 struct TagItem releasetags
[] =
363 {OT_GlyphMap8Bits
, (IPTR
)gm
[i
]},
367 ReleaseInfoA(ge
, releasetags
);
374 /****************************************************************************************/
376 static VOID
OTAG_FreeGlyphMaps(struct GlyphEngine
*ge
,
377 struct GlyphMap
**gm
,
378 struct Library
*BulletBase
,
379 struct DiskfontBase
*DiskfontBase
)
383 for(i
= 0; i
< 257; i
++)
387 struct TagItem releasetags
[] =
389 {OT_GlyphMap
, (IPTR
)gm
[i
]},
393 ReleaseInfoA(ge
, releasetags
);
400 /****************************************************************************************/
402 static BOOL
OTAG_GetGlyphMaps(struct GlyphEngine
*ge
,
403 struct GlyphMap
**gm
,
409 struct Library
*BulletBase
,
410 struct DiskfontBase
*DiskfontBase
)
419 for(i
= 0; i
< 257; i
++)
421 struct TagItem settags
[] =
423 {OT_GlyphCode
, (i
< 256) ? i
: 0x25A1},
426 struct TagItem obtaintags
[] =
428 {OT_GlyphMap
, (IPTR
)&gm
[i
] },
432 SetInfoA(ge
, settags
);
433 ObtainInfoA(ge
, obtaintags
);
439 if (*lochar
== -1) *lochar
= i
;
443 if (gm
[i
]->glm_Y0
/* - (WORD)gm[i]->glm_BlackTop*/ > *baseline
)
445 *baseline
= gm
[i
]->glm_Y0
/* - (WORD)gm[i]->glm_BlackTop*/;
448 *gfxwidth
+= gm
[i
]->glm_BlackWidth
;
452 if (*baseline
>= fontheight
) *baseline
= fontheight
;
453 if (*lochar
> 32) *lochar
= 32;
455 return (*lochar
== -1) ? FALSE
: TRUE
;
458 /****************************************************************************************/
460 static BOOL
OTAG_GetAAGlyphMaps(struct GlyphEngine
*ge
,
461 struct GlyphMap
**gm
,
462 struct Library
*BulletBase
,
463 struct DiskfontBase
*DiskfontBase
)
467 for(i
= 0; i
< 257; i
++)
471 struct TagItem settags
[] =
473 {OT_GlyphCode
, (i
< 256) ? i
: 0x25A1},
476 struct TagItem obtaintags
[] =
478 {OT_GlyphMap8Bits
, (IPTR
)&gm
[i
] },
482 SetInfoA(ge
, settags
);
483 rc
= ObtainInfoA(ge
, obtaintags
);
485 if (i
== 0 && rc
== OTERR_UnknownTag
)
492 /****************************************************************************************/
494 struct AADiskFontHeader
*OTAG_AllocFontStruct(STRPTR name
, UWORD numchars
, LONG gfxwidth
,
495 LONG fontheight
, struct DiskfontBase
*DiskfontBase
)
497 struct AADiskFontHeader
*dfh
;
502 APTR prevsegment
= NULL
;
505 dfh
= prevsegment
= AllocSegment(prevsegment
,
506 sizeof(*dfh
) + sizeof(struct TagItem
) * 5,
507 MEMF_ANY
| MEMF_CLEAR
,
512 charkern
= prevsegment
= AllocSegment(prevsegment
,
513 numchars
* sizeof(WORD
),
514 MEMF_ANY
| MEMF_CLEAR
,
518 charspace
= prevsegment
= AllocSegment(prevsegment
,
519 numchars
* sizeof(WORD
),
520 MEMF_ANY
| MEMF_CLEAR
,
525 charloc
= prevsegment
= AllocSegment(prevsegment
,
526 numchars
* sizeof(LONG
),
527 MEMF_ANY
| MEMF_CLEAR
,
532 gfxwidth
= (gfxwidth
+ 15) & ~15;
534 chardata
= prevsegment
= AllocSegment(prevsegment
,
535 gfxwidth
/ 8 * fontheight
,
536 MEMF_ANY
| MEMF_CLEAR
,
543 dfh
->dfh_FileID
= DFH_ID
;
544 dfh
->dfh_DF
.ln_Name
= dfh
->dfh_Name
;
545 dfh
->dfh_Segment
= MAKE_REAL_SEGMENT(dfh
);
547 i
= strlen(FilePart(name
)) + 1;
548 if (i
>= sizeof(dfh
->dfh_Name
)) i
= sizeof(dfh
->dfh_Name
) - 1;
549 CopyMem(FilePart(name
), dfh
->dfh_Name
, i
);
551 dfh
->dfh_TF
.ctf_TF
.tf_Message
.mn_Node
.ln_Name
= dfh
->dfh_Name
;
552 dfh
->dfh_TF
.ctf_TF
.tf_Message
.mn_Node
.ln_Type
= NT_FONT
;
554 dfh
->dfh_TF
.ctf_TF
.tf_YSize
= fontheight
;
555 dfh
->dfh_TF
.ctf_TF
.tf_CharKern
= charkern
;
556 dfh
->dfh_TF
.ctf_TF
.tf_CharSpace
= charspace
;
557 dfh
->dfh_TF
.ctf_TF
.tf_CharLoc
= charloc
;
558 dfh
->dfh_TF
.ctf_TF
.tf_CharData
= chardata
;
559 dfh
->dfh_TF
.ctf_TF
.tf_Modulo
= gfxwidth
/ 8;
560 dfh
->dfh_TF
.ctf_TF
.tf_BoldSmear
= 1;
567 } /* if (charspace) */
569 } /* if (charkern) */
575 if (dfh
) UnLoadSeg(MAKE_REAL_SEGMENT(dfh
));
582 /****************************************************************************************/
584 static LONG
OTAG_AllocAAData(struct ColorTextFont
*ctf
,
585 struct DiskfontBase
*DiskfontBase
)
589 int gfxwidth
, fontheight
;
591 gfxwidth
= ctf
->ctf_TF
.tf_Modulo
* 8;
592 fontheight
= ctf
->ctf_TF
.tf_YSize
;
594 aadata
= AllocSegment(ctf
->ctf_TF
.tf_CharData
,
595 gfxwidth
* fontheight
,
596 MEMF_ANY
| MEMF_CLEAR
,
601 ctf
->ctf_TF
.tf_Style
|= FSF_COLORFONT
;
602 ctf
->ctf_Flags
= CT_ANTIALIAS
;
604 ctf
->ctf_High
= 0xff;
606 for (k
= 0; k
< 8; ++k
)
607 ctf
->ctf_CharData
[k
] = aadata
;
612 /****************************************************************************************/
614 static VOID
OTAG_CalcMetrics(struct GlyphMap
**gm
, struct TextFont
*tf
)
616 WORD
*charspace
= (UWORD
*)tf
->tf_CharSpace
;
617 WORD
*charkern
= (UWORD
*)tf
->tf_CharKern
;
618 UWORD lochar
= tf
->tf_LoChar
;
619 UWORD hichar
= tf
->tf_HiChar
;
622 for(i
= lochar
; i
<= hichar
+ 1; i
++)
627 index
= (i
<= hichar
) ? i
: 256;
630 if (!g
&& (i
!= 32)) g
= gm
[256];
634 charkern
[i
- lochar
] = ((WORD
)g
->glm_BlackLeft
) - g
->glm_X0
;
635 charspace
[i
- lochar
] = g
->glm_X1
- (WORD
)g
->glm_BlackLeft
;
637 if ((tf
->tf_Flags
& FPF_PROPORTIONAL
) == 0)
640 In a fixed font (charkern + charspace) must always equal
641 calculated fontwidth.
643 x = propspace - propkern
644 fixedkern = (fontwidth - x + 1) / 2
645 fixedspace = fontwidth - fixedkern
648 LONG w
= charspace
[i
- lochar
] - charkern
[i
- lochar
];
650 charkern
[i
- lochar
] = ((LONG
)tf
->tf_XSize
- w
+ 1) / 2;
651 charspace
[i
- lochar
] = (LONG
)tf
->tf_XSize
- charkern
[i
- lochar
];
656 else if ((i
== 32) || ((tf
->tf_Flags
& FPF_PROPORTIONAL
) == 0))
658 charkern
[i
- lochar
] = 0;
659 charspace
[i
- lochar
] = tf
->tf_XSize
;
662 } /* for(i = lochar; i <= hichar + 1; i++) */
665 /****************************************************************************************/
667 static VOID
OTAG_BlitGlyph(struct GlyphMap
*gm
, struct TextFont
*tf
, LONG xpos
,
668 LONG ypos
, struct DiskfontBase
*DiskfontBase
)
671 LONG x
, y
, width
, height
;
672 LONG srcx
, destx
, srcy
;
674 srcx
= gm
->glm_BlackLeft
& 7;
675 srcy
= gm
->glm_BlackTop
;
677 width
= gm
->glm_BlackWidth
;
678 height
= gm
->glm_BlackHeight
;
680 if ((width
< 1) || (height
< 1)) return;
682 /* FIXME: whats the best thing to do here? */
684 /* Check if glyph is bigger/elsewhere than expected,
685 ie. extends outside the bounding box vertically:
696 +--**---**--+ +-----------+ +--**---**--+ +----------+ +----------+
697 | ** ** | | | | ** ** | | | | |
698 | ** ** | | | | ** ** | | | | |
699 | ***** | | | | ** ** | | | | |
700 | | | | | ** ** | | | | |
701 | | | ***** | | ** ** | | | | |
702 | | | ** ** | | ** ** | | | | |
703 | | | ** ** | | ** ** | | | | |
704 +-----------+ +--**---**--+ +--**---**--+ +----------+ +----------+
716 if (height
<= tf
->tf_YSize
)
722 srcy
+= (height
- tf
->tf_YSize
) / 2;
723 height
= tf
->tf_YSize
;
727 else if (ypos
+ height
> tf
->tf_YSize
)
729 if (height
<= tf
->tf_YSize
)
731 ypos
= tf
->tf_YSize
- height
;
735 srcy
+= (height
- tf
->tf_YSize
) / 2;
736 height
= tf
->tf_YSize
;
741 src
= gm
->glm_BitMap
+
742 gm
->glm_BMModulo
* srcy
+
743 gm
->glm_BlackLeft
/ 8 +
746 dest
= (UBYTE
*)tf
->tf_CharData
+
747 ypos
* tf
->tf_Modulo
+
751 for(y
= 0; y
< height
; y
++)
753 LONG smask
= 0x80 >> (srcx
& 7);
754 LONG dmask
= 0x80 >> (destx
& 7);
756 UBYTE
*destxp
= dest
;
758 for(x
= 0; x
< width
; x
++)
779 src
+= gm
->glm_BMModulo
;
780 dest
+= tf
->tf_Modulo
;
784 /****************************************************************************************/
786 static VOID
OTAG_MakeCharData(struct GlyphMap
**gm
, struct TextFont
*tf
,
787 struct DiskfontBase
*DiskfontBase
)
789 ULONG
*charloc
= (ULONG
*)tf
->tf_CharLoc
;
791 UWORD lochar
= tf
->tf_LoChar
;
792 UWORD hichar
= tf
->tf_HiChar
;
795 for(i
= lochar
; i
<= hichar
+ 1; i
++)
800 index
= (i
<= hichar
) ? i
: 256;
806 ypos
= (LONG
)tf
->tf_Baseline
+ 1 - (g
->glm_Y0
/* - (WORD)g->glm_BlackTop*/);
808 OTAG_BlitGlyph(g
, tf
, xpos
, ypos
, DiskfontBase
);
810 charloc
[i
- lochar
] = (xpos
<< 16) + g
->glm_BlackWidth
;
811 xpos
+= g
->glm_BlackWidth
;
817 /****************************************************************************************/
819 static VOID
OTAG_BlitAAGlyph(struct GlyphMap
*gm
, struct ColorTextFont
*tf
, LONG xpos
,
820 LONG ypos
, struct DiskfontBase
*DiskfontBase
)
823 LONG x
, y
, width
, height
;
826 srcx
= gm
->glm_BlackLeft
;
827 srcy
= gm
->glm_BlackTop
;
828 width
= gm
->glm_BlackWidth
;
829 height
= gm
->glm_BlackHeight
;
831 if ((width
< 1) || (height
< 1)) return;
839 if (ypos
+ height
> tf
->ctf_TF
.tf_YSize
)
840 height
= tf
->ctf_TF
.tf_YSize
- ypos
;
842 src
= gm
->glm_BitMap
+
843 gm
->glm_BMModulo
* srcy
+
846 dest
= (UBYTE
*)tf
->ctf_CharData
[0] +
847 ypos
* tf
->ctf_TF
.tf_Modulo
* 8 +
850 for(y
= 0; y
< height
; y
++)
853 UBYTE
*destxp
= dest
;
855 for(x
= 0; x
< width
; x
++)
857 *destxp
++ = *srcxp
++;
860 src
+= gm
->glm_BMModulo
;
861 dest
+= tf
->ctf_TF
.tf_Modulo
* 8;
865 /****************************************************************************************/
867 static VOID
OTAG_MakeAAData(struct GlyphMap
**gm
, struct ColorTextFont
*tf
,
868 struct DiskfontBase
*DiskfontBase
)
870 //ULONG *charloc = (ULONG *)tf->ctf_TF.tf_CharLoc;
872 UWORD lochar
= tf
->ctf_TF
.tf_LoChar
;
873 UWORD hichar
= tf
->ctf_TF
.tf_HiChar
;
876 for(i
= lochar
; i
<= hichar
+ 1; i
++)
881 index
= (i
<= hichar
) ? i
: 256;
887 ypos
= (LONG
)tf
->ctf_TF
.tf_Baseline
+ 1 - (g
->glm_Y0
/* - (WORD)g->glm_BlackTop*/);
889 OTAG_BlitAAGlyph(g
, tf
, xpos
, ypos
, DiskfontBase
);
891 xpos
+= g
->glm_BlackWidth
;
897 /****************************************************************************************/
899 struct TextFont
*OTAG_ReadOutlineFont(struct TTextAttr
*attr
, struct TTextAttr
*reqattr
,
900 struct OTagList
*otag
, struct DiskfontBase
*DiskfontBase
)
902 struct Library
*BulletBase
;
903 struct GlyphEngine
*ge
;
904 struct GlyphMap
**gm
;
905 struct AADiskFontHeader
*dfh
= NULL
;
906 STRPTR enginename
, enginenamebuf
;
908 LONG gfxwidth
, spacewidth
, xdpi
, ydpi
;
909 WORD lochar
, hichar
, baseline
;
910 UBYTE fontstyle
, supportedstyle
;
912 enginename
= (STRPTR
)GetTagData(OT_Engine
, (IPTR
) NULL
, otag
->tags
);
913 if (!enginename
) return NULL
;
915 enginenamebuf
= AllocVec(strlen(enginename
) + sizeof(".library") + 1, MEMF_ANY
);
916 if (!enginenamebuf
) return NULL
;
918 strcpy(enginenamebuf
, enginename
);
919 strcat(enginenamebuf
, ".library");
921 BulletBase
= OpenLibrary(enginenamebuf
, 0);
922 FreeVec(enginenamebuf
);
924 if (!BulletBase
) return NULL
;
929 D(bug("Error opening engine %s\n", enginename
));
930 CloseLibrary(BulletBase
);
934 if (!OTAG_SetupFontEngine(attr
, reqattr
, otag
, ge
, &xdpi
, &ydpi
, BulletBase
, DiskfontBase
))
936 D(bug("Error calling SetupFontengine %s\n", enginename
));
938 CloseLibrary(BulletBase
);
942 fontstyle
= OTAG_GetFontStyle(otag
, DiskfontBase
);
943 supportedstyle
= OTAG_GetSupportedStyles(otag
, DiskfontBase
);
945 if ((reqattr
->tta_Style
& FSF_BOLD
) && !(fontstyle
& FSF_BOLD
) && (supportedstyle
& FSF_BOLD
))
947 struct TagItem bold_tags
[] =
949 {OT_EmboldenX
, 0xE75},
950 {OT_EmboldenY
, 0x99E},
954 if (SetInfoA(ge
, bold_tags
) == OTERR_Success
)
956 fontstyle
|= FSF_BOLD
;
960 if ((reqattr
->tta_Style
& FSF_ITALIC
) && !(fontstyle
& FSF_ITALIC
) && (supportedstyle
& FSF_ITALIC
))
962 struct TagItem italic_tags
[] =
964 {OT_ShearSin
, 0x4690},
965 {OT_ShearCos
, 0xF615},
969 if (SetInfoA(ge
, italic_tags
) == OTERR_Success
)
971 fontstyle
|= FSF_ITALIC
;
975 gm
= (struct GlyphMap
**)AllocVec(sizeof(struct GlyhpMap
*) * 257, MEMF_ANY
| MEMF_CLEAR
);
979 CloseLibrary(BulletBase
);
983 if (!OTAG_GetGlyphMaps(ge
,
993 D(bug("Error getting GlyphMaps\n"));
996 CloseLibrary(BulletBase
);
1000 dfh
= OTAG_AllocFontStruct(reqattr
->tta_Name
,
1001 hichar
- lochar
+ 2,
1007 OTAG_FreeGlyphMaps(ge
, gm
, BulletBase
, DiskfontBase
);
1010 CloseLibrary(BulletBase
);
1014 spacewidth
= GetTagData(OT_SpaceWidth
, 3000, otag
->tags
);
1018 OT_SpaceWidth pointsize
1019 -------------- * --------- * xdpi
1023 /* FIXME: maybe should do 64 bit calculations (long long)? */
1024 spacewidth
= spacewidth
* reqattr
->tta_YSize
/ 250 * xdpi
/ 2540;
1026 dfh
->dfh_TF
.ctf_TF
.tf_Style
= fontstyle
;
1027 dfh
->dfh_TF
.ctf_TF
.tf_Flags
= OTAG_GetFontFlags(otag
, DiskfontBase
) & ~FPF_ROMFONT
;
1028 dfh
->dfh_TF
.ctf_TF
.tf_LoChar
= lochar
;
1029 dfh
->dfh_TF
.ctf_TF
.tf_HiChar
= hichar
;
1030 dfh
->dfh_TF
.ctf_TF
.tf_Baseline
= baseline
- 1; /* CHECKME */
1031 dfh
->dfh_TF
.ctf_TF
.tf_XSize
= spacewidth
;
1033 OTAG_CalcMetrics(gm
, &dfh
->dfh_TF
.ctf_TF
);
1034 OTAG_MakeCharData(gm
, &dfh
->dfh_TF
.ctf_TF
, DiskfontBase
);
1036 OTAG_FreeGlyphMaps(ge
, gm
, BulletBase
, DiskfontBase
);
1038 if (OTAG_GetAAGlyphMaps(ge
,
1043 if (OTAG_AllocAAData(&dfh
->dfh_TF
, DiskfontBase
))
1044 OTAG_MakeAAData(gm
, &dfh
->dfh_TF
, DiskfontBase
);
1045 OTAG_FreeAAGlyphMaps(ge
, gm
, BulletBase
, DiskfontBase
);
1050 CloseLibrary(BulletBase
);
1053 /* TagItems were allocated in OTAG_AllocFontStruct */
1055 struct TagItem
*tags
= (struct TagItem
*)(dfh
+ 1);
1057 tags
[0].ti_Tag
= OT_PointHeight
;
1058 tags
[0].ti_Data
= reqattr
->tta_YSize
<< 16;
1059 tags
[1].ti_Tag
= OT_DeviceDPI
;
1060 tags
[1].ti_Data
= (xdpi
<< 16) | ydpi
;
1061 tags
[2].ti_Tag
= OT_DotSize
;
1062 tags
[2].ti_Data
= (100 << 16) | 100;
1063 tags
[3].ti_Tag
= TAG_DONE
;
1064 tags
[3].ti_Data
= 0;
1066 ExtendFont(&dfh
->dfh_TF
.ctf_TF
, tags
);
1069 return &dfh
->dfh_TF
.ctf_TF
;
1073 /****************************************************************************************/