revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / diskfont / newfontcontents.c
blob843b0e8ef1ee2c8888e2b08f9bea2120058c05ac
1 /*
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /****************************************************************************************/
8 #include "diskfont_intern.h"
10 #include <diskfont/diskfont.h>
11 #include <utility/tagitem.h>
12 #include <dos/dos.h>
13 #include <proto/dos.h>
14 #include <proto/exec.h>
15 #include <proto/utility.h>
16 #include <string.h>
17 #include <aros/debug.h>
18 #include <aros/macros.h>
20 /****************************************************************************************/
23 /****************************************************************************************/
25 VOID CopyContents(struct List *list, APTR mem);
26 VOID FreeBuffers(struct List *list);
28 /****************************************************************************************/
30 struct contentsBuffer
32 struct Node node;
33 struct FontContents fc;
36 /****************************************************************************************/
38 /*****************************************************************************
40 NAME */
41 #include <proto/diskfont.h>
43 AROS_LH2(struct FontContentsHeader *, NewFontContents,
45 /* SYNOPSIS */
46 AROS_LHA(BPTR , fontsLock, A0),
47 AROS_LHA(STRPTR, fontName, A1),
49 /* LOCATION */
50 struct Library *, DiskfontBase, 7, Diskfont)
52 /* FUNCTION
54 Create an array of FontContents entries describing the fonts related
55 with 'fontName' -- this is those in the directory with the same name
56 as 'fontName' without the ".font" suffix.
58 INPUTS
60 fontsLock -- A lock on the FONTS: directory or another directory
61 containing the font file and associated directory
62 exists.
63 fontName -- The font name (with the ".font" suffix).
65 RESULT
67 Pointer to a struct FontContentsHeader describing the font or NULL
68 if something went wrong.
70 NOTES
72 EXAMPLE
74 BUGS
76 SEE ALSO
78 DisposeFontContents()
80 INTERNALS
82 The whole issue of fonts being Amiga executable files is a big mess.
83 We'd better do something about it (define a new format?).
84 Some code here should use a function similar to the one in
85 ReadDiskFont() -- however, we do not want a struct TextFont *.
87 HISTORY
89 5.8.1999 SDuvan partial implementation
91 *****************************************************************************/
93 AROS_LIBFUNC_INIT
95 BPTR oldDir;
96 BPTR lock, otLock = BNULL;
97 STRPTR suffix;
98 char name[MAXFONTNAME];
99 struct List contentsList;
101 struct FileInfoBlock *fib;
102 struct FontContentsHeader *ret = NULL;
103 struct TFontContents *tfc;
105 (void) DiskfontBase;
107 NEWLIST(&contentsList);
108 oldDir = CurrentDir(fontsLock);
110 strcpy((char *)&name, fontName);
111 suffix = strrchr(name, '.');
113 if(suffix == NULL || strcmp(suffix, ".font") != 0)
115 CurrentDir(oldDir);
116 return NULL;
119 strcpy(suffix, ".otag");
121 /* otLock will be an indicator of whether there exists a .otag file */
122 otLock = Lock(name, SHARED_LOCK);
123 UnLock(otLock);
125 /* Get the correct directory name */
126 name[strlen(name) - sizeof(".otag") + 1] = 0;
128 lock = Lock(name, SHARED_LOCK); /* Lock font directory */
130 fib = AllocDosObject(DOS_FIB, NULL);
132 if(fib == NULL)
134 UnLock(lock);
135 CurrentDir(oldDir);
136 return NULL;
139 CurrentDir(lock);
141 if(Examine(lock, fib) == DOSTRUE)
143 struct FontContentsHeader fch = { FCH_ID , 0 };
145 /* Loop through the files in this font's directory */
146 while(ExNext(lock, fib))
148 BPTR fontSeg;
149 struct DiskFontHeader *dfh = NULL;
150 struct contentsBuffer *cNode;
152 /* Skip directories */
153 if(fib->fib_DirEntryType >= 0)
154 continue;
156 fontSeg = LoadSeg(fib->fib_FileName);
158 if(fontSeg == BNULL)
159 continue;
161 /* Skip NextSegment and ReturnCode */
162 dfh = ConvDiskFont(fontSeg, "test", FALSE, (struct DiskfontBase *)DiskfontBase);
163 UnLoadSeg(fontSeg);
165 if(dfh == NULL)
167 FreeBuffers((struct List *)&contentsList);
168 UnLock(lock);
169 FreeDosObject(DOS_FIB, fib);
170 CurrentDir(oldDir);
171 return NULL;
174 cNode = AllocVec(sizeof(struct contentsBuffer),
175 MEMF_PUBLIC | MEMF_CLEAR);
177 if(cNode == NULL)
179 DisposeConvDiskFont(dfh, DFB(DiskfontBase));
180 FreeBuffers((struct List *)&contentsList);
181 UnLock(lock);
182 FreeDosObject(DOS_FIB, fib);
183 CurrentDir(oldDir);
184 return NULL;
187 AddTail((struct List *)&contentsList, (struct Node *)cNode);
189 strcpy(cNode->fc.fc_FileName, name);
190 strcat(cNode->fc.fc_FileName, "/");
191 strcat(cNode->fc.fc_FileName, fib->fib_FileName);
193 /* Embedded tags? */
194 if((dfh->dfh_TF.tf_Style & FSF_TAGGED) && (dfh->dfh_TagList != 0))
196 struct TagItem *ti = (struct TagItem *)(dfh->dfh_TagList); /* dfh_TagList */
197 struct TagItem *tPtr;
198 struct TagItem *item;
199 WORD nTags = 0;
200 WORD i; /* Loop variable */
202 while(ti->ti_Tag != TAG_DONE)
204 ti++;
205 nTags++;
207 nTags++; /* Include TAG_DONE */
209 tfc = (struct TFontContents *)(&cNode->fc);
210 tfc->tfc_TagCount = nTags;
211 fch.fch_FileID = TFCH_ID;
213 tPtr = (struct TagItem *)((IPTR)&(tfc->tfc_TagCount) + 2 - nTags*sizeof(struct TagItem));
215 ti = (struct TagItem *)(dfh->dfh_TagList); /* dfh_TagList */
217 i = 0;
218 while((item = NextTagItem(&ti)) != NULL)
220 tPtr[i].ti_Tag = AROS_BE2LONG(item->ti_Tag);
221 tPtr[i].ti_Data = AROS_BE2LONG(item->ti_Data);
222 i++;
224 /* Add TAG_DONE tag, but no data (to avoid writing over the
225 TagCount) */
226 tPtr[i].ti_Tag = TAG_DONE;
229 } /* if(this was a tagged font) */
231 cNode->fc.fc_YSize = dfh->dfh_TF.tf_YSize;
232 cNode->fc.fc_Style = dfh->dfh_TF.tf_Style;
233 cNode->fc.fc_Flags = dfh->dfh_TF.tf_Flags;
235 cNode->fc.fc_Flags &= ~FPF_REMOVED;
236 cNode->fc.fc_Flags &= ~FPF_ROMFONT;
237 cNode->fc.fc_Flags |= FPF_DISKFONT;
239 fch.fch_NumEntries++;
241 DisposeConvDiskFont(dfh, DFB(DiskfontBase));
242 } /* while(there are files left in the directory) */
244 if(IoErr() == ERROR_NO_MORE_ENTRIES)
246 ret = (struct FontContentsHeader *)AllocVec(sizeof(struct FontContentsHeader) + fch.fch_NumEntries*sizeof(struct TFontContents), MEMF_PUBLIC | MEMF_CLEAR);
248 if(ret != NULL)
250 ret->fch_NumEntries = fch.fch_NumEntries;
251 ret->fch_FileID = (otLock == BNULL ? fch.fch_FileID : OFCH_ID);
253 CopyContents((struct List *)&contentsList,
254 ((UBYTE *)ret + sizeof(struct FontContentsHeader)));
259 FreeBuffers(&contentsList);
261 } /* if(we could examine the font's directory) */
263 FreeDosObject(DOS_FIB, fib);
264 UnLock(lock);
265 CurrentDir(oldDir);
267 return ret;
269 AROS_LIBFUNC_EXIT
271 } /* NewFontContents */
273 /****************************************************************************************/
275 VOID FreeBuffers(struct List *list)
277 struct Node *node, *temp;
279 ForeachNodeSafe(list, node, temp)
281 Remove(node);
282 FreeVec(node);
286 /****************************************************************************************/
288 VOID CopyContents(struct List *list, APTR mem)
290 struct contentsBuffer *temp;
292 ForeachNode(list, temp)
294 CopyMem(&temp->fc, mem, sizeof(struct FontContents));
295 mem += sizeof(struct FontContents);
299 /****************************************************************************************/