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