/* 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 . Copyright (C) 2002-2015 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(posline = copyfrom->line; newentry->tfmname = copyword(copyfrom->tfmname); newentry->psfile = copyword(copyfrom->psfile); newentry->encname = copyword(copyfrom->encname); newentry->encoding = copyfrom->encoding; #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_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(postfmname,fontname)!=0)) { while(pos < end && (*pos=='\r' || *pos=='\n' || *pos==' ' || *pos=='\t' || *pos=='%' || *pos=='*' || *pos==';' || *pos=='#')) { while(pos < end && *pos!='\r' && *pos!='\n') pos++; /* skip comments/empty rows */ pos++; } if (pos < end) { entry=NewPSFont(NULL); entry->line = pos; /* skip tfmname = newword(&pos,end); while(pos < end && *pos!='\r' && *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,("\n PSFONTMAP: %s ",entry->tfmname)); pos=entry->line; end=entry->end; while(pos < end) { if (*pos=='<') { /* filename follows */ pos++; if (pospsfile = newword((char**)&pos,end); DEBUG_PRINT(DEBUG_FT,("<%s ",entry->psfile)); } else if (posencname = newword((char**)&pos,end); DEBUG_PRINT(DEBUG_FT,("<[%s ",entry->encname)); } else { /* encname=word; DEBUG_PRINT(DEBUG_FT,("<[%s ",entry->encname)); } else { /* psfile=word; DEBUG_PRINT(DEBUG_FT,("<%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,("\"")); while(pos < end && *pos!='"') { word=newword((char**)&pos,end); while(pos < end && (*pos==' ' || *pos=='\t')) pos++; if (pos+10ft_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 DEBUG_PRINT(DEBUG_FT,("\" ")); pos++; } else { /* bare word */ switch (++nameno) { case 1: /* first word is tfmname and perhaps psname, NOT psfile */ while(postfmname; break; case 2: /* second word is psname, NOT psfile */ psname = newword((char**)&pos,end); DEBUG_PRINT(DEBUG_FT,("(%s) ",psname)); free(psname); break; case 3: /* third word is encoding */ entry->encname = newword((char**)&pos,end); DEBUG_PRINT(DEBUG_FT,("<[%s ",entry->encname)); break; default: while(pospsfile==NULL) { /* No psfile-name given, use tfmname */ entry->psfile=copyword(entry->tfmname); DEBUG_PRINT(DEBUG_FT,(" <%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); }