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