Prefs/ScreenMode: change the way depth is selected
[AROS.git] / workbench / libs / diskfont / diskfont_io.c
blob783a57b27277b5f11265ab070ac3e0f253cbf1f0
1 /*
2 Copyright © 1995-2010, 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);
46 #define CONVBYTE(ptr, destbyte) \
47 destbyte = ptr[0]; \
48 SKIPBYTE(ptr);
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]); \
54 SKIPPTR(ptr);
57 #if 0
58 #define COPYPTR(ptr, destptr) \
59 ((APTR)destptr) = (APTR)(ptr[0] | ptr[1] << 8 | ptr [2] << 16 | ptr[3] << 24); \
60 SKIPPTR(ptr);
61 #else
63 #define COPYPTR(ptr, destptr) \
64 (destptr) = (APTR)(IPTR)(*((ULONG *)(ptr))); \
65 SKIPPTR(ptr);
66 #endif
67 /****************************************************************************************/
69 /****************/
70 /* ConvDiskFont */
71 /****************/
73 /****************************************************************************************/
75 struct DiskFontHeader *ConvDiskFont(BPTR seglist, CONST_STRPTR fontname, BOOL doextend,
76 struct DiskfontBase *DiskfontBase)
78 UWORD count, numchars;
79 register int i;
81 UBYTE *ptr;
83 UWORD *destptr;
84 ULONG *destlptr;
85 ULONG chardatasize;
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,
94 charloc_ptr = NULL,
95 charspace_ptr = NULL,
96 charkern_ptr = NULL,
97 taglist_ptr = NULL,
98 prevsegment = 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)
121 goto failure;
123 CONVWORD(ptr, tmp_dfh.dfh_Revision); /* dfh_Revision */
125 COPYPTR(ptr, taglist_ptr); /* dfh_Segment */
127 ptr += MAXFONTNAME;
129 /* dfh_TF starts */
131 /* Skip nodes successor and predecessor field */
132 SKIPPTR(ptr);
133 SKIPPTR(ptr);
135 /* skip type and pri */
136 SKIPBYTE(ptr);
137 SKIPBYTE(ptr);
138 tmp_dfh.dfh_TF.tf_Message.mn_Node.ln_Type = NT_FONT;
140 /* Skip name pointer, replyport and msg length */
141 SKIPPTR(ptr);
142 SKIPPTR(ptr);
143 SKIPWORD(ptr);
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);
188 if (doextend)
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;
196 tf = &dfh->dfh_TF;
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)
212 APTR temp_ptr;
213 UBYTE num_planes_data = 0;
215 #undef CTF
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)))
236 num_planes_data++;
241 /* ------------------------------- */
242 /* Handle ColorFontColors structure */
243 #undef CFC
244 #define CFC(p) ((struct ColorFontColors*)p)
246 CTF(tf)->ctf_ColorFontColors = prevsegment = AllocSegment(prevsegment,
247 sizeof(struct ColorFontColors),
248 MEMF_ANY | MEMF_CLEAR,
249 DiskfontBase);
251 if (!CTF(tf)->ctf_ColorFontColors) goto failure;
253 temp_ptr = CTF(tf)->ctf_ColorFontColors;
255 ptr = (UBYTE *)cfc_ptr;
256 SKIPWORD(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),
267 MEMF_ANY,
268 DiskfontBase);
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,
284 chardatasize,
285 MEMF_ANY,
286 DiskfontBase);
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,
302 chardatasize,
303 MEMF_ANY,
304 DiskfontBase);
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 /* ----------------------- */
314 /* Add fontname */
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),
331 MEMF_ANY,
332 DiskfontBase);
334 if (!tf->tf_CharLoc) goto failure;
336 /* Convert charloc data */
337 ptr = charloc_ptr;
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"));
346 if (charspace_ptr)
349 D(bug("Proportional font\n"));
351 tf->tf_CharSpace = prevsegment = AllocSegment(prevsegment,
352 numchars * sizeof (UWORD) ,
353 MEMF_ANY,
354 DiskfontBase);
356 if (!tf->tf_CharSpace) goto failure;
358 /* Convert charspace data */
359 ptr = charspace_ptr;
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));
373 if (charkern_ptr)
375 tf->tf_CharKern = prevsegment = AllocSegment(prevsegment,
376 numchars * sizeof (UWORD),
377 MEMF_ANY,
378 DiskfontBase);
379 if (!tf->tf_CharKern) goto failure;
381 /* Convert charkern data */
382 ptr = charkern_ptr;
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 /* ----------------------- */
396 /* Handle taglist */
398 if ((tf->tf_Style & FSF_TAGGED) && taglist_ptr)
400 UWORD numtags = 0;
401 ULONG tag;
402 struct TagItem *taglist;
404 D(bug("Tagged font\n"));
406 /* Convert the tags */
407 ptr = taglist_ptr;
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 */
416 CONVLONG(ptr, tag)
417 SKIPLONG(ptr);
418 numtags ++;
420 while (tag != TAG_DONE);
422 /* Allocate memory for taglist */
423 prevsegment = taglist = (struct TagItem *)AllocSegment(prevsegment,
424 numtags * sizeof(struct TagItem),
425 MEMF_ANY,
426 DiskfontBase);
427 if (!taglist)
428 goto failure;
430 /* Copy tags into allocated mem */
431 ptr = taglist_ptr;
432 for (i = 0; i < numtags; i ++ )
434 CONVLONG(ptr, taglist[i].ti_Tag);
435 CONVLONG(ptr, taglist[i].ti_Data);
438 if (doextend)
440 if (ExtendFont(tf, taglist))
442 fontextended = TRUE;
444 else
446 goto failure;
449 else
451 dfh->dfh_TagList = (BPTR)taglist;
454 else if (doextend)
456 D(bug("No tags, extending it\n"));
458 if (ExtendFont(tf, NULL))
460 fontextended = TRUE;
462 else
464 goto failure;
468 /* ----------------------- */
470 ReturnPtr("ConvTextFont", struct DiskFontHeader *, dfh);
472 failure:
474 D(bug("failure\n"));
476 if (fontsegment)
478 if (fontextended) StripFont(tf);
480 UnLoadSeg(fontsegment);
483 ReturnPtr("ConvTextFont", struct DiskFontHeader *, 0);
486 void DisposeConvDiskFont(struct DiskFontHeader *dfh,
487 struct DiskfontBase *DiskfontBase)
489 if (dfh!=NULL)
491 StripFont(&dfh->dfh_TF);
492 UnLoadSeg(MKBADDR(((BPTR *)dfh)-1));
496 /****************************************************************************************/
498 /****************/
499 /* ReadDiskFont */
500 /****************/
502 /****************************************************************************************/
504 struct TextFont *ReadDiskFont(
505 struct TTextAttr *reqattr,
506 CONST_STRPTR realfontname,
507 struct DiskfontBase *DiskfontBase)
509 struct DiskFontHeader *dfh = NULL;
510 STRPTR filename;
511 BPTR seglist;
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);
521 UnLoadSeg(seglist);
523 if (dfh != NULL)
525 D(bug("ReadDiskFont: dfh=0x%lx\n"));
526 ReturnPtr("ReadDiskFont", struct TextFont *, &dfh->dfh_TF);
528 else
530 D(bug("ReadDiskFont: error converting seglist\n"));
531 ReturnPtr("ReadDiskFont", struct TextFont *, NULL);
534 else
536 D(bug("Could not load segment list\n"));
537 ReturnPtr("ReadDiskFont", struct TextFont *, NULL);
541 /****************************************************************************************/