Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / libs / diskfont / newfontcontents.c
blob08576014123d364489acba3b4c7d4b5875161d34
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 #define TFC(node) ((struct TFontContents *)(&node->fc))
40 /*****************************************************************************
42 NAME */
43 #include <proto/diskfont.h>
45 AROS_LH2(struct FontContentsHeader *, NewFontContents,
47 /* SYNOPSIS */
48 AROS_LHA(BPTR , fontsLock, A0),
49 AROS_LHA(STRPTR, fontName, A1),
51 /* LOCATION */
52 struct Library *, DiskfontBase, 7, Diskfont)
54 /* FUNCTION
56 Create an array of FontContents entries describing the fonts related
57 with 'fontName' -- this is those in the directory with the same name
58 as 'fontName' without the ".font" suffix.
60 INPUTS
62 fontsLock -- A lock on the FONTS: directory or another directory
63 containing the font file and associated directory
64 exists.
65 fontName -- The font name (with the ".font" suffix).
67 RESULT
69 Pointer to a struct FontContentsHeader describing the font or NULL
70 if something went wrong.
72 NOTES
74 EXAMPLE
76 BUGS
78 SEE ALSO
80 DisposeFontContents()
82 INTERNALS
84 The whole issue of fonts being Amiga executable files is a big mess.
85 We'd better do something about it (define a new format?).
86 Some code here should use a function similar to the one in
87 ReadDiskFont() -- however, we do not want a struct TextFont *.
89 HISTORY
91 5.8.1999 SDuvan partial implementation
93 *****************************************************************************/
95 AROS_LIBFUNC_INIT
97 BPTR oldDir;
98 BPTR lock, otLock = NULL;
99 STRPTR suffix;
100 char name[MAXFONTNAME];
101 struct List contentsList;
103 struct FileInfoBlock *fib;
104 struct FontContentsHeader *ret = NULL;
106 (void) DiskfontBase;
108 NEWLIST(&contentsList);
109 oldDir = CurrentDir(fontsLock);
111 strcpy((char *)&name, fontName);
112 suffix = strrchr(name, '.');
114 if(suffix == NULL || strcmp(suffix, ".font") != 0)
116 CurrentDir(oldDir);
117 return NULL;
120 strcpy(suffix, ".otag");
122 /* otLock will be an indicator of whether there exists a .otag file */
123 otLock = Lock(name, SHARED_LOCK);
124 UnLock(otLock);
126 /* Get the correct directory name */
127 name[strlen(name) - sizeof(".otag") + 1] = 0;
129 lock = Lock(name, SHARED_LOCK); /* Lock font directory */
131 fib = AllocDosObject(DOS_FIB, NULL);
133 if(fib == NULL)
135 UnLock(lock);
136 CurrentDir(oldDir);
137 return NULL;
140 CurrentDir(lock);
142 if(Examine(lock, fib) == DOSTRUE)
144 struct FontContentsHeader fch = { FCH_ID , 0 };
146 /* Loop through the files in this font's directory */
147 while(ExNext(lock, fib))
149 BPTR fontSeg;
150 struct DiskFontHeader *dfh = NULL;
151 struct contentsBuffer *cNode;
153 /* Skip directories */
154 if(fib->fib_DirEntryType >= 0)
155 continue;
157 fontSeg = LoadSeg(fib->fib_FileName);
159 if(fontSeg == NULL)
160 continue;
162 /* Skip NextSegment and ReturnCode */
163 dfh = ConvDiskFont(fontSeg, "test", FALSE, (struct DiskfontBase_intern *)DiskfontBase);
164 UnLoadSeg(fontSeg);
166 if(dfh == NULL)
168 FreeBuffers((struct List *)&contentsList);
169 UnLock(lock);
170 FreeDosObject(DOS_FIB, fib);
171 CurrentDir(oldDir);
172 return NULL;
175 cNode = AllocVec(sizeof(struct contentsBuffer),
176 MEMF_PUBLIC | MEMF_CLEAR);
178 if(cNode == NULL)
180 DisposeConvDiskFont(dfh, DFB(DiskfontBase));
181 FreeBuffers((struct List *)&contentsList);
182 UnLock(lock);
183 FreeDosObject(DOS_FIB, fib);
184 CurrentDir(oldDir);
185 return NULL;
188 AddTail((struct List *)&contentsList, (struct Node *)cNode);
190 strcpy(cNode->fc.fc_FileName, name);
191 strcat(cNode->fc.fc_FileName, "/");
192 strcat(cNode->fc.fc_FileName, fib->fib_FileName);
194 /* Embedded tags? */
195 if((dfh->dfh_TF.tf_Style & FSF_TAGGED) && (dfh->dfh_TagList != NULL))
197 const struct TagItem *ti = (struct TagItem *)(dfh->dfh_TagList); /* dfh_TagList */
198 struct TagItem *tPtr;
199 struct TagItem *item;
200 WORD nTags = 0;
201 WORD i; /* Loop variable */
203 while(ti->ti_Tag != TAG_DONE)
205 ti++;
206 nTags++;
208 nTags++; /* Include TAG_DONE */
210 TFC(cNode)->tfc_TagCount = nTags;
211 fch.fch_FileID = TFCH_ID;
213 tPtr = (struct TagItem *)((IPTR)&(TFC(cNode)->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 == NULL ? 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 /****************************************************************************************/