2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
5 Functions for reading disk font files.
8 /****************************************************************************************/
11 #include <exec/execbase.h>
12 #include <exec/initializers.h>
13 #include <dos/doshunks.h>
14 #include <dos/dosasl.h>
15 #include <dos/dosextens.h>
18 #include <proto/dos.h>
19 #include <proto/graphics.h>
21 #include "diskfont_intern.h"
23 /****************************************************************************************/
26 #include <aros/debug.h>
28 /****************************************************************************************/
30 #define SKIPLONG(ptr) ptr += sizeof(LONG);
32 #define SKIPWORD(ptr) ptr += sizeof(WORD)
34 #define SKIPBYTE(ptr) ptr ++;
36 #define SKIPPTR(ptr) ptr += sizeof(LONG)
38 #define CONVLONG(ptr, destlong) \
39 destlong = ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3]; \
42 #define CONVWORD(ptr, destword) \
43 destword = ptr[0] << 8 | ptr[1]; \
46 #define CONVBYTE(ptr, destbyte) \
51 We don't need endian conversion of pointers since this is done inside LoadSeg_AOS()
52 #define CONVPTR(ptr, destptr) \
53 ((APTR)destptr) = (APTR)(ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3]); \
58 #define COPYPTR(ptr, destptr) \
59 ((APTR)destptr) = (APTR)(ptr[0] | ptr[1] << 8 | ptr [2] << 16 | ptr[3] << 24); \
63 #define COPYPTR(ptr, destptr) \
64 (destptr) = (APTR)(IPTR)(*((ULONG *)(ptr))); \
67 /****************************************************************************************/
73 /****************************************************************************************/
75 struct DiskFontHeader
*ConvDiskFont(BPTR seglist
, CONST_STRPTR fontname
, BOOL doextend
,
76 struct DiskfontBase
*DiskfontBase
)
78 UWORD count
, numchars
;
86 struct DiskFontHeader tmp_dfh
, *dfh
= 0;
87 struct TextFont
*tf
= 0;
89 APTR ctf_chardata_ptrs
[8] = {0};
90 struct ColorFontColors
*cfc_ptr
= 0;
91 UWORD
*colortable_ptr
= NULL
;
93 APTR chardata_ptr
= NULL
,
99 BPTR fontsegment
= BNULL
;
100 BOOL fontextended
= FALSE
;
102 CONST_STRPTR filepart
;
104 EnterFunc(bug("ConvDiskFont(seglist=%p, fontname=%s)\n", seglist
, fontname
));
106 /* Clear temporary diskfontheader struct */
107 memset(&tmp_dfh
, 0, sizeof (struct DiskFontHeader
));
109 /* Get start of diskfontheader. (Go past the dummy exe header) */
110 ptr
= UB(BADDR(seglist
)) + sizeof (ULONG
) + sizeof(BPTR
);
112 /* Skip the whole DiskFontHeader */
113 SKIPPTR(ptr
); /* dfh_TF.ln_Succ */
114 SKIPPTR(ptr
); /* dfh_TF.ln_Pred */
115 CONVBYTE(ptr
, tmp_dfh
.dfh_DF
.ln_Type
); /* dfh_TF.ln_Type */
116 CONVBYTE(ptr
, tmp_dfh
.dfh_DF
.ln_Pri
); /* dfh_TF.ln_Pri */
117 SKIPPTR(ptr
); /* dfh_TF.ln_Name */
118 CONVWORD(ptr
, tmp_dfh
.dfh_FileID
); /* dfh_FileID */
120 if (tmp_dfh
.dfh_FileID
!= DFH_ID
)
123 CONVWORD(ptr
, tmp_dfh
.dfh_Revision
); /* dfh_Revision */
125 COPYPTR(ptr
, taglist_ptr
); /* dfh_Segment */
131 /* Skip nodes successor and predecessor field */
135 /* skip type and pri */
138 tmp_dfh
.dfh_TF
.tf_Message
.mn_Node
.ln_Type
= NT_FONT
;
140 /* Skip name pointer, replyport and msg length */
145 CONVWORD(ptr
, tmp_dfh
.dfh_TF
.tf_YSize
);
146 CONVBYTE(ptr
, tmp_dfh
.dfh_TF
.tf_Style
);
147 CONVBYTE(ptr
, tmp_dfh
.dfh_TF
.tf_Flags
);
148 CONVWORD(ptr
, tmp_dfh
.dfh_TF
.tf_XSize
);
149 CONVWORD(ptr
, tmp_dfh
.dfh_TF
.tf_Baseline
);
150 CONVWORD(ptr
, tmp_dfh
.dfh_TF
.tf_BoldSmear
);
151 SKIPWORD(ptr
); /* tf_Accessors */
152 CONVBYTE(ptr
, tmp_dfh
.dfh_TF
.tf_LoChar
);
153 CONVBYTE(ptr
, tmp_dfh
.dfh_TF
.tf_HiChar
);
154 COPYPTR(ptr
, chardata_ptr
); /* tf_CharData */
155 CONVWORD(ptr
, tmp_dfh
.dfh_TF
.tf_Modulo
);
156 COPYPTR(ptr
, charloc_ptr
); /* tf_CharLoc */
157 COPYPTR(ptr
, charspace_ptr
); /* tf_CharSpace */
158 COPYPTR(ptr
, charkern_ptr
); /* tf_CharKern */
160 D(bug("Textfont struct converted\n"));
161 D(bug("YSize: %d\n", tmp_dfh
.dfh_TF
.tf_YSize
));
162 D(bug("Style: %d\n", tmp_dfh
.dfh_TF
.tf_Style
));
163 D(bug("Flags: %d\n", tmp_dfh
.dfh_TF
.tf_Flags
));
164 D(bug("XSize: %d\n", tmp_dfh
.dfh_TF
.tf_XSize
));
165 D(bug("Baseline: %d\n", tmp_dfh
.dfh_TF
.tf_Baseline
));
166 D(bug("Boldsmear: %d\n", tmp_dfh
.dfh_TF
.tf_BoldSmear
));
167 D(bug("LoChar: %d\n", tmp_dfh
.dfh_TF
.tf_LoChar
));
168 D(bug("HiChar: %d\n", tmp_dfh
.dfh_TF
.tf_HiChar
));
169 D(bug("chardata: %p\n", chardata_ptr
));
170 D(bug("Modulo: %d\n", tmp_dfh
.dfh_TF
.tf_Modulo
));
171 D(bug("charloc: %p\n", charloc_ptr
));
172 D(bug("charspace: %p\n", charspace_ptr
));
173 D(bug("charkern: %p\n", charkern_ptr
));
175 /* Allocate memory for font */
177 i
= sizeof(struct DiskFontHeader
);
178 if (tmp_dfh
.dfh_TF
.tf_Style
& FSF_COLORFONT
)
180 /* +8 should this calc. not work 100 % because of alignments */
181 i
+= (sizeof(struct ColorTextFont
) - sizeof(struct TextFont
) + 8);
184 dfh
= prevsegment
= AllocSegment(prevsegment
, i
, MEMF_ANY
| MEMF_CLEAR
, DiskfontBase
);
185 if (!dfh
) goto failure
;
187 fontsegment
= (BPTR
)MAKE_REAL_SEGMENT(dfh
);
190 /* Don't do this in case of doextend = FALSE (called by NewFontContents),
191 because then code expects taglist to be in there!!!! (dfh_Segment == dfh_TagList) */
193 tmp_dfh
.dfh_Segment
= fontsegment
;
198 D(bug("charkern in temp: %p\n", tmp_dfh
.dfh_TF
.tf_CharKern
));
200 /* Copy already converted stuff into allocated mem */
201 CopyMem(&tmp_dfh
, dfh
, sizeof (struct DiskFontHeader
));
203 D(bug("tmp_tf copied, charkern=%p\n", tf
->tf_CharKern
));
205 /* Calculate size of one character data bitmap */
206 chardatasize
= tf
->tf_YSize
* tf
->tf_Modulo
;
208 numchars
= (tf
->tf_HiChar
- tf
->tf_LoChar
) + 2; /* + 2 because of default character (255) */
210 if (tf
->tf_Style
& FSF_COLORFONT
)
213 UBYTE num_planes_data
= 0;
216 #define CTF(tf) ((struct ColorTextFont *)tf)
218 D(bug("Colorfont found\n"));
220 /* Convert extended colortextfont info */
221 CONVWORD(ptr
, CTF(tf
)->ctf_Flags
);
222 CONVBYTE(ptr
, CTF(tf
)->ctf_Depth
);
223 CONVBYTE(ptr
, CTF(tf
)->ctf_FgColor
);
224 CONVBYTE(ptr
, CTF(tf
)->ctf_Low
);
225 CONVBYTE(ptr
, CTF(tf
)->ctf_High
);
226 CONVBYTE(ptr
, CTF(tf
)->ctf_PlanePick
);
227 CONVBYTE(ptr
, CTF(tf
)->ctf_PlaneOnOff
);
228 COPYPTR(ptr
, cfc_ptr
);
230 for (i
= 0; i
< 8; i
++ )
232 COPYPTR(ptr
, ctf_chardata_ptrs
[i
]);
234 if ((CTF(tf
)->ctf_Depth
> i
) && (CTF(tf
)->ctf_PlanePick
& (1L << i
)))
241 /* ------------------------------- */
242 /* Handle ColorFontColors structure */
244 #define CFC(p) ((struct ColorFontColors*)p)
246 CTF(tf
)->ctf_ColorFontColors
= prevsegment
= AllocSegment(prevsegment
,
247 sizeof(struct ColorFontColors
),
248 MEMF_ANY
| MEMF_CLEAR
,
251 if (!CTF(tf
)->ctf_ColorFontColors
) goto failure
;
253 temp_ptr
= CTF(tf
)->ctf_ColorFontColors
;
255 ptr
= (UBYTE
*)cfc_ptr
;
257 CONVWORD(ptr
, CFC(temp_ptr
)->cfc_Count
);
258 COPYPTR (ptr
, colortable_ptr
);
260 /* ------------------------------- */
261 /* Handle colortable */
262 count
= CFC(temp_ptr
)->cfc_Count
;
263 ptr
= (UBYTE
*)colortable_ptr
;
265 CFC(temp_ptr
)->cfc_ColorTable
= prevsegment
= AllocSegment(prevsegment
,
266 count
* sizeof (UWORD
),
270 if (!CFC(temp_ptr
)->cfc_ColorTable
) goto failure
;
272 for (i
= 0; i
< count
; i
++)
274 CONVWORD(ptr
, CFC(temp_ptr
)->cfc_ColorTable
[i
]);
277 /* ------------------------------- */
278 /* Handle character bitmap data for colorfonts */
279 for (i
= 0; i
< num_planes_data
; i
++)
281 if (!ctf_chardata_ptrs
[i
]) continue;
283 CTF(tf
)->ctf_CharData
[i
] = prevsegment
= AllocSegment(prevsegment
,
288 if (!CTF(tf
)->ctf_CharData
[i
]) goto failure
;
290 CopyMem(ctf_chardata_ptrs
[i
], CTF(tf
)->ctf_CharData
[i
], chardatasize
);
296 if (chardata_ptr
) /* CHECKME: check necessary? Do also colorfonts always have this? */
298 D(bug("B&W font\t Chardatasize: %d\n", chardatasize
));
300 /* Character data for B/W fonts */
301 tf
->tf_CharData
= prevsegment
= AllocSegment(prevsegment
,
305 if (!tf
->tf_CharData
) goto failure
;
308 D(bug("chardataptr=%p\n",chardata_ptr
));
309 CopyMem(chardata_ptr
, tf
->tf_CharData
, chardatasize
);
310 D(bug("Chardata copied\n"));
313 /* ----------------------- */
315 filepart
= FilePart(fontname
);
316 i
= strlen(filepart
) + 1;
317 if (i
>= sizeof(dfh
->dfh_Name
)) i
= sizeof(dfh
->dfh_Name
) - 1;
319 CopyMem((STRPTR
) filepart
, dfh
->dfh_Name
, i
);
321 tf
->tf_Message
.mn_Node
.ln_Name
= dfh
->dfh_Name
;
322 dfh
->dfh_DF
.ln_Name
= dfh
->dfh_Name
;
324 /* ----------------------- */
325 /* Allocate memory for charloc */
327 D(bug("Doing charloc\n"));
329 tf
->tf_CharLoc
= prevsegment
= AllocSegment(prevsegment
,
330 numchars
* sizeof (ULONG
),
334 if (!tf
->tf_CharLoc
) goto failure
;
336 /* Convert charloc data */
338 destlptr
= (ULONG
*) tf
->tf_CharLoc
;
339 for (i
= 0; i
< numchars
; i
++ )
341 CONVLONG(ptr
, *destlptr
++);
342 D(bug("charloc[%d]: %x\n", i
, destlptr
[-1]));
344 D(bug("Charloc OK\n"));
349 D(bug("Proportional font\n"));
351 tf
->tf_CharSpace
= prevsegment
= AllocSegment(prevsegment
,
352 numchars
* sizeof (UWORD
) ,
356 if (!tf
->tf_CharSpace
) goto failure
;
358 /* Convert charspace data */
360 destptr
= tf
->tf_CharSpace
;
361 for (i
= numchars
; i
--;)
363 CONVWORD(ptr
, *destptr
++ );
366 D(bug("Charspace OK\n"));
369 /* ----------------------- */
370 /* Allocate memory for charkern */
372 D(bug("Doing Charkern, ptr =%p\n", charkern_ptr
));
375 tf
->tf_CharKern
= prevsegment
= AllocSegment(prevsegment
,
376 numchars
* sizeof (UWORD
),
379 if (!tf
->tf_CharKern
) goto failure
;
381 /* Convert charkern data */
383 destptr
= tf
->tf_CharKern
;
384 for (i
= numchars
; i
--;)
386 CONVWORD(ptr
, *destptr
++);
387 D(bug("Setting to %d\n", destptr
[-1]));
389 D(bug("Charkern OK\n"));
392 D(bug("Charkern, ptr =%p\n", tf
->tf_CharKern
));
395 /* ----------------------- */
398 if ((tf
->tf_Style
& FSF_TAGGED
) && taglist_ptr
)
402 struct TagItem
*taglist
;
404 D(bug("Tagged font\n"));
406 /* Convert the tags */
409 /* We assume that tags are placed in one single array, and not
410 spread around the whole file with TAG_NEXT
413 /* Count number of tags w/TAG_DONE */
420 while (tag
!= TAG_DONE
);
422 /* Allocate memory for taglist */
423 prevsegment
= taglist
= (struct TagItem
*)AllocSegment(prevsegment
,
424 numtags
* sizeof(struct TagItem
),
430 /* Copy tags into allocated mem */
432 for (i
= 0; i
< numtags
; i
++ )
434 CONVLONG(ptr
, taglist
[i
].ti_Tag
);
435 CONVLONG(ptr
, taglist
[i
].ti_Data
);
440 if (ExtendFont(tf
, taglist
))
451 dfh
->dfh_TagList
= (BPTR
)taglist
;
456 D(bug("No tags, extending it\n"));
458 if (ExtendFont(tf
, NULL
))
468 /* ----------------------- */
470 ReturnPtr("ConvTextFont", struct DiskFontHeader
*, dfh
);
478 if (fontextended
) StripFont(tf
);
480 UnLoadSeg(fontsegment
);
483 ReturnPtr("ConvTextFont", struct DiskFontHeader
*, 0);
486 void DisposeConvDiskFont(struct DiskFontHeader
*dfh
,
487 struct DiskfontBase
*DiskfontBase
)
491 StripFont(&dfh
->dfh_TF
);
492 UnLoadSeg(MKBADDR(((BPTR
*)dfh
)-1));
496 /****************************************************************************************/
502 /****************************************************************************************/
504 struct TextFont
*ReadDiskFont(
505 struct TTextAttr
*reqattr
,
506 CONST_STRPTR realfontname
,
507 struct DiskfontBase
*DiskfontBase
)
509 struct DiskFontHeader
*dfh
= NULL
;
513 EnterFunc(bug("ReadDiskFont(reqattr=%p, name=%s, ysize=%d)\n",
514 reqattr
, reqattr
->tta_Name
, reqattr
->tta_YSize
));
516 filename
= reqattr
->tta_Name
;
518 if ((seglist
= LoadSeg(filename
)) != 0)
520 dfh
= ConvDiskFont(seglist
, realfontname
, TRUE
, DiskfontBase
);
525 D(bug("ReadDiskFont: dfh=0x%lx\n"));
526 ReturnPtr("ReadDiskFont", struct TextFont
*, &dfh
->dfh_TF
);
530 D(bug("ReadDiskFont: error converting seglist\n"));
531 ReturnPtr("ReadDiskFont", struct TextFont
*, NULL
);
536 D(bug("Could not load segment list\n"));
537 ReturnPtr("ReadDiskFont", struct TextFont
*, NULL
);
541 /****************************************************************************************/