Evince
Evince is a document viewer capable of displaying multiple and single page document formats like PDF and Postscript.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
fontmap.c File Reference
#include <config.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include "mdvi.h"
#include "private.h"
#include <kpathsea/expand.h>
#include <kpathsea/pathsearch.h>
+ Include dependency graph for fontmap.c:

Go to the source code of this file.

Data Structures

struct  _DviFontMap
 
struct  _PSFontMap
 

Macros

#define MAP_HASH_SIZE   57
 
#define ENC_HASH_SIZE   31
 
#define PSMAP_HASH_SIZE   57
 
#define ENCNAME_HASH_SIZE   131 /* most TeX fonts have 128 glyphs */
 
#define DROUND(x)   ((x) >= 0 ? floor((x) + 0.5) : ceil((x) - 0.5))
 
#define TRANSFORM(x, y)   DROUND(efactor * (x) + sfactor * (y))
 

Typedefs

typedef struct _DviFontMap DviFontMap
 
typedef struct _PSFontMap PSFontMap
 

Functions

static void ps_init_default_paths __PROTO ((void))
 
static int
mdvi_set_default_encoding 
__PROTO ((const char *name))
 
static int read_encoding (DviEncoding *enc)
 
static DviEncodingfind_encoding (const char *name)
 
static void destroy_encoding (DviEncoding *enc)
 
static void file_hash_free (DviHashKey key, void *data)
 
static DviEncodingregister_encoding (const char *basefile, int replace)
 
DviEncodingmdvi_request_encoding (const char *name)
 
void mdvi_release_encoding (DviEncoding *enc, int should_free)
 
int mdvi_encode_glyph (DviEncoding *enc, const char *name)
 
static void parse_spec (DviFontMapEnt *ent, char *spec)
 
DviFontMapEntmdvi_load_fontmap (const char *file)
 
static void free_ent (DviFontMapEnt *ent)
 
void mdvi_install_fontmap (DviFontMapEnt *head)
 
static void init_static_encoding ()
 
static int mdvi_set_default_encoding (const char *name)
 
static int mdvi_init_fontmaps (void)
 
int mdvi_query_fontmap (DviFontMapInfo *info, const char *fontname)
 
int mdvi_add_fontmap_file (const char *name, const char *fullpath)
 
void mdvi_flush_encodings (void)
 
void mdvi_flush_fontmaps (void)
 
void ps_init_default_paths (void)
 
int mdvi_ps_read_fontmap (const char *name)
 
void mdvi_ps_flush_fonts (void)
 
char * mdvi_ps_find_font (const char *psname)
 
TFMInfomdvi_ps_get_metrics (const char *fontname)
 

Variables

static char * pslibdir = NULL
 
static char * psfontdir = NULL
 
static int psinitialized = 0
 
static ListHead psfonts = MDVI_EMPTY_LIST_HEAD
 
static DviHashTable pstable = MDVI_EMPTY_HASH_TABLE
 
static ListHead fontmaps
 
static DviHashTable maptable
 
static int fontmaps_loaded = 0
 
static ListHead encodings = MDVI_EMPTY_LIST_HEAD
 
static DviEncodingtex_text_encoding = NULL
 
static DviEncodingdefault_encoding = NULL
 
static DviHashTable enctable = MDVI_EMPTY_HASH_TABLE
 
static DviHashTable enctable_file = MDVI_EMPTY_HASH_TABLE
 
static char * tex_text_vector [256]
 

Macro Definition Documentation

#define DROUND (   x)    ((x) >= 0 ? floor((x) + 0.5) : ceil((x) - 0.5))
#define ENC_HASH_SIZE   31

Definition at line 61 of file fontmap.c.

#define ENCNAME_HASH_SIZE   131 /* most TeX fonts have 128 glyphs */

Definition at line 66 of file fontmap.c.

#define MAP_HASH_SIZE   57

Definition at line 60 of file fontmap.c.

#define PSMAP_HASH_SIZE   57

Definition at line 62 of file fontmap.c.

#define TRANSFORM (   x,
 
)    DROUND(efactor * (x) + sfactor * (y))

Typedef Documentation

typedef struct _DviFontMap DviFontMap

Definition at line 33 of file fontmap.c.

typedef struct _PSFontMap PSFontMap

Function Documentation

