3 % Copyright
2005-2006 Han The Thanh
<thanh@@pdftex.org
>
4 % Copyright
2006-2008 Taco Hoekwater
<taco@@luatex.org
>
6 % This file is part of LuaTeX.
8 % LuaTeX is free software
; you can redistribute it and
/or modify it under
9 % the terms of the GNU General Public License as published by the Free
10 % Software Foundation
; either version
2 of the License
, or
(at your
11 % option
) any later version.
13 % LuaTeX is distributed in the hope that it will be useful
, but WITHOUT
14 % ANY WARRANTY
; without even the implied warranty of MERCHANTABILITY or
15 % FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 % License for more details.
18 % You should have received a copy of the GNU General Public License along
19 % with LuaTeX
; if not
, see
<http
://www.gnu.org
/licenses
/>.
28 static struct avl_table
*sfd_tree
= NULL;
30 static unsigned char
*sfd_buffer
= NULL;
31 static int sfd_size
= 0;
32 static int sfd_curbyte
= 0;
34 #define SFD_BUF_SIZE SMALL_BUF_SIZE
36 #define sfd_close
() xfclose
(sfd_file
, cur_file_name
)
37 #define sfd_open
(a
) (sfd_file
= fopen
((char
*)(a
), FOPEN_RBIN_MODE
))
39 #define sfd_read_file
() readbinfile
(sfd_file
,&sfd_buffer,&sfd_size)
40 #define sfd_getchar
() sfd_buffer
[sfd_curbyte
++]
41 #define sfd_eof
() (sfd_curbyte
>=sfd_size
)
44 static
FILE *sfd_file
;
45 static char sfd_line
[SFD_BUF_SIZE
];
47 static subfont_entry
*new_subfont_entry
(void
)
50 subfont_entry
*subfont
;
51 subfont
= xtalloc
(1, subfont_entry
);
52 subfont-
>infix
= NULL;
53 for
(i
= 0; i
< 256; ++i
)
54 subfont-
>charcodes
[i
] = -1; /* unassigned
*/
59 static sfd_entry
*new_sfd_entry
(void
)
62 sfd
= xtalloc
(1, sfd_entry
);
68 static void destroy_sfd_entry
(void
*pa
, void
*pb
)
72 sfd
= (sfd_entry
*) pa
;
84 static int comp_sfd_entry
(const void
*pa
, const void
*pb
, void
*p
)
87 return strcmp
(((const sfd_entry
*) pa
)->name
,
88 ((const sfd_entry
*) pb
)->name
);
94 avl_destroy
(sfd_tree
, destroy_sfd_entry
);
97 static void sfd_getline
(boolean expect_eof
)
104 if
(*sfd_line
== '#'
)
108 normal_error
("sub font","unexpected end of file");
112 c
= (char
) sfd_getchar
();
113 append_char_to_buf
(c
, p
, sfd_line
, SFD_BUF_SIZE
);
114 } while
(c
!= 10 && !sfd_eof());
115 append_eol
(p
, sfd_line
, SFD_BUF_SIZE
);
116 if
(p
- sfd_line
< 2 ||
*sfd_line
== '#'
)
121 static sfd_entry
*read_sfd
(char
*sfd_name
)
124 sfd_entry
*sfd
, tmp_sfd
;
127 char buf
[SMALL_BUF_SIZE
], *p
;
132 /* check whether this sfd has been read
*/
133 tmp_sfd.name
= sfd_name
;
134 if
(sfd_tree
== NULL) {
135 sfd_tree
= avl_create
(comp_sfd_entry
, NULL, &avl_xallocator);
136 assert
(sfd_tree
!= NULL);
138 sfd
= (sfd_entry
*) avl_find
(sfd_tree
, &tmp_sfd);
145 cur_file_name
= luatex_find_file
(sfd_name
, find_sfd_file_callback
);
147 callback_id
= callback_defined
(read_sfd_file_callback
);
148 if
(callback_id
> 0) {
149 if
(!(run_callback
(callback_id
, "S->bSd", cur_file_name
, &file_opened, &sfd_buffer, &sfd_size) &&
150 file_opened
&& sfd_size > 0)) {
151 formatted_warning
("ttf font","cannot open SFD file for reading '%s'", cur_file_name
);
152 cur_file_name
= NULL;
156 if
(!sfd_open
(cur_file_name
)) {
157 formatted_warning
("ttf font", "cannot open SFD file for reading '%s'", cur_file_name
);
158 cur_file_name
= NULL;
166 tex_printf
("%s", cur_file_name
);
167 sfd
= new_sfd_entry
();
168 sfd-
>name
= xstrdup
(sfd_name
);
171 if
(*sfd_line
== 10) /* empty line indicating eof
*/
173 sf
= new_subfont_entry
();
174 sf-
>next
= sfd-
>subfont
;
176 sscanf
(sfd_line
, "%s %n", buf
, &n);
177 sf-
>infix
= xstrdup
(buf
);
178 p
= sfd_line
+ n
; /* skip to the next word
*/
182 if
(*p
== '\\'
) { /* continue on next line
*/
186 } else if
(*p
== 0) /* end of subfont
*/
188 if
(sscanf
(p
, " %li %n", &i, &n) == 0)
189 formatted_error
("sub font","invalid token: %s", p
);
191 if
(*p
== '
:'
) { /* offset
*/
194 } else if
(*p
== '_'
) { /* range
*/
195 if
(sscanf
(p
+ 1, " %li %n", &j, &n) == 0)
196 formatted_error
("sub font","invalid token: %s", p
);
197 if
(i
> j || k
+ (j
- i
) > 255)
198 formatted_error
("sub font","invalid range: %s", p
);
200 sf-
>charcodes
[k
++] = i
++;
202 } else
/* codepoint
*/
203 sf-
>charcodes
[k
++] = i
;
207 aa
= avl_probe
(sfd_tree
, sfd
);
213 boolean handle_subfont_fm
(fm_entry
* fm
, int mode
)
220 char buf
[SMALL_BUF_SIZE
];
221 assert
(fm-
>tfm_name
!= NULL);
223 q
= strchr
(p
, '@@'
); /* search for the first '@@'
*/
226 r
= strchr
(q
+ 1, '@@'
); /* search for the second '@@'
*/
229 if
(q
<= p || r
<= q
+ 1 /* prefix or sfd name is empty
*/
230 || r
- p
!= (int
) strlen
(p
) - 1) /* or the second '@@' is not the last char yet
*/
232 l
= (size_t
) (r
- (q
+ 1)); /* length of sfd name
*/
233 strncpy
(buf
, q
+ 1, l
);
235 check_buf
(strlen
(buf
) + 4, SMALL_BUF_SIZE
);
240 /* at this point we know fm is a subfont
*/
243 /* set default values for PidEid
*/
248 l
= (size_t
) (q
- p
); /* length of base tfm name
(prefix
) */
249 for
(sf
= sfd-
>subfont
; sf
!= NULL; sf
= sf-
>next
) {
252 strcat
(buf
, sf-
>infix
);
253 fm2
= new_fm_entry
();
254 fm2-
>tfm_name
= xstrdup
(buf
);
255 fm2-
>ff_name
= xstrdup
(fm-
>ff_name
);
256 fm2-
>type
= fm-
>type
;
260 if
(avl_do_entry
(fm2
, mode
) != 0) /* try to insert the entry
*/
261 delete_fm_entry
(fm2
); /* delete it if failed
*/