1 /*--------------------------------------------------------------------------
2 ----- File: t1delete.c
3 ----- Author: Rainer Menzner (Rainer.Menzner@web.de)
4 ----- Date: 2002-12-02
5 ----- Description: This file is part of the t1-library. It contains
6 functions for giving free previously allocated
7 memory areas and similar things.
8 ----- Copyright: t1lib is copyrighted (c) Rainer Menzner, 1996-2002.
9 As of version 0.5, t1lib is distributed under the
10 GNU General Public Library Lincense. The
11 conditions can be found in the files LICENSE and
12 LGPL, which should reside in the toplevel
13 directory of the distribution. Please note that
14 there are parts of t1lib that are subject to
15 other licenses:
16 The parseAFM-package is copyrighted by Adobe Systems
17 Inc.
18 The type1 rasterizer is copyrighted by IBM and the
19 X11-consortium.
20 ----- Warranties: Of course, there's NO WARRANTY OF ANY KIND :-)
21 ----- Credits: I want to thank IBM and the X11-consortium for making
22 their rasterizer freely available.
23 Also thanks to Piet Tutelaers for his ps2pk, from
24 which I took the rasterizer sources in a format
25 independent from X11.
26 Thanks to all people who make free software living!
27 --------------------------------------------------------------------------*/
28
29 #define T1DELETE_C
30
31
32 #include <stdio.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #if defined(_MSC_VER)
37 # include <io.h>
38 # include <sys/types.h>
39 # include <sys/stat.h>
40 #else
41 # include <unistd.h>
42 #endif
43 #include <stdlib.h>
44 #include <math.h>
45
46
47 #include "../type1/types.h"
48 #include "parseAFM.h"
49 #include "../type1/objects.h"
50 #include "../type1/spaces.h"
51 #include "../type1/util.h"
52 #include "../type1/fontfcn.h"
53
54 #include "t1types.h"
55 #include "t1extern.h"
56 #include "t1delete.h"
57 #include "t1load.h"
58 #include "t1finfo.h"
59 #include "t1base.h"
60
61
62
63 /* T1_DeleteSize(): Gives back all the memory allocated for size to the
64 system. If size is somewhere in the middle of a linked list of sizes,
65 it further takes care that the remaining list is linked in a proper
66 way. Function returns 0 if successful and otherwise -1*/
T1_DeleteSize(int FontID,float size)67 int T1_DeleteSize( int FontID, float size)
68 {
69 int i, j;
70 FONTSIZEDEPS *ptr, *next_ptr, *prev_ptr;
71 int jobs=0;
72 int antialias;
73 int level[4]={0,T1_AA_NONE,T1_AA_LOW,T1_AA_HIGH};
74
75
76 for ( j=0; j<4; j++){
77 antialias=level[j];
78 /* Check if size exists; if not, return 1 */
79 if ((ptr=T1int_QueryFontSize( FontID, size, antialias))!=NULL){
80 /* We have to remove a size-> */
81 jobs++;
82 /* Get pointers to structure which is before/after the structure
83 to be deleted in the linked list and properly relink
84 structures */
85 next_ptr=((FONTSIZEDEPS *)ptr)->pNextFontSizeDeps;
86 prev_ptr=((FONTSIZEDEPS *)ptr)->pPrevFontSizeDeps;
87
88 if ((prev_ptr==NULL)&&(next_ptr==NULL)){
89 /* There's only one single size, no relink is necessary
90 => reset the initial pointer to indicate that no size
91 dependent data is available */
92 pFontBase->pFontArray[FontID].pFontSizeDeps=NULL;
93 }
94 else{
95 if (prev_ptr!=NULL)
96 /* We are at the first size of the linked list and
97 there are still some sizes left after removing the
98 current */
99 prev_ptr->pNextFontSizeDeps=next_ptr;
100 else
101 pFontBase->pFontArray[FontID].pFontSizeDeps=next_ptr;
102 if (next_ptr!=NULL)
103 /* We are at the end of an list of at least two sizes: */
104 next_ptr->pPrevFontSizeDeps=prev_ptr;
105 }
106
107 /* Now, that the list is properly linked, free the memory used by size: */
108 /* Free the bitmaps memory: */
109 for (i=0; i<256; i++)
110 if (ptr->pFontCache[i].bits)
111 free(ptr->pFontCache[i].bits);
112
113 /* Free memory for glyphs: */
114 free(ptr->pFontCache);
115 /* Free the structure itself: */
116 free(ptr);
117 /* Print log: */
118 sprintf( err_warn_msg_buf, "Size %f deleted for FontID %d (antialias=%d)",
119 size, FontID, antialias);
120 T1_PrintLog( "T1_DeleteSize()", err_warn_msg_buf, T1LOG_STATISTIC);
121 }
122 }
123
124 /* Return the appropriate value */
125 if (jobs==0)
126 return(-1);
127 else
128 return(0);
129
130 }
131
132
133 /* T1_DeleteAllSizes(): Gives back all the memory allocated for all sizes
134 to the system. Function returns the number of removed sizes or -1 if an
135 error ocurred. */
T1_DeleteAllSizes(int FontID)136 int T1_DeleteAllSizes( int FontID)
137 {
138 int sizecount;
139 float currsize;
140
141 FONTSIZEDEPS *ptr;
142
143 if (T1_CheckForFontID(FontID)!=1)
144 return(-1);
145
146 /* Start deleting at the end of the linked list: */
147 sizecount=0;
148 if ((ptr=T1int_GetLastFontSize( FontID))==NULL){
149 /* There has not been any size dependent data: */
150 return(0);
151 }
152
153 while (((ptr=T1int_GetLastFontSize(FontID)) != NULL)){
154 currsize=ptr->size;
155 T1_DeleteSize( FontID, currsize);
156 sizecount++;
157
158 }
159
160 return(sizecount);
161 }
162
163
164 /* T1_FreeGlyph(): Gives the memory used by a glyph back to the system. */
T1_FreeGlyph(GLYPH * glyph)165 int T1_FreeGlyph( GLYPH *glyph)
166 {
167 if (glyph!=NULL) {
168 if (glyph->bits!=NULL) {
169 free(glyph->bits);
170 }
171 free(glyph);
172 }
173 return(0);
174 }
175
176
177 /* T1_FreeCompCharData(): Return emory used by a composite character
178 data information structure to the system */
T1_FreeCompCharData(T1_COMP_CHAR_INFO * cci)179 int T1_FreeCompCharData( T1_COMP_CHAR_INFO *cci)
180 {
181
182 if (cci!=NULL) {
183 if (cci->pieces!=NULL) {
184 free( cci->pieces);
185 }
186 free( cci);
187 }
188 return( 0);
189 }
190
191
192 /* T1_DeleteFont(): Gives all memory used by a font back to the system.
193 If the font is successfully deinstalled 0 is returned. A positive value
194 indicates an error. */
T1_DeleteFont(int FontID)195 int T1_DeleteFont( int FontID)
196 {
197
198 int result;
199
200
201 if (T1_CheckForFontID(FontID)==-1){ /* Invalid ID */
202 T1_errno=T1ERR_INVALID_FONTID;
203 return(-1);
204 }
205
206 if (T1_CheckForFontID(FontID)==0) /* Font is not loaded */
207 return(0);
208
209 /* Memory freeing must be done hierachical, start with size dependent
210 data: */
211 result=T1_DeleteAllSizes(FontID);
212
213 /* Next we delete the AFM-mapping tables */
214 if (pFontBase->pFontArray[FontID].pEncMap!=NULL)
215 free( pFontBase->pFontArray[FontID].pEncMap);
216 if (pFontBase->pFontArray[FontID].pKernMap!=NULL)
217 free( pFontBase->pFontArray[FontID].pKernMap);
218
219 /* We do not touch the file name because this is only to be done by
220 T1_CloseLib(): */
221
222 /* The Type-1 area and tyhe AFM-area may only be free'ed, if the
223 font is a "physical" font and if its reference counter is 1, or
224 if it is a logical font. Otherwise, other logical font use this
225 physical one and it may not be free'ed. In this case, return the
226 number of logical fonts which refer to this physical font. */
227 if ((pFontBase->pFontArray[FontID].physical==1)&&
228 (pFontBase->pFontArray[FontID].refcount==1)){
229 /* Now handle the type 1 data: */
230 if (pFontBase->pFontArray[FontID].pType1Data!=NULL){
231 /* First: VM, which includes CharStrings, Private, .... */
232 free(pFontBase->pFontArray[FontID].vm_base);
233 /* .. then the struct itself: */
234 free(pFontBase->pFontArray[FontID].pType1Data);
235 pFontBase->pFontArray[FontID].pType1Data=NULL;
236 }
237
238 /* afm-data is yet there -> */
239 if (pFontBase->pFontArray[FontID].pAFMData!=NULL){
240 result=FreeAFMData(pFontBase->pFontArray[FontID].pAFMData);
241 pFontBase->pFontArray[FontID].pAFMData=NULL;
242 }
243 }
244 else{
245 if (pFontBase->pFontArray[FontID].physical==1){
246 /* font is physical and is referred to by other fonts ->
247 Do nothing further and return number of references: */
248
249 return(pFontBase->pFontArray[FontID].refcount - 1);
250 }
251 }
252
253 /* If we get here and the font is logical, we have to
254 decrement the refcount of the referred physical font */
255 if (pFontBase->pFontArray[FontID].physical==0){
256 pFontBase->pFontArray[pFontBase->pFontArray[FontID].refcount].refcount--;
257 }
258
259
260 /* Set remaining area explicitly to 0 (all but pFontFileName and
261 pAfmFileName!) */
262 pFontBase->pFontArray[FontID].pAFMData=NULL;
263 pFontBase->pFontArray[FontID].pType1Data=NULL;
264 pFontBase->pFontArray[FontID].pEncMap=NULL;
265 pFontBase->pFontArray[FontID].pKernMap=NULL;
266 pFontBase->pFontArray[FontID].pFontEnc=NULL;
267 pFontBase->pFontArray[FontID].pFontSizeDeps=NULL;
268 pFontBase->pFontArray[FontID].vm_base=NULL;
269 pFontBase->pFontArray[FontID].FontMatrix[0]=0.0;
270 pFontBase->pFontArray[FontID].FontMatrix[1]=0.0;
271 pFontBase->pFontArray[FontID].FontMatrix[2]=0.0;
272 pFontBase->pFontArray[FontID].FontMatrix[3]=0.0;
273 pFontBase->pFontArray[FontID].FontTransform[0]=0.0;
274 pFontBase->pFontArray[FontID].FontTransform[1]=0.0;
275 pFontBase->pFontArray[FontID].FontTransform[2]=0.0;
276 pFontBase->pFontArray[FontID].FontTransform[3]=0.0;
277 pFontBase->pFontArray[FontID].slant=0.0;
278 pFontBase->pFontArray[FontID].extend=0.0;
279 pFontBase->pFontArray[FontID].UndrLnPos=0.0;
280 pFontBase->pFontArray[FontID].UndrLnThick=0.0;
281 pFontBase->pFontArray[FontID].OvrLnPos=0.0;
282 pFontBase->pFontArray[FontID].OvrLnThick=0.0;
283 pFontBase->pFontArray[FontID].OvrStrkPos=0.0;
284 pFontBase->pFontArray[FontID].OvrStrkThick=0.0;
285 pFontBase->pFontArray[FontID].physical=0;
286 pFontBase->pFontArray[FontID].refcount=0;
287 pFontBase->pFontArray[FontID].space_position=0;
288 pFontBase->pFontArray[FontID].info_flags=0;
289
290 return(0);
291
292 }
293
294
295
296 /* FreeAFMData(): Give all memory used by afm-Information back to the
297 system. */
FreeAFMData(FontInfo * pAFMData)298 int FreeAFMData( FontInfo *pAFMData)
299 {
300 if (pAFMData != NULL){
301 if (pAFMData->gfi != NULL){
302 free(pAFMData->gfi->afmVersion); pAFMData->gfi->afmVersion = NULL;
303 free(pAFMData->gfi->fontName); pAFMData->gfi->fontName = NULL;
304 free(pAFMData->gfi->fullName); pAFMData->gfi->fullName = NULL;
305 free(pAFMData->gfi->familyName); pAFMData->gfi->familyName = NULL;
306 free(pAFMData->gfi->weight); pAFMData->gfi->weight = NULL;
307 free(pAFMData->gfi->version); pAFMData->gfi->version = NULL;
308 free(pAFMData->gfi->notice); pAFMData->gfi->notice = NULL;
309 free(pAFMData->gfi->encodingScheme); pAFMData->gfi->encodingScheme = NULL;
310 free(pAFMData->gfi); pAFMData->gfi = NULL;
311 }
312
313 if (pAFMData->cwi != NULL){
314 free(pAFMData->cwi); pAFMData->cwi = NULL;
315 }
316
317 if (pAFMData->cmi != NULL){
318 int i = 0;
319 CharMetricInfo *temp = pAFMData->cmi;
320 Ligature *node = temp->ligs;
321 for (i = 0; i < pAFMData->numOfChars; ++i){
322 for (node = temp->ligs; node != NULL; node = node->next){
323 free(node->succ); node->succ = NULL;
324 free(node->lig); node->lig = NULL;
325 }
326 free(temp->name); temp->name = NULL;
327 temp++;
328 }
329 free(pAFMData->cmi); pAFMData->cmi = NULL;
330 }
331
332 if (pAFMData->tkd != NULL){
333 free(pAFMData->tkd); pAFMData->tkd = NULL;
334 }
335
336 if (pAFMData->pkd != NULL){
337 int i = 0;
338 for (i = 0; i < pAFMData->numOfPairs; ++i){
339 free(pAFMData->pkd[i].name1); pAFMData->pkd[i].name1 = NULL;
340 free(pAFMData->pkd[i].name2); pAFMData->pkd[i].name2 = NULL;
341 }
342 free(pAFMData->pkd); pAFMData->pkd = NULL;
343 }
344
345 if (pAFMData->ccd != NULL){
346 int i = 0, j = 0;
347 CompCharData *ccd = pAFMData->ccd;
348 for (i = 0; i < pAFMData->numOfComps; ++i){
349 for (j = 0; j < ccd[i].numOfPieces; ++j){
350 free(ccd[i].pieces[j].pccName);
351 ccd[i].pieces[j].pccName = NULL;
352 }
353 free(ccd[i].ccName); ccd[i].ccName = NULL;
354 }
355 free(pAFMData->ccd); pAFMData->ccd = NULL;
356 }
357 free(pAFMData);
358 }
359 return(0);
360
361 }
362
363