1 /* sfd.c */
2 
3 /************************************************************************
4 
5   Part of the dvipng distribution
6 
7   This program is free software: you can redistribute it and/or modify
8   it under the terms of the GNU Lesser General Public License as
9   published by the Free Software Foundation, either version 3 of the
10   License, or (at your option) any later version.
11 
12   This program is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   Lesser General Public License for more details.
16 
17   You should have received a copy of the GNU Lesser General Public
18   License along with this program. If not, see
19   <http://www.gnu.org/licenses/>.
20 
21   Copyright (C) 2002-2008 Jan-�ke Larsson
22 
23 ************************************************************************/
24 
25 #include "dvipng.h"
26 struct subfont* subfontp=NULL;
27 
ReadSubfont(char * sfdname,char * infix)28 static struct subfont* ReadSubfont(char* sfdname, char *infix)
29 {
30   char *pos,*max,*sfdfile=NULL;
31   struct subfont* sfdp=NULL;
32   struct filemmap fmmap;
33   boolean mmapfailed;
34 
35   /* OK, find subfont and look for correct infix */
36 #ifdef HAVE_KPSE_ENC_FORMATS
37   sfdfile=kpse_find_file(sfdname,kpse_sfd_format,false);
38 #endif
39   if (sfdfile == NULL) {
40     Warning("subfont file %s could not be found",sfdname);
41     return(NULL);
42   }
43   DEBUG_PRINT((DEBUG_FT|DEBUG_ENC),("\n  OPEN SUBFONT:\t'%s'", sfdfile));
44   mmapfailed = MmapFile(sfdfile,&fmmap);
45   free(sfdfile);
46   if (mmapfailed)
47     return(NULL);
48   pos=fmmap.data;
49   max=fmmap.data+fmmap.size;
50   while(pos<max && (*pos==' ' || *pos=='\r' || *pos=='\n' || *pos=='\t')) pos++;
51   while (pos<max && *pos=='#') {
52     while(pos<max && *pos!='\r' && *pos!='\n') pos++;
53     while(pos<max && (*pos==' ' || *pos=='\r' || *pos=='\n' || *pos=='\t')) pos++;
54   }
55   while(pos+strlen(infix)<max
56 	&& (strncmp(pos,infix,strlen(infix))!=0
57 	    || (pos[strlen(infix)]!=' ' && pos[strlen(infix)]!='\t'))) {
58     /* skip lines, taking line continuation into account */
59     while(pos+1<max && (*(pos+1)!='\r' || *(pos+1)!='\n' || *pos=='\\'))
60       pos++;
61     pos++;
62     while(pos<max && (*pos==' ' || *pos=='\r' || *pos=='\n' || *pos=='\t')) pos++;
63     while (pos<max && *pos=='#') {
64       while(pos<max && *pos!='\r' && *pos!='\n') pos++;
65       while(pos<max && (*pos==' ' || *pos=='\r' || *pos=='\n' || *pos=='\t')) pos++;
66     }
67   }
68   pos=pos+strlen(infix);
69   if (pos<max) {
70     int number,range,codepoint=0;
71 
72     if ((sfdp = calloc(sizeof(struct subfont)+strlen(sfdname)+1
73 		       +strlen(infix)+1,1))==NULL) {
74       Warning("cannot allocate memory for subfont",sfdname);
75       UnMmapFile(&fmmap);
76       return(NULL);
77     }
78     sfdp->name=(char*)sfdp+sizeof(struct subfont);
79     strcpy(sfdp->name,sfdname);
80     sfdp->infix=(char*)sfdp+sizeof(struct subfont)+strlen(sfdname)+1;
81     strcpy(sfdp->infix,infix);
82     sfdp->encoding=FT_ENCODING_UNICODE;
83     while (pos<max && *pos != '\r' && *pos != '\n') {
84       number=strtol(pos,&pos,0);
85       while(pos<max && (*pos==' ' || *pos=='\t')) pos++;
86       switch(*pos) {
87       case ':':
88 	codepoint=number;
89 	pos++;
90 	break;
91       case '_':
92 	range=strtol(pos+1,&pos,0);
93 	while(codepoint<256 && number<range) {
94 	  sfdp->charindex[codepoint]=number;
95 	  DEBUG_PRINT(DEBUG_ENC,("\n  SUBFONT MAP %d %d",codepoint,number));
96 	  number++;
97 	  codepoint++;
98 	}
99       default:
100 	if (codepoint<256)
101 	  sfdp->charindex[codepoint]=number;
102 	DEBUG_PRINT(DEBUG_ENC,("\n  SUBFONT MAP %d %d",codepoint,number));
103       }
104       while(pos<max && (*pos==' ' || *pos=='\t')) pos++;
105       /* take line continuation into account */
106       while(pos+1<max && *pos=='\\' && (*(pos+1)=='\r' || *(pos+1)=='\n')) {
107 	if (pos+2<max && *(pos+1)=='\r' && *(pos+2)=='\n') pos++;
108 	pos+=2;
109 	while(pos<max && (*pos==' ' || *pos=='\t')) pos++;
110       }
111     }
112   }
113   return (sfdp);
114 }
115 
FindSubFont(struct psfontmap * entry,char * fontname)116 struct psfontmap* FindSubFont(struct psfontmap* entry, char* fontname)
117 {
118   struct subfont *temp=subfontp;
119   char *sfdspec=entry->tfmname,*sfdwant=fontname,
120     *sfdname,*infix,*postfix;
121 
122   while (*sfdspec!='\0' && *sfdspec==*sfdwant) {
123     sfdspec++;
124     sfdwant++;
125   }
126   /* Find delimiter */
127   if (*sfdspec!='@')
128     return(NULL);
129   sfdspec++;
130   postfix=sfdspec;
131   while (*postfix!='\0' && *postfix!='@')
132     postfix++;
133   if (*postfix!='@')
134     return(NULL);
135   /* Extract subfont name */
136   if ((sfdname=malloc(postfix-sfdspec+1))==NULL)
137     Fatal("cannot allocate memory for subfont name");
138   strncpy(sfdname,sfdspec,postfix-sfdspec);
139   sfdname[postfix-sfdspec]='\0';
140   /* Check postfix */
141   postfix++;
142   if (strcmp(sfdwant+strlen(sfdwant)-strlen(postfix),postfix)!=0)
143     return(NULL);
144   /* Extract infix */
145   if ((infix=malloc(strlen(sfdwant)-strlen(postfix)+1))==NULL)
146     Fatal("cannot allocate memory for subfont infix");
147   strncpy(infix,sfdwant,strlen(sfdwant)-strlen(postfix));
148   infix[strlen(sfdwant)-strlen(postfix)]='\0';
149   DEBUG_PRINT(DEBUG_ENC,("\n  SUBFONT %s %s %s",fontname,sfdname,infix));
150   /* Find subfont */
151   while(temp!=NULL
152 	&& (strcmp(sfdname,temp->name)!=0 || strcmp(infix,temp->infix)!=0))
153     temp=temp->next;
154   if (temp==NULL) {
155     temp=ReadSubfont(sfdname,infix);
156     if (temp!=NULL) {
157       temp->next=subfontp;
158       subfontp=temp;
159     }
160   }
161   entry=NewPSFont(entry);
162   if (entry!=NULL) {
163     entry->tfmname=copyword(fontname);
164     entry->subfont=temp;
165   }
166   free(infix);
167   free(sfdname);
168   return(entry);
169 }
170 
ClearSubfont(void)171 void ClearSubfont(void)
172 {
173   struct subfont *temp=subfontp;
174 
175   while(temp!=NULL) {
176     subfontp=subfontp->next;
177     free(temp);
178     temp=subfontp;
179   }
180 }
181