(file) Return to afm.c CVS log (file) (dir) Up to [RizwankCVS] / testProject / afmlib

  1 rizwank 1.1 /*
  2              * AFM library public interface.
  3              * Copyright (c) 1995-1999 Markku Rossi.
  4              *
  5              * Author: Markku Rossi <mtr@iki.fi>
  6              */
  7             
  8             /*
  9              * This program is free software; you can redistribute it and/or modify
 10              * it under the terms of the GNU General Public License as published by
 11              * the Free Software Foundation; either version 2, or (at your option)
 12              * any later version.
 13              *
 14              * This program is distributed in the hope that it will be useful,
 15              * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16              * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17              * GNU General Public License for more details.
 18              *
 19              * You should have received a copy of the GNU General Public License
 20              * along with this program; see the file COPYING.  If not, write to
 21              * the Free Software Foundation, 59 Temple Place - Suite 330,
 22 rizwank 1.1  * Boston, MA 02111-1307, USA.
 23              */
 24             
 25             #include "afmint.h"
 26             #include "afm.h"
 27             
 28             /*
 29              * Static variables
 30              */
 31             
 32             static char *default_path = "/usr/local/lib/ps:/usr/lib/ps";
 33             
 34             static char *error_names[] =
 35             {
 36               "AFM Success",
 37               "AFM Error",
 38               "out of memory",
 39               "illegal argument",
 40               "unknown font",
 41               "syntax error",
 42               "unsupported format",
 43 rizwank 1.1   "file IO failed",
 44               "file is not an AFM file",
 45             };
 46             
 47             /*
 48              * Prototypes for static functions.
 49              */
 50             
 51             static void read_font_map ___P ((AFMHandle handle, char *name));
 52             static void apply_encoding ___P ((AFMFont font, AFMEncodingTable *enc,
 53             				  unsigned int flags));
 54             
 55             
 56             /*
 57              * Global functions.
 58              */
 59             
 60             void
 61             afm_error_to_string (AFMError error, char *buf)
 62             {
 63               char *syserr;
 64 rizwank 1.1   int code, syserrno;
 65             
 66               code = error & 0xffff;
 67               syserrno = (error >> 16) & 0xffff;
 68             
 69               if (syserrno)
 70                 syserr = strerror (syserrno);
 71               else
 72                 syserr = NULL;
 73             
 74               if (code >= NUM_ERRORS)
 75                 {
 76                   sprintf (buf, "afm_error_to_string(): illegal error code: %d\n",
 77             	       error);
 78                   return;
 79                 }
 80             
 81               if (code == 0)
 82                 sprintf (buf, "AFM Success");
 83               else if (code == 1)
 84                 sprintf (buf, "%s%s%s", "AFM Error",
 85 rizwank 1.1 	     syserr ? ":" : "",
 86             	     syserr ? syserr : "");
 87               else
 88                 sprintf (buf, "AFM Error: %s%s%s", error_names[code],
 89             	     syserr ? ": " : "",
 90             	     syserr ? syserr : "");
 91             }
 92             
 93             
 94             AFMError
 95             afm_create (const char *path, unsigned int verbose_level,
 96             	    AFMHandle *handle_return)
 97             {
 98               AFMHandle handle;
 99               AFMError error = AFM_SUCCESS;
100               const char *cp, *cp2;
101               int len;
102               char buf[512];
103               struct stat stat_st;
104             
105               /* Init handle. */
106 rizwank 1.1 
107               handle = (AFMHandle) calloc (1, sizeof (*handle));
108               if (handle == NULL)
109                 {
110                   error = AFM_ERROR_MEMORY;
111                   goto error_out;
112                 }
113             
114               handle->font_map = strhash_init ();
115               if (handle->font_map == NULL)
116                 {
117                   error = AFM_ERROR_MEMORY;
118                   goto error_out;
119                 }
120             
121               handle->verbose = verbose_level;
122             
123               /* Traverse path. */
124             
125               if (path == NULL)
126                 path = default_path;
127 rizwank 1.1 
128               afm_message (handle, 1, "AFM: scanning path...\n");
129               for (cp = path; cp; cp = strchr (cp, PATH_SEPARATOR))
130                 {
131                   if (cp != path)
132             	cp++;
133             
134                   cp2 = strchr (cp, PATH_SEPARATOR);
135                   if (cp2)
136             	len = cp2 - cp;
137                   else
138             	len = strlen (cp);
139             
140                   memcpy (buf, cp, len);
141                   buf[len] = '\0';
142                   if (len > 0 && buf[len - 1] == '/')
143             	buf[len - 1] = '\0';
144             
145                   strcat (buf, "/font.map");
146             
147                   if (stat (buf, &stat_st) == 0)
148 rizwank 1.1 	read_font_map (handle, buf);
149                 }
150             
151               *handle_return = handle;
152             
153               return AFM_SUCCESS;
154             
155             
156               /* Error handling. */
157             
158              error_out:
159             
160               (void) afm_destroy (handle);
161             
162               return error;
163             }
164             
165             
166             AFMError
167             afm_destroy (AFMHandle handle)
168             {
169 rizwank 1.1   char *key;
170               int keylen;
171               char *cp;
172             
173               if (handle == NULL)
174                 return AFM_ERROR_ARGUMENT;
175             
176               /* Free filenames. */
177               while (strhash_get_first (handle->font_map, &key, &keylen, (void *) &cp))
178                 free (cp);
179             
180               strhash_free (handle->font_map);
181               free (handle);
182             
183               return AFM_SUCCESS;
184             }
185             
186             
187             AFMError
188             afm_set_verbose (AFMHandle handle, unsigned int level)
189             {
190 rizwank 1.1   if (handle == NULL)
191                 return AFM_ERROR_ARGUMENT;
192             
193               handle->verbose = level;
194             
195               return AFM_SUCCESS;
196             }
197             
198             
199             AFMError
200             afm_font_prefix (AFMHandle handle, const char *fontname,
201             		 const char **prefix_return)
202             {
203               char *filename;
204             
205               if (handle == NULL || fontname == NULL || prefix_return == NULL)
206                 return AFM_ERROR_ARGUMENT;
207             
208               /* Lookup font. */
209               if (!strhash_get (handle->font_map, fontname, strlen (fontname),
210             		    (void *) &filename))
211 rizwank 1.1     return AFM_ERROR_UNKNOWN_FONT;
212             
213               *prefix_return = filename;
214             
215               return AFM_SUCCESS;
216             }
217             
218             
219             AFMError
220             afm_open_font (AFMHandle handle, unsigned int info_level,
221             	       const char *fontname, AFMFont *font_return)
222             {
223               char *filename;
224               char fname[512];
225             
226               if (handle == NULL || fontname == NULL)
227                 return AFM_ERROR_ARGUMENT;
228             
229               /* Lookup font. */
230               if (!strhash_get (handle->font_map, fontname, strlen (fontname),
231             		    (void *) &filename))
232 rizwank 1.1     return AFM_ERROR_UNKNOWN_FONT;
233             
234               /* Append suffix to the filename. */
235               sprintf (fname, "%s.afm", filename);
236             
237               return afm_open_file (handle, info_level, fname, font_return);
238             }
239             
240             
241             AFMError
242             afm_open_file (AFMHandle handle, unsigned int info_level,
243             	       const char *filename, AFMFont *font_return)
244             {
245               AFMFont font;
246               AFMError error = AFM_SUCCESS;
247             
248               if (handle == NULL || filename == NULL)
249                 return AFM_ERROR_ARGUMENT;
250             
251               font = (AFMFont) calloc (1, sizeof (*font));
252               if (font == NULL)
253 rizwank 1.1     return AFM_ERROR_MEMORY;
254             
255               font->private
256                 = (struct afm_font_private_data_st *) calloc (1, sizeof (*font->private));
257               if (font->private == NULL)
258                 {
259                   error = AFM_ERROR_MEMORY;
260                   goto error_out;
261                 }
262               font->private->fontnames = strhash_init ();
263               if (font->private->fontnames == NULL)
264                 {
265                   error = AFM_ERROR_MEMORY;
266                   goto error_out;
267                 }
268             
269               font->private->compositenames = strhash_init ();
270               if (font->private->compositenames == NULL)
271                 {
272                   error = AFM_ERROR_MEMORY;
273                   goto error_out;
274 rizwank 1.1     }
275             
276               font->info_level = info_level;
277             
278               /* Parse file. */
279               if (setjmp (handle->jmpbuf))
280                 {
281                   /* Error during parse. */
282                   error = handle->parse_error;
283                   goto error_out;
284                 }
285               else
286                 {
287                   afm_parse_file (handle, filename, font);
288                   /* Parse successful. */
289                 }
290             
291               *font_return = font;
292               return AFM_SUCCESS;
293             
294             
295 rizwank 1.1   /* Error handling. */
296             
297              error_out:
298             
299               (void) afm_close_font (font);
300             
301               return error;
302             }
303             
304             
305             #define FREE(ptr) if (ptr) free (ptr)
306             AFMError
307             afm_close_font (AFMFont font)
308             {
309               int i;
310             
311               if (font == NULL)
312                 return AFM_ERROR_ARGUMENT;
313             
314               /* Global info. */
315               FREE (font->global_info.FontName);
316 rizwank 1.1   FREE (font->global_info.FullName);
317               FREE (font->global_info.FamilyName);
318               FREE (font->global_info.Weight);
319               FREE (font->global_info.Version);
320               FREE (font->global_info.Notice);
321               FREE (font->global_info.EncodingScheme);
322               FREE (font->global_info.CharacterSet);
323             
324               /* Character metrics. */
325               for (i = 0; i < font->num_character_metrics; i++)
326                 FREE (font->character_metrics[i].name);
327               FREE (font->character_metrics);
328             
329               /* Composites. */
330               for (i = 0; i < font->num_composites; i++)
331                 FREE (font->composites[i].name);
332               FREE (font->composites);
333             
334               /* Kern pairs. */
335               for (i = 0; i < font->num_kern_pairs; i++)
336                 {
337 rizwank 1.1       FREE (font->kern_pairs[i].name1);
338                   FREE (font->kern_pairs[i].name2);
339                 }
340               FREE (font->kern_pairs);
341             
342               /* Track kern. */
343               FREE (font->track_kerns);
344             
345               /* Private data. */
346               strhash_free (font->private->fontnames);
347               strhash_free (font->private->compositenames);
348             
349               free (font);
350             
351               return AFM_SUCCESS;
352             }
353             
354             
355             #define STR(str) (str ? str : "")
356             #define BOOL(val) (val ? "true" : "false")
357             void
358 rizwank 1.1 afm_font_dump (FILE *fp, AFMFont font)
359             {
360               int i;
361             
362               fprintf (fp, "AFM Format Specification version: %g\n", font->version);
363               fprintf (fp, "Global Font Information\n");
364               fprintf (fp, "  FontName:\t%s\n", 	STR (font->global_info.FontName));
365               fprintf (fp, "  FullName:\t%s\n", 	STR (font->global_info.FullName));
366               fprintf (fp, "  FamilyName:\t%s\n", 	STR (font->global_info.FamilyName));
367               fprintf (fp, "  Weight:\t%s\n", 	STR (font->global_info.Weight));
368               fprintf (fp, "  FontBBox:\t%g %g %g %g\n",
369             	   font->global_info.FontBBox_llx, font->global_info.FontBBox_lly,
370             	   font->global_info.FontBBox_urx, font->global_info.FontBBox_ury);
371               fprintf (fp, "  Version:\t%s\n", 	STR (font->global_info.Version));
372               fprintf (fp, "  Notice:\t%s\n", 	STR (font->global_info.Notice));
373               fprintf (fp, "  EncodingScheme:\t%s\n",
374             	   STR (font->global_info.EncodingScheme));
375               fprintf (fp, "  MappingScheme:\t%ld\n", font->global_info.MappingScheme);
376               fprintf (fp, "  EscChar:\t%ld\n", font->global_info.EscChar);
377               fprintf (fp, "  CharacterSet:\t%s\n", STR (font->global_info.CharacterSet));
378               fprintf (fp, "  Characters:\t%ld\n", 	font->global_info.Characters);
379 rizwank 1.1   fprintf (fp, "  IsBaseFont:\t%s\n", 	BOOL(font->global_info.IsBaseFont));
380               fprintf (fp, "  VVector:\t%g %g\n",
381             	   font->global_info.VVector_0,	font->global_info.VVector_1);
382               fprintf (fp, "  IsFixedV:\t%s\n", 	BOOL(font->global_info.IsFixedV));
383               fprintf (fp, "  CapHeight:\t%g\n", 	font->global_info.CapHeight);
384               fprintf (fp, "  XHeight:\t%g\n", 	font->global_info.XHeight);
385               fprintf (fp, "  Ascender:\t%g\n", 	font->global_info.Ascender);
386               fprintf (fp, "  Descender:\t%g\n", 	font->global_info.Descender);
387             
388               for (i = 0; i < 2; i++)
389                 if (font->writing_direction_metrics[i].is_valid)
390                   {
391             	fprintf (fp, "Writing Direction %d\n", i);
392             	fprintf (fp, "  UnderlinePosition: %g\n",
393             		 font->writing_direction_metrics[i].UnderlinePosition);
394             	fprintf (fp, "  UnderlineThickness: %g\n",
395             		 font->writing_direction_metrics[i].UnderlineThickness);
396             	fprintf (fp, "  ItalicAngle: %g\n",
397             		 font->writing_direction_metrics[i].ItalicAngle);
398             	fprintf (fp, "  CharWidth: %g %g\n",
399             		 font->writing_direction_metrics[i].CharWidth_x,
400 rizwank 1.1 		 font->writing_direction_metrics[i].CharWidth_y);
401             	fprintf (fp, "  IsFixedPitch: %s\n",
402             		 BOOL (font->writing_direction_metrics[i].IsFixedPitch));
403                   }
404             
405               /* Individual Character Metrics. */
406               fprintf (fp, "Individual Character Metrics %ld\n",
407             	   font->num_character_metrics);
408               for (i = 0; i < font->num_character_metrics; i++)
409                 {
410                   AFMIndividualCharacterMetrics *cm;
411                   cm = &font->character_metrics[i];
412             
413                   fprintf (fp, "  C %ld ; N %s ; B %g %g %g %g\n",
414             	       cm->character_code, STR (cm->name),
415             	       cm->llx, cm->lly, cm->urx, cm->ury);
416                   fprintf (fp,
417             	       "    W0X %g ; W0Y %g ; W1X %g ; W1Y %g ; VV %g %g\n",
418             	       cm->w0x, cm->w0y, cm->w1x, cm->w1y, cm->vv_x, cm->vv_y);
419                 }
420             
421 rizwank 1.1   /* Composite Character Data. */
422               fprintf (fp, "Composite Character Data %ld\n", font->num_composites);
423               for (i = 0; i < font->num_composites; i++)
424                 {
425                   AFMComposite *cm;
426                   int j;
427             
428                   cm = &font->composites[i];
429             
430                   fprintf (fp, "  CC %s %ld", cm->name, cm->num_components);
431                   for (j = 0; j < cm->num_components; j++)
432             	fprintf (fp, " ; PCC %s %g %g",
433             		 cm->components[j].name,
434             		 cm->components[j].deltax,
435             		 cm->components[j].deltay);
436                   fprintf (fp, "\n");
437                 }
438             
439               /* Kern pairs. */
440               fprintf (fp, "Pair-Wise Kerning %ld\n", font->num_kern_pairs);
441               for (i = 0; i < font->num_kern_pairs; i++)
442 rizwank 1.1     {
443                   AFMPairWiseKerning *kp;
444                   kp = &font->kern_pairs[i];
445             
446                   fprintf (fp, "  KP %s %s %g %g\n", STR (kp->name1), STR (kp->name2),
447             	       kp->kx, kp->ky);
448                 }
449             
450               fprintf (fp, "Track Kerning %ld\n", font->num_track_kerns);
451               for (i = 0; i < font->num_track_kerns; i++)
452                 {
453                   AFMTrackKern *tk;
454                   tk = &font->track_kerns[i];
455             
456                   fprintf (fp, "  TrackKern %ld %g %g %g %g\n", tk->degree,
457             	       tk->min_ptsize, tk->min_kern,
458             	       tk->max_ptsize, tk->max_kern);
459                 }
460             }
461             
462             
463 rizwank 1.1 AFMError
464             afm_font_stringwidth (AFMFont font, AFMNumber ptsize, char *string,
465             		      unsigned int stringlen, AFMNumber *w0x_return,
466             		      AFMNumber *w0y_return)
467             {
468               unsigned int i;
469               AFMNumber x = 0.0;
470               AFMNumber y = 0.0;
471               AFMIndividualCharacterMetrics *cm;
472             
473               if (!font || !string || !font->writing_direction_metrics[0].is_valid)
474                 return AFM_ERROR_ARGUMENT;
475             
476               /* Check shortcut. */
477               if (font->writing_direction_metrics[0].IsFixedPitch)
478                 {
479                   /* This is the easy case. */
480                   x = stringlen * font->writing_direction_metrics[0].CharWidth_x;
481                   y = stringlen * font->writing_direction_metrics[0].CharWidth_y;
482                 }
483               else
484 rizwank 1.1     {
485                   /* Count character by character. */
486                   for (i = 0; i < stringlen; i++)
487             	{
488             	  cm = font->encoding[(unsigned char) string[i]];
489             	  if (cm == AFM_ENC_NONE || cm == AFM_ENC_NON_EXISTENT)
490             	    {
491             	      /* Use the undef font. */
492             	      x += font->private->undef->w0x;
493             	      y += font->private->undef->w0y;
494             	    }
495             	  else
496             	    {
497             	      /* Font found and valid, take values. */
498             	      x += cm->w0x;
499             	      y += cm->w0y;
500             	    }
501             	}
502                 }
503             
504               *w0x_return = x / UNITS_PER_POINT * ptsize;
505 rizwank 1.1   *w0y_return = y / UNITS_PER_POINT * ptsize;
506             
507               return AFM_SUCCESS;
508             }
509             
510             
511             AFMError
512             afm_font_charwidth (AFMFont font, AFMNumber ptsize, char ch,
513             		    AFMNumber *w0x_return, AFMNumber *w0y_return)
514             {
515               AFMNumber x = 0.0;
516               AFMNumber y = 0.0;
517               AFMIndividualCharacterMetrics *cm;
518             
519               if (!font || !font->writing_direction_metrics[0].is_valid)
520                 return AFM_ERROR_ARGUMENT;
521             
522               /* Check shortcut. */
523               if (font->writing_direction_metrics[0].IsFixedPitch)
524                 {
525                   x = font->writing_direction_metrics[0].CharWidth_x;
526 rizwank 1.1       y = font->writing_direction_metrics[0].CharWidth_y;
527                 }
528               else
529                 {
530                   cm = font->encoding[(unsigned char) ch];
531                   if (cm == AFM_ENC_NONE || cm == AFM_ENC_NON_EXISTENT)
532             	{
533             	  /* Use the undef font. */
534             	  x = font->private->undef->w0x;
535             	  y = font->private->undef->w0y;
536             	}
537                   else
538             	{
539             	  /* Font found and valid, take values. */
540             	  x = cm->w0x;
541             	  y = cm->w0y;
542             	}
543                 }
544             
545               *w0x_return = x / UNITS_PER_POINT * ptsize;
546               *w0y_return = y / UNITS_PER_POINT * ptsize;
547 rizwank 1.1 
548               return AFM_SUCCESS;
549             }
550             
551             
552             AFMError
553             afm_font_encode (AFMFont font, unsigned char code, char *name,
554             		 unsigned int flags)
555             {
556               AFMIndividualCharacterMetrics *cm;
557               AFMComposite *comp;
558             
559               if (font == NULL)
560                 return AFM_ERROR_ARGUMENT;
561             
562               if (name)
563                 {
564                   /* Get font. */
565                   if (!strhash_get (font->private->fontnames, name, strlen (name),
566             			(void *) &cm))
567             	{
568 rizwank 1.1 	  /* Check composite characters. */
569             	  if ((flags & AFM_ENCODE_ACCEPT_COMPOSITES) == 0
570             	      || strhash_get (font->private->compositenames, name,
571             			      strlen (name), (void *) &comp) == 0)
572             	    cm = AFM_ENC_NON_EXISTENT;
573             	  else
574             	    {
575             	      /*
576             	       * Ok, composite character found, now find the character
577             	       * specified by the first composite component.
578             	       */
579             	      if (!strhash_get (font->private->fontnames,
580             				comp->components[0].name,
581             				strlen (comp->components[0].name),
582             				(void *) &cm))
583             		cm = AFM_ENC_NON_EXISTENT;
584             	    }
585             	}
586                 }
587               else
588                 cm = AFM_ENC_NONE;
589 rizwank 1.1 
590               font->encoding[(unsigned int) code] = cm;
591             
592               return AFM_SUCCESS;
593             }
594             
595             
596             AFMError
597             afm_font_encoding (AFMFont font, AFMEncoding enc, unsigned int flags)
598             {
599               int i;
600               AFMIndividualCharacterMetrics *cm;
601             
602               if (font == NULL)
603                 return AFM_ERROR_ARGUMENT;
604             
605               switch (enc)
606                 {
607                 case AFM_ENCODING_DEFAULT:
608                   /* Clear encoding. */
609                   for (i = 0; i < 256; i++)
610 rizwank 1.1 	font->encoding[i] = AFM_ENC_NONE;
611             
612                   /* Apply font's default encoding. */
613                   for (i = 0; i < font->num_character_metrics; i++)
614             	{
615             	  cm = &font->character_metrics[i];
616             	  font->encoding[cm->character_code] = cm;
617             	}
618                   break;
619             
620                 case AFM_ENCODING_ISO_8859_1:
621                   apply_encoding (font, afm_88591_encoding, flags);
622                   break;
623             
624                 case AFM_ENCODING_ISO_8859_2:
625                   apply_encoding (font, afm_88592_encoding, flags);
626                   break;
627             
628                 case AFM_ENCODING_ISO_8859_3:
629                   apply_encoding (font, afm_88593_encoding, flags);
630                   break;
631 rizwank 1.1 
632                 case AFM_ENCODING_ISO_8859_4:
633                   apply_encoding (font, afm_88594_encoding, flags);
634                   break;
635             
636                 case AFM_ENCODING_ISO_8859_5:
637                   apply_encoding (font, afm_88595_encoding, flags);
638                   break;
639             
640                 case AFM_ENCODING_ISO_8859_7:
641                   apply_encoding (font, afm_88597_encoding, flags);
642                   break;
643             
644                 case AFM_ENCODING_ISO_8859_9:
645                   apply_encoding (font, afm_88599_encoding, flags);
646                   break;
647             
648                 case AFM_ENCODING_ISO_8859_10:
649                   apply_encoding (font, afm_885910_encoding, flags);
650                   break;
651             
652 rizwank 1.1     case AFM_ENCODING_IBMPC:
653                   apply_encoding (font, afm_ibmpc_encoding, flags);
654                   break;
655             
656                 case AFM_ENCODING_ASCII:
657                   /*
658                    * First apply one encoding (all have equal first 128 characters),
659                    * then zap last 128 chars.
660                    */
661                   apply_encoding (font, afm_88591_encoding, flags);
662                   for (i = 128; i < 256; i++)
663             	font->encoding[i] = AFM_ENC_NONE;
664                   break;
665             
666                 case AFM_ENCODING_MAC:
667                   apply_encoding (font, afm_mac_encoding, flags);
668                   break;
669             
670                 case AFM_ENCODING_VMS:
671                   apply_encoding (font, afm_vms_encoding, flags);
672                   break;
673 rizwank 1.1 
674                 case AFM_ENCODING_HP8:
675                   apply_encoding (font, afm_hp8_encoding, flags);
676                   break;
677             
678                 case AFM_ENCODING_KOI8:
679                   apply_encoding (font, afm_koi8_encoding, flags);
680                   break;
681                 }
682             
683               return AFM_SUCCESS;
684             }
685             
686             
687             /*
688              * Internal help functions.
689              */
690             
691             
692             void
693             afm_message (AFMHandle handle, unsigned int level, char *message)
694 rizwank 1.1 {
695               if (handle->verbose < level)
696                 return;
697             
698               fprintf (stderr, "%s", message);
699             }
700             
701             
702             void
703             afm_error (AFMHandle handle, char *message)
704             {
705               fprintf (stderr, "AFM Error: %s\n", message);
706             }
707             
708             
709             /*
710              * Static functions.
711              */
712             
713             static void
714             read_font_map (AFMHandle handle, char *name)
715 rizwank 1.1 {
716               FILE *fp;
717               char buf[512];
718               char fullname[512];
719               unsigned int dirlen;
720               char *cp, *cp2;
721               char msg[256];
722             
723               sprintf (msg, "AFM: reading font map \"%s\"\n", name);
724               afm_message (handle, 1, msg);
725             
726               fp = fopen (name, "r");
727               if (fp == NULL)
728                 {
729                   sprintf (msg, "AFM: couldn't open font map \"%s\": %s\n", name,
730             	       strerror (errno));
731                   afm_message (handle, 1, msg);
732                   return;
733                 }
734             
735               /* Get directory */
736 rizwank 1.1   cp = strrchr (name, '/');
737               if (cp)
738                 {
739                   dirlen = cp - name + 1;
740                   memcpy (fullname, name, dirlen);
741                 }
742               else
743                 {
744                   dirlen = 2;
745                   memcpy (fullname, "./", dirlen);
746                 }
747             
748               while (fgets (buf, sizeof (buf), fp))
749                 {
750                   char font[256];
751                   char file[256];
752             
753                   if (sscanf (buf, "%s %s", font, file) != 2)
754             	{
755             	  sprintf (msg, "malformed line in font map \"%s\":\n%s",
756             		   name, buf);
757 rizwank 1.1 	  afm_error (handle, msg);
758             	  continue;
759             	}
760             
761                   /* Do we already have this font? */
762                   if (strhash_get (handle->font_map, font, strlen (font), (void *) &cp))
763             	continue;
764             
765                   /* Append file name. */
766                   strcpy (fullname + dirlen, file);
767                   cp = (char *) malloc (strlen (fullname) + 1);
768                   if (cp == NULL)
769             	{
770             	  afm_error (handle, "couldn't add font: out of memory");
771             	  goto out;
772             	}
773                   strcpy (cp, fullname);
774             
775                   sprintf (msg, "AFM: font mapping: %s -> %s\n", font, cp);
776                   afm_message (handle, 2, msg);
777                   (void) strhash_put (handle->font_map, font, strlen (font), cp,
778 rizwank 1.1 			  (void *) &cp2);
779                 }
780             
781              out:
782               fclose (fp);
783             }
784             
785             
786             static void
787             apply_encoding (AFMFont font, AFMEncodingTable *enc, unsigned int flags)
788             {
789               int i;
790               AFMIndividualCharacterMetrics *cm;
791               AFMComposite *comp;
792             
793               for (i = 0; enc[i].code >= 0; i++)
794                 {
795                   if (enc[i].character == AFM_ENC_NONE)
796             	font->encoding[enc[i].code] = AFM_ENC_NONE;
797                   else if (enc[i].character == AFM_ENC_NON_EXISTENT)
798             	font->encoding[enc[i].code] = AFM_ENC_NON_EXISTENT;
799 rizwank 1.1       else
800             	{
801             	  if (strhash_get (font->private->fontnames, enc[i].character,
802             			   strlen (enc[i].character), (void *) &cm))
803             	    font->encoding[enc[i].code] = cm;
804             	  else
805             	    {
806             	      /* Check composite characters. */
807             	      if ((flags & AFM_ENCODE_ACCEPT_COMPOSITES) == 0
808             		  || strhash_get (font->private->compositenames,
809             				  enc[i].character, strlen (enc[i].character),
810             				  (void *) &comp) == 0)
811             		font->encoding[enc[i].code] = AFM_ENC_NON_EXISTENT;
812             	      else
813             		{
814             		  /* Composite character found. */
815             		  if (strhash_get (font->private->fontnames,
816             				   comp->components[0].name,
817             				   strlen (comp->components[0].name),
818             				   (void *) &cm))
819             		    font->encoding[enc[i].code] = cm;
820 rizwank 1.1 		  else
821             		    font->encoding[enc[i].code] = AFM_ENC_NON_EXISTENT;
822             		}
823             	    }
824             	}
825                 }
826             }

Rizwan Kassim
Powered by
ViewCVS 0.9.2