static void ps_init_default_paths __PROTO ( (void)  )
static
static int mdvi_set_default_encoding __PROTO ( (const char *name )
static
static void destroy_encoding ( DviEncoding enc)
static

Definition at line 207 of file fontmap.c.

208 {
209  if(enc == default_encoding) {
211  /* now we use reference counts again */
212  mdvi_release_encoding(enc, 1);
213  }
214  if(enc != tex_text_encoding) {
215  mdvi_hash_reset(&enc->nametab, 0);
216  if(enc->private) {
217  mdvi_free(enc->private);
218  mdvi_free(enc->vector);
219  }
220  if(enc->name)
221  mdvi_free(enc->name);
222  if(enc->filename)
223  mdvi_free(enc->filename);
224  mdvi_free(enc);
225  }
226 }

+ Here is the caller graph for this function:

static void file_hash_free ( DviHashKey  key,
void *  data 
)
static

Definition at line 229 of file fontmap.c.

230 {
231  mdvi_free(key);
232 }

+ Here is the caller graph for this function:

static DviEncoding* find_encoding ( const char *  name)
static

Definition at line 201 of file fontmap.c.

202 {
203  return (DviEncoding *)(encodings.count ?
205 }

+ Here is the caller graph for this function:

static void free_ent ( DviFontMapEnt ent)
static

Definition at line 608 of file fontmap.c.

609 {
610  ASSERT(ent->fontname != NULL);
611  mdvi_free(ent->fontname);
612  if(ent->psname)
613  mdvi_free(ent->psname);
614  if(ent->fontfile)
615  mdvi_free(ent->fontfile);
616  if(ent->encoding)
617  mdvi_free(ent->encoding);
618  if(ent->encfile)
619  mdvi_free(ent->encfile);
620  if(ent->fullfile)
621  mdvi_free(ent->fullfile);
622  mdvi_free(ent);
623 }

+ Here is the caller graph for this function:

static void init_static_encoding ( )
static

Definition at line 648 of file fontmap.c.

649 {
650  DviEncoding *encoding;
651  int i;
652 
653  DEBUG((DBG_FMAP, "installing static TeX text encoding\n"));
654  encoding = xalloc(DviEncoding);
655  encoding->private = "";
656  encoding->filename = "";
657  encoding->name = "TeXTextEncoding";
658  encoding->vector = tex_text_vector;
659  encoding->links = 1;
660  encoding->offset = 0;
662  for(i = 0; i < 256; i++) {
663  if(encoding->vector[i]) {
664  mdvi_hash_add(&encoding->nametab,
665  MDVI_KEY(encoding->vector[i]),
666  (DviHashKey)Int2Ptr(i),
668  }
669  }
674  mdvi_hash_add(&enctable, MDVI_KEY(encoding->name),
675  encoding, MDVI_HASH_UNCHECKED);
676  listh_prepend(&encodings, LIST(encoding));
677  tex_text_encoding = encoding;
679 }

+ Here is the caller graph for this function:

int mdvi_add_fontmap_file ( const char *  name,
const char *  fullpath 
)

Definition at line 822 of file fontmap.c.

823 {
824  DviFontMapEnt *ent;
825 
826  if(!fontmaps_loaded && mdvi_init_fontmaps() < 0)
827  return -1;
829  if(ent == NULL)
830  return -1;
831  if(ent->fullfile)
832  mdvi_free(ent->fullfile);
833  ent->fullfile = mdvi_strdup(fullpath);
834  return 0;
835 }
int mdvi_encode_glyph ( DviEncoding enc,
const char *  name 
)

Definition at line 404 of file fontmap.c.

405 {
406  void *data;
407 
408  data = mdvi_hash_lookup(&enc->nametab, MDVI_KEY(name));
409  if(data == NULL)
410  return -1;
411  /* we added +1 to the hashed index just to distinguish
412  * a failed lookup from a zero index. Adjust it now. */
413  return (Ptr2Int(data) - 1);
414 }
void mdvi_flush_encodings ( void  )

Definition at line 838 of file fontmap.c.

839 {
840  DviEncoding *enc;
841 
842  if(enctable.nbucks == 0)
843  return;
844 
845  DEBUG((DBG_FMAP, "flushing %d encodings\n", encodings.count));
846  /* asked to remove all encodings */
847  for(; (enc = (DviEncoding *)encodings.head); ) {
848  encodings.head = LIST(enc->next);
849  if((enc != tex_text_encoding && enc->links) || enc->links > 1) {
850  mdvi_warning(_("encoding vector `%s' is in use\n"),
851  enc->name);
852  }
853  destroy_encoding(enc);
854  }
855  /* destroy the static encoding */
860 }
void mdvi_flush_fontmaps ( void  )

Definition at line 862 of file fontmap.c.

863 {
864  DviFontMapEnt *ent;
865 
866  if(!fontmaps_loaded)
867  return;
868 
869  DEBUG((DBG_FMAP, "flushing %d fontmaps\n", fontmaps.count));
870  for(; (ent = (DviFontMapEnt *)fontmaps.head); ) {
871  fontmaps.head = LIST(ent->next);
872  free_ent(ent);
873  }
875  fontmaps_loaded = 0;
876 }
static int mdvi_init_fontmaps ( void  )
static

Definition at line 702 of file fontmap.c.

703 {
704  char *file;
705  char *line;
706  FILE *in;
707  Dstring input;
708  int count = 0;
709  char *config;
710 
711  if(fontmaps_loaded)
712  return 0;
713  /* we will only try this once */
714  fontmaps_loaded = 1;
715 
716  DEBUG((DBG_FMAP, "reading fontmaps\n"));
717 
718  /* make sure the static encoding is there */
720 
721  /* create the fontmap hash table */
723 
724  /* get the name of our configuration file */
725  config = kpse_cnf_get("mdvi-config");
726  if(config == NULL)
727  config = MDVI_DEFAULT_CONFIG;
728  /* let's ask kpathsea for the file first */
729  file = kpse_find_file(config, kpse_program_text_format, 0);
730  if(file == NULL)
731  in = fopen(config, "rb");
732  else {
733  in = fopen(file, "rb");
734  mdvi_free(file);
735  }
736  if(in == NULL)
737  return -1;
738  dstring_init(&input);
739  while((line = dgets(&input, in)) != NULL) {
740  char *arg, *map_file;
741 
742  SKIPSP(line);
743  if(*line < ' ' || *line == '#' || *line == '%')
744  continue;
745  if(STRNEQ(line, "fontmap", 7)) {
746  DviFontMapEnt *ent;
747 
748  arg = getstring(line + 7, " \t", &line); *line = 0;
749  DEBUG((DBG_FMAP, "%s: loading fontmap\n", arg));
750  ent = mdvi_load_fontmap(arg);
751  if(ent == NULL) {
752  map_file = kpse_find_file(arg, kpse_fontmap_format, 0);
753  if (map_file)
754  ent = mdvi_load_fontmap(map_file);
755  }
756  if(ent == NULL)
757  mdvi_warning(_("%s: could not load fontmap\n"), arg);
758  else {
759  DEBUG((DBG_FMAP,
760  "%s: installing fontmap\n", arg));
762  count++;
763  }
764  } else if(STRNEQ(line, "encoding", 8)) {
765  arg = getstring(line + 8, " \t", &line); *line = 0;
766  if(arg && *arg)
767  register_encoding(arg, 1);
768  } else if(STRNEQ(line, "default-encoding", 16)) {
769  arg = getstring(line + 16, " \t", &line); *line = 0;
770  if(mdvi_set_default_encoding(arg) < 0)
771  mdvi_warning(_("%s: could not set as default encoding\n"),
772  arg);
773  } else if(STRNEQ(line, "psfontpath", 10)) {
774  arg = getstring(line + 11, " \t", &line); *line = 0;
775  if(!psinitialized)
777  if(psfontdir)
779  psfontdir = kpse_path_expand(arg);
780  } else if(STRNEQ(line, "pslibpath", 9)) {
781  arg = getstring(line + 10, " \t", &line); *line = 0;
782  if(!psinitialized)
784  if(pslibdir)
786  pslibdir = kpse_path_expand(arg);
787  } else if(STRNEQ(line, "psfontmap", 9)) {
788  arg = getstring(line + 9, " \t", &line); *line = 0;
789  if(mdvi_ps_read_fontmap(arg) < 0)
790  mdvi_warning("%s: %s: could not read PS fontmap\n",
791  config, arg);
792  }
793  }
794  fclose(in);
795  dstring_reset(&input);
796  fontmaps_loaded = 1;
797  DEBUG((DBG_FMAP, "%d files installed, %d fontmaps\n",
798  count, fontmaps.count));
799  return count;
800 }

+ Here is the caller graph for this function:

void mdvi_install_fontmap ( DviFontMapEnt head)

Definition at line 625 of file fontmap.c.

626 {
627  DviFontMapEnt *ent, *next;
628 
629  for(ent = head; ent; ent = next) {
630  /* add all the entries, overriding old ones */
631  DviFontMapEnt *old;
632 
633  old = (DviFontMapEnt *)
635  if(old != NULL) {
636  DEBUG((DBG_FMAP, "%s: overriding fontmap entry\n",
637  old->fontname));
638  listh_remove(&fontmaps, LIST(old));
639  free_ent(old);
640  }
641  next = ent->next;
643  ent, MDVI_HASH_UNCHECKED);
644  listh_append(&fontmaps, LIST(ent));
645  }
646 }

+ Here is the caller graph for this function:

DviFontMapEnt* mdvi_load_fontmap ( const char *  file)

Definition at line 464 of file fontmap.c.

465 {
466  char *ptr;
467  FILE *in;
468  int lineno = 1;
469  Dstring input;
470  ListHead list;
471  DviFontMapEnt *ent;
472  DviEncoding *last_encoding;
473  char *last_encfile;
474 
475  ptr = kpse_find_file(file, kpse_program_text_format, 0);
476  if(ptr == NULL)
477  ptr = kpse_find_file(file, kpse_tex_ps_header_format, 0);
478  if(ptr == NULL)
479  ptr = kpse_find_file(file, kpse_dvips_config_format, 0);
480  if(ptr == NULL)
481  in = fopen(file, "rb");
482  else {
483  in = fopen(ptr, "rb");
484  mdvi_free(ptr);
485  }
486  if(in == NULL)
487  return NULL;
488 
489  ent = NULL;
490  listh_init(&list);
491  dstring_init(&input);
492  last_encoding = NULL;
493  last_encfile = NULL;
494 
495  while((ptr = dgets(&input, in)) != NULL) {
496  char *font_file;
497  char *tex_name;
498  char *ps_name;
499  char *vec_name;
500  int is_encoding;
501  DviEncoding *enc;
502 
503  lineno++;
504  SKIPSP(ptr);
505 
506  /* we skip what dvips does */
507  if(*ptr <= ' ' || *ptr == '*' || *ptr == '#' ||
508  *ptr == ';' || *ptr == '%')
509  continue;
510 
511  font_file = NULL;
512  tex_name = NULL;
513  ps_name = NULL;
514  vec_name = NULL;
515  is_encoding = 0;
516 
517  if(ent == NULL) {
518  ent = xalloc(DviFontMapEnt);
519  ent->encoding = NULL;
520  ent->slant = 0;
521  ent->extend = 0;
522  }
523  while(*ptr) {
524  char *hdr_name = NULL;
525 
526  while(*ptr && *ptr <= ' ')
527  ptr++;
528  if(*ptr == 0)
529  break;
530  if(*ptr == '"') {
531  char *str;
532 
533  str = getstring(ptr, " \t", &ptr);
534  if(*ptr) *ptr++ = 0;
535  parse_spec(ent, str);
536  continue;
537  } else if(*ptr == '<') {
538  ptr++;
539  if(*ptr == '<')
540  ptr++;
541  else if(*ptr == '[') {
542  is_encoding = 1;
543  ptr++;
544  }
545  SKIPSP(ptr);
546  hdr_name = ptr;
547  } else if(!tex_name)
548  tex_name = ptr;
549  else if(!ps_name)
550  ps_name = ptr;
551  else
552  hdr_name = ptr;
553 
554  /* get next word */
555  getword(ptr, " \t", &ptr);
556  if(*ptr) *ptr++ = 0;
557 
558  if(hdr_name) {
559  const char *ext = file_extension(hdr_name);
560 
561  if(is_encoding || (ext && STRCEQ(ext, "enc")))
562  vec_name = hdr_name;
563  else
564  font_file = hdr_name;
565  }
566  }
567 
568  if(tex_name == NULL)
569  continue;
570  ent->fontname = mdvi_strdup(tex_name);
571  ent->psname = ps_name ? mdvi_strdup(ps_name) : NULL;
572  ent->fontfile = font_file ? mdvi_strdup(font_file) : NULL;
573  ent->encfile = vec_name ? mdvi_strdup(vec_name) : NULL;
574  ent->fullfile = NULL;
575  enc = NULL; /* we don't have this yet */
576 
577  /* if we have an encoding file, register it */
578  if(ent->encfile) {
579  /* register_encoding is smart enough not to load the
580  * same file twice */
581  if(!last_encfile || !STREQ(last_encfile, ent->encfile)) {
582  last_encfile = ent->encfile;
583  last_encoding = register_encoding(ent->encfile, 1);
584  }
585  enc = last_encoding;
586  }
587  if(ent->encfile && enc){
588  if(ent->encoding && !STREQ(ent->encoding, enc->name)) {
589  mdvi_warning(
590  _("%s: %d: [%s] requested encoding `%s' does not match vector `%s'\n"),
591  file, lineno, ent->encfile,
592  ent->encoding, enc->name);
593  } else if(!ent->encoding)
594  ent->encoding = mdvi_strdup(enc->name);
595  }
596 
597  /* add it to the list */
598  /*print_ent(ent);*/
599  listh_append(&list, LIST(ent));
600  ent = NULL;
601  }
602  dstring_reset(&input);
603  fclose(in);
604 
605  return (DviFontMapEnt *)list.head;
606 }

+ Here is the caller graph for this function:

char* mdvi_ps_find_font ( const char *  psname)

Definition at line 1022 of file fontmap.c.

1023 {
1024  PSFontMap *map, *smap;
1025  char *filename;
1026  int recursion_limit = 32;
1027 
1028  DEBUG((DBG_FMAP, "(ps) resolving PS font `%s'\n", psname));
1029  if(!psinitialized)
1030  return NULL;
1031  map = (PSFontMap *)mdvi_hash_lookup(&pstable, MDVI_KEY(psname));
1032  if(map == NULL)
1033  return NULL;
1034  if(map->fullname)
1035  return mdvi_strdup(map->fullname);
1036 
1037  /* is it an alias? */
1038  smap = map;
1039  while(recursion_limit-- > 0 && smap && *smap->mapname == '/')
1040  smap = (PSFontMap *)mdvi_hash_lookup(&pstable,
1041  MDVI_KEY(smap->mapname + 1));
1042  if(smap == NULL) {
1043  if(recursion_limit == 0)
1044  DEBUG((DBG_FMAP,
1045  "(ps) %s: possible loop in PS font map\n",
1046  psname));
1047  return NULL;
1048  }
1049 
1050  if(psfontdir)
1051  filename = kpse_path_search(psfontdir, smap->mapname, 1);
1052  else if(file_exists(map->mapname))
1053  filename = mdvi_strdup(map->mapname);
1054  else
1055  filename = NULL;
1056  if(filename)
1057  map->fullname = mdvi_strdup(filename);
1058 
1059  return filename;
1060 }

+ Here is the caller graph for this function:

void mdvi_ps_flush_fonts ( void  )

Definition at line 993 of file fontmap.c.

994 {
995  PSFontMap *map;
996 
997  if(!psinitialized)
998  return;
999  DEBUG((DBG_FMAP, "(ps) flushing PS font map (%d) entries\n",
1000  psfonts.count));
1001  mdvi_hash_reset(&pstable, 0);
1002  for(; (map = (PSFontMap *)psfonts.head); ) {
1003  psfonts.head = LIST(map->next);
1004  mdvi_free(map->psname);
1005  mdvi_free(map->mapname);
1006  if(map->fullname)
1007  mdvi_free(map->fullname);
1008  mdvi_free(map);
1009  }
1010  listh_init(&psfonts);
1011  if(pslibdir) {
1013  pslibdir = NULL;
1014  }
1015  if(psfontdir) {
1017  psfontdir = NULL;
1018  }
1019  psinitialized = 0;
1020 }
TFMInfo* mdvi_ps_get_metrics ( const char *  fontname)

Definition at line 1082 of file fontmap.c.

1083 {
1084  TFMInfo *info;
1085  DviFontMapInfo map;
1086  char buffer[64]; /* to avoid mallocs */
1087  char *psfont;
1088  char *basefile;
1089  char *afmfile;
1090  char *ext;
1091  int baselen;
1092  int nc;
1093  TFMChar *ch;
1094  double efactor;
1095  double sfactor;
1096 
1097  DEBUG((DBG_FMAP, "(ps) %s: looking for metric data\n", fontname));
1098  info = get_font_metrics(fontname, DviFontAny, NULL);
1099  if(info != NULL)
1100  return info;
1101 
1102  /* query the fontmap */
1103  if(mdvi_query_fontmap(&map, fontname) < 0 || !map.psname)
1104  return NULL;
1105 
1106  /* get the PS font */
1107  psfont = mdvi_ps_find_font(map.psname);
1108  if(psfont == NULL)
1109  return NULL;
1110  DEBUG((DBG_FMAP, "(ps) %s: found as PS font `%s'\n",
1111  fontname, psfont));
1112  /* replace its extension */
1113  basefile = strrchr(psfont, '/');
1114  if(basefile == NULL)
1115  basefile = psfont;
1116  baselen = strlen(basefile);
1117  ext = strrchr(basefile, '.');
1118  if(ext != NULL)
1119  *ext = 0;
1120  if(baselen + 4 < 64)
1121  afmfile = &buffer[0];
1122  else
1123  afmfile = mdvi_malloc(baselen + 5);
1124  strcpy(afmfile, basefile);
1125  strcpy(afmfile + baselen, ".afm");
1126  /* we don't need this anymore */
1127  mdvi_free(psfont);
1128  DEBUG((DBG_FMAP, "(ps) %s: looking for `%s'\n",
1129  fontname, afmfile));
1130  /* lookup the file */
1131  psfont = kpse_path_search(psfontdir, afmfile, 1);
1132  /* don't need this anymore */
1133  if(afmfile != &buffer[0])
1134  mdvi_free(afmfile);
1135  if(psfont != NULL) {
1136  info = get_font_metrics(fontname, DviFontAFM, psfont);
1137  mdvi_free(psfont);
1138  } else
1139  info = NULL;
1140  if(info == NULL || (!map.extend && !map.slant))
1141  return info;
1142 
1143  /*
1144  * transform the data as prescribed -- keep in mind that `info'
1145  * points to CACHED data, so we're modifying the metric cache
1146  * in place.
1147  */
1148 
1149 #define DROUND(x) ((x) >= 0 ? floor((x) + 0.5) : ceil((x) - 0.5))
1150 #define TRANSFORM(x,y) DROUND(efactor * (x) + sfactor * (y))
1151 
1152  efactor = (double)map.extend / 10000.0;
1153  sfactor = (double)map.slant / 10000.0;
1154  DEBUG((DBG_FMAP, "(ps) %s: applying extend=%f, slant=%f\n",
1155  efactor, sfactor));
1156 
1157  nc = info->hic - info->loc + 1;
1158  for(ch = info->chars; ch < info->chars + nc; ch++) {
1159  /* the AFM bounding box is:
1160  * wx = ch->advance
1161  * llx = ch->left
1162  * lly = -ch->depth
1163  * urx = ch->right
1164  * ury = ch->height
1165  * what we do here is transform wx, llx, and urx by
1166  * newX = efactor * oldX + sfactor * oldY
1167  * where for `wx' oldY = 0. Also, these numbers are all in
1168  * TFM units (i.e. TFM's fix-words, which is just the actual
1169  * number times 2^20, no need to do anything to it).
1170  */
1171  if(ch->present) {
1172  ch->advance = TRANSFORM(ch->advance, 0);
1173  ch->left = TRANSFORM(ch->left, -ch->depth);
1174  ch->right = TRANSFORM(ch->right, ch->height);
1175  }
1176  }
1177 
1178  return info;
1179 }
int mdvi_ps_read_fontmap ( const char *  name)

Definition at line 900 of file fontmap.c.

901 {
902  char *fullname;
903  FILE *in;
904  Dstring dstr;
905  char *line;
906  int count = 0;
907 
908  if(!psinitialized)
910  if(pslibdir)
911  fullname = kpse_path_search(pslibdir, name, 1);
912  else
913  fullname = (char *)name;
914  in = fopen(fullname, "rb");
915  if(in == NULL) {
916  if(fullname != name)
917  mdvi_free(fullname);
918  return -1;
919  }
920  dstring_init(&dstr);
921 
922  while((line = dgets(&dstr, in)) != NULL) {
923  char *name;
924  char *mapname;
925  const char *ext;
926  PSFontMap *ps;
927 
928  SKIPSP(line);
929  /* we're looking for lines of the form
930  * /FONT-NAME (fontfile)
931  * /FONT-NAME /FONT-ALIAS
932  */
933  if(*line != '/')
934  continue;
935  name = getword(line + 1, " \t", &line);
936  if(*line) *line++ = 0;
937  mapname = getword(line, " \t", &line);
938  if(*line) *line++ = 0;
939 
940  if(!name || !mapname || !*name)
941  continue;
942  if(*mapname == '(') {
943  char *end;
944 
945  mapname++;
946  for(end = mapname; *end && *end != ')'; end++);
947  *end = 0;
948  }
949  if(!*mapname)
950  continue;
951  /* dont add `.gsf' fonts, which require a full blown
952  * PostScript interpreter */
953  ext = file_extension(mapname);
954  if(ext && STREQ(ext, "gsf")) {
955  DEBUG((DBG_FMAP, "(ps) %s: font `%s' ignored\n",
956  name, mapname));
957  continue;
958  }
959  ps = (PSFontMap *)mdvi_hash_lookup(&pstable, MDVI_KEY(name));
960  if(ps != NULL) {
961  if(STREQ(ps->mapname, mapname))
962  continue;
963  DEBUG((DBG_FMAP,
964  "(ps) replacing font `%s' (%s) by `%s'\n",
965  name, ps->mapname, mapname));
966  mdvi_free(ps->mapname);
967  ps->mapname = mdvi_strdup(mapname);
968  if(ps->fullname) {
969  mdvi_free(ps->fullname);
970  ps->fullname = NULL;
971  }
972  } else {
973  DEBUG((DBG_FMAP, "(ps) adding font `%s' as `%s'\n",
974  name, mapname));
975  ps = xalloc(PSFontMap);
976  ps->psname = mdvi_strdup(name);
977  ps->mapname = mdvi_strdup(mapname);
978  ps->fullname = NULL;
979  listh_append(&psfonts, LIST(ps));
981  ps, MDVI_HASH_UNCHECKED);
982  count++;
983  }
984  }
985  fclose(in);
986  dstring_reset(&dstr);
987 
988  DEBUG((DBG_FMAP, "(ps) %s: %d PostScript fonts registered\n",
989  fullname, count));
990  return 0;
991 }

+ Here is the caller graph for this function:

int mdvi_query_fontmap ( DviFontMapInfo info,
const char *  fontname 
)

Definition at line 802 of file fontmap.c.

803 {
804  DviFontMapEnt *ent;
805 
806  if(!fontmaps_loaded && mdvi_init_fontmaps() < 0)
807  return -1;
808  ent = (DviFontMapEnt *)mdvi_hash_lookup(&maptable, MDVI_KEY(fontname));
809 
810  if(ent == NULL)
811  return -1;
812  info->psname = ent->psname;
813  info->encoding = ent->encoding;
814  info->fontfile = ent->fontfile;
815  info->extend = ent->extend;
816  info->slant = ent->slant;
817  info->fullfile = ent->fullfile;
818 
819  return 0;
820 }

+ Here is the caller graph for this function:

void mdvi_release_encoding ( DviEncoding enc,
int  should_free 
)

Definition at line 393 of file fontmap.c.

394 {
395  /* ignore our static encoding */
396  if(enc == tex_text_encoding)
397  return;
398  if(!enc->links || --enc->links > 0 || !should_free)
399  return;
400  DEBUG((DBG_FMAP, "%s: resetting encoding vector\n", enc->name));
401  mdvi_hash_reset(&enc->nametab, 1); /* we'll reuse it */
402 }

+ Here is the caller graph for this function:

DviEncoding* mdvi_request_encoding ( const char *  name)

Definition at line 360 of file fontmap.c.

361 {
363 
364  if(enc == NULL) {
365  DEBUG((DBG_FMAP, "%s: encoding not found, returning default `%s'\n",
367  return default_encoding;
368  }
369  /* we don't keep reference counts for this */
370  if(enc == tex_text_encoding)
371  return enc;
372  if(!enc->private && read_encoding(enc) < 0)
373  return NULL;
374  enc->links++;
375 
376  /* if the hash table is empty, rebuild it */
377  if(enc->nametab.nkeys == 0) {
378  int i;
379 
380  DEBUG((DBG_FMAP, "%s: rehashing\n", enc->name));
381  for(i = 0; i < 256; i++) {
382  if(enc->vector[i] == NULL)
383  continue;
384  mdvi_hash_add(&enc->nametab,
385  MDVI_KEY(enc->vector[i]),
386  (DviHashKey)Int2Ptr(i),
388  }
389  }
390  return enc;
391 }

+ Here is the caller graph for this function:

static int mdvi_set_default_encoding ( const char *  name)
static

Definition at line 681 of file fontmap.c.

682 {
683  DviEncoding *enc, *old;
684 
685  enc = find_encoding(name);
686  if(enc == NULL)
687  return -1;
688  if(enc == default_encoding)
689  return 0;
690  /* this will read it from file if necessary,
691  * but it can fail if the file is corrupted */
693  if(enc == NULL)
694  return -1;
695  old = default_encoding;
696  default_encoding = enc;
697  if(old != tex_text_encoding)
698  mdvi_release_encoding(old, 1);
699  return 0;
700 }

+ Here is the caller graph for this function:

static void parse_spec ( DviFontMapEnt ent,
char *  spec 
)
static

Definition at line 420 of file fontmap.c.

421 {
422  char *arg, *command;
423 
424  /* this is a ridiculously simple parser, and recognizes only
425  * things of the form <argument> <command>. Of these, only
426  * command=SlantFont, ExtendFont and ReEncodeFont are handled */
427  while(*spec) {
428  arg = getword(spec, " \t", &spec);
429  if(*spec) *spec++ = 0;
430  command = getword(spec, " \t", &spec);
431  if(*spec) *spec++ = 0;
432  if(!arg || !command)
433  continue;
434  if(STREQ(command, "SlantFont")) {
435  double x = 10000 * strtod(arg, 0);
436 
437  /* SFROUND evaluates arguments twice */
438  ent->slant = SFROUND(x);
439  } else if(STREQ(command, "ExtendFont")) {
440  double x = 10000 * strtod(arg, 0);
441 
442  ent->extend = SFROUND(x);
443  } else if(STREQ(command, "ReEncodeFont")) {
444  if(ent->encoding)
445  mdvi_free(ent->encoding);
446  ent->encoding = mdvi_strdup(arg);
447  }
448  }
449 }

+ Here is the caller graph for this function:

void ps_init_default_paths ( void  )

Definition at line 880 of file fontmap.c.

881 {
882  char *kppath;
883  char *kfpath;
884 
885  ASSERT(psinitialized == 0);
886 
887  kppath = getenv("GS_LIB");
888  kfpath = getenv("GS_FONTPATH");
889 
890  if(kppath != NULL)
891  pslibdir = kpse_path_expand(kppath);
892  if(kfpath != NULL)
893  psfontdir = kpse_path_expand(kfpath);
894 
897  psinitialized = 1;
898 }

+ Here is the caller graph for this function:

static int read_encoding ( DviEncoding enc)
static

Definition at line 111 of file fontmap.c.

112 {
113  FILE *in;
114  int curr;
115  char *line;
116  char *name;
117  char *next;
118  struct stat st;
119 
120  ASSERT(enc->private == NULL);
121 
122  in = fopen(enc->filename, "rb");
123  if(in == NULL) {
124  DEBUG((DBG_FMAP, "%s: could not read `%s' (%s)\n",
125  enc->name, enc->filename, strerror(errno)));
126  return -1;
127  }
128  if(fstat(fileno(in), &st) < 0) {
129  /* should not happen */
130  fclose(in);
131  return -1;
132  }
133  st.st_size -= enc->offset;
134 
135  /* this will be one big string */
136  enc->private = (char *)malloc(st.st_size + 1);
137  /* setup the hash table */
139  /* setup the encoding vector */
140  enc->vector = (char **)mdvi_malloc(256 * sizeof(char *));
141 
142  /* jump to the beginning of the interesting part */
143  fseek(in, enc->offset, SEEK_SET);
144  /* and read everything */
145  if(fread(enc->private, st.st_size, 1, in) != 1) {
146  fclose(in);
147  mdvi_free(enc->private);
148  enc->private = NULL;
149  return -1;
150  }
151  /* we don't need this anymore */
152  fclose(in);
153  curr = 0;
154 
155  next = name = NULL;
156  DEBUG((DBG_FMAP, "%s: reading encoding vector\n", enc->name));
157  for(line = enc->private; *line && curr < 256; line = next) {
158  SKIPSP(line);
159  if(*line == ']') {
160  line++; SKIPSP(line);
161  if(STRNEQ(line, "def", 3))
162  break;
163  }
164  name = getword(line, " \t\n", &next);
165  if(name == NULL)
166  break;
167  /* next > line */
168  if(*name < ' ')
169  continue;
170  if(*name == '%') {
171  while(*next && *next != '\n')
172  next++;
173  if(*next) next++; /* skip \n */
174  continue;
175  }
176 
177  /* got a name */
178  if(*next) *next++ = 0;
179 
180  if(*name == '/')
181  name++;
182  enc->vector[curr] = name;
183  /* add it to the hash table */
184  if(!STREQ(name, ".notdef")) {
185  mdvi_hash_add(&enc->nametab, MDVI_KEY(name),
186  Int2Ptr(curr + 1), MDVI_HASH_REPLACE);
187  }
188  curr++;
189  }
190  if(curr == 0) {
191  mdvi_hash_reset(&enc->nametab, 0);
192  mdvi_free(enc->private);
193  mdvi_free(enc);
194  return -1;
195  }
196  while(curr < 256)
197  enc->vector[curr++] = NULL;
198  return 0;
199 }

+ Here is the caller graph for this function:

static DviEncoding* register_encoding ( const char *  basefile,
int  replace 
)
static

Definition at line 234 of file fontmap.c.

235 {
236  DviEncoding *enc;
237  FILE *in;
238  char *filename;
239  char *name;
240  Dstring input;
241  char *line;
242  long offset;
243 
244  DEBUG((DBG_FMAP, "register_encoding(%s)\n", basefile));
245 
246  if(encodings.count) {
247  enc = mdvi_hash_lookup(&enctable_file, MDVI_KEY(basefile));
248  if(enc != NULL) {
249  DEBUG((DBG_FMAP, "%s: already there\n", basefile));
250  return enc; /* no error */
251  }
252  }
253 
254  /* try our own files first */
255  filename = kpse_find_file(basefile,
256  kpse_program_text_format, 0);
257 
258  /* then try the system-wide ones */
259  if(filename == NULL)
260  filename = kpse_find_file(basefile,
261  kpse_tex_ps_header_format, 0);
262  if(filename == NULL)
263  filename = kpse_find_file(basefile,
264  kpse_dvips_config_format, 0);
265 
266  /* finally try the given name */
267  if(filename == NULL)
268  filename = mdvi_strdup(basefile);
269 
270  in = fopen(filename, "rb");
271  if(in == NULL) {
272  mdvi_free(filename);
273  return NULL;
274  }
275 
276  /* just lookup the name of the encoding */
277  name = NULL;
278  dstring_init(&input);
279  while((line = dgets(&input, in)) != NULL) {
280  if(STRNEQ(line, "Encoding=", 9)) {
281  name = getword(line + 9, " \t", &line);
282  if(*line) *line++ = 0;
283  break;
284  } else if(*line == '/') {
285  char *label = getword(line + 1, " \t", &line);
286  if(*line) {
287  *line++ = 0;
288  SKIPSP(line);
289  if(*line == '[') {
290  *line = 0;
291  name = label;
292  break;
293  }
294  }
295  }
296  }
297  offset = ftell(in);
298  fclose(in);
299  if(name == NULL || *name == 0) {
300  DEBUG((DBG_FMAP,
301  "%s: could not determine name of encoding\n",
302  basefile));
303  mdvi_free(filename);
304  return NULL;
305  }
306 
307  /* check if the encoding is already there */
308  enc = find_encoding(name);
309  if(enc == tex_text_encoding) {
310  /* A special case: if the vector we found is the static one,
311  * allow the user to override it with an external file */
312  listh_remove(&encodings, LIST(enc));
314  if(enc == default_encoding)
315  default_encoding = NULL;
316  } else if(enc) {
317  /* if the encoding is being used, refuse to remove it */
318  if(enc->links) {
319  mdvi_free(filename);
320  dstring_reset(&input);
321  return NULL;
322  }
323  if(replace) {
326  listh_remove(&encodings, LIST(enc));
327  if(enc == default_encoding) {
328  default_encoding = NULL;
329  mdvi_release_encoding(enc, 1);
330  }
331  DEBUG((DBG_FMAP, "%s: overriding encoding\n", name));
332  destroy_encoding(enc);
333  } else {
334  mdvi_free(filename);
335  dstring_reset(&input);
336  return enc; /* no error */
337  }
338  }
339  enc = xalloc(DviEncoding);
340  enc->name = mdvi_strdup(name);
341  enc->filename = filename;
342  enc->links = 0;
343  enc->offset = offset;
344  enc->private = NULL;
345  enc->vector = NULL;
346  mdvi_hash_init(&enc->nametab);
347  dstring_reset(&input);
348  if(default_encoding == NULL)
349  default_encoding = enc;
351  enc, MDVI_HASH_UNCHECKED);
353  enc, MDVI_HASH_REPLACE);
354  listh_prepend(&encodings, LIST(enc));
355  DEBUG((DBG_FMAP, "%s: encoding `%s' registered\n",
356  basefile, enc->name));
357  return enc;
358 }

+ Here is the caller graph for this function:

Variable Documentation

DviEncoding* default_encoding = NULL
static

Definition at line 70 of file fontmap.c.

ListHead encodings = MDVI_EMPTY_LIST_HEAD
static

Definition at line 68 of file fontmap.c.

Definition at line 74 of file fontmap.c.

DviHashTable enctable_file = MDVI_EMPTY_HASH_TABLE
static

Definition at line 75 of file fontmap.c.

ListHead fontmaps
static

Definition at line 56 of file fontmap.c.

int fontmaps_loaded = 0
static

Definition at line 58 of file fontmap.c.

DviHashTable maptable
static

Definition at line 57 of file fontmap.c.

char* psfontdir = NULL
static

Definition at line 50 of file fontmap.c.

ListHead psfonts = MDVI_EMPTY_LIST_HEAD
static

Definition at line 53 of file fontmap.c.

int psinitialized = 0
static

Definition at line 51 of file fontmap.c.

char* pslibdir = NULL
static

Definition at line 49 of file fontmap.c.

Definition at line 54 of file fontmap.c.

DviEncoding* tex_text_encoding = NULL
static

Definition at line 69 of file fontmap.c.

char* tex_text_vector[256]
static
Initial value:
= {
"Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi", "Sigma", "Upsilon",
"Phi", "Psi", "Omega", "arrowup", "arrowdown", "quotesingle",
"exclamdown", "questiondown", "dotlessi", "dotlessj", "grave",
"acute", "caron", "breve", "macron", "ring", "cedilla",
"germandbls", "ae", "oe", "oslash", "AE", "OE", "Oslash", "space",
"exclam", "quotedbl", "numbersign", "dollar", "percent",
"ampersand", "quoteright", "parenleft", "parenright", "asterisk",
"plus", "comma", "hyphen", "period", "slash", "zero", "one", "two",
"three", "four", "five", "six", "seven", "eight", "nine", "colon",
"semicolon", "less", "equal", "greater", "question", "at", "A", "B",
"C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
"P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"bracketleft", "backslash", "bracketright", "circumflex",
"underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h",
"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u",
"v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "tilde",
"dieresis", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}

Definition at line 78 of file fontmap.c.