2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Hook for handling fonts in FONTS:
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>
19 #include "diskfont_intern.h"
21 /****************************************************************************************/
23 #include <aros/debug.h>
25 /****************************************************************************************/
32 struct DirEntry
*DirEntry
;
34 struct DateStamp FileChanged
;
36 UBYTE SupportedStyles
;
39 struct TTextAttr
*Attrs
;
46 struct DateStamp DirChanged
;
47 struct MinList FileList
;
50 struct DF_FontsData
/*DiskFontData */
52 #ifdef PROGDIRFONTSDIR
53 struct DirEntry
*ProgdirDirEntry
;
55 struct DirEntry
*CurrentDirEntry
;
56 struct FileEntry
*CurrentFileEntry
, *PrevFileEntry
;
58 struct FileEntry
*RememberFileEntry
;
64 struct FontDescrHeader
*FDH
;
67 struct TTextAttr
*LastAttr
;
70 struct TTextAttr ExtraAttr
;
73 typedef enum {DF_FONTSDATA
, DF_FILEDATA
} DF_DataType
;
78 struct TTextAttr
*ReqAttr
;
81 struct DF_FontsData FontsData
;
82 struct DF_FileData FileData
;
87 /****************************************************************************************/
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
;
101 struct TagItem
*tagitems
;
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
);
110 D(bug("ReadFileEntry: error in ReadFontDescr\n"));
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
);
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
;
165 retval
->Attrs
[i
].tta_Tags
= NULL
;
168 FreeFontDescr(fdh
, DiskfontBase
);
170 ReturnPtr("ReadFileEntry", struct FileEntry
*, retval
);
173 /****************************************************************************************/
179 /****************************************************************************************/
181 STATIC VOID
FreeFileEntry(struct FileEntry
*feptr
, struct DiskfontBase_intern
*DiskfontBase
)
186 /****************************************************************************************/
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
)
203 FreeFileEntry(feptr
, DiskfontBase
);
206 ReturnVoid("FreeFileList");
209 /****************************************************************************************/
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
));
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
))
239 else if (eac
->eac_Entries
== 0)
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));
256 /* Is a FileEntry for this file already in the list */
257 for (fe
= (struct FileEntry
*)GetHead(&direntry
->FileList
);
259 fe
= (struct FileEntry
*)GetSucc(fe
))
261 if (strcmp(eadit
->ed_Name
, fe
->FileName
) == 0)
267 D(bug("GetFileList: Filename not yet in memory\n"));
269 fe
= ReadFileEntry(eadit
, DiskfontBase
);
272 fe
->DirEntry
= direntry
;
274 D(bug("GetFileList: Add to list: 0x%lx\n", fe
));
275 ADDTAIL(&newlist
, 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
);
296 D(bug("GetFileList: Date changed rereading information\n"));
298 FreeFileEntry(fe
, DiskfontBase
);
300 fe
= ReadFileEntry(eadit
, DiskfontBase
);
303 D(bug("GetFileList: Reading information failed\n"));
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
);
324 D(bug("GetFileList: Not OK freeing FileList\n"));
325 FreeFileList(&newlist
, DiskfontBase
);
329 /* Remove FileEntries that are still in memory but not anymore
331 FreeFileList(&direntry
->FileList
, DiskfontBase
);
333 ForeachNodeSafe(&newlist
, fe
, nextfe
)
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
;
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
);
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
;
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
);
422 attrs
= AllocVec(fe2
.Numentries
* sizeof(struct TTextAttr
), MEMF_ANY
|MEMF_CLEAR
);
424 ok
= ok
&& attrs
!= NULL
;
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
);
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
));
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
;
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
;
478 ADDTAIL(&direntry
->FileList
, fe
);
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
);
493 FreeVec(fe2
.FileName
);
497 D(bug("StreamInFileList: FileName empty\n"));
498 FreeVec(fe2
.FileName
);
502 D(bug("StreamInFileList: Error reading chachefile\n"));
503 FreeFileList(&direntry
->FileList
, DiskfontBase
);
509 /****************************************************************************************/
515 /****************************************************************************************/
517 STATIC VOID
FreeDirEntry(struct DirEntry
*direntry
, struct DiskfontBase_intern
*DiskfontBase
)
521 FreeFileList(&direntry
->FileList
, DiskfontBase
);
522 UnLock(direntry
->DirLock
);
527 /****************************************************************************************/
533 /****************************************************************************************/
535 STATIC
struct DirEntry
*ReadDirEntry(BPTR dirlock
, struct DirEntry
*direntry
, struct DiskfontBase_intern
*DiskfontBase
)
537 struct Process
*Self
;
539 struct FileInfoBlock
*fib
;
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
);
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
);
566 D(bug("ReadDirEntry: Could not allocate DirEntry\n"));
567 FreeDosObject(DOS_FIB
, fib
);
569 ReturnPtr("ReadDirEntry", struct DirEntry
*, NULL
);
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
);
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
);
588 ok
= StreamInFileList(direntry
, fh
, DiskfontBase
);
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
;
606 ReturnPtr("ReadDirEntry", struct DirEntry
*, direntry
);
613 CurrentDir(direntry
->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
;
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
);
632 UnLock(direntry
->DirLock
);
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
);
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
);
649 ok
= StreamOutFileList(&direntry
->FileList
, fh
, DiskfontBase
);
655 Examine(direntry
->DirLock
, fib
);
656 direntry
->DirChanged
= fib
->fib_Date
;
657 fh
= Open(CACHE_FILE
, MODE_OLDFILE
);
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
);
669 DeleteFile(CACHE_FILE
);
672 FreeDosObject(DOS_FIB
, fib
);
674 Self
->pr_WindowPtr
= oldwinptr
;
676 ReturnPtr("ReadDirEntry", struct DirEntry
*, direntry
);
679 /****************************************************************************************/
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
)
696 #ifdef PROGDIRFONTSDIR
697 FreeDirEntry(df_data
->u
.FontsData
.ProgdirDirEntry
, DiskfontBase
);
702 if (df_data
->u
.FileData
.FDH
!= NULL
)
703 FreeFontDescr(df_data
->u
.FileData
.FDH
, DiskfontBase
);
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 /****************************************************************************************/
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
;
766 df_data
->u
.FontsData
.ProgdirDirEntry
= NULL
;
768 if (!GetProgramDir())
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
));
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
));
787 NEWLIST(&newdirlist
);
788 while((dp
= GetDeviceProc(FONTSDIR
, dp
))!=NULL
)
792 D(bug("AllocResources: FONTS: lock = 0x%lx\n", dp
->dvp_Lock
));
794 lock
= DupLock(dp
->dvp_Lock
);
797 D(bug("AllocResources: Could not duplicate lock\n"));
801 /* See if direntry is already in memory */
802 for (direntry
= (struct DirEntry
*)GetHead(&DiskfontBase
->fontsdirentrylist
);
804 direntry
= (struct DirEntry
*)GetSucc(direntry
))
806 if (SameLock(direntry
->DirLock
, lock
) == LOCK_SAME
)
813 /* Read or update fonts information in this directory */
814 direntry
= ReadDirEntry(lock
, direntry
, DiskfontBase
);
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
);
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
)
830 FreeDirEntry(direntry
, DiskfontBase
);
833 ForeachNodeSafe(&newdirlist
, direntry
, direntry2
)
836 ADDTAIL(&DiskfontBase
->fontsdirentrylist
, direntry
);
843 struct FontDescrHeader
*fdh
;
845 df_data
->Type
= DF_FILEDATA
;
846 fdh
= ReadFontDescr(reqattr
->tta_Name
, DiskfontBase
);
847 df_data
->u
.FileData
.FDH
= fdh
;
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
);
905 D(bug("DF_IteratorInit: Error executing Allocresources\n"));
906 ReturnPtr("DF_IteratorInit", APTR
, NULL
);
909 switch (df_data
->Type
)
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
);
923 D(bug("DF_IteratorInit: No ProgdirEntry found\n"));
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;
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
;
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
));
975 ReturnPtr("DF_IteratorGetNext", struct TTextAttr
*, NULL
);
977 switch (df_data
->Type
)
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"
987 " AttrIndex: %d, Numentries: %d\n",
988 df_data
->u
.FontsData
.CurrentFileEntry
->ContentsID
, OFCH_ID
,
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
);
1045 df_data
->u
.FontsData
.CurrentDirEntry
= (struct DirEntry
*)GetSucc(df_data
->u
.FontsData
.CurrentDirEntry
);
1047 df_data
->u
.FontsData
.CurrentDirEntry
= (struct DirEntry
*)GetSucc(df_data
->u
.FontsData
.CurrentDirEntry
);
1049 if (df_data
->u
.FontsData
.CurrentDirEntry
!= NULL
)
1050 df_data
->u
.FontsData
.CurrentFileEntry
= (struct FileEntry
*)GetHead(&df_data
->u
.FontsData
.CurrentDirEntry
->FileList
);
1056 df_data
->u
.FontsData
.AttrsIndex
++;
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
;
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
++;
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
)
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
;
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
));
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
));
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
)
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
];
1181 RememberAttr
= &fdh
->TAttrArray
[df_data
->u
.FontsData
.RememberIndex
];
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
);
1196 D(bug("DF_IteratorRememberOpen: Could not lock file\n"));
1200 dirlock
= ParentDir(lock
);
1202 if (dirlock
== NULL
)
1204 D(bug("DF_IteratorRememberOpen: Could not get ParentDir\n"));
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
;
1213 RememberAttr
= &fdh
->TAttrArray
[df_data
->u
.FileData
.RememberIndex
];
1217 if (RememberAttr
== 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
,
1232 D(bug("DF_IteratorRememberOpen: tf=0x%lx\n", tf
));
1237 D(bug("DF_IteratorRememberOpen: loading bitmap font\n"));
1239 tf
= ReadDiskFont(RememberAttr
,
1240 FilePart(df_data
->ReqAttr
->tta_Name
),
1243 D(bug("DF_IteratorRememberOpen: tf=0x%lx\n", tf
));
1247 D(bug("DF_IteratorRememberOpen: Font Description read failed\n"));
1249 dirlock
= CurrentDir(olddir
);
1250 switch (df_data
->Type
)
1253 FreeFontDescr(fdh
, DiskfontBase
);
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. */
1284 dfh
= (struct DiskFontHeader
*)((UBYTE
*)(tf
) - (LONG
)OFFSET(DiskFontHeader
, dfh_TF
));
1286 /* Paranoia check */
1287 if (dfh
->dfh_FileID
== DFH_ID
)
1288 ADDTAIL(&DiskfontBase
->diskfontlist
, &dfh
->dfh_DF
);
1292 D(bug("Font added\n"));
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
);
1332 D(bug("DF_OpenFontPath: Could not lock file\n"));
1336 dirlock
= ParentDir(lock
);
1338 if (dirlock
== NULL
)
1340 D(bug("DF_OpenFontPath: Could not get ParentDir\n"));
1344 olddir
= CurrentDir(dirlock
);
1346 fdh
= ReadFontDescr(reqattr
->ta_Name
, DiskfontBase
);
1350 WORD max_match_weight
= 0, match_weight
;
1351 LONG match_index
= -1;
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
;
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
,
1379 D(bug("DF_OpenFontPath: tf=0x%lx\n", tf
));
1384 D(bug("DF_OpenFontPath: loading bitmap font\n"));
1386 tf
= ReadDiskFont(&fdh
->TAttrArray
[match_index
],
1390 D(bug("DF_OpenFontPath: tf=0x%lx\n", tf
));
1394 D(bug("DF_OpenFontPath: No matching font found\n"));
1396 FreeFontDescr(fdh
, DiskfontBase
);
1399 D(bug("DF_OpenFontPath: Font Description read failed\n"));
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. */
1427 dfh
= (struct DiskFontHeader
*)((UBYTE
*)(tf
) - (LONG
)OFFSET(DiskFontHeader
, dfh_TF
));
1429 /* Paranoia check */
1430 if (dfh
->dfh_FileID
== DFH_ID
)
1431 ADDTAIL(&DiskfontBase
->diskfontlist
, &dfh
->dfh_DF
);
1435 D(bug("Font added\n"));