Added memory-stored debug output to safe mode.
[cake.git] / workbench / libs / diskfont / diskfont_io.c
blob4f1d0b14a0bec011aca656d9967c21f4707ce0fa
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Functions for reading disk font files.
6 */
8 /****************************************************************************************/
10 #include <stdio.h>
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>
16 #include <string.h>
18 #include <proto/dos.h>
19 #include <proto/graphics.h>
21 #include "diskfont_intern.h"
23 /****************************************************************************************/
25 #define DEBUG 0
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]; \
40 SKIPLONG(ptr);
42 #define CONVWORD(ptr, destword) \
43 destword = ptr[0] << 8 | ptr[1]; \
44 SKIPWORD(ptr);
47 #define CONVBYTE(ptr, destbyte) \
48 destbyte = ptr[0]; \
49 SKIPBYTE(ptr);
52 We don't need endian conversion of pointers since this is done inside LoadSeg_AOS()
53 #define CONVPTR(ptr, destptr) \
54 ((APTR)destptr) = (APTR)(ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3]); \
55 SKIPPTR(ptr);
58 #if 0
59 #define COPYPTR(ptr, destptr) \
60 ((APTR)destptr) = (APTR)(ptr[0] | ptr[1] << 8 | ptr [2] << 16 | ptr[3] << 24); \
61 SKIPPTR(ptr);
62 #else
64 #define COPYPTR(ptr,destptr) \
65 (destptr) = (APTR)(*((ULONG *)(ptr))); \
66 SKIPPTR(ptr);
67 #endif
68 /****************************************************************************************/
70 /****************/
71 /* ConvDiskFont */
72 /****************/
74 /****************************************************************************************/
76 struct DiskFontHeader *ConvDiskFont(BPTR seglist, CONST_STRPTR fontname, BOOL doextend,
77 struct DiskfontBase_intern *DiskfontBase)
79 UWORD count, numchars;
80 register int i;
82 UBYTE *ptr;
84 UWORD *destptr;
85 ULONG *destlptr;
86 ULONG chardatasize;
87 struct DiskFontHeader tmp_dfh, *dfh = 0;
88 struct TextFont *tf = 0;
90 APTR ctf_chardata_ptrs[8] = {0};
91 struct ColorFontColors *cfc_ptr = 0;
92 UWORD *colortable_ptr = NULL;
94 APTR chardata_ptr = NULL,
95 charloc_ptr = NULL,
96 charspace_ptr = NULL,
97 charkern_ptr = NULL,
98 taglist_ptr = NULL,
99 prevsegment = NULL;
100 BPTR fontsegment = NULL;
101 BOOL fontextended = FALSE;
103 CONST_STRPTR filepart;
105 EnterFunc(bug("ConvDiskFont(seglist=%p, fontname=%s)\n", seglist, fontname));
107 /* Clear temporary diskfontheader struct */
108 memset(&tmp_dfh, 0, sizeof (struct DiskFontHeader));
110 /* Get start of diskfontheader. (Go past the dummy exe header) */
111 ptr = UB(BADDR(seglist)) + sizeof (ULONG) + sizeof(BPTR);
113 /* Skip the whole DiskFontHeader */
114 SKIPPTR(ptr); /* dfh_TF.ln_Succ */
115 SKIPPTR(ptr); /* dfh_TF.ln_Pred */
116 CONVBYTE(ptr, tmp_dfh.dfh_DF.ln_Type); /* dfh_TF.ln_Type */
117 CONVBYTE(ptr, tmp_dfh.dfh_DF.ln_Pri); /* dfh_TF.ln_Pri */
118 SKIPPTR(ptr); /* dfh_TF.ln_Name */
119 CONVWORD(ptr, tmp_dfh.dfh_FileID); /* dfh_FileID */
121 if (tmp_dfh.dfh_FileID != DFH_ID)
122 goto failure;
124 CONVWORD(ptr, tmp_dfh.dfh_Revision); /* dfh_Revision */
126 COPYPTR(ptr, taglist_ptr); /* dfh_Segment */
128 ptr += MAXFONTNAME;
130 /* dfh_TF starts */
132 /* Skip nodes successor and predecessor field */
133 SKIPPTR(ptr);
134 SKIPPTR(ptr);
136 /* skip type and pri */
137 SKIPBYTE(ptr);
138 SKIPBYTE(ptr);
139 tmp_dfh.dfh_TF.tf_Message.mn_Node.ln_Type = NT_FONT;
141 /* Skip name pointer, replyport and msg length */
142 SKIPPTR(ptr);
143 SKIPPTR(ptr);
144 SKIPWORD(ptr);
146 CONVWORD(ptr, tmp_dfh.dfh_TF.tf_YSize);
147 CONVBYTE(ptr, tmp_dfh.dfh_TF.tf_Style);
148 CONVBYTE(ptr, tmp_dfh.dfh_TF.tf_Flags);
149 CONVWORD(ptr, tmp_dfh.dfh_TF.tf_XSize);
150 CONVWORD(ptr, tmp_dfh.dfh_TF.tf_Baseline);
151 CONVWORD(ptr, tmp_dfh.dfh_TF.tf_BoldSmear);
152 SKIPWORD(ptr); /* tf_Accessors */
153 CONVBYTE(ptr, tmp_dfh.dfh_TF.tf_LoChar);
154 CONVBYTE(ptr, tmp_dfh.dfh_TF.tf_HiChar);
155 COPYPTR(ptr, chardata_ptr); /* tf_CharData */
156 CONVWORD(ptr, tmp_dfh.dfh_TF.tf_Modulo);
157 COPYPTR(ptr, charloc_ptr); /* tf_CharLoc */
158 COPYPTR(ptr, charspace_ptr); /* tf_CharSpace */
159 COPYPTR(ptr, charkern_ptr); /* tf_CharKern */
161 D(bug("Textfont struct converted\n"));
162 D(bug("YSize: %d\n", tmp_dfh.dfh_TF.tf_YSize));
163 D(bug("Style: %d\n", tmp_dfh.dfh_TF.tf_Style));
164 D(bug("Flags: %d\n", tmp_dfh.dfh_TF.tf_Flags));
165 D(bug("XSize: %d\n", tmp_dfh.dfh_TF.tf_XSize));
166 D(bug("Baseline: %d\n", tmp_dfh.dfh_TF.tf_Baseline));
167 D(bug("Boldsmear: %d\n", tmp_dfh.dfh_TF.tf_BoldSmear));
168 D(bug("LoChar: %d\n", tmp_dfh.dfh_TF.tf_LoChar));
169 D(bug("HiChar: %d\n", tmp_dfh.dfh_TF.tf_HiChar));
170 D(bug("chardara: %p\n", chardata_ptr));
171 D(bug("Modulo: %d\n", tmp_dfh.dfh_TF.tf_Modulo));
172 D(bug("charloc: %p\n", charloc_ptr));
173 D(bug("charspace: %p\n", charspace_ptr));
174 D(bug("charkern: %p\n", charkern_ptr));
176 /* Allocate memory for font */
178 i = sizeof(struct DiskFontHeader);
179 if (tmp_dfh.dfh_TF.tf_Style & FSF_COLORFONT)
181 /* +8 should this calc. not work 100 % because of alignments */
182 i += (sizeof(struct ColorTextFont) - sizeof(struct TextFont) + 8);
185 dfh = prevsegment = AllocSegment(prevsegment, i, MEMF_ANY | MEMF_CLEAR, DiskfontBase);
186 if (!dfh) goto failure;
188 fontsegment = (BPTR)MAKE_REAL_SEGMENT(dfh);
189 if (doextend)
191 /* Don't do this in case of doextend = FALSE (called by NewFontContents),
192 because then code expects taglist to be in there!!!! (dfh_Segment == dfh_TagList) */
194 tmp_dfh.dfh_Segment = fontsegment;
197 tf = &dfh->dfh_TF;
199 D(bug("charkern in temp: %p\n", tmp_dfh.dfh_TF.tf_CharKern));
201 /* Copy already converted stuff into allocated mem */
202 CopyMem(&tmp_dfh, dfh, sizeof (struct DiskFontHeader));
204 D(bug("tmp_tf copied, charkern=%p\n", tf->tf_CharKern));
206 /* Calculate size of one character data bitmap */
207 chardatasize = tf->tf_YSize * tf->tf_Modulo;
209 numchars = (tf->tf_HiChar - tf->tf_LoChar) + 2; /* + 2 because of default character (255) */
211 if (tf->tf_Style & FSF_COLORFONT)
213 APTR temp_ptr;
214 UBYTE num_planes_data = 0;
216 #undef CTF
217 #define CTF(tf) ((struct ColorTextFont *)tf)
219 D(bug("Colorfont found\n"));
221 /* Convert extended colortextfont info */
222 CONVWORD(ptr, CTF(tf)->ctf_Flags);
223 CONVBYTE(ptr, CTF(tf)->ctf_Depth);
224 CONVBYTE(ptr, CTF(tf)->ctf_FgColor);
225 CONVBYTE(ptr, CTF(tf)->ctf_Low);
226 CONVBYTE(ptr, CTF(tf)->ctf_High);
227 CONVBYTE(ptr, CTF(tf)->ctf_PlanePick);
228 CONVBYTE(ptr, CTF(tf)->ctf_PlaneOnOff);
229 COPYPTR(ptr, cfc_ptr);
231 for (i = 0; i < 8; i ++ )
233 COPYPTR(ptr, ctf_chardata_ptrs[i]);
235 if ((CTF(tf)->ctf_Depth > i) && (CTF(tf)->ctf_PlanePick & (1L << i)))
237 num_planes_data++;
242 /* ------------------------------- */
243 /* Handle ColorFontColors structure */
244 #undef CFC
245 #define CFC(p) ((struct ColorFontColors*)p)
247 CTF(tf)->ctf_ColorFontColors = prevsegment = AllocSegment(prevsegment,
248 sizeof(struct ColorFontColors),
249 MEMF_ANY | MEMF_CLEAR,
250 DiskfontBase);
252 if (!CTF(tf)->ctf_ColorFontColors) goto failure;
254 temp_ptr = CTF(tf)->ctf_ColorFontColors;
256 ptr = (UBYTE *)cfc_ptr;
257 SKIPWORD(ptr);
258 CONVWORD(ptr, CFC(temp_ptr)->cfc_Count);
259 COPYPTR (ptr, colortable_ptr);
261 /* ------------------------------- */
262 /* Handle colortable */
263 count = CFC(temp_ptr)->cfc_Count;
264 ptr = (UBYTE *)colortable_ptr;
266 CFC(temp_ptr)->cfc_ColorTable = prevsegment = AllocSegment(prevsegment,
267 count * sizeof (UWORD),
268 MEMF_ANY,
269 DiskfontBase);
271 if (!CFC(temp_ptr)->cfc_ColorTable) goto failure;
273 for (i = 0; i < count; i ++)
275 CONVWORD(ptr, CFC(temp_ptr)->cfc_ColorTable[i]);
278 /* ------------------------------- */
279 /* Handle character bitmap data for colorfonts */
280 for (i = 0; i < num_planes_data; i ++)
282 if (!ctf_chardata_ptrs[i]) continue;
284 CTF(tf)->ctf_CharData[i] = prevsegment = AllocSegment(prevsegment,
285 chardatasize,
286 MEMF_ANY,
287 DiskfontBase);
289 if (!CTF(tf)->ctf_CharData[i]) goto failure;
291 CopyMem(ctf_chardata_ptrs[i], CTF(tf)->ctf_CharData[i], chardatasize);
297 if (chardata_ptr) /* CHECKME: check necessary? Do also colorfonts always have this? */
299 D(bug("B&W font\t Chardatasize: %d\n", chardatasize));
301 /* Character data for B/W fonts */
302 tf->tf_CharData = prevsegment = AllocSegment(prevsegment,
303 chardatasize,
304 MEMF_ANY,
305 DiskfontBase);
306 if (!tf->tf_CharData) goto failure;
309 D(bug("chardataptr=%p\n",chardata_ptr));
310 CopyMem(chardata_ptr, tf->tf_CharData, chardatasize);
311 D(bug("Chardata copied\n"));
314 /* ----------------------- */
315 /* Add fontname */
316 filepart = FilePart(fontname);
317 i = strlen(filepart) + 1;
318 if (i >= sizeof(dfh->dfh_Name)) i = sizeof(dfh->dfh_Name) - 1;
320 CopyMem((STRPTR) filepart, dfh->dfh_Name, i);
322 tf->tf_Message.mn_Node.ln_Name = dfh->dfh_Name;
323 dfh->dfh_DF.ln_Name = dfh->dfh_Name;
325 /* ----------------------- */
326 /* Allocate memory for charloc */
328 D(bug("Doing charloc\n"));
330 tf->tf_CharLoc = prevsegment = AllocSegment(prevsegment,
331 numchars * sizeof (ULONG),
332 MEMF_ANY,
333 DiskfontBase);
335 if (!tf->tf_CharLoc) goto failure;
337 /* Convert charloc data */
338 ptr = charloc_ptr;
339 destlptr = (ULONG *) tf->tf_CharLoc;
340 for (i = 0; i < numchars; i ++ )
342 CONVLONG(ptr, *destlptr ++);
343 D(bug("charloc[%d]: %x\n", i, destlptr[-1]));
345 D(bug("Charloc OK\n"));
347 if (charspace_ptr)
350 D(bug("Proportional font\n"));
352 tf->tf_CharSpace = prevsegment = AllocSegment(prevsegment,
353 numchars * sizeof (UWORD) ,
354 MEMF_ANY,
355 DiskfontBase);
357 if (!tf->tf_CharSpace) goto failure;
359 /* Convert charspace data */
360 ptr = charspace_ptr;
361 destptr = tf->tf_CharSpace;
362 for (i = numchars; i --;)
364 CONVWORD(ptr, *destptr ++ );
367 D(bug("Charspace OK\n"));
370 /* ----------------------- */
371 /* Allocate memory for charkern */
373 D(bug("Doing Charkern, ptr =%p\n", charkern_ptr));
374 if (charkern_ptr)
376 tf->tf_CharKern = prevsegment = AllocSegment(prevsegment,
377 numchars * sizeof (UWORD),
378 MEMF_ANY,
379 DiskfontBase);
380 if (!tf->tf_CharKern) goto failure;
382 /* Convert charkern data */
383 ptr = charkern_ptr;
384 destptr = tf->tf_CharKern;
385 for (i = numchars; i --;)
387 CONVWORD(ptr, *destptr ++);
388 D(bug("Setting to %d\n", destptr[-1]));
390 D(bug("Charkern OK\n"));
393 D(bug("Charkern, ptr =%p\n", tf->tf_CharKern));
396 /* ----------------------- */
397 /* Handle taglist */
399 if ((tf->tf_Style & FSF_TAGGED) && taglist_ptr)
401 UWORD numtags = 0;
402 ULONG tag;
403 struct TagItem *taglist;
405 D(bug("Tagged font\n"));
407 /* Convert the tags */
408 ptr = taglist_ptr;
410 /* We assume that tags are placed in one single array, and not
411 spread around the whole file with TAG_NEXT
414 /* Count number of tags w/TAG_DONE */
417 CONVLONG(ptr, tag)
418 SKIPLONG(ptr);
419 numtags ++;
421 while (tag != TAG_DONE);
423 /* Allocate memory for taglist */
424 prevsegment = taglist = (struct TagItem *)AllocSegment(prevsegment,
425 numtags * sizeof(struct TagItem),
426 MEMF_ANY,
427 DiskfontBase);
428 if (!taglist)
429 goto failure;
431 /* Copy tags into allocated mem */
432 ptr = taglist_ptr;
433 for (i = 0; i < numtags; i ++ )
435 CONVLONG(ptr, taglist[i].ti_Tag);
436 CONVLONG(ptr, taglist[i].ti_Data);
439 if (doextend)
441 if (ExtendFont(tf, taglist))
443 fontextended = TRUE;
445 else
447 goto failure;
450 else
452 dfh->dfh_TagList = taglist;
455 else if (doextend)
457 D(bug("No tags, extending it\n"));
459 if (ExtendFont(tf, NULL))
461 fontextended = TRUE;
463 else
465 goto failure;
469 /* ----------------------- */
471 ReturnPtr("ConvTextFont", struct DiskFontHeader *, dfh);
473 failure:
475 D(bug("failure\n"));
477 if (fontsegment)
479 if (fontextended) StripFont(tf);
481 UnLoadSeg(fontsegment);
484 ReturnPtr("ConvTextFont", struct DiskFontHeader *, 0);
487 void DisposeConvDiskFont(struct DiskFontHeader *dfh,
488 struct DiskfontBase_intern *DiskfontBase)
490 if (dfh!=NULL)
492 StripFont(&dfh->dfh_TF);
493 UnLoadSeg(MKBADDR(((BPTR *)dfh)-1));
497 /****************************************************************************************/
499 /****************/
500 /* ReadDiskFont */
501 /****************/
503 /****************************************************************************************/
505 struct TextFont *ReadDiskFont(
506 struct TTextAttr *reqattr,
507 CONST_STRPTR realfontname,
508 struct DiskfontBase_intern *DiskfontBase)
510 struct DiskFontHeader *dfh = NULL;
511 STRPTR filename;
512 BPTR seglist;
514 EnterFunc(bug("ReadDiskFont(reqattr=%p, name=%s, ysize=%d)\n",
515 reqattr, reqattr->tta_Name, reqattr->tta_YSize));
517 filename = reqattr->tta_Name;
519 if ((seglist = LoadSeg(filename)) != 0)
521 dfh = ConvDiskFont(seglist, realfontname, TRUE, DiskfontBase);
522 UnLoadSeg(seglist);
524 if (dfh != NULL)
526 D(bug("ReadDiskFont: dfh=0x%lx\n"));
527 ReturnPtr("ReadDiskFont", struct TextFont *, &dfh->dfh_TF);
529 else
531 D(bug("ReadDiskFont: error converting seglist\n"));
532 ReturnPtr("ReadDiskFont", struct TextFont *, NULL);
535 else
537 D(bug("Could not load segment list\n"));
538 ReturnPtr("ReadDiskFont", struct TextFont *, NULL);
542 /****************************************************************************************/