revert between 56095 -> 55830 in arch
[AROS.git] / workbench / system / FixFonts.c
blob5edf9f98e9d50febfd196dde63e50f3361ba8ea0
1 /*****************************************************************
2 ** FixFonts **
3 ** **
4 ** A recompile of the CBM fixfonts program **
5 ** **
6 ** Version 40.2 vom 16.01.1999 © THOR-Software, Thomas Richter **
7 ** Changes to compile with AROS - Henning Kiel, hkiel@aros.org **
8 *****************************************************************/
10 #include <exec/types.h>
11 #include <exec/memory.h>
13 #include <dos/dos.h>
14 #include <dos/dosextens.h>
15 #include <dos/dosasl.h>
16 #include <dos/exall.h>
18 #include <diskfont/diskfont.h>
20 #ifdef __AROS__
21 #include <aros/macros.h>
22 #else
23 #define AROS_ALIGN(x) x
24 #endif
25 #include <proto/exec.h>
26 #include <proto/dos.h>
27 #include <proto/diskfont.h>
29 #include <string.h>
31 #define MAXFONTLEN 25L
34 char version[] = "$VER: FixFonts 40.2 (16.9.1999) (c) THOR";
36 int main()
38 struct ExAllControl *exall;
39 struct ExAllData *ead;
40 struct DevProc *devproc=NULL;
41 BPTR lock,
42 oldlock;
43 BPTR file;
44 struct FontContentsHeader *fhead;
45 LONG size;
46 ULONG fontflags;
47 int len;
48 long rc = 20;
49 int more;
50 char fullname[32];
51 char *buffer;
52 ULONG bufsize = 4096L;
54 if ((buffer=AllocMem(bufsize,MEMF_PUBLIC)))
56 if ((exall=AllocDosObject(DOS_EXALLCONTROL,TAG_DONE)))
58 /* Set return code to fine */
59 rc=0;
63 if ((devproc=GetDeviceProc("FONTS:",devproc)))
65 /* User abort? */
66 if (CheckSignal(SIGBREAKF_CTRL_C)) {
67 rc=ERROR_BREAK;
68 break;
71 exall->eac_LastKey=0L;
72 if ((lock=DupLock(devproc->dvp_Lock)))
74 oldlock=CurrentDir(lock);
77 ead=(struct ExAllData *)buffer;
78 more=ExAll(lock,ead,bufsize,ED_TYPE,exall);
79 if (!more)
81 size=IoErr();
82 if (size!=ERROR_NO_MORE_ENTRIES) rc=size; /* break on an error */
84 else
86 /* if there are more entries and an error, abort */
87 if (rc) ExAllEnd(lock,ead,bufsize,ED_TYPE,exall);
90 /* quit loop on error */
91 if (rc) break;
93 if (exall->eac_Entries==0) continue; /* Ignore empty entries */
97 if (ead->ed_Type>0)
99 len=strlen(ead->ed_Name);
102 len <= MAXFONTLEN
103 && strncmp(ead->ed_Name, "TrueType", len) != 0
106 /* check for user abort */
107 if (CheckSignal(SIGBREAKF_CTRL_C))
109 rc=ERROR_BREAK;
110 break;
112 /* Build name of the directory */
113 strcpy(fullname,ead->ed_Name);
114 strcpy(fullname+len,".font"); /* Add .font */
116 /* Build a contents header */
117 fhead=NewFontContents(lock,fullname);
118 if (fhead)
120 if (fhead->fch_NumEntries>0)
122 #ifdef __AROS__
123 #if !AROS_BIG_ENDIAN
124 WORD i;
126 for(i = 0; i < fhead->fch_NumEntries; i++)
128 if(fhead->fch_FileID == FCH_ID)
130 struct FontContents *fc;
132 fc = (struct FontContents *)(fhead + 1);
133 fc += i;
135 fc->fc_YSize = AROS_WORD2BE(fc->fc_YSize);
137 else if
139 (fhead->fch_FileID == TFCH_ID)
140 || (fhead->fch_FileID == OFCH_ID)
143 struct TFontContents *tfc;
145 tfc = (struct TFontContents *)(fhead + 1);
146 tfc += i;
148 if (tfc->tfc_TagCount)
150 ULONG *tags;
151 WORD t;
153 tags = (ULONG *)(&tfc->tfc_FileName[MAXFONTPATH-(tfc->tfc_TagCount*8)]);
154 for (t = 0; t < tfc->tfc_TagCount * 2 - 1; t++)
156 tags[t] = AROS_LONG2BE(tags[t]);
159 tfc->tfc_TagCount = AROS_WORD2BE(tfc->tfc_TagCount);
160 tfc->tfc_YSize = AROS_WORD2BE(tfc->tfc_YSize);
163 } /* for(i = 0; i < fhead->fch_NumEntries; i++) */
165 fhead->fch_FileID = AROS_WORD2BE(fhead->fch_FileID);
166 fhead->fch_NumEntries = AROS_WORD2BE(fhead->fch_NumEntries);
168 #endif
169 #endif
170 file=Open(fullname,MODE_NEWFILE);
171 if (file)
173 /* Find the size of the header. This is definitely a hack... */
174 size=*((LONG *)((UBYTE *)fhead-AROS_ALIGN(sizeof(ULONG))))-sizeof(LONG); /* Ehem. This is AllocVec'd */
175 rc=0;
176 if (Write(file,fhead,size)<0) rc=IoErr();
177 Close(file);
178 /* Delete the file on failure, clear executeable otherwise */
179 if (rc) DeleteFile(fullname);
180 else SetProtection(fullname,FIBF_EXECUTE);
182 else
184 rc=IoErr();
187 else
189 DeleteFile(fullname); /* Remove empty fonts */
191 DisposeFontContents(fhead); /* remove the fcheader */
193 else
195 /* FontContents allocation */
196 size=IoErr();
197 if (size==0) rc=ERROR_NO_FREE_STORE;
198 else rc=size;
200 } /* if name small enough */
201 } /* if type is directory */
203 if (rc) break;
204 /* Abort on failure */
206 ead=ead->ed_Next;
207 } while(ead); /* ExAll buffer loop */
208 } while(more); /* while more entries in exall-loop */
210 /* restore the old directory */
211 UnLock(lock);
212 CurrentDir(oldlock);
214 else
216 rc=IoErr();
217 } /* If DupLock() */
219 /* No more entries? */
220 if ((devproc->dvp_Flags & DVPF_ASSIGN)==0) break;
223 else
224 { /* GetDeviceProc worked */
225 rc=IoErr();
226 if (rc==ERROR_NO_MORE_ENTRIES) rc=0; /* Default fault is fine */
227 break; /* loop abort */
229 } while(rc==0); /* GetDeviceProc loop */
231 FreeDeviceProc(devproc);
232 FreeDosObject(DOS_EXALLCONTROL,exall);
234 else
236 rc=ERROR_NO_FREE_STORE;
239 /* Still no error? Rewrite font cache! */
240 if (rc==0)
242 fontflags=AFF_DISK;
243 while (rc==0)
245 for (;;)
247 size=AvailFonts((STRPTR)buffer,bufsize,fontflags);
248 if (size>0)
250 FreeMem(buffer,bufsize);
251 bufsize+=size;
252 buffer=AllocMem(bufsize,MEMF_PUBLIC);
253 if (buffer==NULL)
255 rc=ERROR_NO_FREE_STORE;
256 break;
259 else if (size==0)
261 break;
263 else
265 rc=IoErr();
266 break;
267 } /* size switch */
268 } /* buffer enlarge loop */
270 if (fontflags & AFF_TAGGED) break;
272 fontflags |= AFF_TAGGED; /* and now for the tagged stuff */
274 } /* FontCache rewrite */
276 FreeMem(buffer,bufsize);
278 else
280 rc=ERROR_NO_FREE_STORE; /* buffer allocation */
283 if (rc)
285 if (rc>64)
287 PrintFault(rc,"FixFonts failed");
289 if (rc==ERROR_BREAK) rc=0;
290 else rc=10;
294 return rc;