Prefs/ScreenMode: change the way depth is selected
[AROS.git] / workbench / libs / diskfont / af_fontdescr_io.c
blob5a5a2220c1043b76947b8f8e5d09552e39bccba2
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Functions for readin .font files
6 Lang: English.
7 */
9 /****************************************************************************************/
11 #include <diskfont/diskfonttag.h>
12 #include <aros/macros.h>
14 #include <proto/dos.h>
15 #include <proto/utility.h>
16 #include <proto/arossupport.h>
17 #include <string.h>
18 #include "diskfont_intern.h"
20 #include <aros/debug.h>
22 /****************************************************************************************/
24 /******************/
25 /* ReadFontDescr */
26 /******************/
28 /****************************************************************************************/
30 struct FontDescrHeader *ReadFontDescr(CONST_STRPTR filename, struct DiskfontBase *DiskfontBase)
32 struct FontDescrHeader *fdh = 0;
33 struct TTextAttr *tattr;
34 BPTR fh;
35 UWORD aword, numentries, numtags;
36 UWORD *availsizes = NULL;
37 UWORD numoutlineentries = 0;
38 UBYTE strbuf[MAXFONTPATH + 1];
40 D(bug("ReadFontDescr(filename=%s\n", filename));
42 /* Allocate the FontDescrHeader */
43 if (!(fh = Open(filename, MODE_OLDFILE)))
44 goto failure;
46 if (!(fdh = AllocMem(sizeof (struct FontDescrHeader), MEMF_ANY | MEMF_CLEAR)) )
47 goto failure;
49 /* First read the file id (FCH_ID or TFCH_ID) */
50 if (!ReadWord( &DFB(DiskfontBase)->dsh, &aword, (void *)fh ))
51 goto failure;
53 /* Check that this is a .font file */
55 if ( (aword != FCH_ID) && (aword != TFCH_ID) && (aword != OFCH_ID) )
57 D(bug("ReadFontDescr: unsupported file id\n"));
58 goto failure;
61 fdh->ContentsID = aword;
63 fdh->Tagged = ((aword == TFCH_ID) || (aword == OFCH_ID));
65 /* Read number of (T)FontContents structs in the file */
66 if (!ReadWord( &DFB(DiskfontBase)->dsh, &numentries , (void *)fh ))
68 D(bug("ReadFontDescr: error reading numentries\n"));
69 goto failure;
72 fdh->NumEntries = numentries;
74 if (fdh->ContentsID == OFCH_ID)
76 fdh->OTagList = OTAG_GetFile(filename, DiskfontBase);
77 if (fdh->OTagList)
79 availsizes = (UWORD *)GetTagData(OT_AvailSizes, (IPTR) NULL, fdh->OTagList->tags);
80 if (availsizes)
82 /* OT_AvailSizes points to an UWORD array, where the first UWORD
83 is the number of entries, and the following <numentry> UWORD's
84 are the sizes */
86 numoutlineentries = AROS_BE2WORD(*availsizes);
87 availsizes++;
91 else
93 D(bug("ReadFontDescr: No OTagList for outlined font\n"));
95 /* TODO: stegerg: CHECKME!! Prevent OTAG_ functions from being called on NULL/non existing otag / taglist
97 fdh->ContentsID = TFCH_ID;
101 if (!(numentries + numoutlineentries)) goto failure;
103 /* Allocate mem for array of TTextAttrs */
104 fdh->TAttrArray = AllocVec((fdh->NumEntries + numoutlineentries) * sizeof(struct TTextAttr), MEMF_ANY|MEMF_CLEAR);
105 if (!fdh->TAttrArray) goto failure;
107 tattr = fdh->TAttrArray;
109 while (numentries--)
112 /* Read the fontname */
114 STRPTR strptr;
115 UWORD len = 0; /* Length of fontname in file including null-termination */
117 strptr = strbuf;
121 if (!ReadByte( &DFB(DiskfontBase)->dsh, strptr, (void *)fh))
122 goto failure;
124 len ++;
126 while (*strptr ++);
128 /* We set tattr->tta_Name to the real font name, for
129 example FONTS:helvetica/15 */
131 if (!(tattr->tta_Name = AllocVec(len + 1, MEMF_ANY)))
132 goto failure;
134 strcpy(tattr->tta_Name, strbuf);
136 D(bug("ReadFontDescr: tta_Name \"%s\"\n", tattr->tta_Name));
138 /* Seek to the end of the fontnamebuffer ( - 2 if tagged) */
139 Flush(fh);
140 Seek
143 MAXFONTPATH - ( len + (fdh->Tagged ? 2 : 0) ),
144 OFFSET_CURRENT
148 /* Do special stuff for files with tags in them */
149 if (fdh->Tagged)
152 /* Next thing up is the tagcount */
153 if (!ReadWord(&DFB(DiskfontBase)->dsh, &numtags, (void *)fh))
154 goto failure;
157 if (numtags)
159 /* Seek back and read the tags. Note, that the TAG_DONE
160 tagitem "goes over" the numtags, ie. it's ti_Data will
161 contain the numtags in the lower WORD:
163 TAGLIST start
165 00000000 80000008 00370000 80000001
166 003F003F 80000002 00640064 00000000
167 00000004 00378022 \TAG_DONE
168 |||| ||||||||
169 TagCount ||||||Flags
170 ||||||
171 ||||Style
172 ||||
173 YSize
176 Flush(fh);
177 Seek
179 fh,
180 -(numtags * 8), /* sizeof (struct TagItem) = 8 */
181 OFFSET_CURRENT
184 if (!(tattr->tta_Tags = ReadTags(fh, numtags, DFB(DiskfontBase) )))
185 goto failure;
187 } /* if (numtags) */
188 else
189 tattr->tta_Tags = NULL;
191 } /* if (fdh->Tagged) */
192 else
193 tattr->tta_Tags = NULL;
195 D(bug("ReadFontDescr: font \"%s\" tags %p\n", tattr->tta_Name, tattr->tta_Tags));
197 /* Read the rest of the info */
198 if (!ReadWord( &DFB(DiskfontBase)->dsh, &(tattr->tta_YSize), (void *)fh ))
199 goto failure;
201 if (!ReadByte(&DFB(DiskfontBase)->dsh, &(tattr->tta_Style), (void *)fh ))
202 goto failure;
204 if (!ReadByte( &DFB(DiskfontBase)->dsh, &(tattr->tta_Flags), (void *)fh ))
205 goto failure;
207 tattr ++;
209 } /* while (numentries--) */
211 Close(fh); fh = 0;
213 if (numoutlineentries)
215 UBYTE flags = OTAG_GetFontFlags(fdh->OTagList, DiskfontBase);
216 UBYTE style = OTAG_GetFontStyle(fdh->OTagList, DiskfontBase);
218 while(numoutlineentries--)
220 UWORD size;
221 UWORD i;
222 BOOL exists = FALSE;
224 size = AROS_BE2WORD(*availsizes);
225 availsizes++;
227 /* Check if this size already exists as bitmap
228 font. If it does, then ignore it */
230 for(i = 0; i < fdh->NumEntries; i++)
232 if (fdh->TAttrArray[i].tta_YSize == size)
234 exists = TRUE;
235 break;
239 if (exists) continue;
241 /* NumEntries contains the total number of entries, ie.
242 bitmap fonts and outline fonts included. NumOutlineEntries
243 tells how many among these (at the end of the array) are
244 outline fonts */
246 fdh->NumEntries++;
247 fdh->NumOutlineEntries++;
249 tattr->tta_Name = fdh->OTagList->filename;
250 tattr->tta_YSize = size;
251 tattr->tta_Flags = flags;
252 tattr->tta_Style = style;
253 tattr->tta_Tags = NULL;
255 D(bug("ReadFontDescr: font \"%s\" tags %p\n", tattr->tta_Name, tattr->tta_Tags));
257 tattr++;
258 } /* while(numoutlineentries--) */
260 } /* if (numoutlineentries) */
262 ReturnPtr ("ReadFontDescr", struct FontDescrHeader *, fdh);
264 failure:
265 /* Free all allocated memory */
267 if (fh) Close(fh);
269 if (fdh)
270 FreeFontDescr(fdh, DFB(DiskfontBase) );
272 ReturnPtr ("ReadFontDescr", struct FontDescrHeader*, FALSE);
276 /****************************************************************************************/
278 /******************/
279 /* FreeFontDescr */
280 /******************/
282 /****************************************************************************************/
284 VOID FreeFontDescr(struct FontDescrHeader *fdh, struct DiskfontBase *DiskfontBase)
286 struct TTextAttr *tattr;
288 UWORD numentries;
290 D(bug("FreeFontDescr(fdh=%p\n", fdh));
292 if (fdh)
294 tattr = fdh->TAttrArray;
295 numentries = fdh->NumEntries - fdh->NumOutlineEntries;
297 if (tattr)
299 /* Go through the whole array of bitmap font entries
300 freeing strings and tags. Outline font entries
301 always have the tta_Name pointing to the otag file
302 and must not get the tta_Name freed. They also have
303 tta_Tags always being NULL. Therefore the loop below
304 goes only through the bitmap font entries */
306 while(numentries--)
308 if (tattr->tta_Name)
309 FreeVec(tattr->tta_Name);
311 if (tattr->tta_Tags)
312 FreeVec(tattr->tta_Tags);
314 tattr ++;
317 FreeVec(fdh->TAttrArray);
320 if (fdh->OTagList) OTAG_KillFile(fdh->OTagList, DiskfontBase);
322 FreeMem(fdh, sizeof (struct FontDescrHeader));
325 ReturnVoid("FreeFontDescr");
328 /****************************************************************************************/