diff options
Diffstat (limited to 'Build/source/texk/dvipng/dvipng-1.13/fontmap.c')
-rw-r--r-- | Build/source/texk/dvipng/dvipng-1.13/fontmap.c | 340 |
1 files changed, 340 insertions, 0 deletions
diff --git a/Build/source/texk/dvipng/dvipng-1.13/fontmap.c b/Build/source/texk/dvipng/dvipng-1.13/fontmap.c new file mode 100644 index 00000000000..c779d6674b4 --- /dev/null +++ b/Build/source/texk/dvipng/dvipng-1.13/fontmap.c @@ -0,0 +1,340 @@ +/* fontmap.c */ + +/************************************************************************ + + Part of the dvipng distribution + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. + + Copyright (C) 2002-2010 Jan-Åke Larsson + +************************************************************************/ + +#include "dvipng.h" + +static struct filemmap psfont_mmap; +#ifdef HAVE_FT2 +static struct filemmap ttfont_mmap; +#endif +static struct psfontmap *psfontmap=NULL; + +static char* newword(char** buffer, char* end) +{ + char *word,*pos=*buffer; + + while(pos<end && *pos!=' ' && *pos!='\t' && *pos!='"') pos++; + if ((word=malloc(pos-*buffer+1))==NULL) + Fatal("cannot malloc space for string"); + strncpy(word,*buffer,pos-*buffer); + word[pos-*buffer]='\0'; + *buffer=pos; + return(word); +} + +char* copyword(char* orig) +{ + char *word; + + if (orig==NULL) + return(NULL); + if ((word=malloc(strlen(orig)+1))==NULL) + Fatal("cannot malloc space for string"); + strcpy(word,orig); + return(word); +} + +static char* find_format(const char* name) +{ + /* Cater for both new (first case) and old (second case) kpathsea */ + char* format = + kpse_find_file(name,kpse_fontmap_format,false); + + if (format==NULL) + format = kpse_find_file(name,kpse_dvips_config_format,false); + return(format); +} + +void InitPSFontMap(void) +{ + char* psfont_name=NULL; + /* Prefer ps2pk.map, fonts are present more often */ + psfont_name=find_format("ps2pk.map"); + if (psfont_name==NULL) + psfont_name=find_format("psfonts.map"); + if (psfont_name==NULL) { + Warning("cannot find ps2pk.map, nor psfonts.map"); + } else { + DEBUG_PRINT((DEBUG_FT|DEBUG_T1), + ("\n OPEN PSFONT MAP:\t'%s'", psfont_name)); + if (MmapFile(psfont_name,&psfont_mmap)) { + Warning("psfonts map %s could not be opened", psfont_name); + } + free(psfont_name); + } +#ifdef HAVE_FT2 + psfont_name=find_format("ttfonts.map"); + if (psfont_name!=NULL) { + DEBUG_PRINT(DEBUG_FT,("\n OPEN TTFONT MAP:\t'%s'", psfont_name)); + if (MmapFile(psfont_name,&ttfont_mmap)) { + Warning("ttfonts map %s could not be opened", psfont_name); + } + free(psfont_name); + } +#endif +} + +struct psfontmap *NewPSFont(struct psfontmap* copyfrom) +{ + struct psfontmap *newentry=NULL; + if ((newentry=malloc(sizeof(struct psfontmap)))==NULL) + Fatal("cannot malloc psfontmap space"); + if (copyfrom!=NULL) { + newentry->line = copyfrom->line; + newentry->tfmname = copyword(copyfrom->tfmname); + newentry->psfile = copyword(copyfrom->psfile); + newentry->encname = copyword(copyfrom->encname); + newentry->encoding = copyfrom->encoding; +#ifdef HAVE_LIBT1 + newentry->t1_transformp = copyfrom->t1_transformp; +#endif +#ifdef HAVE_FT2 + newentry->ft_transformp = copyfrom->ft_transformp; + newentry->subfont = copyfrom->subfont; +#endif + newentry->end = copyfrom->end; + } else { + newentry->line = NULL; + newentry->tfmname = NULL; + newentry->psfile = NULL; + newentry->encname = NULL; + newentry->encoding = NULL; +#ifdef HAVE_LIBT1 + newentry->t1_transformp = NULL; +#endif +#ifdef HAVE_FT2 + newentry->ft_transformp = NULL; + newentry->subfont = NULL; +#endif + newentry->end = NULL; + } + newentry->next=psfontmap; + psfontmap=newentry; + return(newentry); +} + +static struct psfontmap *SearchPSFontMap(char* fontname, + struct filemmap* search_mmap) +{ + static char *pos=NULL,*end=NULL; + static struct filemmap* searching_mmap=NULL; + struct psfontmap *entry=NULL; + + if (pos==end && search_mmap!=searching_mmap) { + searching_mmap=search_mmap; + pos=searching_mmap->data; + end=searching_mmap->data+searching_mmap->size; + } + while(pos<end && (entry==NULL || strcmp(entry->tfmname,fontname)!=0)) { + while(pos < end + && (*pos=='\n' || *pos==' ' || *pos=='\t' + || *pos=='%' || *pos=='*' || *pos==';' || *pos=='#')) { + while(pos < end && *pos!='\n') pos++; /* skip comments/empty rows */ + pos++; + } + if (pos < end) { + entry=NewPSFont(NULL); + entry->line = pos; + /* skip <something and quoted entries */ + while(pos < end && (*pos=='<' || *pos=='"')) { + if (*pos=='<') + while(pos < end && *pos!=' ' && *pos!='\t') pos++; + else + while(pos < end && *pos!='"') pos++; + while(pos < end && (*pos==' ' || *pos=='\t')) pos++; + } + /* first word is font name */ + entry->tfmname = newword(&pos,end); + while(pos < end && *pos!='\n') pos++; + entry->end = pos; + } + pos++; + } + if (entry!=NULL && strcmp(entry->tfmname,fontname)!=0) + entry=NULL; + return(entry); +} + +void ClearPSFontMap(void) +{ + struct psfontmap *entry; + + while(psfontmap!=NULL) { + entry=psfontmap; + psfontmap=psfontmap->next; + free(entry->tfmname); + if (entry->psfile!=NULL) + free(entry->psfile); + if (entry->encname!=NULL) + free(entry->encname); + free(entry); + } + UnMmapFile(&psfont_mmap); +#ifdef HAVE_FT2 + UnMmapFile(&ttfont_mmap); +#endif +} + +static void ReadPSFontMap(struct psfontmap *entry) +{ + char *pos,*end,*psname; + int nameno = 0; + + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),("\n PSFONTMAP: %s ",entry->tfmname)); + pos=entry->line; + end=entry->end; + while(pos < end) { + if (*pos=='<') { /* filename follows */ + pos++; + if (pos<end && *pos=='<') { /* <<download.font */ + pos++; + entry->psfile = newword((char**)&pos,end); + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),("<%s ",entry->psfile)); + } else if (pos<end && *pos=='[') { /* <[encoding.file */ + pos++; + entry->encname = newword((char**)&pos,end); + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),("<[%s ",entry->encname)); + } else { /* <some.file */ + char* word =newword((char**)&pos,end); + if (strncmp(word+strlen(word)-4,".enc",4)==0) {/* <some.enc */ + entry->encname=word; + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),("<[%s ",entry->encname)); + } else { /* <font */ + entry->psfile=word; + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),("<%s ",entry->psfile)); + } + } + } else if (*pos=='"') { /* PS code: reencoding/tranformation exists */ + char *word; + double cxx=1.0,cxy=0.0; + pos++; + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),("\"")); + while(pos < end && *pos!='"') { + word=newword((char**)&pos,end); + while(pos < end && (*pos==' ' || *pos=='\t')) pos++; + if (pos+10<end && strncmp(pos,"ExtendFont",10)==0) { + cxx=strtod(word,NULL); + pos+=10; + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),("%f ExtendFont ",cxx)); + } else if (pos+9<end && strncmp(pos,"SlantFont",9)==0) { + pos+=9; + cxy=strtod(word,NULL); + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),("%f SlantFont ",cxy)); + } else if (pos+12<end && strncmp(pos,"ReEncodeFont",12)==0) { + pos+=12; + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),("%s ReEncodeFont ",word)); + } else { + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),("(?:%s) ",word)); + } + free(word); + } +#ifdef HAVE_FT2 + entry->ft_transformp=&(entry->ft_transform); + entry->ft_transform.xx=(FT_Fixed)(cxx*0x10000); + entry->ft_transform.xy=(FT_Fixed)(cxy*0x10000); + entry->ft_transform.yx=0; + entry->ft_transform.yy=0x10000; +#endif +#ifdef HAVE_LIBT1 + entry->t1_transformp=&(entry->t1_transform); + entry->t1_transform.cxx=cxx; + entry->t1_transform.cxy=cxy; + entry->t1_transform.cyx=0.0; + entry->t1_transform.cyy=1.0; +#endif + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),("\" ")); + pos++; + } else { /* bare word */ + switch (++nameno) { + case 1: /* first word is tfmname and perhaps psname, NOT psfile */ + while(pos<end && *pos!=' ' && *pos!='\t') pos++; + psname=entry->tfmname; + break; + case 2: /* second word is psname, NOT psfile */ + psname = newword((char**)&pos,end); + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),("(%s) ",psname)); + free(psname); + break; + case 3: /* third word is encoding */ + entry->encname = newword((char**)&pos,end); + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),("<[%s ",entry->encname)); + break; + default: + while(pos<end && *pos!=' ' && *pos!='\t') pos++; + Warning("more than three bare words in font map entry"); + } + } + while(pos < end && (*pos==' ' || *pos=='\t')) pos++; + } + if (entry->psfile==NULL) { + /* No psfile-name given, use tfmname */ + entry->psfile=copyword(entry->tfmname); + DEBUG_PRINT((DEBUG_FT|DEBUG_T1),(" <%s ",entry->psfile)); + } + if (entry->encname!=NULL + && (entry->encoding=FindEncoding(entry->encname))==NULL) + Warning("unable to load font encoding '%s' for %s", + entry->encname,entry->tfmname); +} + + +struct psfontmap* FindPSFontMap(char* fontname) +{ + struct psfontmap *entry; + static struct filemmap* search_mmap_p=&psfont_mmap; + + entry=psfontmap; + while(entry!=NULL && strcmp(entry->tfmname,fontname)!=0) + entry=entry->next; + if(entry==NULL) { + entry=SearchPSFontMap(fontname,search_mmap_p); +#ifdef HAVE_FT2 + if(entry==NULL && search_mmap_p!=&ttfont_mmap) { + search_mmap_p=&ttfont_mmap; + entry=SearchPSFontMap(fontname,search_mmap_p); + } + } + if(entry==NULL) { + struct psfontmap* entry_subfont=NULL; + entry=psfontmap; + while(entry!=NULL && strcmp(entry->tfmname,fontname)!=0) { + while(entry!=NULL && strchr(entry->tfmname,'@')==NULL) + entry=entry->next; + if (entry!=NULL) { + entry_subfont=FindSubFont(entry,fontname); + if (entry_subfont!=NULL) + entry=entry_subfont; + else + entry=entry->next; + } + } +#endif + } + if (entry!=NULL && entry->psfile==NULL) + ReadPSFontMap(entry); + if (entry!=NULL && entry->encname!=NULL && entry->encoding==NULL) + /* Encoding given but it cannot be found. Unusable font */ + return(NULL); + return(entry); +} |