Nonsense removed: upper case and lower case the same time.
[AROS.git] / workbench / libs / diskfont / diskfontfunc.c
blob72dacb4b8822322e271e68f98837c0d17e4c4d18
1 /*
2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Hook for handling fonts in FONTS:
6 Lang: English.
7 */
9 /****************************************************************************************/
11 #include <exec/initializers.h>
12 #include <dos/dosextens.h>
13 #include <proto/dos.h>
14 #include <proto/graphics.h>
15 #include <proto/arossupport.h>
16 //#include <proto/alib.h>
17 #include <string.h>
19 #include "diskfont_intern.h"
21 /****************************************************************************************/
23 #include <aros/debug.h>
25 /****************************************************************************************/
27 struct DirEntry;
29 struct FileEntry
31 struct MinNode Node;
32 struct DirEntry *DirEntry;
33 STRPTR FileName;
34 struct DateStamp FileChanged;
35 UWORD ContentsID;
36 UBYTE SupportedStyles;
37 UBYTE FontStyle;
38 ULONG Numentries;
39 struct TTextAttr *Attrs;
42 struct DirEntry
44 struct MinNode Node;
45 BPTR DirLock;
46 struct DateStamp DirChanged;
47 struct MinList FileList;
50 struct DF_FontsData /*DiskFontData */
52 #ifdef PROGDIRFONTSDIR
53 struct DirEntry *ProgdirDirEntry;
54 #endif
55 struct DirEntry *CurrentDirEntry;
56 struct FileEntry *CurrentFileEntry, *PrevFileEntry;
57 UWORD AttrsIndex;
58 struct FileEntry *RememberFileEntry;
59 UWORD RememberIndex;
62 struct DF_FileData
64 struct FontDescrHeader *FDH;
65 STRPTR FilePart;
66 STRPTR OrigName;
67 struct TTextAttr *LastAttr;
68 UWORD AttrsIndex;
69 UWORD RememberIndex;
70 struct TTextAttr ExtraAttr;
73 typedef enum {DF_FONTSDATA, DF_FILEDATA} DF_DataType;
75 struct DF_Data
77 DF_DataType Type;
78 struct TTextAttr *ReqAttr;
79 union
81 struct DF_FontsData FontsData;
82 struct DF_FileData FileData;
83 } u;
87 /****************************************************************************************/
89 /*****************/
90 /* ReadFileEntry */
91 /*****************/
93 /****************************************************************************************/
95 STATIC struct FileEntry *ReadFileEntry(struct ExAllData *ead, struct DiskfontBase_intern *DiskfontBase)
97 struct FontDescrHeader *fdh;
98 struct FileEntry *retval = NULL;
99 ULONG size, strsize, tagcount;
100 int i;
101 struct TagItem *tagitems;
102 STRPTR filename;
104 D(bug("ReadFileEntry: ead: 0x%lx\n", ead));
105 D(bug("ReadFileEntry: name=\"%s\"\n", ead->ed_Name));
107 fdh = ReadFontDescr(ead->ed_Name, DiskfontBase);
108 if (fdh == NULL)
110 D(bug("ReadFileEntry: error in ReadFontDescr\n"));
111 return NULL;
114 strsize = strlen(ead->ed_Name) + 1;
115 size = sizeof(struct FileEntry) + strsize + fdh->NumEntries * sizeof(struct TTextAttr);
116 if (fdh->ContentsID == OFCH_ID) /* Reserve extra Attr for outline fonts */
117 size += sizeof(struct TTextAttr);
119 for (i = 0; i < fdh->NumEntries; i++)
120 if (fdh->TAttrArray[i].tta_Tags != NULL)
121 size += NumTags(fdh->TAttrArray[i].tta_Tags, DiskfontBase) * sizeof(struct TagItem);
123 retval = AllocVec(size, MEMF_ANY|MEMF_CLEAR);
124 if (retval == NULL)
126 D(bug("ReadFileEntry: Could not allocate memory\n"));
127 FreeFontDescr(fdh, DiskfontBase);
128 ReturnPtr("ReadFileEntry", struct FileEntry *, NULL);
131 filename = (STRPTR)(retval + 1);
132 strcpy(filename, ead->ed_Name);
133 retval->FileName = filename;
134 retval->FileChanged = *(struct DateStamp *)&ead->ed_Days;
136 retval->Numentries = fdh->NumEntries;
137 retval->ContentsID = fdh->ContentsID;
138 retval->Attrs = (struct TTextAttr *)(filename + strsize);
139 memcpy(retval->Attrs, fdh->TAttrArray, fdh->NumEntries * sizeof(struct TTextAttr));
140 if (retval->ContentsID == OFCH_ID)
142 int ind = retval->Numentries;
144 retval->Numentries++;
145 retval->SupportedStyles = OTAG_GetSupportedStyles(fdh->OTagList, DiskfontBase);
146 retval->FontStyle = OTAG_GetFontStyle(fdh->OTagList, DiskfontBase);
147 retval->Attrs[ind].tta_Name = filename;
148 retval->Attrs[ind].tta_Flags = OTAG_GetFontFlags(fdh->OTagList, DiskfontBase);
151 tagitems = (struct TagItem *)(retval->Attrs + retval->Numentries);
153 for (i = 0; i < fdh->NumEntries; i++)
155 retval->Attrs[i].tta_Name = retval->FileName;
157 if (fdh->TAttrArray[i].tta_Tags != NULL)
159 tagcount = NumTags(fdh->TAttrArray[i].tta_Tags, DiskfontBase);
160 CopyTagItems(tagitems, fdh->TAttrArray[i].tta_Tags, DiskfontBase);
161 retval->Attrs[i].tta_Tags = tagitems;
162 tagitems += tagcount;
164 else
165 retval->Attrs[i].tta_Tags = NULL;
168 FreeFontDescr(fdh, DiskfontBase);
170 ReturnPtr("ReadFileEntry", struct FileEntry *, retval);
173 /****************************************************************************************/
175 /*****************/
176 /* FreeFileEntry */
177 /*****************/
179 /****************************************************************************************/
181 STATIC VOID FreeFileEntry(struct FileEntry *feptr, struct DiskfontBase_intern *DiskfontBase)
183 FreeVec(feptr);
186 /****************************************************************************************/
188 /****************/
189 /* FreeFileList */
190 /****************/
192 /****************************************************************************************/
194 STATIC VOID FreeFileList(struct MinList *filelist, struct DiskfontBase_intern *DiskfontBase)
196 struct FileEntry *feptr, *nextfeptr;
198 D(bug("FreeFileList(filelist=%p)\n", filelist));
200 ForeachNodeSafe(filelist, feptr, nextfeptr)
202 REMOVE(feptr);
203 FreeFileEntry(feptr, DiskfontBase);
206 ReturnVoid("FreeFileList");
209 /****************************************************************************************/
211 /****************/
212 /* GetFileList */
213 /****************/
215 /****************************************************************************************/
217 /* Build the list of .font file names using Examine() */
218 STATIC BOOL GetFileList(struct DirEntry *direntry, struct DiskfontBase_intern *DiskfontBase)
220 struct MinList newlist;
221 struct FileEntry *fe, *nextfe;
222 BOOL retval = TRUE, more;
223 struct ExAllControl *eac;
224 struct ExAllData *ead, *eadit;
226 D(bug("GetFileList(direntry=%p)\n", direntry));
228 NEWLIST(&newlist);
230 eac = AllocDosObject(DOS_EXALLCONTROL, NULL);
231 eac->eac_LastKey = 0;
232 ead = (struct ExAllData *)AllocMem(1024, MEMF_ANY);
236 more = ExAll(direntry->DirLock, ead, 1024, ED_DATE, eac);
237 if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES))
238 retval = FALSE;
239 else if (eac->eac_Entries == 0)
240 continue;
241 else
243 for (eadit = ead; eadit != NULL; eadit = eadit->ed_Next)
245 ULONG namelen = strlen(eadit->ed_Name);
247 D(bug("GetFileList: Scanning file: %s\n", eadit->ed_Name));
249 /* Maybe this can be done in a hook function passed in eac */
250 if (namelen < 5 || strncmp(eadit->ed_Name+namelen-5, ".font", 5) != 0)
252 D(bug("GetFileList: wrong suffix: %s\n", eadit->ed_Name+namelen-5));
253 continue;
256 /* Is a FileEntry for this file already in the list */
257 for (fe = (struct FileEntry *)GetHead(&direntry->FileList);
258 fe != NULL;
259 fe = (struct FileEntry *)GetSucc(fe))
261 if (strcmp(eadit->ed_Name, fe->FileName) == 0)
262 break;
265 if (fe == NULL)
267 D(bug("GetFileList: Filename not yet in memory\n"));
269 fe = ReadFileEntry(eadit, DiskfontBase);
270 if (fe != NULL)
272 fe->DirEntry = direntry;
274 D(bug("GetFileList: Add to list: 0x%lx\n", fe));
275 ADDTAIL(&newlist, fe);
278 else
280 struct DateStamp ds;
281 REMOVE(fe);
283 ds.ds_Days = eadit->ed_Days;
284 ds.ds_Minute = eadit->ed_Mins;
285 ds.ds_Tick = eadit->ed_Ticks;
287 D(bug("GetFileList: Found filename already in memory\n"));
289 if (CompareDates(&ds, &fe->FileChanged) == 0)
291 D(bug("GetFileList: File's date not changed: Add to list 0x%lx\n", fe));
292 ADDTAIL(&newlist, fe);
294 else
296 D(bug("GetFileList: Date changed rereading information\n"));
298 FreeFileEntry(fe, DiskfontBase);
300 fe = ReadFileEntry(eadit, DiskfontBase);
301 if (fe == NULL)
303 D(bug("GetFileList: Reading information failed\n"));
304 retval = FALSE;
305 break;
307 else
309 fe->DirEntry = direntry;
310 D(bug("GetFileList: Reading OK, add to list: 0x%lx\n", fe));
311 ADDTAIL(&newlist, fe);
315 } /* for (eadit = ... */
317 } while (more && retval);
319 FreeDosObject(DOS_EXALLCONTROL, eac);
320 FreeMem(ead, 1024);
322 if (!retval)
324 D(bug("GetFileList: Not OK freeing FileList\n"));
325 FreeFileList(&newlist, DiskfontBase);
327 else
329 /* Remove FileEntries that are still in memory but not anymore
330 * on disk */
331 FreeFileList(&direntry->FileList, DiskfontBase);
333 ForeachNodeSafe(&newlist, fe, nextfe)
335 REMOVE(fe);
336 ADDTAIL(&direntry->FileList, fe);
337 D(bug("GetFileList: Adding fe=%p\n", fe));
341 ReturnBool ("GetFileList", retval);
344 /****************************************************************************************/
346 /*********************/
347 /* StreamOutFileList */
348 /*********************/
350 /****************************************************************************************/
352 STATIC BOOL StreamOutFileList(struct MinList *filelist, BPTR fh, struct DiskfontBase_intern *DiskfontBase)
354 struct FileEntry *fe;
355 ULONG i;
356 BOOL ok = TRUE;
358 ForeachNode(filelist, fe)
360 D(bug("StreamOutFileList: Writing file %s\n", fe->FileName));
361 ok = ok && WriteString(&DiskfontBase->dsh, fe->FileName, fh);
362 D(bug("StreamOutFileList: Write days: %d minute: %d, tick: %d\n",
363 fe->FileChanged.ds_Days, fe->FileChanged.ds_Minute,
364 fe->FileChanged.ds_Tick));
365 ok = ok && WriteLong(&DiskfontBase->dsh, fe->FileChanged.ds_Days, fh);
366 ok = ok && WriteLong(&DiskfontBase->dsh, fe->FileChanged.ds_Minute, fh);
367 ok = ok && WriteLong(&DiskfontBase->dsh, fe->FileChanged.ds_Tick, fh);
368 ok = ok && WriteWord(&DiskfontBase->dsh, fe->ContentsID, fh);
369 ok = ok && WriteByte(&DiskfontBase->dsh, fe->SupportedStyles, fh);
370 ok = ok && WriteByte(&DiskfontBase->dsh, fe->FontStyle, fh);
371 D(bug("StreamOutFileList: Write numentries=%d\n", fe->Numentries));
372 ok = ok && WriteLong(&DiskfontBase->dsh, fe->Numentries, fh);
374 for (i=0; ok && i<fe->Numentries; i++)
376 ok = ok && WriteWord(&DiskfontBase->dsh, fe->Attrs[i].tta_YSize, fh);
377 ok = ok && WriteByte(&DiskfontBase->dsh, fe->Attrs[i].tta_Style, fh);
378 ok = ok && WriteByte(&DiskfontBase->dsh, fe->Attrs[i].tta_Flags, fh);
379 ok = ok && WriteTagsNum(fh, fe->Attrs[i].tta_Tags, DiskfontBase);
382 ok = ok && WriteString(&DiskfontBase->dsh, "", fh);
384 return ok;
387 /****************************************************************************************/
389 /********************/
390 /* StreamInFileList */
391 /********************/
393 /****************************************************************************************/
395 STATIC BOOL StreamInFileList(struct DirEntry *direntry, BPTR fh, struct DiskfontBase_intern *DiskfontBase)
397 struct FileEntry *fe, fe2;
398 ULONG i, numtags, totnumtags;
399 BOOL ok = TRUE;
400 struct TTextAttr *attrs;
401 struct TagItem *tagptr;
403 for (ok = ReadString(&DiskfontBase->dsh, &fe2.FileName, fh);
404 ok && strlen(fe2.FileName)>0;
405 ok = ok && ReadString(&DiskfontBase->dsh, &fe2.FileName, fh))
407 D(bug("StreamInFileList: reading data for \"%s\"\n", fe2.FileName));
409 ok = ok && ReadLong(&DiskfontBase->dsh, &fe2.FileChanged.ds_Days, fh);
410 ok = ok && ReadLong(&DiskfontBase->dsh, &fe2.FileChanged.ds_Minute, fh);
411 ok = ok && ReadLong(&DiskfontBase->dsh, &fe2.FileChanged.ds_Tick, fh);
412 D(bug("StreamInFileList: read days: %d minute: %d tick: %d\n",
413 fe2.FileChanged.ds_Days, fe2.FileChanged.ds_Minute,
414 fe2.FileChanged.ds_Tick));
415 ok = ok && ReadWord(&DiskfontBase->dsh, &fe2.ContentsID, fh);
416 ok = ok && ReadByte(&DiskfontBase->dsh, &fe2.SupportedStyles, fh);
417 ok = ok && ReadByte(&DiskfontBase->dsh, &fe2.FontStyle, fh);
418 ok = ok && ReadLong(&DiskfontBase->dsh, &fe2.Numentries, fh);
420 if (ok)
422 attrs = AllocVec(fe2.Numentries * sizeof(struct TTextAttr), MEMF_ANY|MEMF_CLEAR);
424 ok = ok && attrs != NULL;
426 if (ok)
427 for (i = 0; i < fe2.Numentries; i++)
428 attrs[i].tta_Tags = NULL;
430 for (i = 0, totnumtags = 0; ok && i < fe2.Numentries; i++)
432 ok = ok && ReadWord(&DiskfontBase->dsh, &attrs[i].tta_YSize, fh);
433 ok = ok && ReadByte(&DiskfontBase->dsh, &attrs[i].tta_Style, fh);
434 ok = ok && ReadByte(&DiskfontBase->dsh, &attrs[i].tta_Flags, fh);
435 if (ok)
437 attrs[i].tta_Tags = ReadTagsNum(fh, &numtags, DiskfontBase);
438 D(bug("StreamInFileList: read tags %p\n", attrs[i].tta_Tags));
439 totnumtags += numtags;
440 ok = ok && numtags > 0;
443 D(bug("StreamInFileList: totnumtags == %u\n", totnumtags));
445 if (ok)
447 ULONG size = sizeof(struct FileEntry) +
448 strlen(fe2.FileName)+1 +
449 fe2.Numentries * sizeof(struct TTextAttr) +
450 totnumtags * sizeof(struct TagItem);
452 fe = (struct FileEntry *)AllocVec(size, MEMF_ANY);
453 ok = ok && fe != NULL;
455 if (ok)
457 fe->DirEntry = direntry;
458 fe->FileName = (STRPTR)(fe+1);
459 strcpy(fe->FileName, fe2.FileName);
460 fe->FileChanged = fe2.FileChanged;
461 fe->ContentsID = fe2.ContentsID;
462 fe->SupportedStyles = fe2.SupportedStyles;
463 fe->FontStyle = fe2.FontStyle;
464 fe->Numentries = fe2.Numentries;
465 fe->Attrs = (struct TTextAttr *)(fe->FileName + strlen(fe2.FileName)+1);
467 tagptr = (struct TagItem *)(fe->Attrs + fe2.Numentries);
468 for (i = 0; i < fe2.Numentries; i++)
470 fe->Attrs[i].tta_Name = fe->FileName;
471 fe->Attrs[i].tta_YSize = attrs[i].tta_YSize;
472 fe->Attrs[i].tta_Style = attrs[i].tta_Style;
473 fe->Attrs[i].tta_Flags = attrs[i].tta_Flags;
474 numtags = CopyTagItems(tagptr, attrs[i].tta_Tags, DiskfontBase);
475 fe->Attrs[i].tta_Tags = tagptr;
476 tagptr += numtags;
478 ADDTAIL(&direntry->FileList, fe);
481 if (attrs != NULL)
483 for (i = 0; i < fe2.Numentries; i++)
484 if (attrs[i].tta_Tags != NULL)
486 D(bug("StreamInFileList: freeing tags %p\n", attrs[i].tta_Tags));
487 FreeVec(attrs[i].tta_Tags);
489 FreeVec(attrs);
493 FreeVec(fe2.FileName);
495 if (ok)
497 D(bug("StreamInFileList: FileName empty\n"));
498 FreeVec(fe2.FileName);
500 else
502 D(bug("StreamInFileList: Error reading chachefile\n"));
503 FreeFileList(&direntry->FileList, DiskfontBase);
506 return ok;
509 /****************************************************************************************/
511 /****************/
512 /* FreeDirEntry */
513 /****************/
515 /****************************************************************************************/
517 STATIC VOID FreeDirEntry(struct DirEntry *direntry, struct DiskfontBase_intern *DiskfontBase)
519 if (direntry!=NULL)
521 FreeFileList(&direntry->FileList, DiskfontBase);
522 UnLock(direntry->DirLock);
523 FreeVec(direntry);
527 /****************************************************************************************/
529 /****************/
530 /* ReadDirEntry */
531 /****************/
533 /****************************************************************************************/
535 STATIC struct DirEntry *ReadDirEntry(BPTR dirlock, struct DirEntry *direntry, struct DiskfontBase_intern *DiskfontBase)
537 struct Process *Self;
538 APTR oldwinptr;
539 struct FileInfoBlock *fib;
540 BPTR olddir;
541 BPTR fh;
543 D(bug("ReadDirEntry(dirlock=0x%lx, direntry=0x%lx)\n", dirlock, direntry));
545 Self = (struct Process *) FindTask(NULL);
546 oldwinptr = Self->pr_WindowPtr;
547 Self->pr_WindowPtr = (APTR) -1;
549 fib = AllocDosObject(DOS_FIB, NULL);
550 if (fib == NULL)
552 D(bug("ReadDirEntry: Could not allocate DosObject\n"));
553 Self->pr_WindowPtr = oldwinptr;
554 ReturnPtr("ReadDirEntry", struct DirEntry *, NULL);
556 Examine(dirlock, fib);
557 Self->pr_WindowPtr = oldwinptr;
559 olddir = CurrentDir(dirlock);
561 if (direntry == NULL)
563 direntry = AllocVec(sizeof(struct DirEntry), MEMF_ANY | MEMF_CLEAR);
564 if (direntry==NULL)
566 D(bug("ReadDirEntry: Could not allocate DirEntry\n"));
567 FreeDosObject(DOS_FIB, fib);
568 CurrentDir(olddir);
569 ReturnPtr("ReadDirEntry", struct DirEntry *, NULL);
571 else
572 D(bug("ReadDirEntry: allocated direntry = 0x%lx\n", direntry));
574 direntry->DirLock = dirlock;
575 NEWLIST(&direntry->FileList);
577 /* Try to read the direntry from the file */
578 fh = Open(CACHE_FILE, MODE_OLDFILE);
579 if (fh != NULL)
581 BOOL ok;
583 ok = ReadLong(&DiskfontBase->dsh, &direntry->DirChanged.ds_Days, fh);
584 ok = ok && ReadLong(&DiskfontBase->dsh, &direntry->DirChanged.ds_Minute, fh);
585 ok = ok && ReadLong(&DiskfontBase->dsh, &direntry->DirChanged.ds_Tick, fh);
587 if (ok)
588 ok = StreamInFileList(direntry, fh, DiskfontBase);
590 Close(fh);
592 #warning CHECKME
593 #if 0
594 /* This part is disabled because in emul_handler on UNIX the date
595 * of a parent directory is changed only when a file is added or
596 * removed from the directory
599 /* If dates are the same return the direntry as is */
600 if (ok && CompareDates(&direntry->DirChanged, &fib->fib_Date) == 0)
602 D(bug("ReadDirEntry: date in cache not changed\n"));
603 FreeDosObject(DOS_FIB, fib);
604 Self->pr_WindowPtr = oldwinptr;
605 CurrentDir(olddir);
606 ReturnPtr("ReadDirEntry", struct DirEntry *, direntry);
608 #endif
611 else
613 CurrentDir(direntry->DirLock);
614 UnLock(dirlock);
615 if (CompareDates(&direntry->DirChanged, &fib->fib_Date) == 0)
617 D(bug("ReadDirEntry: direntry 0x%lx not changed\n", direntry));
618 FreeDosObject(DOS_FIB, fib);
619 Self->pr_WindowPtr = oldwinptr;
620 CurrentDir(olddir);
621 ReturnPtr("ReadDirEntry", struct DirEntry *, direntry);
625 direntry->DirChanged = fib->fib_Date;
627 if (!GetFileList(direntry, DiskfontBase))
629 D(bug("ReadDirEntry: Error reading FileList\n"));
630 FreeDosObject(DOS_FIB, fib);
631 CurrentDir(olddir);
632 UnLock(direntry->DirLock);
633 FreeVec(direntry);
634 Self->pr_WindowPtr = oldwinptr;
635 ReturnPtr("ReadDirEntry", struct DirEntry *, NULL);
638 /* If everything went OK Write the cache file */
639 fh = Open(CACHE_FILE, MODE_NEWFILE);
640 if (fh != NULL)
642 BOOL ok;
644 ok = WriteLong(&DiskfontBase->dsh, fib->fib_Date.ds_Days, fh);
645 ok = ok && WriteLong(&DiskfontBase->dsh, fib->fib_Date.ds_Minute, fh);
646 ok = ok && WriteLong(&DiskfontBase->dsh, fib->fib_Date.ds_Tick, fh);
648 if (ok)
649 ok = StreamOutFileList(&direntry->FileList, fh, DiskfontBase);
651 Close(fh);
653 if (ok)
655 Examine(direntry->DirLock, fib);
656 direntry->DirChanged = fib->fib_Date;
657 fh = Open(CACHE_FILE, MODE_OLDFILE);
658 if (fh != NULL)
660 Seek(fh, 0, OFFSET_BEGINNING);
661 ok = WriteLong(&DiskfontBase->dsh, fib->fib_Date.ds_Days, fh);
662 ok = ok && WriteLong(&DiskfontBase->dsh, fib->fib_Date.ds_Minute, fh);
663 ok = ok && WriteLong(&DiskfontBase->dsh, fib->fib_Date.ds_Tick, fh);
664 Close(fh);
668 if (!ok)
669 DeleteFile(CACHE_FILE);
672 FreeDosObject(DOS_FIB, fib);
673 CurrentDir(olddir);
674 Self->pr_WindowPtr = oldwinptr;
676 ReturnPtr("ReadDirEntry", struct DirEntry *, direntry);
679 /****************************************************************************************/
681 /****************/
682 /* FreeResouces */
683 /****************/
685 /****************************************************************************************/
687 STATIC VOID FreeResources(struct DF_Data *df_data, struct DiskfontBase_intern *DiskfontBase)
689 D(bug("FreeResources(df_data=%p)\n", df_data));
691 ReleaseSemaphore(&DiskfontBase->fontssemaphore);
693 switch (df_data->Type)
695 case DF_FONTSDATA:
696 #ifdef PROGDIRFONTSDIR
697 FreeDirEntry(df_data->u.FontsData.ProgdirDirEntry, DiskfontBase);
698 #endif
699 break;
701 case DF_FILEDATA:
702 if (df_data->u.FileData.FDH != NULL)
703 FreeFontDescr(df_data->u.FileData.FDH, DiskfontBase);
704 break;
707 FreeMem(df_data, sizeof (struct DF_Data));
709 ReturnVoid("FreeResources");
712 /****************************************************************************************/
714 /****************************/
715 /* CleanUpFontsDirEntryList */
716 /****************************/
718 /****************************************************************************************/
720 VOID CleanUpFontsDirEntryList(struct DiskfontBase_intern *DiskfontBase)
722 struct DirEntry *direntry, *direntry2;
724 ForeachNodeSafe(&DiskfontBase->fontsdirentrylist, direntry, direntry2)
725 FreeDirEntry(direntry, DiskfontBase);
727 ReturnVoid("CleanUpFontsDirEntryList");
730 /****************************************************************************************/
732 /******************/
733 /* AllocResources */
734 /******************/
736 /****************************************************************************************/
738 STATIC struct DF_Data *AllocResources(struct TTextAttr *reqattr, struct DiskfontBase_intern *DiskfontBase)
740 struct DF_Data *df_data;
742 D(bug("AllocResources(void)\n"));
744 ObtainSemaphore(&DiskfontBase->fontssemaphore);
746 /* Allocate user data */
747 if ((df_data = AllocMem( sizeof (struct DF_Data), MEMF_ANY | MEMF_CLEAR)))
749 df_data->ReqAttr = reqattr;
751 if (reqattr==NULL || FilePart(reqattr->tta_Name)==reqattr->tta_Name)
753 struct DevProc *dp = NULL;
754 struct MinList newdirlist;
755 struct DirEntry *direntry, *direntry2;
757 df_data->Type = DF_FONTSDATA;
759 #ifdef PROGDIRFONTSDIR
762 struct Process *Self;
763 APTR oldwinptr;
764 BPTR lock;
766 df_data->u.FontsData.ProgdirDirEntry = NULL;
768 if (!GetProgramDir())
769 break;
771 Self = (struct Process *) FindTask(NULL);
772 oldwinptr = Self->pr_WindowPtr;
773 Self->pr_WindowPtr = (APTR) -1;
774 lock = Lock(PROGDIRFONTSDIR, ACCESS_READ);
775 Self->pr_WindowPtr = oldwinptr;
777 D(bug("AllocResources: PROGDIR:Fonts DirLock = 0x%lx\n", lock));
779 if (!lock)
780 break;
782 df_data->u.FontsData.ProgdirDirEntry = ReadDirEntry(lock, NULL, DiskfontBase);
783 D(bug("AllocResources: PROGDIR:Fonts direntry 0x%lx\n", df_data->u.FontsData.ProgdirDirEntry));
784 } while (0);
785 #endif
787 NEWLIST(&newdirlist);
788 while((dp = GetDeviceProc(FONTSDIR, dp))!=NULL)
790 BPTR lock;
792 D(bug("AllocResources: FONTS: lock = 0x%lx\n", dp->dvp_Lock));
794 lock = DupLock(dp->dvp_Lock);
795 if (lock==NULL)
797 D(bug("AllocResources: Could not duplicate lock\n"));
798 continue;
801 /* See if direntry is already in memory */
802 for (direntry = (struct DirEntry *)GetHead(&DiskfontBase->fontsdirentrylist);
803 direntry != NULL;
804 direntry = (struct DirEntry *)GetSucc(direntry))
806 if (SameLock(direntry->DirLock, lock) == LOCK_SAME)
808 REMOVE(direntry);
809 break;
813 /* Read or update fonts information in this directory */
814 direntry = ReadDirEntry(lock, direntry, DiskfontBase);
815 if (direntry!=NULL)
817 D(bug("AllocResources: addtail direntry 0x%lx\n", direntry));
818 D(bug("AllocResources: first FileEntry: %p\n", GetHead(&direntry->FileList)));
819 ADDTAIL(&newdirlist, direntry);
821 else
822 D(bug("AllocResources: Error reading DirEntry\n"));
825 /* Clean up directory lists that are in memory but not in the
826 * FONTS: assign anymore */
827 ForeachNodeSafe(&DiskfontBase->fontsdirentrylist, direntry, direntry2)
829 REMOVE(direntry);
830 FreeDirEntry(direntry, DiskfontBase);
833 ForeachNodeSafe(&newdirlist, direntry, direntry2)
835 REMOVE(direntry);
836 ADDTAIL(&DiskfontBase->fontsdirentrylist, direntry);
839 FreeDeviceProc(dp);
841 else
843 struct FontDescrHeader *fdh;
845 df_data->Type = DF_FILEDATA;
846 fdh = ReadFontDescr(reqattr->tta_Name, DiskfontBase);
847 df_data->u.FileData.FDH = fdh;
849 if (fdh != NULL)
851 if (fdh->ContentsID==OFCH_ID)
853 UBYTE SupportedStyles = OTAG_GetSupportedStyles(fdh->OTagList, DiskfontBase);
855 df_data->u.FileData.ExtraAttr.tta_Name = reqattr->tta_Name;
856 df_data->u.FileData.ExtraAttr.tta_YSize = reqattr->tta_YSize;
857 df_data->u.FileData.ExtraAttr.tta_Style = OTAG_GetFontStyle(fdh->OTagList, DiskfontBase);
858 df_data->u.FileData.ExtraAttr.tta_Flags = OTAG_GetFontFlags(fdh->OTagList, DiskfontBase);
860 df_data->u.FileData.ExtraAttr.tta_Tags = NULL;
861 if (reqattr->tta_Style & FSF_TAGGED)
863 df_data->u.FileData.ExtraAttr.tta_Style |= FSF_TAGGED;
864 df_data->u.FileData.ExtraAttr.tta_Tags = reqattr->tta_Tags;
867 if ((reqattr->tta_Style & FSF_BOLD)
868 && !(df_data->u.FileData.ExtraAttr.tta_Style & FSF_BOLD)
869 && (SupportedStyles & FSF_BOLD))
871 df_data->u.FileData.ExtraAttr.tta_Style |= FSF_BOLD;
874 if ((reqattr->tta_Style & FSF_ITALIC)
875 && !(df_data->u.FileData.ExtraAttr.tta_Style & FSF_ITALIC)
876 && (SupportedStyles & FSF_ITALIC))
878 df_data->u.FileData.ExtraAttr.tta_Style |= FSF_ITALIC;
885 ReturnPtr("AllocResources", struct DF_Data *, df_data);
888 /****************************************************************************************/
890 /*******************/
891 /* DF_IteratorInit */
892 /*******************/
894 /****************************************************************************************/
896 APTR DF_IteratorInit(struct TTextAttr *reqattr, struct DiskfontBase_intern *DiskfontBase)
898 struct DF_Data *df_data;
900 D(bug("DF_IteratorInit(reqattr=0x%lx)\n", reqattr));
902 df_data = AllocResources(reqattr, DiskfontBase);
903 if (df_data == NULL)
905 D(bug("DF_IteratorInit: Error executing Allocresources\n"));
906 ReturnPtr("DF_IteratorInit", APTR, NULL);
909 switch (df_data->Type)
911 case DF_FONTSDATA:
912 df_data->u.FontsData.CurrentDirEntry = NULL;
913 df_data->u.FontsData.CurrentFileEntry = NULL;
915 #ifdef PROGDIRFONTSDIR
916 if (df_data->u.FontsData.ProgdirDirEntry != NULL)
918 D(bug("DF_IteratorInit: ProgdirDirEntry found\n"));
919 df_data->u.FontsData.CurrentDirEntry = df_data->u.FontsData.ProgdirDirEntry;
920 df_data->u.FontsData.CurrentFileEntry = (struct FileEntry *)GetHead(&df_data->u.FontsData.ProgdirDirEntry->FileList);
922 else
923 D(bug("DF_IteratorInit: No ProgdirEntry found\n"));
924 #endif
925 if (df_data->u.FontsData.CurrentDirEntry == NULL || df_data->u.FontsData.CurrentFileEntry == NULL)
927 df_data->u.FontsData.CurrentDirEntry = (struct DirEntry *)GetHead(&DiskfontBase->fontsdirentrylist);
928 if (df_data->u.FontsData.CurrentDirEntry != NULL)
929 df_data->u.FontsData.CurrentFileEntry = (struct FileEntry *)GetHead(&df_data->u.FontsData.CurrentDirEntry->FileList);
932 D(bug("DF_IteratorInit: CurrentDirEntry: %p CurrentFileEntry: %p\n",
933 df_data->u.FontsData.CurrentDirEntry, df_data->u.FontsData.CurrentFileEntry));
935 /* If DirEntry was empty search for one that is not empty */
936 while (df_data->u.FontsData.CurrentDirEntry != NULL && df_data->u.FontsData.CurrentFileEntry == NULL)
938 df_data->u.FontsData.CurrentDirEntry = (struct DirEntry *)GetSucc(df_data->u.FontsData.CurrentDirEntry);
939 if (df_data->u.FontsData.CurrentDirEntry != NULL)
940 df_data->u.FontsData.CurrentFileEntry = (struct FileEntry *)GetHead(&df_data->u.FontsData.CurrentDirEntry->FileList);
942 D(bug("DF_IteratorInit: CurrentDirEntry: %p CurrentFileEntry: %p\n",
943 df_data->u.FontsData.CurrentDirEntry, df_data->u.FontsData.CurrentFileEntry));
945 df_data->u.FontsData.AttrsIndex = 0;
947 break;
949 case DF_FILEDATA:
950 df_data->u.FileData.AttrsIndex = 0;
951 df_data->u.FileData.FilePart = FilePart(df_data->ReqAttr->tta_Name);
952 df_data->u.FileData.LastAttr = NULL;
953 break;
956 ReturnPtr("DF_IteratorInit", APTR, df_data);
959 /****************************************************************************************/
961 /**********************/
962 /* DF_IteratorGetNext */
963 /**********************/
965 /****************************************************************************************/
967 struct TTextAttr *DF_IteratorGetNext(APTR iterator, struct DiskfontBase_intern *DiskfontBase)
969 struct TTextAttr *retval = NULL;
970 struct DF_Data *df_data = (struct DF_Data *)iterator;
972 D(bug("DF_IteratorGetNext(iterator=0x%lx)\n", iterator));
974 if (df_data==NULL)
975 ReturnPtr("DF_IteratorGetNext", struct TTextAttr *, NULL);
977 switch (df_data->Type)
979 case DF_FONTSDATA:
980 if (df_data->u.FontsData.CurrentDirEntry==NULL)
981 ReturnPtr("DF_IteratorGetNext", struct TTextAttr *, NULL);
983 retval = df_data->u.FontsData.CurrentFileEntry->Attrs + df_data->u.FontsData.AttrsIndex;
984 D(bug("DF_IteratorGetNext:\n"
985 " ContentsID: 0x%x == 0x%x\n"
986 " ReqAttr: %p\n"
987 " AttrIndex: %d, Numentries: %d\n",
988 df_data->u.FontsData.CurrentFileEntry->ContentsID, OFCH_ID,
989 df_data->ReqAttr,
990 df_data->u.FontsData.AttrsIndex, df_data->u.FontsData.CurrentFileEntry->Numentries));
992 if (df_data->u.FontsData.CurrentFileEntry->ContentsID == OFCH_ID
993 && df_data->ReqAttr != NULL
994 && df_data->u.FontsData.AttrsIndex == df_data->u.FontsData.CurrentFileEntry->Numentries-1)
996 D(bug("DF_IteratorGetNext: Setting last outline element\n"));
998 /* The last attr for a outline font is filled with values matching
999 * as close as possible the reqattr */
1000 retval->tta_YSize = df_data->ReqAttr->tta_YSize;
1001 retval->tta_Style = df_data->u.FontsData.CurrentFileEntry->FontStyle;
1003 retval->tta_Tags = NULL;
1005 if (df_data->ReqAttr->tta_Style & FSF_TAGGED)
1007 retval->tta_Style |= FSF_TAGGED;
1008 retval->tta_Tags = df_data->ReqAttr->tta_Tags;
1011 if ((df_data->ReqAttr->tta_Style & FSF_BOLD)
1012 && !(retval->tta_Style & FSF_BOLD)
1013 && (df_data->u.FontsData.CurrentFileEntry->SupportedStyles & FSF_BOLD))
1015 retval->tta_Style |= FSF_BOLD;
1018 if ((df_data->ReqAttr->tta_Style & FSF_ITALIC)
1019 && !(retval->tta_Style & FSF_ITALIC)
1020 && (df_data->u.FontsData.CurrentFileEntry->SupportedStyles & FSF_ITALIC))
1022 retval->tta_Style |= FSF_ITALIC;
1026 /* Let the iterator point to the next attr */
1027 if ((df_data->u.FontsData.AttrsIndex == df_data->u.FontsData.CurrentFileEntry->Numentries-1)
1028 || (df_data->u.FontsData.CurrentFileEntry->ContentsID == OFCH_ID
1029 && df_data->ReqAttr==NULL &&
1030 df_data->u.FontsData.AttrsIndex == df_data->u.FontsData.CurrentFileEntry->Numentries-2
1034 df_data->u.FontsData.PrevFileEntry = df_data->u.FontsData.CurrentFileEntry;
1035 df_data->u.FontsData.CurrentFileEntry = (struct FileEntry *)GetSucc(df_data->u.FontsData.CurrentFileEntry);
1036 df_data->u.FontsData.AttrsIndex = 0;
1037 if (df_data->u.FontsData.CurrentFileEntry == NULL)
1039 while (df_data->u.FontsData.CurrentDirEntry != NULL && df_data->u.FontsData.CurrentFileEntry == NULL)
1041 #ifdef PROGDIRFONTSDIR
1042 if (df_data->u.FontsData.CurrentDirEntry == df_data->u.FontsData.ProgdirDirEntry)
1043 df_data->u.FontsData.CurrentDirEntry = (struct DirEntry *)GetHead(&DiskfontBase->fontsdirentrylist);
1044 else
1045 df_data->u.FontsData.CurrentDirEntry = (struct DirEntry *)GetSucc(df_data->u.FontsData.CurrentDirEntry);
1046 #else
1047 df_data->u.FontsData.CurrentDirEntry = (struct DirEntry *)GetSucc(df_data->u.FontsData.CurrentDirEntry);
1048 #endif
1049 if (df_data->u.FontsData.CurrentDirEntry != NULL)
1050 df_data->u.FontsData.CurrentFileEntry = (struct FileEntry *)GetHead(&df_data->u.FontsData.CurrentDirEntry->FileList);
1055 else
1056 df_data->u.FontsData.AttrsIndex++;
1057 break;
1059 case DF_FILEDATA:
1060 if (df_data->u.FileData.LastAttr != NULL)
1062 df_data->u.FileData.LastAttr->tta_Name = df_data->u.FileData.OrigName;
1063 df_data->u.FileData.LastAttr = NULL;
1066 /* Do not return the best-match attribute if it is not an outline font! */
1068 if (df_data->u.FileData.FDH==NULL
1069 || df_data->u.FileData.AttrsIndex > df_data->u.FileData.FDH->NumEntries
1070 || (df_data->u.FileData.FDH->ContentsID != OFCH_ID &&
1071 df_data->u.FileData.AttrsIndex == df_data->u.FileData.FDH->NumEntries))
1073 ReturnPtr("DF_IteratorGetNext", struct TTextAttr *, NULL);
1075 /* Get the TextAttr the iterator is pointing to
1076 * If it points to the element after the last element return
1077 * the Extra Attr that matches the outline font as close as possible
1079 if (df_data->u.FileData.AttrsIndex == df_data->u.FileData.FDH->NumEntries)
1080 retval = &df_data->u.FileData.ExtraAttr;
1081 else
1083 retval = &df_data->u.FileData.FDH->TAttrArray[df_data->u.FileData.AttrsIndex];
1084 df_data->u.FileData.OrigName = retval->tta_Name;
1085 retval->tta_Name = df_data->u.FileData.FilePart;
1086 df_data->u.FileData.LastAttr = retval;
1089 /* Let the iterator point to the next element.
1091 df_data->u.FileData.AttrsIndex++;
1093 break;
1096 ReturnPtr("DF_IteratorGetNext", struct TTextAttr *, retval);
1099 /****************************************************************************************/
1101 /***********************/
1102 /* DF_IteratorRemember */
1103 /***********************/
1105 /****************************************************************************************/
1107 VOID DF_IteratorRemember(APTR iterator, struct DiskfontBase_intern *DiskfontBase)
1109 struct DF_Data *df_data = (struct DF_Data *)iterator;
1111 D(bug("DF_IteratorRemember(iterator=0x%lx)\n", iterator));
1113 switch (df_data->Type)
1115 case DF_FONTSDATA:
1116 if (df_data->u.FontsData.AttrsIndex > 0)
1118 df_data->u.FontsData.RememberIndex = df_data->u.FontsData.AttrsIndex-1;
1119 df_data->u.FontsData.RememberFileEntry = df_data->u.FontsData.CurrentFileEntry;
1121 else
1123 df_data->u.FontsData.RememberFileEntry = df_data->u.FontsData.PrevFileEntry;
1124 df_data->u.FontsData.RememberIndex = df_data->u.FontsData.RememberFileEntry->Numentries-1;
1125 if (df_data->u.FontsData.RememberFileEntry->ContentsID == OFCH_ID
1126 && df_data->ReqAttr == NULL
1129 df_data->u.FontsData.RememberIndex--;
1133 D(bug("DF_IteratorRemember: Remembered font: %s/%d\n",
1134 df_data->u.FontsData.RememberFileEntry->Attrs[df_data->u.FontsData.RememberIndex].tta_Name,
1135 df_data->u.FontsData.RememberFileEntry->Attrs[df_data->u.FontsData.RememberIndex].tta_YSize));
1136 break;
1138 case DF_FILEDATA:
1139 df_data->u.FileData.RememberIndex = df_data->u.FileData.AttrsIndex-1;
1141 D(bug("DF_IteratorRemember: Remembered font: %s(%d)\n",
1142 df_data->ReqAttr->tta_Name, df_data->u.FileData.RememberIndex));
1143 break;
1147 /****************************************************************************************/
1149 /***************************/
1150 /* DF_IteratorRememberOpen */
1151 /***************************/
1153 /****************************************************************************************/
1155 struct TextFont *DF_IteratorRememberOpen(APTR iterator, struct DiskfontBase_intern *DiskfontBase)
1157 struct DF_Data *df_data = (struct DF_Data *)iterator;
1158 struct FontDescrHeader *fdh = NULL;
1159 struct TTextAttr *RememberAttr = NULL;
1160 struct TextFont *tf = NULL;
1161 BPTR olddir = 0, lock, dirlock;
1163 D(bug("DF_IteratorRememberOpen(iterator=0x%lx)\n", iterator));
1165 /* Set current dir and get the Remember TextAttr */
1166 switch (df_data->Type)
1168 case DF_FONTSDATA:
1170 struct FileEntry *rementry = df_data->u.FontsData.RememberFileEntry;
1172 olddir = CurrentDir(rementry->DirEntry->DirLock);
1173 fdh = ReadFontDescr(rementry->FileName, DiskfontBase);
1174 if (rementry->ContentsID == OFCH_ID
1175 && df_data->u.FontsData.RememberIndex == rementry->Numentries - 1)
1177 /* It is the TAttr generated for best matching */
1178 RememberAttr = &rementry->Attrs[df_data->u.FontsData.RememberIndex];
1180 else
1181 RememberAttr = &fdh->TAttrArray[df_data->u.FontsData.RememberIndex];
1183 break;
1185 case DF_FILEDATA:
1186 if (df_data->u.FileData.LastAttr != NULL)
1188 df_data->u.FileData.LastAttr->tta_Name = df_data->u.FileData.OrigName;
1189 df_data->u.FileData.LastAttr = NULL;
1192 RememberAttr = NULL;
1193 lock = Lock(df_data->ReqAttr->tta_Name, ACCESS_READ);
1194 if (lock == NULL)
1196 D(bug("DF_IteratorRememberOpen: Could not lock file\n"));
1197 break;
1200 dirlock = ParentDir(lock);
1201 UnLock(lock);
1202 if (dirlock == NULL)
1204 D(bug("DF_IteratorRememberOpen: Could not get ParentDir\n"));
1205 break;
1207 olddir = CurrentDir(dirlock);
1209 fdh = df_data->u.FileData.FDH;
1210 if (df_data->u.FileData.RememberIndex == fdh->NumEntries)
1211 RememberAttr = &df_data->u.FileData.ExtraAttr;
1212 else
1213 RememberAttr = &fdh->TAttrArray[df_data->u.FileData.RememberIndex];
1214 break;
1217 if (RememberAttr == NULL)
1218 return NULL;
1220 if (fdh != NULL)
1222 D(bug("DF_IteratorRememberOpen: Font Description read\n"));
1224 if (IS_OUTLINE_FONT(RememberAttr))
1226 D(bug("DF_IteratorRememberOpen: loading outline font\n"));
1228 tf = OTAG_ReadOutlineFont(RememberAttr,
1229 df_data->ReqAttr,
1230 fdh->OTagList,
1231 DiskfontBase);
1232 D(bug("DF_IteratorRememberOpen: tf=0x%lx\n", tf));
1235 else
1237 D(bug("DF_IteratorRememberOpen: loading bitmap font\n"));
1239 tf = ReadDiskFont(RememberAttr,
1240 FilePart(df_data->ReqAttr->tta_Name),
1241 DiskfontBase);
1243 D(bug("DF_IteratorRememberOpen: tf=0x%lx\n", tf));
1246 else
1247 D(bug("DF_IteratorRememberOpen: Font Description read failed\n"));
1249 dirlock = CurrentDir(olddir);
1250 switch (df_data->Type)
1252 case DF_FONTSDATA:
1253 FreeFontDescr(fdh, DiskfontBase);
1254 break;
1256 case DF_FILEDATA:
1257 UnLock(dirlock);
1258 break;
1261 if (tf != NULL)
1263 struct DiskFontHeader *dfh;
1265 /* PPaint's personal.font/8 has not set FPF_DISKFONT,
1266 (FPF_ROMFONT neither), but AmigaOS diskfont.library
1267 still shows FPF_DISKFONT set when opening this font */
1269 tf->tf_Flags &= ~FPF_ROMFONT;
1270 tf->tf_Flags |= FPF_DISKFONT;
1272 D(bug("Adding font: %p\n", tf));
1274 /* Forbid() must be called before AddFont, because AddFont clears
1275 tf_Accessors and in the worst case it could happen to us that
1276 after the AddFont() another task opens and closes/frees the
1277 diskfont, before we manage to increase tf_Accessors. */
1279 Forbid();
1281 AddFont(tf);
1282 tf->tf_Accessors++;
1284 dfh = (struct DiskFontHeader *)((UBYTE *)(tf) - (IPTR)OFFSET(DiskFontHeader, dfh_TF));
1286 /* Paranoia check */
1287 if (dfh->dfh_FileID == DFH_ID)
1288 ADDTAIL(&DiskfontBase->diskfontlist, &dfh->dfh_DF);
1290 Permit();
1292 D(bug("Font added\n"));
1295 return tf;
1298 /****************************************************************************************/
1300 /*******************/
1301 /* DF_IteratorFree */
1302 /*******************/
1304 /****************************************************************************************/
1306 VOID DF_IteratorFree(APTR iterator, struct DiskfontBase_intern *DiskfontBase)
1308 struct DF_Data *df_data = (struct DF_Data *)iterator;
1310 FreeResources(df_data, DiskfontBase);
1313 /****************************************************************************************/
1315 /*******************/
1316 /* DF_OpenFontPath */
1317 /*******************/
1319 /****************************************************************************************/
1321 struct TextFont *DF_OpenFontPath(struct TextAttr *reqattr, struct DiskfontBase_intern *DiskfontBase)
1323 struct TextFont *tf = NULL;
1324 struct FontDescrHeader *fdh;
1325 BPTR olddir, lock, dirlock;
1327 D(bug("DF_OpenFontPath(reqattr=0x%lx)\n", reqattr));
1329 lock = Lock(reqattr->ta_Name, ACCESS_READ);
1330 if (lock == NULL)
1332 D(bug("DF_OpenFontPath: Could not lock file\n"));
1333 return NULL;
1336 dirlock = ParentDir(lock);
1337 UnLock(lock);
1338 if (dirlock == NULL)
1340 D(bug("DF_OpenFontPath: Could not get ParentDir\n"));
1341 return NULL;
1344 olddir = CurrentDir(dirlock);
1346 fdh = ReadFontDescr(reqattr->ta_Name, DiskfontBase);
1348 if (fdh != NULL)
1350 WORD max_match_weight = 0, match_weight;
1351 LONG match_index = -1;
1352 int i;
1354 D(bug("DF_OpenFontPath: Font Description read\n"));
1356 for (i=0; i<fdh->NumEntries; i++)
1358 match_weight = WeighTAMatch((struct TextAttr *)reqattr,
1359 (struct TextAttr *)&fdh->TAttrArray[i],
1360 fdh->TAttrArray[i].tta_Tags);
1362 if (match_weight > max_match_weight)
1364 max_match_weight = match_weight;
1365 match_index = i;
1369 if (match_index >= 0)
1371 if (IS_OUTLINE_FONT(&fdh->TAttrArray[match_index]))
1373 D(bug("DF_OpenFontPath: loading outline font\n"));
1375 tf = OTAG_ReadOutlineFont(&fdh->TAttrArray[match_index],
1376 (struct TTextAttr *)reqattr,
1377 fdh->OTagList,
1378 DiskfontBase);
1379 D(bug("DF_OpenFontPath: tf=0x%lx\n", tf));
1382 else
1384 D(bug("DF_OpenFontPath: loading bitmap font\n"));
1386 tf = ReadDiskFont(&fdh->TAttrArray[match_index],
1387 reqattr->ta_Name,
1388 DiskfontBase);
1390 D(bug("DF_OpenFontPath: tf=0x%lx\n", tf));
1393 else
1394 D(bug("DF_OpenFontPath: No matching font found\n"));
1396 FreeFontDescr(fdh, DiskfontBase);
1398 else
1399 D(bug("DF_OpenFontPath: Font Description read failed\n"));
1401 CurrentDir(olddir);
1402 UnLock(dirlock);
1404 if (tf != NULL)
1406 struct DiskFontHeader *dfh;
1408 /* PPaint's personal.font/8 has not set FPF_DISKFONT,
1409 (FPF_ROMFONT neither), but AmigaOS diskfont.library
1410 still shows FPF_DISKFONT set when opening this font */
1412 tf->tf_Flags &= ~FPF_ROMFONT;
1413 tf->tf_Flags |= FPF_DISKFONT;
1415 D(bug("Adding font: %p\n", tf));
1417 /* Forbid() must be called before AddFont, because AddFont clears
1418 tf_Accessors and in the worst case it could happen to us that
1419 after the AddFont() another task opens and closes/frees the
1420 diskfont, before we manage to increase tf_Accessors. */
1422 Forbid();
1424 AddFont(tf);
1425 tf->tf_Accessors++;
1427 dfh = (struct DiskFontHeader *)((UBYTE *)(tf) - (IPTR)OFFSET(DiskFontHeader, dfh_TF));
1429 /* Paranoia check */
1430 if (dfh->dfh_FileID == DFH_ID)
1431 ADDTAIL(&DiskfontBase->diskfontlist, &dfh->dfh_DF);
1433 Permit();
1435 D(bug("Font added\n"));
1438 return tf;