add a missing section header table index conversion
[tangerine.git] / workbench / system / FixFonts.c
blob3d519c6c3cf5a77ca69af13da6b6270f75947183
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 #include <aros/macros.h>
21 #include <proto/exec.h>
22 #include <proto/dos.h>
23 #include <proto/diskfont.h>
25 #include <string.h>
27 #define MAXFONTLEN 25L
30 char version[] = "$VER: FixFonts 40.2 (16.9.1999) (c) THOR";
32 int main()
34 struct ExAllControl *exall;
35 struct ExAllData *ead;
36 struct DevProc *devproc=NULL;
37 BPTR lock,
38 oldlock;
39 BPTR file;
40 struct FontContentsHeader *fhead;
41 LONG size;
42 ULONG fontflags;
43 int len;
44 long rc = 20;
45 int more;
46 char fullname[32];
47 char *buffer;
48 ULONG bufsize = 4096L;
50 if ((buffer=AllocMem(bufsize,MEMF_PUBLIC)))
52 if ((exall=AllocDosObject(DOS_EXALLCONTROL,TAG_DONE)))
54 /* Set return code to fine */
55 rc=0;
59 if ((devproc=GetDeviceProc("FONTS:",devproc)))
61 /* User abort? */
62 if (CheckSignal(SIGBREAKF_CTRL_C)) {
63 rc=ERROR_BREAK;
64 break;
67 exall->eac_LastKey=0L;
68 if ((lock=DupLock(devproc->dvp_Lock)))
70 oldlock=CurrentDir(lock);
73 ead=(struct ExAllData *)buffer;
74 more=ExAll(lock,ead,bufsize,ED_TYPE,exall);
75 if (!more)
77 size=IoErr();
78 if (size!=ERROR_NO_MORE_ENTRIES) rc=size; /* break on an error */
80 else
82 /* if there are more entries and an error, abort */
83 if (rc) ExAllEnd(lock,ead,bufsize,ED_TYPE,exall);
86 /* quit loop on error */
87 if (rc) break;
89 if (exall->eac_Entries==0) continue; /* Ignore empty entries */
93 if (ead->ed_Type>0)
95 len=strlen(ead->ed_Name);
98 len <= MAXFONTLEN
99 && strncmp(ead->ed_Name, "TrueType", len) != 0
102 /* check for user abort */
103 if (CheckSignal(SIGBREAKF_CTRL_C))
105 rc=ERROR_BREAK;
106 break;
108 /* Build name of the directory */
109 strcpy(fullname,ead->ed_Name);
110 strcpy(fullname+len,".font"); /* Add .font */
112 /* Build a contents header */
113 fhead=NewFontContents(lock,fullname);
114 if (fhead)
116 if (fhead->fch_NumEntries>0)
118 #ifdef __AROS__
119 #if !AROS_BIG_ENDIAN
120 WORD i;
122 for(i = 0; i < fhead->fch_NumEntries; i++)
124 if(fhead->fch_FileID == FCH_ID)
126 struct FontContents *fc;
128 fc = (struct FontContents *)(fhead + 1);
129 fc += i;
131 fc->fc_YSize = AROS_WORD2BE(fc->fc_YSize);
133 else if
135 (fhead->fch_FileID == TFCH_ID)
136 || (fhead->fch_FileID == OFCH_ID)
139 struct TFontContents *tfc;
141 tfc = (struct TFontContents *)(fhead + 1);
142 tfc += i;
144 if (tfc->tfc_TagCount)
146 ULONG *tags;
147 WORD t;
149 tags = (ULONG *)(&tfc->tfc_FileName[MAXFONTPATH-(tfc->tfc_TagCount*8)]);
150 for (t = 0; t < tfc->tfc_TagCount * 2 - 1; t++)
152 tags[t] = AROS_LONG2BE(tags[t]);
155 tfc->tfc_TagCount = AROS_WORD2BE(tfc->tfc_TagCount);
156 tfc->tfc_YSize = AROS_WORD2BE(tfc->tfc_YSize);
159 } /* for(i = 0; i < fhead->fch_NumEntries; i++) */
161 fhead->fch_FileID = AROS_WORD2BE(fhead->fch_FileID);
162 fhead->fch_NumEntries = AROS_WORD2BE(fhead->fch_NumEntries);
164 #endif
165 #endif
166 file=Open(fullname,MODE_NEWFILE);
167 if (file)
169 /* Find the size of the header. This is definitely a hack... */
170 size=*((LONG *)((UBYTE *)fhead-AROS_ALIGN(sizeof(ULONG))))-sizeof(LONG); /* Ehem. This is AllocVec'd */
171 rc=0;
172 if (Write(file,fhead,size)<0) rc=IoErr();
173 Close(file);
174 /* Delete the file on failure, clear executeable otherwise */
175 if (rc) DeleteFile(fullname);
176 else SetProtection(fullname,FIBF_EXECUTE);
178 else
180 rc=IoErr();
183 else
185 DeleteFile(fullname); /* Remove empty fonts */
187 DisposeFontContents(fhead); /* remove the fcheader */
189 else
191 /* FontContents allocation */
192 size=IoErr();
193 if (size==0) rc=ERROR_NO_FREE_STORE;
194 else rc=size;
196 } /* if name small enough */
197 } /* if type is directory */
199 if (rc) break;
200 /* Abort on failure */
202 ead=ead->ed_Next;
203 } while(ead); /* ExAll buffer loop */
204 } while(more); /* while more entries in exall-loop */
206 /* restore the old directory */
207 UnLock(lock);
208 CurrentDir(oldlock);
210 else
212 rc=IoErr();
213 } /* If DupLock() */
215 /* No more entries? */
216 if ((devproc->dvp_Flags & DVPF_ASSIGN)==0) break;
219 else
220 { /* GetDeviceProc worked */
221 rc=IoErr();
222 if (rc==ERROR_NO_MORE_ENTRIES) rc=0; /* Default fault is fine */
223 break; /* loop abort */
225 } while(rc==0); /* GetDeviceProc loop */
227 FreeDeviceProc(devproc);
228 FreeDosObject(DOS_EXALLCONTROL,exall);
230 else
232 rc=ERROR_NO_FREE_STORE;
235 /* Still no error? Rewrite font cache! */
236 if (rc==0)
238 fontflags=AFF_DISK;
239 while (rc==0)
241 for (;;)
243 size=AvailFonts((STRPTR)buffer,bufsize,fontflags);
244 if (size>0)
246 FreeMem(buffer,bufsize);
247 bufsize+=size;
248 buffer=AllocMem(bufsize,MEMF_PUBLIC);
249 if (buffer==NULL)
251 rc=ERROR_NO_FREE_STORE;
252 break;
255 else if (size==0)
257 break;
259 else
261 rc=IoErr();
262 break;
263 } /* size switch */
264 } /* buffer enlarge loop */
266 if (fontflags & AFF_TAGGED) break;
268 fontflags |= AFF_TAGGED; /* and now for the tagged stuff */
270 } /* FontCache rewrite */
272 FreeMem(buffer,bufsize);
274 else
276 rc=ERROR_NO_FREE_STORE; /* buffer allocation */
279 if (rc)
281 if (rc>64)
283 PrintFault(rc,"FixFonts failed");
285 if (rc==ERROR_BREAK) rc=0;
286 else rc=10;
290 return rc;